OSDN Git Service

From "Serge Nikulin" <nikulin@actsw.amat.com>:
[pf3gnuchains/pf3gnuchains3x.git] / gdb / m68k-tdep.c
1 /* Target dependent code for the Motorola 68000 series.
2    Copyright (C) 1990, 1992, 1993, 1994, 1995, 1996, 1999, 2000
3    Free Software Foundation, Inc.
4
5    This file is part of GDB.
6
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.
11
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.
16
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.  */
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"
28 #include "inferior.h"
29 \f
30
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
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
46 extern CORE_ADDR
47 altos_skip_prologue (pc)
48      CORE_ADDR pc;
49 {
50   register int op = read_memory_integer (pc, 2);
51   if (op == P_LINKW_FP)
52     pc += 4;                    /* Skip link #word */
53   else if (op == P_LINKL_FP)
54     pc += 6;                    /* Skip link #long */
55   /* Not sure why branches are here.  */
56   /* From tm-isi.h, tm-altos.h */
57   else if (op == 0060000)
58     pc += 4;                    /* Skip bra #word */
59   else if (op == 00600377)
60     pc += 6;                    /* skip bra #long */
61   else if ((op & 0177400) == 0060000)
62     pc += 2;                    /* skip bra #char */
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
69 extern CORE_ADDR
70 isi_skip_prologue (pc)
71      CORE_ADDR pc;
72 {
73   register int op = read_memory_integer (pc, 2);
74   if (op == P_LINKW_FP)
75     pc += 4;                    /* Skip link #word */
76   else if (op == P_LINKL_FP)
77     pc += 6;                    /* Skip link #long */
78   /* Not sure why branches are here.  */
79   /* From tm-isi.h, tm-altos.h */
80   else if (op == 0060000)
81     pc += 4;                    /* Skip bra #word */
82   else if (op == 00600377)
83     pc += 6;                    /* skip bra #long */
84   else if ((op & 0177400) == 0060000)
85     pc += 2;                    /* skip bra #char */
86   return pc;
87 }
88
89 int
90 delta68_in_sigtramp (pc, name)
91      CORE_ADDR pc;
92      char *name;
93 {
94   if (name != NULL)
95     return strcmp (name, "_sigcode") == 0;
96   else
97     return 0;
98 }
99
100 CORE_ADDR
101 delta68_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
120 CORE_ADDR
121 delta68_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
127 /* Return number of args passed to a frame.
128    Can return -1, meaning no way to tell.  */
129
130 int
131 isi_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;
138   if (insn == 0047757 || insn == 0157374)       /* lea W(sp),sp or addaw #W,sp */
139     val = read_memory_integer (pc + 2, 2);
140   else if ((insn & 0170777) == 0050217  /* addql #N, sp */
141            || (insn & 0170777) == 0050117)      /* addqw */
142     {
143       val = (insn >> 9) & 7;
144       if (val == 0)
145         val = 8;
146     }
147   else if (insn == 0157774)     /* addal #WW, sp */
148     val = read_memory_integer (pc + 2, 4);
149   val >>= 2;
150   return val;
151 }
152
153 int
154 delta68_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;
161   if (insn == 0047757 || insn == 0157374)       /* lea W(sp),sp or addaw #W,sp */
162     val = read_memory_integer (pc + 2, 2);
163   else if ((insn & 0170777) == 0050217  /* addql #N, sp */
164            || (insn & 0170777) == 0050117)      /* addqw */
165     {
166       val = (insn >> 9) & 7;
167       if (val == 0)
168         val = 8;
169     }
170   else if (insn == 0157774)     /* addal #WW, sp */
171     val = read_memory_integer (pc + 2, 4);
172   val >>= 2;
173   return val;
174 }
175
176 int
177 news_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;
184   if (insn == 0047757 || insn == 0157374)       /* lea W(sp),sp or addaw #W,sp */
185     val = read_memory_integer (pc + 2, 2);
186   else if ((insn & 0170777) == 0050217  /* addql #N, sp */
187            || (insn & 0170777) == 0050117)      /* addqw */
188     {
189       val = (insn >> 9) & 7;
190       if (val == 0)
191         val = 8;
192     }
193   else if (insn == 0157774)     /* addal #WW, sp */
194     val = read_memory_integer (pc + 2, 4);
195   val >>= 2;
196   return val;
197 }
198
199 /* Push an empty stack frame, to record the current PC, etc.  */
200
201 void
202 m68k_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
231 void
232 m68k_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);
242   for (regnum = FP0_REGNUM + 7; regnum >= FP0_REGNUM; regnum--)
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     }
250   for (regnum = FP_REGNUM - 1; regnum >= 0; regnum--)
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 }
266 \f
267
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
279    link.w       %a6,&0                  4e56  XXXX
280
281    A link instruction, long form:
282
283    link.l  %fp,&F%1             480e  XXXX  XXXX
284
285    A movm instruction to preserve integer regs:
286
287    movm.l  &M%1,(4,%sp)         48ef  XXXX  XXXX
288
289    A fmovm instruction to preserve float regs:
290
291    fmovm   &FPM%1,(FPO%1,%sp)   f237  XXXX  XXXX  XXXX  XXXX
292
293    Some profiling setup code (FIXME, not recognized yet):
294
295    lea.l   (.L3,%pc),%a1                43fb  XXXX  XXXX  XXXX
296    bsr     _mcount                      61ff  XXXX  XXXX
297
298  */
299
300 CORE_ADDR
301 m68k_skip_prologue (ip)
302      CORE_ADDR ip;
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);
312   limit = (sal.end) ? sal.end : (CORE_ADDR) ~ 0;
313
314   while (ip < limit)
315     {
316       op = read_memory_integer (ip, 2);
317       op &= 0xFFFF;
318
319       if (op == P_LINKW_FP)
320         ip += 4;                /* Skip link.w */
321       else if (op == P_PEA_FP)
322         ip += 2;                /* Skip pea %fp */
323       else if (op == P_MOVL_SP_FP)
324         ip += 2;                /* Skip move.l %sp, %fp */
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 */
329       else if (op == P_FMOVM)
330         ip += 10;               /* Skip fmovm */
331       else
332         break;          /* Found unknown code, bail out. */
333     }
334   return (ip);
335 }
336
337 void
338 m68k_find_saved_regs (frame_info, saved_regs)
339      struct frame_info *frame_info;
340      struct frame_saved_regs *saved_regs;
341 {
342   register int regnum;
343   register int regmask;
344   register CORE_ADDR next_addr;
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 =
349   (frame_info)->frame - CALL_DUMMY_LENGTH - FP_REGNUM * 4 - 4 - 8 * 12;
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
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.  */
361
362       next_addr = (frame_info)->frame;
363       pc = possible_call_dummy_start;
364     }
365   else
366     {
367       pc = get_pc_function_start ((frame_info)->pc);
368
369       nextinsn = read_memory_integer (pc, 2);
370       if (P_PEA_FP == nextinsn
371           && P_MOVL_SP_FP == read_memory_integer (pc + 2, 2))
372         {
373           /* pea %fp
374              move.l %sp, %fp */
375           next_addr = frame_info->frame;
376           pc += 4;
377         }
378       else if (P_LINKL_FP == nextinsn)
379         /* link.l %fp */
380         /* Find the address above the saved   
381            regs using the amount of storage from the link instruction.  */
382         {
383           next_addr = (frame_info)->frame + read_memory_integer (pc + 2, 4);
384           pc += 6;
385         }
386       else if (P_LINKW_FP == nextinsn)
387         /* link.w %fp */
388         /* Find the address above the saved   
389            regs using the amount of storage from the link instruction.  */
390         {
391           next_addr = (frame_info)->frame + read_memory_integer (pc + 2, 2);
392           pc += 4;
393         }
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     }
401
402   for ( ; ; )
403     {
404       nextinsn = 0xffff & read_memory_integer (pc, 2);
405       regmask = read_memory_integer (pc + 2, 2);
406       /* fmovemx to -(sp) */
407       if (0xf227 == nextinsn && (regmask & 0xff00) == 0xe000)
408         {
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;
470           saved_regs->regs[regnum] = (next_addr -= 4);
471           pc += 2;
472         }
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;
493     }
494 lose:;
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;
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
506 #ifdef USE_PROC_FS              /* Target dependent support for /proc */
507
508 #include <sys/procfs.h>
509
510 /*  The /proc interface divides the target machine's register set up into
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.
514
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:
519
520    typedef int gregset_t[18];
521
522    #define      R_D0    0
523    ...
524    #define      R_PS    17
525
526    and the floating point set by:
527
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;
534
535    These routines provide the packing and unpacking of gregset_t and
536    fpregset_t formatted data.
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 *),
547    unpack the register contents and supply them as gdb's idea of the current
548    register values. */
549
550 void
551 supply_gregset (gregsetp)
552      gregset_t *gregsetp;
553 {
554   register int regi;
555   register greg_t *regp = (greg_t *) gregsetp;
556
557   for (regi = 0; regi < R_PC; regi++)
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
565 void
566 fill_gregset (gregsetp, regno)
567      gregset_t *gregsetp;
568      int regno;
569 {
570   register int regi;
571   register greg_t *regp = (greg_t *) gregsetp;
572
573   for (regi = 0; regi < R_PC; regi++)
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
593    (fpregset_t *), unpack the register contents and supply them as gdb's
594    idea of the current floating point register values. */
595
596 void
597 supply_fpregset (fpregsetp)
598      fpregset_t *fpregsetp;
599 {
600   register int regi;
601   char *from;
602
603   for (regi = FP0_REGNUM; regi < FPC_REGNUM; regi++)
604     {
605       from = (char *) &(fpregsetp->f_fpregs[regi - FP0_REGNUM][0]);
606       supply_register (regi, from);
607     }
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));
611 }
612
613 /*  Given a pointer to a floating point register set in /proc format
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. */
617
618 void
619 fill_fpregset (fpregsetp, regno)
620      fpregset_t *fpregsetp;
621      int regno;
622 {
623   int regi;
624   char *to;
625   char *from;
626
627   for (regi = FP0_REGNUM; regi < FPC_REGNUM; regi++)
628     {
629       if ((regno == -1) || (regno == regi))
630         {
631           from = (char *) &registers[REGISTER_BYTE (regi)];
632           to = (char *) &(fpregsetp->f_fpregs[regi - FP0_REGNUM][0]);
633           memcpy (to, from, REGISTER_RAW_SIZE (regi));
634         }
635     }
636   if ((regno == -1) || (regno == FPC_REGNUM))
637     {
638       fpregsetp->f_pcr = *(int *) &registers[REGISTER_BYTE (FPC_REGNUM)];
639     }
640   if ((regno == -1) || (regno == FPS_REGNUM))
641     {
642       fpregsetp->f_psr = *(int *) &registers[REGISTER_BYTE (FPS_REGNUM)];
643     }
644   if ((regno == -1) || (regno == FPI_REGNUM))
645     {
646       fpregsetp->f_fpiaddr = *(int *) &registers[REGISTER_BYTE (FPI_REGNUM)];
647     }
648 }
649
650 #endif /* defined (FP0_REGNUM) */
651
652 #endif /* USE_PROC_FS */
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
660 int
661 get_longjmp_target (pc)
662      CORE_ADDR *pc;
663 {
664   char buf[TARGET_PTR_BIT / TARGET_CHAR_BIT];
665   CORE_ADDR sp, jb_addr;
666
667   sp = read_register (SP_REGNUM);
668
669   if (target_read_memory (sp + SP_ARG0,         /* Offset of first arg on stack */
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
691 CORE_ADDR
692 m68k_saved_pc_after_call (frame)
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
707
708 void
709 _initialize_m68k_tdep ()
710 {
711   tm_print_insn = print_insn_m68k;
712 }