2002-06-19 Pierre Muller <muller@ics.u-strasbg.fr>
[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 {
b5d78d39
GS
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;
89c3b6d3
PDM
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 {
b5d78d39
GS
229 write_register (PS_REGNUM,
230 read_memory_integer (fsr.regs[PS_REGNUM], 4));
c906108c
SS
231 }
232 write_register (FP_REGNUM, read_memory_integer (fp, 4));
233 write_register (PC_REGNUM, read_memory_integer (fp + 4, 4));
234 write_register (SP_REGNUM, fp + 8);
235 flush_cached_frames ();
236}
c906108c 237\f
c5aa993b 238
c906108c
SS
239/* Given an ip value corresponding to the start of a function,
240 return the ip of the first instruction after the function
241 prologue. This is the generic m68k support. Machines which
242 require something different can override the SKIP_PROLOGUE
243 macro to point elsewhere.
244
245 Some instructions which typically may appear in a function
246 prologue include:
247
248 A link instruction, word form:
249
c5aa993b 250 link.w %a6,&0 4e56 XXXX
c906108c
SS
251
252 A link instruction, long form:
253
c5aa993b 254 link.l %fp,&F%1 480e XXXX XXXX
c906108c
SS
255
256 A movm instruction to preserve integer regs:
257
c5aa993b 258 movm.l &M%1,(4,%sp) 48ef XXXX XXXX
c906108c
SS
259
260 A fmovm instruction to preserve float regs:
261
c5aa993b 262 fmovm &FPM%1,(FPO%1,%sp) f237 XXXX XXXX XXXX XXXX
c906108c
SS
263
264 Some profiling setup code (FIXME, not recognized yet):
265
c5aa993b
JM
266 lea.l (.L3,%pc),%a1 43fb XXXX XXXX XXXX
267 bsr _mcount 61ff XXXX XXXX
c906108c 268
c5aa993b 269 */
c906108c 270
c906108c 271CORE_ADDR
fba45db2 272m68k_skip_prologue (CORE_ADDR ip)
c906108c
SS
273{
274 register CORE_ADDR limit;
275 struct symtab_and_line sal;
276 register int op;
277
278 /* Find out if there is a known limit for the extent of the prologue.
279 If so, ensure we don't go past it. If not, assume "infinity". */
280
281 sal = find_pc_line (ip, 0);
b5d78d39 282 limit = (sal.end) ? sal.end : (CORE_ADDR) ~0;
c906108c
SS
283
284 while (ip < limit)
285 {
286 op = read_memory_integer (ip, 2);
287 op &= 0xFFFF;
c5aa993b 288
89c3b6d3
PDM
289 if (op == P_LINKW_FP)
290 ip += 4; /* Skip link.w */
291 else if (op == P_PEA_FP)
c5aa993b 292 ip += 2; /* Skip pea %fp */
89c3b6d3 293 else if (op == P_MOVL_SP_FP)
c5aa993b 294 ip += 2; /* Skip move.l %sp, %fp */
89c3b6d3
PDM
295 else if (op == P_LINKL_FP)
296 ip += 6; /* Skip link.l */
297 else if (op == P_MOVML)
298 ip += 6; /* Skip movm.l */
c906108c 299 else if (op == P_FMOVM)
89c3b6d3 300 ip += 10; /* Skip fmovm */
c906108c 301 else
b5d78d39 302 break; /* Found unknown code, bail out. */
c906108c
SS
303 }
304 return (ip);
305}
306
307void
fba45db2
KB
308m68k_find_saved_regs (struct frame_info *frame_info,
309 struct frame_saved_regs *saved_regs)
c906108c 310{
c5aa993b
JM
311 register int regnum;
312 register int regmask;
313 register CORE_ADDR next_addr;
c906108c
SS
314 register CORE_ADDR pc;
315
316 /* First possible address for a pc in a call dummy for this frame. */
317 CORE_ADDR possible_call_dummy_start =
b5d78d39 318 (frame_info)->frame - CALL_DUMMY_LENGTH - FP_REGNUM * 4 - 4 - 8 * 12;
c906108c
SS
319
320 int nextinsn;
321 memset (saved_regs, 0, sizeof (*saved_regs));
322 if ((frame_info)->pc >= possible_call_dummy_start
323 && (frame_info)->pc <= (frame_info)->frame)
324 {
325
326 /* It is a call dummy. We could just stop now, since we know
c5aa993b
JM
327 what the call dummy saves and where. But this code proceeds
328 to parse the "prologue" which is part of the call dummy.
329 This is needlessly complex and confusing. FIXME. */
c906108c
SS
330
331 next_addr = (frame_info)->frame;
332 pc = possible_call_dummy_start;
333 }
c5aa993b 334 else
c906108c 335 {
c5aa993b 336 pc = get_pc_function_start ((frame_info)->pc);
c906108c 337
89c3b6d3
PDM
338 nextinsn = read_memory_integer (pc, 2);
339 if (P_PEA_FP == nextinsn
340 && P_MOVL_SP_FP == read_memory_integer (pc + 2, 2))
c906108c 341 {
89c3b6d3 342 /* pea %fp
c5aa993b 343 move.l %sp, %fp */
c906108c 344 next_addr = frame_info->frame;
89c3b6d3 345 pc += 4;
c906108c 346 }
89c3b6d3 347 else if (P_LINKL_FP == nextinsn)
c906108c
SS
348 /* link.l %fp */
349 /* Find the address above the saved
350 regs using the amount of storage from the link instruction. */
89c3b6d3
PDM
351 {
352 next_addr = (frame_info)->frame + read_memory_integer (pc + 2, 4);
353 pc += 6;
354 }
355 else if (P_LINKW_FP == nextinsn)
c906108c
SS
356 /* link.w %fp */
357 /* Find the address above the saved
358 regs using the amount of storage from the link instruction. */
89c3b6d3
PDM
359 {
360 next_addr = (frame_info)->frame + read_memory_integer (pc + 2, 2);
361 pc += 4;
362 }
c5aa993b
JM
363 else
364 goto lose;
365
366 /* If have an addal #-n, sp next, adjust next_addr. */
367 if ((0177777 & read_memory_integer (pc, 2)) == 0157774)
368 next_addr += read_memory_integer (pc += 2, 4), pc += 4;
369 }
c5aa993b 370
b5d78d39 371 for (;;)
c5aa993b 372 {
89c3b6d3 373 nextinsn = 0xffff & read_memory_integer (pc, 2);
c5aa993b 374 regmask = read_memory_integer (pc + 2, 2);
89c3b6d3
PDM
375 /* fmovemx to -(sp) */
376 if (0xf227 == nextinsn && (regmask & 0xff00) == 0xe000)
c906108c 377 {
89c3b6d3
PDM
378 /* Regmask's low bit is for register fp7, the first pushed */
379 for (regnum = FP0_REGNUM + 8; --regnum >= FP0_REGNUM; regmask >>= 1)
380 if (regmask & 1)
381 saved_regs->regs[regnum] = (next_addr -= 12);
382 pc += 4;
383 }
384 /* fmovemx to (fp + displacement) */
385 else if (0171056 == nextinsn && (regmask & 0xff00) == 0xf000)
386 {
387 register CORE_ADDR addr;
388
389 addr = (frame_info)->frame + read_memory_integer (pc + 4, 2);
390 /* Regmask's low bit is for register fp7, the first pushed */
391 for (regnum = FP0_REGNUM + 8; --regnum >= FP0_REGNUM; regmask >>= 1)
392 if (regmask & 1)
393 {
394 saved_regs->regs[regnum] = addr;
395 addr += 12;
396 }
397 pc += 6;
398 }
399 /* moveml to (sp) */
400 else if (0044327 == nextinsn)
401 {
402 /* Regmask's low bit is for register 0, the first written */
403 for (regnum = 0; regnum < 16; regnum++, regmask >>= 1)
404 if (regmask & 1)
405 {
406 saved_regs->regs[regnum] = next_addr;
407 next_addr += 4;
408 }
409 pc += 4;
410 }
411 /* moveml to (fp + displacement) */
412 else if (0044356 == nextinsn)
413 {
414 register CORE_ADDR addr;
415
416 addr = (frame_info)->frame + read_memory_integer (pc + 4, 2);
417 /* Regmask's low bit is for register 0, the first written */
418 for (regnum = 0; regnum < 16; regnum++, regmask >>= 1)
419 if (regmask & 1)
420 {
421 saved_regs->regs[regnum] = addr;
422 addr += 4;
423 }
424 pc += 6;
425 }
426 /* moveml to -(sp) */
427 else if (0044347 == nextinsn)
428 {
429 /* Regmask's low bit is for register 15, the first pushed */
430 for (regnum = 16; --regnum >= 0; regmask >>= 1)
431 if (regmask & 1)
432 saved_regs->regs[regnum] = (next_addr -= 4);
433 pc += 4;
434 }
435 /* movl r,-(sp) */
436 else if (0x2f00 == (0xfff0 & nextinsn))
437 {
438 regnum = 0xf & nextinsn;
c906108c 439 saved_regs->regs[regnum] = (next_addr -= 4);
89c3b6d3 440 pc += 2;
c906108c 441 }
89c3b6d3
PDM
442 /* fmovemx to index of sp */
443 else if (0xf236 == nextinsn && (regmask & 0xff00) == 0xf000)
444 {
445 /* Regmask's low bit is for register fp0, the first written */
446 for (regnum = FP0_REGNUM + 8; --regnum >= FP0_REGNUM; regmask >>= 1)
447 if (regmask & 1)
448 {
449 saved_regs->regs[regnum] = next_addr;
450 next_addr += 12;
451 }
452 pc += 10;
453 }
454 /* clrw -(sp); movw ccr,-(sp) */
455 else if (0x4267 == nextinsn && 0x42e7 == regmask)
456 {
457 saved_regs->regs[PS_REGNUM] = (next_addr -= 4);
458 pc += 4;
459 }
460 else
461 break;
c906108c 462 }
c5aa993b
JM
463lose:;
464 saved_regs->regs[SP_REGNUM] = (frame_info)->frame + 8;
465 saved_regs->regs[FP_REGNUM] = (frame_info)->frame;
466 saved_regs->regs[PC_REGNUM] = (frame_info)->frame + 4;
c906108c
SS
467#ifdef SIG_SP_FP_OFFSET
468 /* Adjust saved SP_REGNUM for fake _sigtramp frames. */
469 if (frame_info->signal_handler_caller && frame_info->next)
470 saved_regs->regs[SP_REGNUM] = frame_info->next->frame + SIG_SP_FP_OFFSET;
471#endif
472}
473
474
c5aa993b 475#ifdef USE_PROC_FS /* Target dependent support for /proc */
c906108c
SS
476
477#include <sys/procfs.h>
478
c60c0f5f
MS
479/* Prototypes for supply_gregset etc. */
480#include "gregset.h"
481
c906108c 482/* The /proc interface divides the target machine's register set up into
c5aa993b
JM
483 two different sets, the general register set (gregset) and the floating
484 point register set (fpregset). For each set, there is an ioctl to get
485 the current register set and another ioctl to set the current values.
c906108c 486
c5aa993b
JM
487 The actual structure passed through the ioctl interface is, of course,
488 naturally machine dependent, and is different for each set of registers.
489 For the m68k for example, the general register set is typically defined
490 by:
c906108c 491
c5aa993b 492 typedef int gregset_t[18];
c906108c 493
c5aa993b
JM
494 #define R_D0 0
495 ...
496 #define R_PS 17
c906108c 497
c5aa993b 498 and the floating point set by:
c906108c 499
c5aa993b
JM
500 typedef struct fpregset {
501 int f_pcr;
502 int f_psr;
503 int f_fpiaddr;
504 int f_fpregs[8][3]; (8 regs, 96 bits each)
505 } fpregset_t;
c906108c 506
c5aa993b
JM
507 These routines provide the packing and unpacking of gregset_t and
508 fpregset_t formatted data.
c906108c
SS
509
510 */
511
512/* Atari SVR4 has R_SR but not R_PS */
513
514#if !defined (R_PS) && defined (R_SR)
515#define R_PS R_SR
516#endif
517
518/* Given a pointer to a general register set in /proc format (gregset_t *),
c5aa993b
JM
519 unpack the register contents and supply them as gdb's idea of the current
520 register values. */
c906108c
SS
521
522void
fba45db2 523supply_gregset (gregset_t *gregsetp)
c906108c
SS
524{
525 register int regi;
526 register greg_t *regp = (greg_t *) gregsetp;
527
c5aa993b 528 for (regi = 0; regi < R_PC; regi++)
c906108c
SS
529 {
530 supply_register (regi, (char *) (regp + regi));
531 }
532 supply_register (PS_REGNUM, (char *) (regp + R_PS));
533 supply_register (PC_REGNUM, (char *) (regp + R_PC));
534}
535
536void
fba45db2 537fill_gregset (gregset_t *gregsetp, int regno)
c906108c
SS
538{
539 register int regi;
540 register greg_t *regp = (greg_t *) gregsetp;
c906108c 541
c5aa993b 542 for (regi = 0; regi < R_PC; regi++)
c906108c
SS
543 {
544 if ((regno == -1) || (regno == regi))
545 {
546 *(regp + regi) = *(int *) &registers[REGISTER_BYTE (regi)];
547 }
548 }
549 if ((regno == -1) || (regno == PS_REGNUM))
550 {
551 *(regp + R_PS) = *(int *) &registers[REGISTER_BYTE (PS_REGNUM)];
552 }
553 if ((regno == -1) || (regno == PC_REGNUM))
554 {
555 *(regp + R_PC) = *(int *) &registers[REGISTER_BYTE (PC_REGNUM)];
556 }
557}
558
559#if defined (FP0_REGNUM)
560
561/* Given a pointer to a floating point register set in /proc format
c5aa993b
JM
562 (fpregset_t *), unpack the register contents and supply them as gdb's
563 idea of the current floating point register values. */
c906108c 564
c5aa993b 565void
fba45db2 566supply_fpregset (fpregset_t *fpregsetp)
c906108c
SS
567{
568 register int regi;
569 char *from;
c5aa993b
JM
570
571 for (regi = FP0_REGNUM; regi < FPC_REGNUM; regi++)
c906108c 572 {
c5aa993b 573 from = (char *) &(fpregsetp->f_fpregs[regi - FP0_REGNUM][0]);
c906108c
SS
574 supply_register (regi, from);
575 }
c5aa993b
JM
576 supply_register (FPC_REGNUM, (char *) &(fpregsetp->f_pcr));
577 supply_register (FPS_REGNUM, (char *) &(fpregsetp->f_psr));
578 supply_register (FPI_REGNUM, (char *) &(fpregsetp->f_fpiaddr));
c906108c
SS
579}
580
581/* Given a pointer to a floating point register set in /proc format
c5aa993b
JM
582 (fpregset_t *), update the register specified by REGNO from gdb's idea
583 of the current floating point register set. If REGNO is -1, update
584 them all. */
c906108c
SS
585
586void
fba45db2 587fill_fpregset (fpregset_t *fpregsetp, int regno)
c906108c
SS
588{
589 int regi;
590 char *to;
591 char *from;
c906108c 592
c5aa993b 593 for (regi = FP0_REGNUM; regi < FPC_REGNUM; regi++)
c906108c
SS
594 {
595 if ((regno == -1) || (regno == regi))
596 {
597 from = (char *) &registers[REGISTER_BYTE (regi)];
c5aa993b 598 to = (char *) &(fpregsetp->f_fpregs[regi - FP0_REGNUM][0]);
c906108c
SS
599 memcpy (to, from, REGISTER_RAW_SIZE (regi));
600 }
601 }
602 if ((regno == -1) || (regno == FPC_REGNUM))
603 {
c5aa993b 604 fpregsetp->f_pcr = *(int *) &registers[REGISTER_BYTE (FPC_REGNUM)];
c906108c
SS
605 }
606 if ((regno == -1) || (regno == FPS_REGNUM))
607 {
c5aa993b 608 fpregsetp->f_psr = *(int *) &registers[REGISTER_BYTE (FPS_REGNUM)];
c906108c
SS
609 }
610 if ((regno == -1) || (regno == FPI_REGNUM))
611 {
c5aa993b 612 fpregsetp->f_fpiaddr = *(int *) &registers[REGISTER_BYTE (FPI_REGNUM)];
c906108c
SS
613 }
614}
615
c5aa993b 616#endif /* defined (FP0_REGNUM) */
c906108c 617
c5aa993b 618#endif /* USE_PROC_FS */
c906108c 619
c906108c
SS
620/* Figure out where the longjmp will land. Slurp the args out of the stack.
621 We expect the first arg to be a pointer to the jmp_buf structure from which
622 we extract the pc (JB_PC) that we will land at. The pc is copied into PC.
623 This routine returns true on success. */
624
2765b798
AC
625/* NOTE: cagney/2000-11-08: For this function to be fully multi-arched
626 the macro's JB_PC and JB_ELEMENT_SIZE would need to be moved into
627 the ``struct gdbarch_tdep'' object and then set on a target ISA/ABI
628 dependant basis. */
629
c906108c 630int
f4281f55 631m68k_get_longjmp_target (CORE_ADDR *pc)
c906108c 632{
2765b798 633#if defined (JB_PC) && defined (JB_ELEMENT_SIZE)
35fc8285 634 char *buf;
c906108c
SS
635 CORE_ADDR sp, jb_addr;
636
35fc8285 637 buf = alloca (TARGET_PTR_BIT / TARGET_CHAR_BIT);
c5aa993b 638 sp = read_register (SP_REGNUM);
c906108c 639
b5d78d39
GS
640 if (target_read_memory (sp + SP_ARG0, /* Offset of first arg on stack */
641 buf, TARGET_PTR_BIT / TARGET_CHAR_BIT))
c906108c
SS
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
152d9db6
GS
680/* Function: m68k_gdbarch_init
681 Initializer function for the m68k gdbarch vector.
682 Called by gdbarch. Sets up the gdbarch vector(s) for this target. */
683
684static struct gdbarch *
685m68k_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
686{
687 struct gdbarch_tdep *tdep = NULL;
688 struct gdbarch *gdbarch;
689
690 /* find a candidate among the list of pre-declared architectures. */
691 arches = gdbarch_list_lookup_by_info (arches, &info);
692 if (arches != NULL)
693 return (arches->gdbarch);
694
695#if 0
696 tdep = (struct gdbarch_tdep *) xmalloc (sizeof (struct gdbarch_tdep));
697#endif
698
699 gdbarch = gdbarch_alloc (&info, 0);
700
701 return gdbarch;
702}
703
704
705static void
706m68k_dump_tdep (struct gdbarch *current_gdbarch, struct ui_file *file)
707{
708
709}
2acceee2 710
c906108c 711void
fba45db2 712_initialize_m68k_tdep (void)
c906108c 713{
152d9db6 714 gdbarch_register (bfd_arch_m68k, m68k_gdbarch_init, m68k_dump_tdep);
c906108c
SS
715 tm_print_insn = print_insn_m68k;
716}
This page took 0.227892 seconds and 4 git commands to generate.