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