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