HPPA merge.
[deliverable/binutils-gdb.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 */
This page took 0.041067 seconds and 4 git commands to generate.