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