bcopy -> memcpy
[external/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., 675 Mass Ave, Cambridge, MA 02139, USA.  */
19
20 #include "defs.h"
21 #include "frame.h"
22 #include "symtab.h"
23
24 \f
25 /* Things needed for making the inferior call functions.
26    It seems like every m68k based machine has almost identical definitions
27    in the individual machine's configuration files.  Most other cpu types
28    (mips, i386, etc) have routines in their *-tdep.c files to handle this
29    for most configurations.  The m68k family should be able to do this as
30    well.  These macros can still be overridden when necessary.  */
31
32 /* Push an empty stack frame, to record the current PC, etc.  */
33
34 void
35 m68k_push_dummy_frame ()
36 {
37   register CORE_ADDR sp = read_register (SP_REGNUM);
38   register int regnum;
39   char raw_buffer[12];
40
41   sp = push_word (sp, read_register (PC_REGNUM));
42   sp = push_word (sp, read_register (FP_REGNUM));
43   write_register (FP_REGNUM, sp);
44 #if defined (HAVE_68881)
45   for (regnum = FP0_REGNUM + 7; regnum >= FP0_REGNUM; regnum--)
46     {
47       read_register_bytes (REGISTER_BYTE (regnum), raw_buffer, 12);
48       sp = push_bytes (sp, raw_buffer, 12);
49     }
50 #endif
51   for (regnum = FP_REGNUM - 1; regnum >= 0; regnum--)
52     {
53       sp = push_word (sp, read_register (regnum));
54     }
55   sp = push_word (sp, read_register (PS_REGNUM));
56   write_register (SP_REGNUM, sp);
57 }
58
59 /* Discard from the stack the innermost frame,
60    restoring all saved registers.  */
61
62 void
63 m68k_pop_frame ()
64 {
65   register FRAME frame = get_current_frame ();
66   register CORE_ADDR fp;
67   register int regnum;
68   struct frame_saved_regs fsr;
69   struct frame_info *fi;
70   char raw_buffer[12];
71
72   fi = get_frame_info (frame);
73   fp = fi -> frame;
74   get_frame_saved_regs (fi, &fsr);
75 #if defined (HAVE_68881)
76   for (regnum = FP0_REGNUM + 7 ; regnum >= FP0_REGNUM ; regnum--)
77     {
78       if (fsr.regs[regnum])
79         {
80           read_memory (fsr.regs[regnum], raw_buffer, 12);
81           write_register_bytes (REGISTER_BYTE (regnum), raw_buffer, 12);
82         }
83     }
84 #endif
85   for (regnum = FP_REGNUM - 1 ; regnum >= 0 ; regnum--)
86     {
87       if (fsr.regs[regnum])
88         {
89           write_register (regnum, read_memory_integer (fsr.regs[regnum], 4));
90         }
91     }
92   if (fsr.regs[PS_REGNUM])
93     {
94       write_register (PS_REGNUM, read_memory_integer (fsr.regs[PS_REGNUM], 4));
95     }
96   write_register (FP_REGNUM, read_memory_integer (fp, 4));
97   write_register (PC_REGNUM, read_memory_integer (fp + 4, 4));
98   write_register (SP_REGNUM, fp + 8);
99   flush_cached_frames ();
100   set_current_frame (create_new_frame (read_register (FP_REGNUM),
101                                        read_pc ()));
102 }
103
104 \f
105 /* Given an ip value corresponding to the start of a function,
106    return the ip of the first instruction after the function 
107    prologue.  This is the generic m68k support.  Machines which
108    require something different can override the SKIP_PROLOGUE
109    macro to point elsewhere.
110
111    Some instructions which typically may appear in a function
112    prologue include:
113
114    A link instruction, word form:
115
116         link.w  %a6,&0                  4e56  XXXX
117
118    A link instruction, long form:
119
120         link.l  %fp,&F%1                480e  XXXX  XXXX
121
122    A movm instruction to preserve integer regs:
123
124         movm.l  &M%1,(4,%sp)            48ef  XXXX  XXXX
125
126    A fmovm instruction to preserve float regs:
127
128         fmovm   &FPM%1,(FPO%1,%sp)      f237  XXXX  XXXX  XXXX  XXXX
129
130    Some profiling setup code (FIXME, not recognized yet):
131
132         lea.l   (.L3,%pc),%a1           43fb  XXXX  XXXX  XXXX
133         bsr     _mcount                 61ff  XXXX  XXXX
134
135   */
136
137 #define P_LINK_L        0x480e
138 #define P_LINK_W        0x4e56
139 #define P_MOV_L         0x207c
140 #define P_JSR           0x4eb9
141 #define P_BSR           0x61ff
142 #define P_LEA_L         0x43fb
143 #define P_MOVM_L        0x48ef
144 #define P_FMOVM         0xf237
145 #define P_TRAP          0x4e40
146
147 CORE_ADDR
148 m68k_skip_prologue (ip)
149 CORE_ADDR ip;
150 {
151   register CORE_ADDR limit;
152   struct symtab_and_line sal;
153   register int op;
154
155   /* Find out if there is a known limit for the extent of the prologue.
156      If so, ensure we don't go past it.  If not, assume "infinity". */
157
158   sal = find_pc_line (ip, 0);
159   limit = (sal.end) ? sal.end : (CORE_ADDR) ~0;
160
161   while (ip < limit)
162     {
163       op = read_memory_integer (ip, 2);
164       op &= 0xFFFF;
165       
166       if (op == P_LINK_W)
167         {
168           ip += 4;      /* Skip link.w */
169         }
170       else if (op == P_LINK_L)
171         {
172           ip += 6;      /* Skip link.l */
173         }
174       else if (op == P_MOVM_L)
175         {
176           ip += 6;      /* Skip movm.l */
177         }
178       else if (op == P_FMOVM)
179         {
180           ip += 10;     /* Skip fmovm */
181         }
182       else
183         {
184           break;        /* Found unknown code, bail out. */
185         }
186     }
187   return (ip);
188 }
189
190 void
191 m68k_find_saved_regs (frame_info, saved_regs)
192      struct frame_info *frame_info;
193      struct frame_saved_regs *saved_regs;
194 {
195   register int regnum;                                                  
196   register int regmask;                                                 
197   register CORE_ADDR next_addr;                                         
198   register CORE_ADDR pc;
199
200   /* First possible address for a pc in a call dummy for this frame.  */
201   CORE_ADDR possible_call_dummy_start =
202     (frame_info)->frame - CALL_DUMMY_LENGTH - FP_REGNUM*4 - 4
203 #if defined (HAVE_68881)
204       - 8*12
205 #endif
206         ;
207
208   int nextinsn;
209   memset (saved_regs, 0, sizeof (*saved_regs));
210   if ((frame_info)->pc >= possible_call_dummy_start
211       && (frame_info)->pc <= (frame_info)->frame)
212     {
213
214       /* It is a call dummy.  We could just stop now, since we know
215          what the call dummy saves and where.  But this code proceeds
216          to parse the "prologue" which is part of the call dummy.
217          This is needlessly complex, confusing, and also is the only
218          reason that the call dummy is customized based on HAVE_68881.
219          FIXME.  */
220
221       next_addr = (frame_info)->frame;
222       pc = possible_call_dummy_start;
223     }
224   else                                                                  
225     {
226       pc = get_pc_function_start ((frame_info)->pc);                    
227       /* Verify we have a link a6 instruction next;                     
228          if not we lose.  If we win, find the address above the saved   
229          regs using the amount of storage from the link instruction.  */
230       if (044016 == read_memory_integer (pc, 2))                        
231         next_addr = (frame_info)->frame + read_memory_integer (pc += 2, 4), pc+=4; 
232       else if (047126 == read_memory_integer (pc, 2))                   
233         next_addr = (frame_info)->frame + read_memory_integer (pc += 2, 2), pc+=2; 
234       else goto lose;                                                   
235       /* If have an addal #-n, sp next, adjust next_addr.  */           
236       if ((0177777 & read_memory_integer (pc, 2)) == 0157774)           
237         next_addr += read_memory_integer (pc += 2, 4), pc += 4;         
238     }                                                                   
239   regmask = read_memory_integer (pc + 2, 2);                            
240 #if defined (HAVE_68881)
241   /* Here can come an fmovem.  Check for it.  */                
242   nextinsn = 0xffff & read_memory_integer (pc, 2);                      
243   if (0xf227 == nextinsn                                                
244       && (regmask & 0xff00) == 0xe000)                                  
245     { pc += 4; /* Regmask's low bit is for register fp7, the first pushed */ 
246       for (regnum = FP0_REGNUM + 7; regnum >= FP0_REGNUM; regnum--, regmask >>= 1)              
247         if (regmask & 1)                                                
248           saved_regs->regs[regnum] = (next_addr -= 12);         
249       regmask = read_memory_integer (pc + 2, 2); }
250 #endif
251   /* next should be a moveml to (sp) or -(sp) or a movl r,-(sp) */      
252   if (0044327 == read_memory_integer (pc, 2))                           
253     { pc += 4; /* Regmask's low bit is for register 0, the first written */ 
254       for (regnum = 0; regnum < 16; regnum++, regmask >>= 1)            
255         if (regmask & 1)                                                
256           saved_regs->regs[regnum] = (next_addr += 4) - 4; }    
257   else if (0044347 == read_memory_integer (pc, 2))                      
258     {
259       pc += 4; /* Regmask's low bit is for register 15, the first pushed */ 
260       for (regnum = 15; regnum >= 0; regnum--, regmask >>= 1)           
261         if (regmask & 1)                                                
262           saved_regs->regs[regnum] = (next_addr -= 4);
263     }
264   else if (0x2f00 == (0xfff0 & read_memory_integer (pc, 2)))            
265     {
266       regnum = 0xf & read_memory_integer (pc, 2); pc += 2;              
267       saved_regs->regs[regnum] = (next_addr -= 4);
268       /* gcc, at least, may use a pair of movel instructions when saving
269          exactly 2 registers.  */
270       if (0x2f00 == (0xfff0 & read_memory_integer (pc, 2)))
271         {
272           regnum = 0xf & read_memory_integer (pc, 2);
273           pc += 2;
274           saved_regs->regs[regnum] = (next_addr -= 4);
275         }
276     }
277 #if defined (HAVE_68881)
278   /* fmovemx to index of sp may follow.  */                             
279   regmask = read_memory_integer (pc + 2, 2);                            
280   nextinsn = 0xffff & read_memory_integer (pc, 2);                      
281   if (0xf236 == nextinsn                                                
282       && (regmask & 0xff00) == 0xf000)                                  
283     { pc += 10; /* Regmask's low bit is for register fp0, the first written */ 
284       for (regnum = FP0_REGNUM + 7; regnum >= FP0_REGNUM; regnum--, regmask >>= 1)              
285         if (regmask & 1)                                                
286           saved_regs->regs[regnum] = (next_addr += 12) - 12;    
287       regmask = read_memory_integer (pc + 2, 2); }                      
288 #endif
289   /* clrw -(sp); movw ccr,-(sp) may follow.  */                         
290   if (0x426742e7 == read_memory_integer (pc, 4))                        
291     saved_regs->regs[PS_REGNUM] = (next_addr -= 4);             
292   lose: ;                                                               
293   saved_regs->regs[SP_REGNUM] = (frame_info)->frame + 8;                
294   saved_regs->regs[FP_REGNUM] = (frame_info)->frame;            
295   saved_regs->regs[PC_REGNUM] = (frame_info)->frame + 4;                
296 #ifdef SIG_SP_FP_OFFSET
297   /* Adjust saved SP_REGNUM for fake _sigtramp frames.  */
298   if (frame_info->signal_handler_caller && frame_info->next)
299     saved_regs->regs[SP_REGNUM] = frame_info->next->frame + SIG_SP_FP_OFFSET;
300 #endif
301 }
302
303
304 #ifdef USE_PROC_FS      /* Target dependent support for /proc */
305
306 #include <sys/procfs.h>
307
308 /*  The /proc interface divides the target machine's register set up into
309     two different sets, the general register set (gregset) and the floating
310     point register set (fpregset).  For each set, there is an ioctl to get
311     the current register set and another ioctl to set the current values.
312
313     The actual structure passed through the ioctl interface is, of course,
314     naturally machine dependent, and is different for each set of registers.
315     For the m68k for example, the general register set is typically defined
316     by:
317
318         typedef int gregset_t[18];
319
320         #define R_D0    0
321         ...
322         #define R_PS    17
323
324     and the floating point set by:
325
326         typedef struct fpregset {
327           int   f_pcr;
328           int   f_psr;
329           int   f_fpiaddr;
330           int   f_fpregs[8][3];         (8 regs, 96 bits each)
331         } fpregset_t;
332
333     These routines provide the packing and unpacking of gregset_t and
334     fpregset_t formatted data.
335
336  */
337
338
339 /*  Given a pointer to a general register set in /proc format (gregset_t *),
340     unpack the register contents and supply them as gdb's idea of the current
341     register values. */
342
343 void
344 supply_gregset (gregsetp)
345 gregset_t *gregsetp;
346 {
347   register int regi;
348   register greg_t *regp = (greg_t *) gregsetp;
349
350   for (regi = 0 ; regi < R_PC ; regi++)
351     {
352       supply_register (regi, (char *) (regp + regi));
353     }
354   supply_register (PS_REGNUM, (char *) (regp + R_PS));
355   supply_register (PC_REGNUM, (char *) (regp + R_PC));
356 }
357
358 void
359 fill_gregset (gregsetp, regno)
360 gregset_t *gregsetp;
361 int regno;
362 {
363   register int regi;
364   register greg_t *regp = (greg_t *) gregsetp;
365   extern char registers[];
366
367   for (regi = 0 ; regi < R_PC ; regi++)
368     {
369       if ((regno == -1) || (regno == regi))
370         {
371           *(regp + regi) = *(int *) &registers[REGISTER_BYTE (regi)];
372         }
373     }
374   if ((regno == -1) || (regno == PS_REGNUM))
375     {
376       *(regp + R_PS) = *(int *) &registers[REGISTER_BYTE (PS_REGNUM)];
377     }
378   if ((regno == -1) || (regno == PC_REGNUM))
379     {
380       *(regp + R_PC) = *(int *) &registers[REGISTER_BYTE (PC_REGNUM)];
381     }
382 }
383
384 #if defined (FP0_REGNUM)
385
386 /*  Given a pointer to a floating point register set in /proc format
387     (fpregset_t *), unpack the register contents and supply them as gdb's
388     idea of the current floating point register values. */
389
390 void 
391 supply_fpregset (fpregsetp)
392 fpregset_t *fpregsetp;
393 {
394   register int regi;
395   char *from;
396   
397   for (regi = FP0_REGNUM ; regi < FPC_REGNUM ; regi++)
398     {
399       from = (char *) &(fpregsetp -> f_fpregs[regi-FP0_REGNUM][0]);
400       supply_register (regi, from);
401     }
402   supply_register (FPC_REGNUM, (char *) &(fpregsetp -> f_pcr));
403   supply_register (FPS_REGNUM, (char *) &(fpregsetp -> f_psr));
404   supply_register (FPI_REGNUM, (char *) &(fpregsetp -> f_fpiaddr));
405 }
406
407 /*  Given a pointer to a floating point register set in /proc format
408     (fpregset_t *), update the register specified by REGNO from gdb's idea
409     of the current floating point register set.  If REGNO is -1, update
410     them all. */
411
412 void
413 fill_fpregset (fpregsetp, regno)
414 fpregset_t *fpregsetp;
415 int regno;
416 {
417   int regi;
418   char *to;
419   char *from;
420   extern char registers[];
421
422   for (regi = FP0_REGNUM ; regi < FPC_REGNUM ; regi++)
423     {
424       if ((regno == -1) || (regno == regi))
425         {
426           from = (char *) &registers[REGISTER_BYTE (regi)];
427           to = (char *) &(fpregsetp -> f_fpregs[regi-FP0_REGNUM][0]);
428           memcpy (to, from, REGISTER_RAW_SIZE (regi));
429         }
430     }
431   if ((regno == -1) || (regno == FPC_REGNUM))
432     {
433       fpregsetp -> f_pcr = *(int *) &registers[REGISTER_BYTE (FPC_REGNUM)];
434     }
435   if ((regno == -1) || (regno == FPS_REGNUM))
436     {
437       fpregsetp -> f_psr = *(int *) &registers[REGISTER_BYTE (FPS_REGNUM)];
438     }
439   if ((regno == -1) || (regno == FPI_REGNUM))
440     {
441       fpregsetp -> f_fpiaddr = *(int *) &registers[REGISTER_BYTE (FPI_REGNUM)];
442     }
443 }
444
445 #endif  /* defined (FP0_REGNUM) */
446
447 #endif  /* USE_PROC_FS */
448
449 #ifdef GET_LONGJMP_TARGET
450 /* Figure out where the longjmp will land.  Slurp the args out of the stack.
451    We expect the first arg to be a pointer to the jmp_buf structure from which
452    we extract the pc (JB_PC) that we will land at.  The pc is copied into PC.
453    This routine returns true on success. */
454
455 int
456 get_longjmp_target(pc)
457      CORE_ADDR *pc;
458 {
459   char buf[TARGET_PTR_BIT / TARGET_CHAR_BIT];
460   CORE_ADDR sp, jb_addr;
461
462   sp = read_register(SP_REGNUM);
463
464   if (target_read_memory (sp + SP_ARG0, /* Offset of first arg on stack */
465                           buf,
466                           TARGET_PTR_BIT / TARGET_CHAR_BIT))
467     return 0;
468
469   jb_addr = extract_address (buf, TARGET_PTR_BIT / TARGET_CHAR_BIT);
470
471   if (target_read_memory (jb_addr + JB_PC * JB_ELEMENT_SIZE, buf,
472                           TARGET_PTR_BIT / TARGET_CHAR_BIT))
473     return 0;
474
475   *pc = extract_address (buf, TARGET_PTR_BIT / TARGET_CHAR_BIT);
476
477   return 1;
478 }
479 #endif /* GET_LONGJMP_TARGET */
480
481 /* Immediately after a function call, return the saved pc before the frame
482    is setup.  For sun3's, we check for the common case of being inside of a
483    system call, and if so, we know that Sun pushes the call # on the stack
484    prior to doing the trap. */
485
486 CORE_ADDR
487 m68k_saved_pc_after_call(frame)
488      struct frame_info *frame;
489 {
490 #ifdef GDB_TARGET_IS_SUN3
491   int op;
492
493   op = read_memory_integer (frame->pc, 2);
494   op &= 0xFFFF;
495
496   if (op == P_TRAP)
497     return read_memory_integer (read_register (SP_REGNUM) + 4, 4);
498   else
499 #endif /* GDB_TARGET_IS_SUN3 */
500     return read_memory_integer (read_register (SP_REGNUM), 4);
501 }