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