]> Git Repo - binutils.git/blob - gdb/m68k-tdep.c
* m68k-tdep.c (P_LINKL_FP, P_LINKW_FP): Macros renamed from P_LINK_L
[binutils.git] / gdb / m68k-tdep.c
1 /* Target dependent code for the Motorola 68000 series.
2    Copyright (C) 1990, 1992 Free Software Foundation, Inc.
3
4    This file is part of GDB.
5
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.
10
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.
15
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.  */
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"
27 #include "inferior.h"
28 \f
29
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
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
45 extern CORE_ADDR
46 altos_skip_prologue (pc)
47      CORE_ADDR pc;
48 {
49   register int op = read_memory_integer (pc, 2);
50   if (op == P_LINKW_FP)
51     pc += 4;                    /* Skip link #word */
52   else if (op == P_LINKL_FP)
53     pc += 6;                    /* Skip link #long */
54   /* Not sure why branches are here.  */
55   /* From tm-isi.h, tm-altos.h */
56   else if (op == 0060000)
57     pc += 4;                    /* Skip bra #word */
58   else if (op == 00600377)
59     pc += 6;                    /* skip bra #long */
60   else if ((op & 0177400) == 0060000)
61     pc += 2;                    /* skip bra #char */
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
68 extern CORE_ADDR
69 isi_skip_prologue (pc)
70      CORE_ADDR pc;
71 {
72   register int op = read_memory_integer (pc, 2);
73   if (op == P_LINKW_FP)
74     pc += 4;                    /* Skip link #word */
75   else if (op == P_LINKL_FP)
76     pc += 6;                    /* Skip link #long */
77   /* Not sure why branches are here.  */
78   /* From tm-isi.h, tm-altos.h */
79   else if (op == 0060000)
80     pc += 4;                    /* Skip bra #word */
81   else if (op == 00600377)
82     pc += 6;                    /* skip bra #long */
83   else if ((op & 0177400) == 0060000)
84     pc += 2;                    /* skip bra #char */
85   return pc;
86 }
87
88 int
89 delta68_in_sigtramp (pc, name)
90      CORE_ADDR pc;
91      char *name;
92 {
93   return strcmp (name, "_sigcode") == 0;
94 }
95
96 CORE_ADDR
97 delta68_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
116 CORE_ADDR
117 delta68_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
123 /* Return number of args passed to a frame.
124    Can return -1, meaning no way to tell.  */
125
126 int
127 isi_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;
134   if (insn == 0047757 || insn == 0157374)       /* lea W(sp),sp or addaw #W,sp */
135     val = read_memory_integer (pc + 2, 2);
136   else if ((insn & 0170777) == 0050217  /* addql #N, sp */
137            || (insn & 0170777) == 0050117)      /* addqw */
138     {
139       val = (insn >> 9) & 7;
140       if (val == 0)
141         val = 8;
142     }
143   else if (insn == 0157774)     /* addal #WW, sp */
144     val = read_memory_integer (pc + 2, 4);
145   val >>= 2;
146   return val;
147 }
148
149 int
150 delta68_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;
157   if (insn == 0047757 || insn == 0157374)       /* lea W(sp),sp or addaw #W,sp */
158     val = read_memory_integer (pc + 2, 2);
159   else if ((insn & 0170777) == 0050217  /* addql #N, sp */
160            || (insn & 0170777) == 0050117)      /* addqw */
161     {
162       val = (insn >> 9) & 7;
163       if (val == 0)
164         val = 8;
165     }
166   else if (insn == 0157774)     /* addal #WW, sp */
167     val = read_memory_integer (pc + 2, 4);
168   val >>= 2;
169   return val;
170 }
171
172 int
173 news_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;
180   if (insn == 0047757 || insn == 0157374)       /* lea W(sp),sp or addaw #W,sp */
181     val = read_memory_integer (pc + 2, 2);
182   else if ((insn & 0170777) == 0050217  /* addql #N, sp */
183            || (insn & 0170777) == 0050117)      /* addqw */
184     {
185       val = (insn >> 9) & 7;
186       if (val == 0)
187         val = 8;
188     }
189   else if (insn == 0157774)     /* addal #WW, sp */
190     val = read_memory_integer (pc + 2, 4);
191   val >>= 2;
192   return val;
193 }
194
195 /* Push an empty stack frame, to record the current PC, etc.  */
196
197 void
198 m68k_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
227 void
228 m68k_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);
238   for (regnum = FP0_REGNUM + 7; regnum >= FP0_REGNUM; regnum--)
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     }
246   for (regnum = FP_REGNUM - 1; regnum >= 0; regnum--)
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 }
262 \f
263
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
275    link.w       %a6,&0                  4e56  XXXX
276
277    A link instruction, long form:
278
279    link.l  %fp,&F%1             480e  XXXX  XXXX
280
281    A movm instruction to preserve integer regs:
282
283    movm.l  &M%1,(4,%sp)         48ef  XXXX  XXXX
284
285    A fmovm instruction to preserve float regs:
286
287    fmovm   &FPM%1,(FPO%1,%sp)   f237  XXXX  XXXX  XXXX  XXXX
288
289    Some profiling setup code (FIXME, not recognized yet):
290
291    lea.l   (.L3,%pc),%a1                43fb  XXXX  XXXX  XXXX
292    bsr     _mcount                      61ff  XXXX  XXXX
293
294  */
295
296 CORE_ADDR
297 m68k_skip_prologue (ip)
298      CORE_ADDR ip;
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);
308   limit = (sal.end) ? sal.end : (CORE_ADDR) ~ 0;
309
310   while (ip < limit)
311     {
312       op = read_memory_integer (ip, 2);
313       op &= 0xFFFF;
314
315       if (op == P_LINKW_FP)
316         ip += 4;                /* Skip link.w */
317       else if (op == P_PEA_FP)
318         ip += 2;                /* Skip pea %fp */
319       else if (op == P_MOVL_SP_FP)
320         ip += 2;                /* Skip move.l %sp, %fp */
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 */
325       else if (op == P_FMOVM)
326         ip += 10;               /* Skip fmovm */
327       else
328         break;          /* Found unknown code, bail out. */
329     }
330   return (ip);
331 }
332
333 void
334 m68k_find_saved_regs (frame_info, saved_regs)
335      struct frame_info *frame_info;
336      struct frame_saved_regs *saved_regs;
337 {
338   register int regnum;
339   register int regmask;
340   register CORE_ADDR next_addr;
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 =
345   (frame_info)->frame - CALL_DUMMY_LENGTH - FP_REGNUM * 4 - 4 - 8 * 12;
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
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.  */
357
358       next_addr = (frame_info)->frame;
359       pc = possible_call_dummy_start;
360     }
361   else
362     {
363       pc = get_pc_function_start ((frame_info)->pc);
364
365       nextinsn = read_memory_integer (pc, 2);
366       if (P_PEA_FP == nextinsn
367           && P_MOVL_SP_FP == read_memory_integer (pc + 2, 2))
368         {
369           /* pea %fp
370              move.l %sp, %fp */
371           next_addr = frame_info->frame;
372           pc += 4;
373         }
374       else if (P_LINKL_FP == nextinsn)
375         /* link.l %fp */
376         /* Find the address above the saved   
377            regs using the amount of storage from the link instruction.  */
378         {
379           next_addr = (frame_info)->frame + read_memory_integer (pc + 2, 4);
380           pc += 6;
381         }
382       else if (P_LINKW_FP == nextinsn)
383         /* link.w %fp */
384         /* Find the address above the saved   
385            regs using the amount of storage from the link instruction.  */
386         {
387           next_addr = (frame_info)->frame + read_memory_integer (pc + 2, 2);
388           pc += 4;
389         }
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     }
397
398   for ( ; ; )
399     {
400       nextinsn = 0xffff & read_memory_integer (pc, 2);
401       regmask = read_memory_integer (pc + 2, 2);
402       /* fmovemx to -(sp) */
403       if (0xf227 == nextinsn && (regmask & 0xff00) == 0xe000)
404         {
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;
466           saved_regs->regs[regnum] = (next_addr -= 4);
467           pc += 2;
468         }
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;
489     }
490 lose:;
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;
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
502 #ifdef USE_PROC_FS              /* Target dependent support for /proc */
503
504 #include <sys/procfs.h>
505
506 /*  The /proc interface divides the target machine's register set up into
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.
510
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:
515
516    typedef int gregset_t[18];
517
518    #define      R_D0    0
519    ...
520    #define      R_PS    17
521
522    and the floating point set by:
523
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;
530
531    These routines provide the packing and unpacking of gregset_t and
532    fpregset_t formatted data.
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 *),
543    unpack the register contents and supply them as gdb's idea of the current
544    register values. */
545
546 void
547 supply_gregset (gregsetp)
548      gregset_t *gregsetp;
549 {
550   register int regi;
551   register greg_t *regp = (greg_t *) gregsetp;
552
553   for (regi = 0; regi < R_PC; regi++)
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
561 void
562 fill_gregset (gregsetp, regno)
563      gregset_t *gregsetp;
564      int regno;
565 {
566   register int regi;
567   register greg_t *regp = (greg_t *) gregsetp;
568
569   for (regi = 0; regi < R_PC; regi++)
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
589    (fpregset_t *), unpack the register contents and supply them as gdb's
590    idea of the current floating point register values. */
591
592 void
593 supply_fpregset (fpregsetp)
594      fpregset_t *fpregsetp;
595 {
596   register int regi;
597   char *from;
598
599   for (regi = FP0_REGNUM; regi < FPC_REGNUM; regi++)
600     {
601       from = (char *) &(fpregsetp->f_fpregs[regi - FP0_REGNUM][0]);
602       supply_register (regi, from);
603     }
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));
607 }
608
609 /*  Given a pointer to a floating point register set in /proc format
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. */
613
614 void
615 fill_fpregset (fpregsetp, regno)
616      fpregset_t *fpregsetp;
617      int regno;
618 {
619   int regi;
620   char *to;
621   char *from;
622
623   for (regi = FP0_REGNUM; regi < FPC_REGNUM; regi++)
624     {
625       if ((regno == -1) || (regno == regi))
626         {
627           from = (char *) &registers[REGISTER_BYTE (regi)];
628           to = (char *) &(fpregsetp->f_fpregs[regi - FP0_REGNUM][0]);
629           memcpy (to, from, REGISTER_RAW_SIZE (regi));
630         }
631     }
632   if ((regno == -1) || (regno == FPC_REGNUM))
633     {
634       fpregsetp->f_pcr = *(int *) &registers[REGISTER_BYTE (FPC_REGNUM)];
635     }
636   if ((regno == -1) || (regno == FPS_REGNUM))
637     {
638       fpregsetp->f_psr = *(int *) &registers[REGISTER_BYTE (FPS_REGNUM)];
639     }
640   if ((regno == -1) || (regno == FPI_REGNUM))
641     {
642       fpregsetp->f_fpiaddr = *(int *) &registers[REGISTER_BYTE (FPI_REGNUM)];
643     }
644 }
645
646 #endif /* defined (FP0_REGNUM) */
647
648 #endif /* USE_PROC_FS */
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
656 int
657 get_longjmp_target (pc)
658      CORE_ADDR *pc;
659 {
660   char buf[TARGET_PTR_BIT / TARGET_CHAR_BIT];
661   CORE_ADDR sp, jb_addr;
662
663   sp = read_register (SP_REGNUM);
664
665   if (target_read_memory (sp + SP_ARG0,         /* Offset of first arg on stack */
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
687 CORE_ADDR
688 m68k_saved_pc_after_call (frame)
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
703
704 void
705 _initialize_m68k_tdep ()
706 {
707   tm_print_insn = print_insn_m68k;
708 }
This page took 0.064339 seconds and 4 git commands to generate.