2000-05-22 H.J. Lu <hjl@gnu.org>
[deliverable/binutils-gdb.git] / gdb / m68k-tdep.c
CommitLineData
c906108c 1/* Target dependent code for the Motorola 68000 series.
a1de33a8
PDM
2 Copyright (C) 1990, 1992, 1993, 1994, 1995, 1996, 1999, 2000
3 Free Software Foundation, Inc.
c906108c 4
c5aa993b 5 This file is part of GDB.
c906108c 6
c5aa993b
JM
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
c906108c 11
c5aa993b
JM
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
c906108c 16
c5aa993b
JM
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 59 Temple Place - Suite 330,
20 Boston, MA 02111-1307, USA. */
c906108c
SS
21
22#include "defs.h"
23#include "frame.h"
24#include "symtab.h"
25#include "gdbcore.h"
26#include "value.h"
27#include "gdb_string.h"
7a292a7a 28#include "inferior.h"
c906108c 29\f
c5aa993b 30
89c3b6d3
PDM
31#define P_LINKL_FP 0x480e
32#define P_LINKW_FP 0x4e56
33#define P_PEA_FP 0x4856
34#define P_MOVL_SP_FP 0x2c4f
35#define P_MOVL 0x207c
36#define P_JSR 0x4eb9
37#define P_BSR 0x61ff
38#define P_LEAL 0x43fb
39#define P_MOVML 0x48ef
40#define P_FMOVM 0xf237
41#define P_TRAP 0x4e40
42
b83266a0
SS
43/* The only reason this is here is the tm-altos.h reference below. It
44 was moved back here from tm-m68k.h. FIXME? */
45
46extern CORE_ADDR
47altos_skip_prologue (pc)
48 CORE_ADDR pc;
49{
50 register int op = read_memory_integer (pc, 2);
89c3b6d3 51 if (op == P_LINKW_FP)
c5aa993b 52 pc += 4; /* Skip link #word */
89c3b6d3 53 else if (op == P_LINKL_FP)
c5aa993b 54 pc += 6; /* Skip link #long */
b83266a0
SS
55 /* Not sure why branches are here. */
56 /* From tm-isi.h, tm-altos.h */
57 else if (op == 0060000)
c5aa993b 58 pc += 4; /* Skip bra #word */
b83266a0 59 else if (op == 00600377)
c5aa993b 60 pc += 6; /* skip bra #long */
b83266a0 61 else if ((op & 0177400) == 0060000)
c5aa993b 62 pc += 2; /* skip bra #char */
b83266a0
SS
63 return pc;
64}
65
66/* The only reason this is here is the tm-isi.h reference below. It
67 was moved back here from tm-m68k.h. FIXME? */
68
69extern CORE_ADDR
70isi_skip_prologue (pc)
71 CORE_ADDR pc;
72{
73 register int op = read_memory_integer (pc, 2);
89c3b6d3 74 if (op == P_LINKW_FP)
c5aa993b 75 pc += 4; /* Skip link #word */
89c3b6d3 76 else if (op == P_LINKL_FP)
c5aa993b 77 pc += 6; /* Skip link #long */
b83266a0
SS
78 /* Not sure why branches are here. */
79 /* From tm-isi.h, tm-altos.h */
80 else if (op == 0060000)
c5aa993b 81 pc += 4; /* Skip bra #word */
b83266a0 82 else if (op == 00600377)
c5aa993b 83 pc += 6; /* skip bra #long */
b83266a0 84 else if ((op & 0177400) == 0060000)
c5aa993b 85 pc += 2; /* skip bra #char */
b83266a0
SS
86 return pc;
87}
88
89c3b6d3
PDM
89int
90delta68_in_sigtramp (pc, name)
91 CORE_ADDR pc;
92 char *name;
93{
1bd54964
AC
94 if (name != NULL)
95 return strcmp (name, "_sigcode") == 0;
96 else
97 return 0;
89c3b6d3
PDM
98}
99
100CORE_ADDR
101delta68_frame_args_address (frame_info)
102 struct frame_info * frame_info;
103{
104 /* we assume here that the only frameless functions are the system calls
105 or other functions who do not put anything on the stack. */
106 if (frame_info->signal_handler_caller)
107 return frame_info->frame + 12;
108 else if (frameless_look_for_prologue (frame_info))
109 {
110 /* Check for an interrupted system call */
111 if (frame_info->next && frame_info->next->signal_handler_caller)
112 return frame_info->next->frame + 16;
113 else
114 return frame_info->frame + 4;
115 }
116 else
117 return frame_info->frame;
118}
119
120CORE_ADDR
121delta68_frame_saved_pc (frame_info)
122 struct frame_info * frame_info;
123{
124 return read_memory_integer (delta68_frame_args_address (frame_info) + 4, 4);
125}
126
392a587b
JM
127/* Return number of args passed to a frame.
128 Can return -1, meaning no way to tell. */
129
130int
131isi_frame_num_args (fi)
132 struct frame_info *fi;
133{
134 int val;
135 CORE_ADDR pc = FRAME_SAVED_PC (fi);
136 int insn = 0177777 & read_memory_integer (pc, 2);
137 val = 0;
c5aa993b 138 if (insn == 0047757 || insn == 0157374) /* lea W(sp),sp or addaw #W,sp */
392a587b 139 val = read_memory_integer (pc + 2, 2);
c5aa993b
JM
140 else if ((insn & 0170777) == 0050217 /* addql #N, sp */
141 || (insn & 0170777) == 0050117) /* addqw */
392a587b
JM
142 {
143 val = (insn >> 9) & 7;
144 if (val == 0)
145 val = 8;
146 }
c5aa993b 147 else if (insn == 0157774) /* addal #WW, sp */
392a587b
JM
148 val = read_memory_integer (pc + 2, 4);
149 val >>= 2;
150 return val;
151}
152
153int
154delta68_frame_num_args (fi)
155 struct frame_info *fi;
156{
157 int val;
158 CORE_ADDR pc = FRAME_SAVED_PC (fi);
159 int insn = 0177777 & read_memory_integer (pc, 2);
160 val = 0;
c5aa993b 161 if (insn == 0047757 || insn == 0157374) /* lea W(sp),sp or addaw #W,sp */
392a587b 162 val = read_memory_integer (pc + 2, 2);
c5aa993b
JM
163 else if ((insn & 0170777) == 0050217 /* addql #N, sp */
164 || (insn & 0170777) == 0050117) /* addqw */
392a587b
JM
165 {
166 val = (insn >> 9) & 7;
167 if (val == 0)
168 val = 8;
169 }
c5aa993b 170 else if (insn == 0157774) /* addal #WW, sp */
392a587b
JM
171 val = read_memory_integer (pc + 2, 4);
172 val >>= 2;
173 return val;
174}
175
176int
177news_frame_num_args (fi)
178 struct frame_info *fi;
179{
180 int val;
181 CORE_ADDR pc = FRAME_SAVED_PC (fi);
182 int insn = 0177777 & read_memory_integer (pc, 2);
183 val = 0;
c5aa993b 184 if (insn == 0047757 || insn == 0157374) /* lea W(sp),sp or addaw #W,sp */
392a587b 185 val = read_memory_integer (pc + 2, 2);
c5aa993b
JM
186 else if ((insn & 0170777) == 0050217 /* addql #N, sp */
187 || (insn & 0170777) == 0050117) /* addqw */
392a587b
JM
188 {
189 val = (insn >> 9) & 7;
190 if (val == 0)
191 val = 8;
192 }
c5aa993b 193 else if (insn == 0157774) /* addal #WW, sp */
392a587b
JM
194 val = read_memory_integer (pc + 2, 4);
195 val >>= 2;
196 return val;
197}
b83266a0 198
c906108c
SS
199/* Push an empty stack frame, to record the current PC, etc. */
200
201void
202m68k_push_dummy_frame ()
203{
204 register CORE_ADDR sp = read_register (SP_REGNUM);
205 register int regnum;
206 char raw_buffer[12];
207
208 sp = push_word (sp, read_register (PC_REGNUM));
209 sp = push_word (sp, read_register (FP_REGNUM));
210 write_register (FP_REGNUM, sp);
211
212 /* Always save the floating-point registers, whether they exist on
213 this target or not. */
214 for (regnum = FP0_REGNUM + 7; regnum >= FP0_REGNUM; regnum--)
215 {
216 read_register_bytes (REGISTER_BYTE (regnum), raw_buffer, 12);
217 sp = push_bytes (sp, raw_buffer, 12);
218 }
219
220 for (regnum = FP_REGNUM - 1; regnum >= 0; regnum--)
221 {
222 sp = push_word (sp, read_register (regnum));
223 }
224 sp = push_word (sp, read_register (PS_REGNUM));
225 write_register (SP_REGNUM, sp);
226}
227
228/* Discard from the stack the innermost frame,
229 restoring all saved registers. */
230
231void
232m68k_pop_frame ()
233{
234 register struct frame_info *frame = get_current_frame ();
235 register CORE_ADDR fp;
236 register int regnum;
237 struct frame_saved_regs fsr;
238 char raw_buffer[12];
239
240 fp = FRAME_FP (frame);
241 get_frame_saved_regs (frame, &fsr);
c5aa993b 242 for (regnum = FP0_REGNUM + 7; regnum >= FP0_REGNUM; regnum--)
c906108c
SS
243 {
244 if (fsr.regs[regnum])
245 {
246 read_memory (fsr.regs[regnum], raw_buffer, 12);
247 write_register_bytes (REGISTER_BYTE (regnum), raw_buffer, 12);
248 }
249 }
c5aa993b 250 for (regnum = FP_REGNUM - 1; regnum >= 0; regnum--)
c906108c
SS
251 {
252 if (fsr.regs[regnum])
253 {
254 write_register (regnum, read_memory_integer (fsr.regs[regnum], 4));
255 }
256 }
257 if (fsr.regs[PS_REGNUM])
258 {
259 write_register (PS_REGNUM, read_memory_integer (fsr.regs[PS_REGNUM], 4));
260 }
261 write_register (FP_REGNUM, read_memory_integer (fp, 4));
262 write_register (PC_REGNUM, read_memory_integer (fp + 4, 4));
263 write_register (SP_REGNUM, fp + 8);
264 flush_cached_frames ();
265}
c906108c 266\f
c5aa993b 267
c906108c
SS
268/* Given an ip value corresponding to the start of a function,
269 return the ip of the first instruction after the function
270 prologue. This is the generic m68k support. Machines which
271 require something different can override the SKIP_PROLOGUE
272 macro to point elsewhere.
273
274 Some instructions which typically may appear in a function
275 prologue include:
276
277 A link instruction, word form:
278
c5aa993b 279 link.w %a6,&0 4e56 XXXX
c906108c
SS
280
281 A link instruction, long form:
282
c5aa993b 283 link.l %fp,&F%1 480e XXXX XXXX
c906108c
SS
284
285 A movm instruction to preserve integer regs:
286
c5aa993b 287 movm.l &M%1,(4,%sp) 48ef XXXX XXXX
c906108c
SS
288
289 A fmovm instruction to preserve float regs:
290
c5aa993b 291 fmovm &FPM%1,(FPO%1,%sp) f237 XXXX XXXX XXXX XXXX
c906108c
SS
292
293 Some profiling setup code (FIXME, not recognized yet):
294
c5aa993b
JM
295 lea.l (.L3,%pc),%a1 43fb XXXX XXXX XXXX
296 bsr _mcount 61ff XXXX XXXX
c906108c 297
c5aa993b 298 */
c906108c 299
c906108c
SS
300CORE_ADDR
301m68k_skip_prologue (ip)
c5aa993b 302 CORE_ADDR ip;
c906108c
SS
303{
304 register CORE_ADDR limit;
305 struct symtab_and_line sal;
306 register int op;
307
308 /* Find out if there is a known limit for the extent of the prologue.
309 If so, ensure we don't go past it. If not, assume "infinity". */
310
311 sal = find_pc_line (ip, 0);
c5aa993b 312 limit = (sal.end) ? sal.end : (CORE_ADDR) ~ 0;
c906108c
SS
313
314 while (ip < limit)
315 {
316 op = read_memory_integer (ip, 2);
317 op &= 0xFFFF;
c5aa993b 318
89c3b6d3
PDM
319 if (op == P_LINKW_FP)
320 ip += 4; /* Skip link.w */
321 else if (op == P_PEA_FP)
c5aa993b 322 ip += 2; /* Skip pea %fp */
89c3b6d3 323 else if (op == P_MOVL_SP_FP)
c5aa993b 324 ip += 2; /* Skip move.l %sp, %fp */
89c3b6d3
PDM
325 else if (op == P_LINKL_FP)
326 ip += 6; /* Skip link.l */
327 else if (op == P_MOVML)
328 ip += 6; /* Skip movm.l */
c906108c 329 else if (op == P_FMOVM)
89c3b6d3 330 ip += 10; /* Skip fmovm */
c906108c 331 else
89c3b6d3 332 break; /* Found unknown code, bail out. */
c906108c
SS
333 }
334 return (ip);
335}
336
337void
338m68k_find_saved_regs (frame_info, saved_regs)
339 struct frame_info *frame_info;
340 struct frame_saved_regs *saved_regs;
341{
c5aa993b
JM
342 register int regnum;
343 register int regmask;
344 register CORE_ADDR next_addr;
c906108c
SS
345 register CORE_ADDR pc;
346
347 /* First possible address for a pc in a call dummy for this frame. */
348 CORE_ADDR possible_call_dummy_start =
c5aa993b 349 (frame_info)->frame - CALL_DUMMY_LENGTH - FP_REGNUM * 4 - 4 - 8 * 12;
c906108c
SS
350
351 int nextinsn;
352 memset (saved_regs, 0, sizeof (*saved_regs));
353 if ((frame_info)->pc >= possible_call_dummy_start
354 && (frame_info)->pc <= (frame_info)->frame)
355 {
356
357 /* It is a call dummy. We could just stop now, since we know
c5aa993b
JM
358 what the call dummy saves and where. But this code proceeds
359 to parse the "prologue" which is part of the call dummy.
360 This is needlessly complex and confusing. FIXME. */
c906108c
SS
361
362 next_addr = (frame_info)->frame;
363 pc = possible_call_dummy_start;
364 }
c5aa993b 365 else
c906108c 366 {
c5aa993b 367 pc = get_pc_function_start ((frame_info)->pc);
c906108c 368
89c3b6d3
PDM
369 nextinsn = read_memory_integer (pc, 2);
370 if (P_PEA_FP == nextinsn
371 && P_MOVL_SP_FP == read_memory_integer (pc + 2, 2))
c906108c 372 {
89c3b6d3 373 /* pea %fp
c5aa993b 374 move.l %sp, %fp */
c906108c 375 next_addr = frame_info->frame;
89c3b6d3 376 pc += 4;
c906108c 377 }
89c3b6d3 378 else if (P_LINKL_FP == nextinsn)
c906108c
SS
379 /* link.l %fp */
380 /* Find the address above the saved
381 regs using the amount of storage from the link instruction. */
89c3b6d3
PDM
382 {
383 next_addr = (frame_info)->frame + read_memory_integer (pc + 2, 4);
384 pc += 6;
385 }
386 else if (P_LINKW_FP == nextinsn)
c906108c
SS
387 /* link.w %fp */
388 /* Find the address above the saved
389 regs using the amount of storage from the link instruction. */
89c3b6d3
PDM
390 {
391 next_addr = (frame_info)->frame + read_memory_integer (pc + 2, 2);
392 pc += 4;
393 }
c5aa993b
JM
394 else
395 goto lose;
396
397 /* If have an addal #-n, sp next, adjust next_addr. */
398 if ((0177777 & read_memory_integer (pc, 2)) == 0157774)
399 next_addr += read_memory_integer (pc += 2, 4), pc += 4;
400 }
c5aa993b 401
89c3b6d3 402 for ( ; ; )
c5aa993b 403 {
89c3b6d3 404 nextinsn = 0xffff & read_memory_integer (pc, 2);
c5aa993b 405 regmask = read_memory_integer (pc + 2, 2);
89c3b6d3
PDM
406 /* fmovemx to -(sp) */
407 if (0xf227 == nextinsn && (regmask & 0xff00) == 0xe000)
c906108c 408 {
89c3b6d3
PDM
409 /* Regmask's low bit is for register fp7, the first pushed */
410 for (regnum = FP0_REGNUM + 8; --regnum >= FP0_REGNUM; regmask >>= 1)
411 if (regmask & 1)
412 saved_regs->regs[regnum] = (next_addr -= 12);
413 pc += 4;
414 }
415 /* fmovemx to (fp + displacement) */
416 else if (0171056 == nextinsn && (regmask & 0xff00) == 0xf000)
417 {
418 register CORE_ADDR addr;
419
420 addr = (frame_info)->frame + read_memory_integer (pc + 4, 2);
421 /* Regmask's low bit is for register fp7, the first pushed */
422 for (regnum = FP0_REGNUM + 8; --regnum >= FP0_REGNUM; regmask >>= 1)
423 if (regmask & 1)
424 {
425 saved_regs->regs[regnum] = addr;
426 addr += 12;
427 }
428 pc += 6;
429 }
430 /* moveml to (sp) */
431 else if (0044327 == nextinsn)
432 {
433 /* Regmask's low bit is for register 0, the first written */
434 for (regnum = 0; regnum < 16; regnum++, regmask >>= 1)
435 if (regmask & 1)
436 {
437 saved_regs->regs[regnum] = next_addr;
438 next_addr += 4;
439 }
440 pc += 4;
441 }
442 /* moveml to (fp + displacement) */
443 else if (0044356 == nextinsn)
444 {
445 register CORE_ADDR addr;
446
447 addr = (frame_info)->frame + read_memory_integer (pc + 4, 2);
448 /* Regmask's low bit is for register 0, the first written */
449 for (regnum = 0; regnum < 16; regnum++, regmask >>= 1)
450 if (regmask & 1)
451 {
452 saved_regs->regs[regnum] = addr;
453 addr += 4;
454 }
455 pc += 6;
456 }
457 /* moveml to -(sp) */
458 else if (0044347 == nextinsn)
459 {
460 /* Regmask's low bit is for register 15, the first pushed */
461 for (regnum = 16; --regnum >= 0; regmask >>= 1)
462 if (regmask & 1)
463 saved_regs->regs[regnum] = (next_addr -= 4);
464 pc += 4;
465 }
466 /* movl r,-(sp) */
467 else if (0x2f00 == (0xfff0 & nextinsn))
468 {
469 regnum = 0xf & nextinsn;
c906108c 470 saved_regs->regs[regnum] = (next_addr -= 4);
89c3b6d3 471 pc += 2;
c906108c 472 }
89c3b6d3
PDM
473 /* fmovemx to index of sp */
474 else if (0xf236 == nextinsn && (regmask & 0xff00) == 0xf000)
475 {
476 /* Regmask's low bit is for register fp0, the first written */
477 for (regnum = FP0_REGNUM + 8; --regnum >= FP0_REGNUM; regmask >>= 1)
478 if (regmask & 1)
479 {
480 saved_regs->regs[regnum] = next_addr;
481 next_addr += 12;
482 }
483 pc += 10;
484 }
485 /* clrw -(sp); movw ccr,-(sp) */
486 else if (0x4267 == nextinsn && 0x42e7 == regmask)
487 {
488 saved_regs->regs[PS_REGNUM] = (next_addr -= 4);
489 pc += 4;
490 }
491 else
492 break;
c906108c 493 }
c5aa993b
JM
494lose:;
495 saved_regs->regs[SP_REGNUM] = (frame_info)->frame + 8;
496 saved_regs->regs[FP_REGNUM] = (frame_info)->frame;
497 saved_regs->regs[PC_REGNUM] = (frame_info)->frame + 4;
c906108c
SS
498#ifdef SIG_SP_FP_OFFSET
499 /* Adjust saved SP_REGNUM for fake _sigtramp frames. */
500 if (frame_info->signal_handler_caller && frame_info->next)
501 saved_regs->regs[SP_REGNUM] = frame_info->next->frame + SIG_SP_FP_OFFSET;
502#endif
503}
504
505
c5aa993b 506#ifdef USE_PROC_FS /* Target dependent support for /proc */
c906108c
SS
507
508#include <sys/procfs.h>
509
510/* The /proc interface divides the target machine's register set up into
c5aa993b
JM
511 two different sets, the general register set (gregset) and the floating
512 point register set (fpregset). For each set, there is an ioctl to get
513 the current register set and another ioctl to set the current values.
c906108c 514
c5aa993b
JM
515 The actual structure passed through the ioctl interface is, of course,
516 naturally machine dependent, and is different for each set of registers.
517 For the m68k for example, the general register set is typically defined
518 by:
c906108c 519
c5aa993b 520 typedef int gregset_t[18];
c906108c 521
c5aa993b
JM
522 #define R_D0 0
523 ...
524 #define R_PS 17
c906108c 525
c5aa993b 526 and the floating point set by:
c906108c 527
c5aa993b
JM
528 typedef struct fpregset {
529 int f_pcr;
530 int f_psr;
531 int f_fpiaddr;
532 int f_fpregs[8][3]; (8 regs, 96 bits each)
533 } fpregset_t;
c906108c 534
c5aa993b
JM
535 These routines provide the packing and unpacking of gregset_t and
536 fpregset_t formatted data.
c906108c
SS
537
538 */
539
540/* Atari SVR4 has R_SR but not R_PS */
541
542#if !defined (R_PS) && defined (R_SR)
543#define R_PS R_SR
544#endif
545
546/* Given a pointer to a general register set in /proc format (gregset_t *),
c5aa993b
JM
547 unpack the register contents and supply them as gdb's idea of the current
548 register values. */
c906108c
SS
549
550void
551supply_gregset (gregsetp)
c5aa993b 552 gregset_t *gregsetp;
c906108c
SS
553{
554 register int regi;
555 register greg_t *regp = (greg_t *) gregsetp;
556
c5aa993b 557 for (regi = 0; regi < R_PC; regi++)
c906108c
SS
558 {
559 supply_register (regi, (char *) (regp + regi));
560 }
561 supply_register (PS_REGNUM, (char *) (regp + R_PS));
562 supply_register (PC_REGNUM, (char *) (regp + R_PC));
563}
564
565void
566fill_gregset (gregsetp, regno)
c5aa993b
JM
567 gregset_t *gregsetp;
568 int regno;
c906108c
SS
569{
570 register int regi;
571 register greg_t *regp = (greg_t *) gregsetp;
c906108c 572
c5aa993b 573 for (regi = 0; regi < R_PC; regi++)
c906108c
SS
574 {
575 if ((regno == -1) || (regno == regi))
576 {
577 *(regp + regi) = *(int *) &registers[REGISTER_BYTE (regi)];
578 }
579 }
580 if ((regno == -1) || (regno == PS_REGNUM))
581 {
582 *(regp + R_PS) = *(int *) &registers[REGISTER_BYTE (PS_REGNUM)];
583 }
584 if ((regno == -1) || (regno == PC_REGNUM))
585 {
586 *(regp + R_PC) = *(int *) &registers[REGISTER_BYTE (PC_REGNUM)];
587 }
588}
589
590#if defined (FP0_REGNUM)
591
592/* Given a pointer to a floating point register set in /proc format
c5aa993b
JM
593 (fpregset_t *), unpack the register contents and supply them as gdb's
594 idea of the current floating point register values. */
c906108c 595
c5aa993b 596void
c906108c 597supply_fpregset (fpregsetp)
c5aa993b 598 fpregset_t *fpregsetp;
c906108c
SS
599{
600 register int regi;
601 char *from;
c5aa993b
JM
602
603 for (regi = FP0_REGNUM; regi < FPC_REGNUM; regi++)
c906108c 604 {
c5aa993b 605 from = (char *) &(fpregsetp->f_fpregs[regi - FP0_REGNUM][0]);
c906108c
SS
606 supply_register (regi, from);
607 }
c5aa993b
JM
608 supply_register (FPC_REGNUM, (char *) &(fpregsetp->f_pcr));
609 supply_register (FPS_REGNUM, (char *) &(fpregsetp->f_psr));
610 supply_register (FPI_REGNUM, (char *) &(fpregsetp->f_fpiaddr));
c906108c
SS
611}
612
613/* Given a pointer to a floating point register set in /proc format
c5aa993b
JM
614 (fpregset_t *), update the register specified by REGNO from gdb's idea
615 of the current floating point register set. If REGNO is -1, update
616 them all. */
c906108c
SS
617
618void
619fill_fpregset (fpregsetp, regno)
c5aa993b
JM
620 fpregset_t *fpregsetp;
621 int regno;
c906108c
SS
622{
623 int regi;
624 char *to;
625 char *from;
c906108c 626
c5aa993b 627 for (regi = FP0_REGNUM; regi < FPC_REGNUM; regi++)
c906108c
SS
628 {
629 if ((regno == -1) || (regno == regi))
630 {
631 from = (char *) &registers[REGISTER_BYTE (regi)];
c5aa993b 632 to = (char *) &(fpregsetp->f_fpregs[regi - FP0_REGNUM][0]);
c906108c
SS
633 memcpy (to, from, REGISTER_RAW_SIZE (regi));
634 }
635 }
636 if ((regno == -1) || (regno == FPC_REGNUM))
637 {
c5aa993b 638 fpregsetp->f_pcr = *(int *) &registers[REGISTER_BYTE (FPC_REGNUM)];
c906108c
SS
639 }
640 if ((regno == -1) || (regno == FPS_REGNUM))
641 {
c5aa993b 642 fpregsetp->f_psr = *(int *) &registers[REGISTER_BYTE (FPS_REGNUM)];
c906108c
SS
643 }
644 if ((regno == -1) || (regno == FPI_REGNUM))
645 {
c5aa993b 646 fpregsetp->f_fpiaddr = *(int *) &registers[REGISTER_BYTE (FPI_REGNUM)];
c906108c
SS
647 }
648}
649
c5aa993b 650#endif /* defined (FP0_REGNUM) */
c906108c 651
c5aa993b 652#endif /* USE_PROC_FS */
c906108c
SS
653
654#ifdef GET_LONGJMP_TARGET
655/* Figure out where the longjmp will land. Slurp the args out of the stack.
656 We expect the first arg to be a pointer to the jmp_buf structure from which
657 we extract the pc (JB_PC) that we will land at. The pc is copied into PC.
658 This routine returns true on success. */
659
660int
c5aa993b 661get_longjmp_target (pc)
c906108c
SS
662 CORE_ADDR *pc;
663{
664 char buf[TARGET_PTR_BIT / TARGET_CHAR_BIT];
665 CORE_ADDR sp, jb_addr;
666
c5aa993b 667 sp = read_register (SP_REGNUM);
c906108c 668
c5aa993b 669 if (target_read_memory (sp + SP_ARG0, /* Offset of first arg on stack */
c906108c
SS
670 buf,
671 TARGET_PTR_BIT / TARGET_CHAR_BIT))
672 return 0;
673
674 jb_addr = extract_address (buf, TARGET_PTR_BIT / TARGET_CHAR_BIT);
675
676 if (target_read_memory (jb_addr + JB_PC * JB_ELEMENT_SIZE, buf,
677 TARGET_PTR_BIT / TARGET_CHAR_BIT))
678 return 0;
679
680 *pc = extract_address (buf, TARGET_PTR_BIT / TARGET_CHAR_BIT);
681
682 return 1;
683}
684#endif /* GET_LONGJMP_TARGET */
685
686/* Immediately after a function call, return the saved pc before the frame
687 is setup. For sun3's, we check for the common case of being inside of a
688 system call, and if so, we know that Sun pushes the call # on the stack
689 prior to doing the trap. */
690
691CORE_ADDR
c5aa993b 692m68k_saved_pc_after_call (frame)
c906108c
SS
693 struct frame_info *frame;
694{
695#ifdef SYSCALL_TRAP
696 int op;
697
698 op = read_memory_integer (frame->pc - SYSCALL_TRAP_OFFSET, 2);
699
700 if (op == SYSCALL_TRAP)
701 return read_memory_integer (read_register (SP_REGNUM) + 4, 4);
702 else
703#endif /* SYSCALL_TRAP */
704 return read_memory_integer (read_register (SP_REGNUM), 4);
705}
706
2acceee2 707
c906108c
SS
708void
709_initialize_m68k_tdep ()
710{
711 tm_print_insn = print_insn_m68k;
712}
This page took 0.084013 seconds and 4 git commands to generate.