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