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