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