* Makefile.in (depend): Fix dependancy generation so that it does
[external/binutils.git] / gdb / m68k-tdep.c
1 /* Target dependent code for the Motorola 68000 series.
2    Copyright (C) 1990 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 "ieee-float.h"
22 #include "param.h"
23 #include "frame.h"
24 #include "symtab.h"
25
26 const struct ext_format ext_format_68881 = {
27 /* tot sbyte smask expbyte manbyte */
28    12, 0,    0x80, 0,1,    4,8          /* mc68881 */
29 };
30
31 \f
32 /* Things needed for making the inferior call functions.
33    It seems like every m68k based machine has almost identical definitions
34    in the individual machine's configuration files.  Most other cpu types
35    (mips, i386, etc) have routines in their *-tdep.c files to handle this
36    for most configurations.  The m68k family should be able to do this as
37    well.  These macros can still be overridden when necessary.  */
38
39 /* Push an empty stack frame, to record the current PC, etc.  */
40
41 void
42 m68k_push_dummy_frame ()
43 {
44   register CORE_ADDR sp = read_register (SP_REGNUM);
45   register int regnum;
46   char raw_buffer[12];
47
48   sp = push_word (sp, read_register (PC_REGNUM));
49   sp = push_word (sp, read_register (FP_REGNUM));
50   write_register (FP_REGNUM, sp);
51 #if defined (HAVE_68881)
52   for (regnum = FP0_REGNUM + 7; regnum >= FP0_REGNUM; regnum--)
53     {
54       read_register_bytes (REGISTER_BYTE (regnum), raw_buffer, 12);
55       sp = push_bytes (sp, raw_buffer, 12);
56     }
57 #endif
58   for (regnum = FP_REGNUM - 1; regnum >= 0; regnum--)
59     {
60       sp = push_word (sp, read_register (regnum));
61     }
62   sp = push_word (sp, read_register (PS_REGNUM));
63   write_register (SP_REGNUM, sp);
64 }
65
66 /* Discard from the stack the innermost frame,
67    restoring all saved registers.  */
68
69 void
70 m68k_pop_frame ()
71 {
72   register FRAME frame = get_current_frame ();
73   register CORE_ADDR fp;
74   register int regnum;
75   struct frame_saved_regs fsr;
76   struct frame_info *fi;
77   char raw_buffer[12];
78
79   fi = get_frame_info (frame);
80   fp = fi -> frame;
81   get_frame_saved_regs (fi, &fsr);
82 #if defined (HAVE_68881)
83   for (regnum = FP0_REGNUM + 7 ; regnum >= FP0_REGNUM ; regnum--)
84     {
85       if (fsr.regs[regnum])
86         {
87           read_memory (fsr.regs[regnum], raw_buffer, 12);
88           write_register_bytes (REGISTER_BYTE (regnum), raw_buffer, 12);
89         }
90     }
91 #endif
92   for (regnum = FP_REGNUM - 1 ; regnum >= 0 ; regnum--)
93     {
94       if (fsr.regs[regnum])
95         {
96           write_register (regnum, read_memory_integer (fsr.regs[regnum], 4));
97         }
98     }
99   if (fsr.regs[PS_REGNUM])
100     {
101       write_register (PS_REGNUM, read_memory_integer (fsr.regs[PS_REGNUM], 4));
102     }
103   write_register (FP_REGNUM, read_memory_integer (fp, 4));
104   write_register (PC_REGNUM, read_memory_integer (fp + 4, 4));
105   write_register (SP_REGNUM, fp + 8);
106   flush_cached_frames ();
107   set_current_frame (create_new_frame (read_register (FP_REGNUM),
108                                        read_pc ()));
109 }
110
111 \f
112 /* Given an ip value corresponding to the start of a function,
113    return the ip of the first instruction after the function 
114    prologue.  This is the generic m68k support.  Machines which
115    require something different can override the SKIP_PROLOGUE
116    macro to point elsewhere.
117
118    Some instructions which typically may appear in a function
119    prologue include:
120
121    A link instruction, word form:
122
123         link.w  %a6,&0                  4e56  XXXX
124
125    A link instruction, long form:
126
127         link.l  %fp,&F%1                480e  XXXX  XXXX
128
129    A movm instruction to preserve integer regs:
130
131         movm.l  &M%1,(4,%sp)            48ef  XXXX  XXXX
132
133    A fmovm instruction to preserve float regs:
134
135         fmovm   &FPM%1,(FPO%1,%sp)      f237  XXXX  XXXX  XXXX  XXXX
136
137    Some profiling setup code (FIXME, not recognized yet):
138
139         lea.l   (.L3,%pc),%a1           43fb  XXXX  XXXX  XXXX
140         bsr     _mcount                 61ff  XXXX  XXXX
141
142   */
143
144 #define P_LINK_L        0x480e
145 #define P_LINK_W        0x4e56
146 #define P_MOV_L         0x207c
147 #define P_JSR           0x4eb9
148 #define P_BSR           0x61ff
149 #define P_LEA_L         0x43fb
150 #define P_MOVM_L        0x48ef
151 #define P_FMOVM         0xf237
152
153 CORE_ADDR
154 m68k_skip_prologue (ip)
155 CORE_ADDR ip;
156 {
157   register CORE_ADDR limit;
158   struct symtab_and_line sal;
159   register int op;
160
161   /* Find out if there is a known limit for the extent of the prologue.
162      If so, ensure we don't go past it.  If not, assume "infinity". */
163
164   sal = find_pc_line (ip, 0);
165   limit = (sal.end) ? sal.end : (CORE_ADDR) ~0;
166
167   while (ip < limit)
168     {
169       op = read_memory_integer (ip, 2);
170       op &= 0xFFFF;
171       
172       if (op == P_LINK_W)
173         {
174           ip += 4;      /* Skip link.w */
175         }
176       else if (op == P_LINK_L)
177         {
178           ip += 6;      /* Skip link.l */
179         }
180       else if (op == P_MOVM_L)
181         {
182           ip += 6;      /* Skip movm.l */
183         }
184       else if (op == P_FMOVM)
185         {
186           ip += 10;     /* Skip fmovm */
187         }
188       else
189         {
190           break;        /* Found unknown code, bail out. */
191         }
192     }
193   return (ip);
194 }
195
196 #ifdef USE_PROC_FS      /* Target dependent support for /proc */
197
198 #include <sys/procfs.h>
199
200 /*  The /proc interface divides the target machine's register set up into
201     two different sets, the general register set (gregset) and the floating
202     point register set (fpregset).  For each set, there is an ioctl to get
203     the current register set and another ioctl to set the current values.
204
205     The actual structure passed through the ioctl interface is, of course,
206     naturally machine dependent, and is different for each set of registers.
207     For the m68k for example, the general register set is typically defined
208     by:
209
210         typedef int gregset_t[18];
211
212         #define R_D0    0
213         ...
214         #define R_PS    17
215
216     and the floating point set by:
217
218         typedef struct fpregset {
219           int   f_pcr;
220           int   f_psr;
221           int   f_fpiaddr;
222           int   f_fpregs[8][3];         (8 regs, 96 bits each)
223         } fpregset_t;
224
225     These routines provide the packing and unpacking of gregset_t and
226     fpregset_t formatted data.
227
228  */
229
230
231 /*  Given a pointer to a general register set in /proc format (gregset_t *),
232     unpack the register contents and supply them as gdb's idea of the current
233     register values. */
234
235 void
236 supply_gregset (gregsetp)
237 gregset_t *gregsetp;
238 {
239   register int regno;
240   register greg_t *regp = (greg_t *) gregsetp;
241
242   for (regno = 0 ; regno < R_PC ; regno++)
243     {
244       supply_register (regno, (char *) (regp + regno));
245     }
246   supply_register (PS_REGNUM, (char *) (regp + R_PS));
247   supply_register (PC_REGNUM, (char *) (regp + R_PC));
248 }
249
250 void
251 fill_gregset (gregsetp, regno)
252 gregset_t *gregsetp;
253 int regno;
254 {
255   int regi;
256   register greg_t *regp = (greg_t *) gregsetp;
257   extern char registers[];
258
259   for (regi = 0 ; regi < R_PC ; regi++)
260     {
261       if ((regno == -1) || (regno == regi))
262         {
263           *(regp + regno) = *(int *) &registers[REGISTER_BYTE (regi)];
264         }
265     }
266   if ((regno == -1) || (regno == PS_REGNUM))
267     {
268       *(regp + R_PS) = *(int *) &registers[REGISTER_BYTE (PS_REGNUM)];
269     }
270   if ((regno == -1) || (regno == PC_REGNUM))
271     {
272       *(regp + R_PC) = *(int *) &registers[REGISTER_BYTE (PC_REGNUM)];
273     }
274 }
275
276 #if defined (FP0_REGNUM)
277
278 /*  Given a pointer to a floating point register set in /proc format
279     (fpregset_t *), unpack the register contents and supply them as gdb's
280     idea of the current floating point register values. */
281
282 void 
283 supply_fpregset (fpregsetp)
284 fpregset_t *fpregsetp;
285 {
286   register int regno;
287   
288   for (regno = FP0_REGNUM ; regno < FPC_REGNUM ; regno++)
289     {
290       supply_register (regno, (char *) &(fpregsetp -> f_fpregs[regno][0]));
291     }
292   supply_register (FPC_REGNUM, (char *) &(fpregsetp -> f_pcr));
293   supply_register (FPS_REGNUM, (char *) &(fpregsetp -> f_psr));
294   supply_register (FPI_REGNUM, (char *) &(fpregsetp -> f_fpiaddr));
295 }
296
297 /*  Given a pointer to a floating point register set in /proc format
298     (fpregset_t *), update the register specified by REGNO from gdb's idea
299     of the current floating point register set.  If REGNO is -1, update
300     them all. */
301
302 void
303 fill_fpregset (fpregsetp, regno)
304 fpregset_t *fpregsetp;
305 int regno;
306 {
307   int regi;
308   char *to;
309   char *from;
310   extern char registers[];
311
312   for (regi = FP0_REGNUM ; regi < FPC_REGNUM ; regi++)
313     {
314       if ((regno == -1) || (regno == regi))
315         {
316           from = (char *) &registers[REGISTER_BYTE (regi)];
317           to = (char *) &(fpregsetp -> f_fpregs[regi][0]);
318           bcopy (from, to, REGISTER_RAW_SIZE (regno));
319         }
320     }
321   if ((regno == -1) || (regno == FPC_REGNUM))
322     {
323       fpregsetp -> f_pcr = *(int *) &registers[REGISTER_BYTE (FPC_REGNUM)];
324     }
325   if ((regno == -1) || (regno == FPS_REGNUM))
326     {
327       fpregsetp -> f_psr = *(int *) &registers[REGISTER_BYTE (FPS_REGNUM)];
328     }
329   if ((regno == -1) || (regno == FPI_REGNUM))
330     {
331       fpregsetp -> f_fpiaddr = *(int *) &registers[REGISTER_BYTE (FPI_REGNUM)];
332     }
333 }
334
335 #endif  /* defined (FP0_REGNUM) */
336
337 #endif  /* USE_PROC_FS */