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