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