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