2002-11-23 Andrew Cagney <ac131313@redhat.com>
[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"
5d3ed2e3 30#include "arch-utils.h"
c906108c 31\f
c5aa993b 32
89c3b6d3
PDM
33#define P_LINKL_FP 0x480e
34#define P_LINKW_FP 0x4e56
35#define P_PEA_FP 0x4856
36#define P_MOVL_SP_FP 0x2c4f
37#define P_MOVL 0x207c
38#define P_JSR 0x4eb9
39#define P_BSR 0x61ff
40#define P_LEAL 0x43fb
41#define P_MOVML 0x48ef
42#define P_FMOVM 0xf237
43#define P_TRAP 0x4e40
44
103a1597
GS
45
46/* Register numbers of various important registers.
47 Note that some of these values are "real" register numbers,
48 and correspond to the general registers of the machine,
49 and some are "phony" register numbers which are too large
50 to be actual register numbers as far as the user is concerned
51 but do serve to get the desired values when passed to read_register. */
52
53/* Note: Since they are used in files other than this (monitor files),
54 D0_REGNUM and A0_REGNUM are currently defined in tm-m68k.h. */
55
6300c360
GS
56enum
57{
103a1597 58 E_A1_REGNUM = 9,
6300c360
GS
59 E_FP_REGNUM = 14, /* Contains address of executing stack frame */
60 E_SP_REGNUM = 15, /* Contains address of top of stack */
61 E_PS_REGNUM = 16, /* Contains processor status */
62 E_PC_REGNUM = 17, /* Contains program counter */
103a1597
GS
63 E_FP0_REGNUM = 18, /* Floating point register 0 */
64 E_FPC_REGNUM = 26, /* 68881 control register */
65 E_FPS_REGNUM = 27, /* 68881 status register */
66 E_FPI_REGNUM = 28
6300c360
GS
67};
68
103a1597
GS
69#define REGISTER_BYTES_FP (16*4 + 8 + 8*12 + 3*4)
70#define REGISTER_BYTES_NOFP (16*4 + 8)
71
72#define NUM_FREGS (NUM_REGS-24)
73
74/* Offset from SP to first arg on stack at first instruction of a function */
75
76#define SP_ARG0 (1 * 4)
77
78/* This was determined by experimentation on hp300 BSD 4.3. Perhaps
79 it corresponds to some offset in /usr/include/sys/user.h or
80 something like that. Using some system include file would
81 have the advantage of probably being more robust in the face
82 of OS upgrades, but the disadvantage of being wrong for
83 cross-debugging. */
84
85#define SIG_PC_FP_OFFSET 530
86
87#define TARGET_M68K
88
89
90#if !defined (BPT_VECTOR)
91#define BPT_VECTOR 0xf
92#endif
93
94#if !defined (REMOTE_BPT_VECTOR)
95#define REMOTE_BPT_VECTOR 1
96#endif
97
98
7f8e7424
GS
99void m68k_frame_init_saved_regs (struct frame_info *frame_info);
100
103a1597
GS
101
102/* gdbarch_breakpoint_from_pc is set to m68k_local_breakpoint_from_pc
103 so m68k_remote_breakpoint_from_pc is currently not used. */
104
105const static unsigned char *
106m68k_remote_breakpoint_from_pc (CORE_ADDR *pcptr, int *lenptr)
107{
108 static unsigned char break_insn[] = {0x4e, (0x40 | REMOTE_BPT_VECTOR)};
109 *lenptr = sizeof (break_insn);
110 return break_insn;
111}
112
113const static unsigned char *
114m68k_local_breakpoint_from_pc (CORE_ADDR *pcptr, int *lenptr)
115{
116 static unsigned char break_insn[] = {0x4e, (0x40 | BPT_VECTOR)};
117 *lenptr = sizeof (break_insn);
118 return break_insn;
119}
120
121
942dc0e9 122static int
5ae5f592 123m68k_register_bytes_ok (long numbytes)
942dc0e9
GS
124{
125 return ((numbytes == REGISTER_BYTES_FP)
126 || (numbytes == REGISTER_BYTES_NOFP));
127}
128
5d3ed2e3
GS
129/* Number of bytes of storage in the actual machine representation
130 for register regnum. On the 68000, all regs are 4 bytes
131 except the floating point regs which are 12 bytes. */
132/* Note that the unsigned cast here forces the result of the
133 subtraction to very high positive values if regnum < FP0_REGNUM */
134
135static int
136m68k_register_raw_size (int regnum)
137{
138 return (((unsigned) (regnum) - FP0_REGNUM) < 8 ? 12 : 4);
139}
140
141/* Number of bytes of storage in the program's representation
142 for register regnum. On the 68000, all regs are 4 bytes
143 except the floating point regs which are 12-byte long doubles. */
144
145static int
146m68k_register_virtual_size (int regnum)
147{
148 return (((unsigned) (regnum) - FP0_REGNUM) < 8 ? 12 : 4);
149}
150
d85fe7f7
AS
151/* Return the GDB type object for the "standard" data type of data in
152 register N. This should be int for D0-D7, SR, FPCONTROL and
153 FPSTATUS, long double for FP0-FP7, and void pointer for all others
154 (A0-A7, PC, FPIADDR). Note, for registers which contain
155 addresses return pointer to void, not pointer to char, because we
156 don't want to attempt to print the string after printing the
157 address. */
5d3ed2e3
GS
158
159static struct type *
160m68k_register_virtual_type (int regnum)
161{
03dac896
AS
162 if (regnum >= FP0_REGNUM && regnum <= FP0_REGNUM + 7)
163 return builtin_type_m68881_ext;
164
165 if (regnum == E_FPI_REGNUM || regnum == PC_REGNUM)
166 return builtin_type_void_func_ptr;
167
168 if (regnum == E_FPC_REGNUM || regnum == E_FPS_REGNUM || regnum == PS_REGNUM)
169 return builtin_type_int32;
170
171 if (regnum >= A0_REGNUM && regnum <= A0_REGNUM + 7)
172 return builtin_type_void_data_ptr;
173
174 return builtin_type_int32;
5d3ed2e3
GS
175}
176
177/* Function: m68k_register_name
178 Returns the name of the standard m68k register regnum. */
179
180static const char *
181m68k_register_name (int regnum)
182{
183 static char *register_names[] = {
184 "d0", "d1", "d2", "d3", "d4", "d5", "d6", "d7",
185 "a0", "a1", "a2", "a3", "a4", "a5", "fp", "sp",
186 "ps", "pc",
187 "fp0", "fp1", "fp2", "fp3", "fp4", "fp5", "fp6", "fp7",
188 "fpcontrol", "fpstatus", "fpiaddr", "fpcode", "fpflags"
189 };
190
191 if (regnum < 0 ||
192 regnum >= sizeof (register_names) / sizeof (register_names[0]))
193 internal_error (__FILE__, __LINE__,
194 "m68k_register_name: illegal register number %d", regnum);
195 else
196 return register_names[regnum];
197}
198
199/* Stack must be kept short aligned when doing function calls. */
200
201static CORE_ADDR
202m68k_stack_align (CORE_ADDR addr)
203{
204 return ((addr + 1) & ~1);
205}
206
207/* Index within `registers' of the first byte of the space for
208 register regnum. */
209
210static int
211m68k_register_byte (int regnum)
212{
103a1597
GS
213 if (regnum >= E_FPC_REGNUM)
214 return (((regnum - E_FPC_REGNUM) * 4) + 168);
5d3ed2e3
GS
215 else if (regnum >= FP0_REGNUM)
216 return (((regnum - FP0_REGNUM) * 12) + 72);
217 else
218 return (regnum * 4);
219}
220
942dc0e9
GS
221/* Store the address of the place in which to copy the structure the
222 subroutine will return. This is called from call_function. */
223
224static void
225m68k_store_struct_return (CORE_ADDR addr, CORE_ADDR sp)
226{
103a1597 227 write_register (E_A1_REGNUM, addr);
942dc0e9
GS
228}
229
230/* Extract from an array regbuf containing the (raw) register state
231 a function return value of type type, and copy that, in virtual format,
232 into valbuf. This is assuming that floating point values are returned
233 as doubles in d0/d1. */
234
235static void
236m68k_deprecated_extract_return_value (struct type *type, char *regbuf,
237 char *valbuf)
238{
239 int offset = 0;
240 int typeLength = TYPE_LENGTH (type);
241
242 if (typeLength < 4)
243 offset = 4 - typeLength;
244
245 memcpy (valbuf, regbuf + offset, typeLength);
246}
247
248static CORE_ADDR
249m68k_deprecated_extract_struct_value_address (char *regbuf)
250{
251 return (*(CORE_ADDR *) (regbuf));
252}
253
254/* Write into appropriate registers a function return value
255 of type TYPE, given in virtual format. Assumes floats are passed
256 in d0/d1. */
257
258static void
259m68k_store_return_value (struct type *type, char *valbuf)
260{
73937e03 261 deprecated_write_register_bytes (0, valbuf, TYPE_LENGTH (type));
942dc0e9
GS
262}
263
264/* Describe the pointer in each stack frame to the previous stack frame
265 (its caller). */
266
267/* FRAME_CHAIN takes a frame's nominal address and produces the frame's
268 chain-pointer.
269 In the case of the 68000, the frame's nominal address
270 is the address of a 4-byte word containing the calling frame's address. */
271
272/* If we are chaining from sigtramp, then manufacture a sigtramp frame
273 (which isn't really on the stack. I'm not sure this is right for anything
274 but BSD4.3 on an hp300. */
275
276static CORE_ADDR
277m68k_frame_chain (struct frame_info *thisframe)
278{
5a203e44 279 if ((get_frame_type (thisframe) == SIGTRAMP_FRAME))
942dc0e9
GS
280 return thisframe->frame;
281 else if (!inside_entry_file ((thisframe)->pc))
282 return read_memory_integer ((thisframe)->frame, 4);
283 else
284 return 0;
285}
286
287/* A function that tells us whether the function invocation represented
288 by fi does not have a frame on the stack associated with it. If it
289 does not, FRAMELESS is set to 1, else 0. */
290
291static int
292m68k_frameless_function_invocation (struct frame_info *fi)
293{
5a203e44 294 if ((get_frame_type (fi) == SIGTRAMP_FRAME))
942dc0e9
GS
295 return 0;
296 else
297 return frameless_look_for_prologue (fi);
298}
299
300static CORE_ADDR
301m68k_frame_saved_pc (struct frame_info *frame)
302{
5a203e44 303 if ((get_frame_type (frame) == SIGTRAMP_FRAME))
942dc0e9
GS
304 {
305 if (frame->next)
306 return read_memory_integer (frame->next->frame + SIG_PC_FP_OFFSET, 4);
307 else
308 return read_memory_integer (read_register (SP_REGNUM)
309 + SIG_PC_FP_OFFSET - 8, 4);
310 }
311 else
312 return read_memory_integer (frame->frame + 4, 4);
313}
314
315
b83266a0
SS
316/* The only reason this is here is the tm-altos.h reference below. It
317 was moved back here from tm-m68k.h. FIXME? */
318
319extern CORE_ADDR
fba45db2 320altos_skip_prologue (CORE_ADDR pc)
b83266a0
SS
321{
322 register int op = read_memory_integer (pc, 2);
89c3b6d3 323 if (op == P_LINKW_FP)
c5aa993b 324 pc += 4; /* Skip link #word */
89c3b6d3 325 else if (op == P_LINKL_FP)
c5aa993b 326 pc += 6; /* Skip link #long */
b83266a0 327 /* Not sure why branches are here. */
514e603d 328 /* From tm-altos.h */
b83266a0 329 else if (op == 0060000)
c5aa993b 330 pc += 4; /* Skip bra #word */
b83266a0 331 else if (op == 00600377)
c5aa993b 332 pc += 6; /* skip bra #long */
b83266a0 333 else if ((op & 0177400) == 0060000)
c5aa993b 334 pc += 2; /* skip bra #char */
b83266a0
SS
335 return pc;
336}
337
89c3b6d3 338int
fba45db2 339delta68_in_sigtramp (CORE_ADDR pc, char *name)
89c3b6d3 340{
1bd54964
AC
341 if (name != NULL)
342 return strcmp (name, "_sigcode") == 0;
343 else
344 return 0;
89c3b6d3
PDM
345}
346
347CORE_ADDR
fba45db2 348delta68_frame_args_address (struct frame_info *frame_info)
89c3b6d3
PDM
349{
350 /* we assume here that the only frameless functions are the system calls
351 or other functions who do not put anything on the stack. */
5a203e44 352 if ((get_frame_type (frame_info) == SIGTRAMP_FRAME))
89c3b6d3
PDM
353 return frame_info->frame + 12;
354 else if (frameless_look_for_prologue (frame_info))
355 {
b5d78d39 356 /* Check for an interrupted system call */
5a203e44 357 if (frame_info->next && (get_frame_type (frame_info->next) == SIGTRAMP_FRAME))
b5d78d39
GS
358 return frame_info->next->frame + 16;
359 else
360 return frame_info->frame + 4;
89c3b6d3
PDM
361 }
362 else
363 return frame_info->frame;
364}
365
366CORE_ADDR
fba45db2 367delta68_frame_saved_pc (struct frame_info *frame_info)
89c3b6d3
PDM
368{
369 return read_memory_integer (delta68_frame_args_address (frame_info) + 4, 4);
370}
371
392a587b
JM
372/* Return number of args passed to a frame.
373 Can return -1, meaning no way to tell. */
374
375int
fba45db2 376isi_frame_num_args (struct frame_info *fi)
392a587b
JM
377{
378 int val;
379 CORE_ADDR pc = FRAME_SAVED_PC (fi);
380 int insn = 0177777 & read_memory_integer (pc, 2);
381 val = 0;
c5aa993b 382 if (insn == 0047757 || insn == 0157374) /* lea W(sp),sp or addaw #W,sp */
392a587b 383 val = read_memory_integer (pc + 2, 2);
c5aa993b
JM
384 else if ((insn & 0170777) == 0050217 /* addql #N, sp */
385 || (insn & 0170777) == 0050117) /* addqw */
392a587b
JM
386 {
387 val = (insn >> 9) & 7;
388 if (val == 0)
389 val = 8;
390 }
c5aa993b 391 else if (insn == 0157774) /* addal #WW, sp */
392a587b
JM
392 val = read_memory_integer (pc + 2, 4);
393 val >>= 2;
394 return val;
395}
396
397int
fba45db2 398delta68_frame_num_args (struct frame_info *fi)
392a587b
JM
399{
400 int val;
401 CORE_ADDR pc = FRAME_SAVED_PC (fi);
402 int insn = 0177777 & read_memory_integer (pc, 2);
403 val = 0;
c5aa993b 404 if (insn == 0047757 || insn == 0157374) /* lea W(sp),sp or addaw #W,sp */
392a587b 405 val = read_memory_integer (pc + 2, 2);
c5aa993b
JM
406 else if ((insn & 0170777) == 0050217 /* addql #N, sp */
407 || (insn & 0170777) == 0050117) /* addqw */
392a587b
JM
408 {
409 val = (insn >> 9) & 7;
410 if (val == 0)
411 val = 8;
412 }
c5aa993b 413 else if (insn == 0157774) /* addal #WW, sp */
392a587b
JM
414 val = read_memory_integer (pc + 2, 4);
415 val >>= 2;
416 return val;
417}
418
419int
fba45db2 420news_frame_num_args (struct frame_info *fi)
392a587b
JM
421{
422 int val;
423 CORE_ADDR pc = FRAME_SAVED_PC (fi);
424 int insn = 0177777 & read_memory_integer (pc, 2);
425 val = 0;
c5aa993b 426 if (insn == 0047757 || insn == 0157374) /* lea W(sp),sp or addaw #W,sp */
392a587b 427 val = read_memory_integer (pc + 2, 2);
c5aa993b
JM
428 else if ((insn & 0170777) == 0050217 /* addql #N, sp */
429 || (insn & 0170777) == 0050117) /* addqw */
392a587b
JM
430 {
431 val = (insn >> 9) & 7;
432 if (val == 0)
433 val = 8;
434 }
c5aa993b 435 else if (insn == 0157774) /* addal #WW, sp */
392a587b
JM
436 val = read_memory_integer (pc + 2, 4);
437 val >>= 2;
438 return val;
439}
b83266a0 440
7f8e7424
GS
441/* Insert the specified number of args and function address
442 into a call sequence of the above form stored at DUMMYNAME.
443 We use the BFD routines to store a big-endian value of known size. */
444
445void
a2c6a6d5
GS
446m68k_fix_call_dummy (char *dummy, CORE_ADDR pc, CORE_ADDR fun, int nargs,
447 struct value **args, struct type *type, int gcc_p)
7f8e7424 448{
a2c6a6d5
GS
449 bfd_putb32 (fun, (unsigned char *) dummy + CALL_DUMMY_START_OFFSET + 2);
450 bfd_putb32 (nargs * 4,
451 (unsigned char *) dummy + CALL_DUMMY_START_OFFSET + 8);
7f8e7424
GS
452}
453
454
c906108c
SS
455/* Push an empty stack frame, to record the current PC, etc. */
456
457void
fba45db2 458m68k_push_dummy_frame (void)
c906108c
SS
459{
460 register CORE_ADDR sp = read_register (SP_REGNUM);
461 register int regnum;
462 char raw_buffer[12];
463
464 sp = push_word (sp, read_register (PC_REGNUM));
465 sp = push_word (sp, read_register (FP_REGNUM));
466 write_register (FP_REGNUM, sp);
467
468 /* Always save the floating-point registers, whether they exist on
469 this target or not. */
470 for (regnum = FP0_REGNUM + 7; regnum >= FP0_REGNUM; regnum--)
471 {
73937e03 472 deprecated_read_register_bytes (REGISTER_BYTE (regnum), raw_buffer, 12);
c906108c
SS
473 sp = push_bytes (sp, raw_buffer, 12);
474 }
475
476 for (regnum = FP_REGNUM - 1; regnum >= 0; regnum--)
477 {
478 sp = push_word (sp, read_register (regnum));
479 }
480 sp = push_word (sp, read_register (PS_REGNUM));
481 write_register (SP_REGNUM, sp);
482}
483
484/* Discard from the stack the innermost frame,
485 restoring all saved registers. */
486
487void
fba45db2 488m68k_pop_frame (void)
c906108c
SS
489{
490 register struct frame_info *frame = get_current_frame ();
491 register CORE_ADDR fp;
492 register int regnum;
c906108c
SS
493 char raw_buffer[12];
494
495 fp = FRAME_FP (frame);
7f8e7424 496 m68k_frame_init_saved_regs (frame);
c5aa993b 497 for (regnum = FP0_REGNUM + 7; regnum >= FP0_REGNUM; regnum--)
c906108c 498 {
7f8e7424 499 if (frame->saved_regs[regnum])
c906108c 500 {
7f8e7424 501 read_memory (frame->saved_regs[regnum], raw_buffer, 12);
73937e03
AC
502 deprecated_write_register_bytes (REGISTER_BYTE (regnum), raw_buffer,
503 12);
c906108c
SS
504 }
505 }
c5aa993b 506 for (regnum = FP_REGNUM - 1; regnum >= 0; regnum--)
c906108c 507 {
7f8e7424 508 if (frame->saved_regs[regnum])
c906108c 509 {
a2c6a6d5
GS
510 write_register (regnum,
511 read_memory_integer (frame->saved_regs[regnum], 4));
c906108c
SS
512 }
513 }
7f8e7424 514 if (frame->saved_regs[PS_REGNUM])
c906108c 515 {
b5d78d39 516 write_register (PS_REGNUM,
7f8e7424 517 read_memory_integer (frame->saved_regs[PS_REGNUM], 4));
c906108c
SS
518 }
519 write_register (FP_REGNUM, read_memory_integer (fp, 4));
520 write_register (PC_REGNUM, read_memory_integer (fp + 4, 4));
521 write_register (SP_REGNUM, fp + 8);
522 flush_cached_frames ();
523}
c906108c 524\f
c5aa993b 525
c906108c
SS
526/* Given an ip value corresponding to the start of a function,
527 return the ip of the first instruction after the function
528 prologue. This is the generic m68k support. Machines which
529 require something different can override the SKIP_PROLOGUE
530 macro to point elsewhere.
531
532 Some instructions which typically may appear in a function
533 prologue include:
534
535 A link instruction, word form:
536
c5aa993b 537 link.w %a6,&0 4e56 XXXX
c906108c
SS
538
539 A link instruction, long form:
540
c5aa993b 541 link.l %fp,&F%1 480e XXXX XXXX
c906108c
SS
542
543 A movm instruction to preserve integer regs:
544
c5aa993b 545 movm.l &M%1,(4,%sp) 48ef XXXX XXXX
c906108c
SS
546
547 A fmovm instruction to preserve float regs:
548
c5aa993b 549 fmovm &FPM%1,(FPO%1,%sp) f237 XXXX XXXX XXXX XXXX
c906108c
SS
550
551 Some profiling setup code (FIXME, not recognized yet):
552
c5aa993b
JM
553 lea.l (.L3,%pc),%a1 43fb XXXX XXXX XXXX
554 bsr _mcount 61ff XXXX XXXX
c906108c 555
c5aa993b 556 */
c906108c 557
c906108c 558CORE_ADDR
fba45db2 559m68k_skip_prologue (CORE_ADDR ip)
c906108c
SS
560{
561 register CORE_ADDR limit;
562 struct symtab_and_line sal;
563 register int op;
564
565 /* Find out if there is a known limit for the extent of the prologue.
566 If so, ensure we don't go past it. If not, assume "infinity". */
567
568 sal = find_pc_line (ip, 0);
b5d78d39 569 limit = (sal.end) ? sal.end : (CORE_ADDR) ~0;
c906108c
SS
570
571 while (ip < limit)
572 {
573 op = read_memory_integer (ip, 2);
574 op &= 0xFFFF;
c5aa993b 575
89c3b6d3
PDM
576 if (op == P_LINKW_FP)
577 ip += 4; /* Skip link.w */
578 else if (op == P_PEA_FP)
c5aa993b 579 ip += 2; /* Skip pea %fp */
89c3b6d3 580 else if (op == P_MOVL_SP_FP)
c5aa993b 581 ip += 2; /* Skip move.l %sp, %fp */
89c3b6d3
PDM
582 else if (op == P_LINKL_FP)
583 ip += 6; /* Skip link.l */
584 else if (op == P_MOVML)
585 ip += 6; /* Skip movm.l */
c906108c 586 else if (op == P_FMOVM)
89c3b6d3 587 ip += 10; /* Skip fmovm */
c906108c 588 else
b5d78d39 589 break; /* Found unknown code, bail out. */
c906108c
SS
590 }
591 return (ip);
592}
593
7f8e7424
GS
594/* Store the addresses of the saved registers of the frame described by
595 FRAME_INFO in its saved_regs field.
596 This includes special registers such as pc and fp saved in special
597 ways in the stack frame. sp is even more special:
598 the address we return for it IS the sp for the next frame. */
599
c906108c 600void
7f8e7424 601m68k_frame_init_saved_regs (struct frame_info *frame_info)
c906108c 602{
c5aa993b
JM
603 register int regnum;
604 register int regmask;
605 register CORE_ADDR next_addr;
c906108c
SS
606 register CORE_ADDR pc;
607
608 /* First possible address for a pc in a call dummy for this frame. */
609 CORE_ADDR possible_call_dummy_start =
7f8e7424 610 (frame_info)->frame - 28 - FP_REGNUM * 4 - 4 - 8 * 12;
c906108c
SS
611
612 int nextinsn;
7f8e7424
GS
613
614 if (frame_info->saved_regs)
615 return;
616
617 frame_saved_regs_zalloc (frame_info);
618
619 memset (frame_info->saved_regs, 0, SIZEOF_FRAME_SAVED_REGS);
620
c906108c
SS
621 if ((frame_info)->pc >= possible_call_dummy_start
622 && (frame_info)->pc <= (frame_info)->frame)
623 {
624
625 /* It is a call dummy. We could just stop now, since we know
c5aa993b
JM
626 what the call dummy saves and where. But this code proceeds
627 to parse the "prologue" which is part of the call dummy.
628 This is needlessly complex and confusing. FIXME. */
c906108c
SS
629
630 next_addr = (frame_info)->frame;
631 pc = possible_call_dummy_start;
632 }
c5aa993b 633 else
c906108c 634 {
c5aa993b 635 pc = get_pc_function_start ((frame_info)->pc);
c906108c 636
89c3b6d3
PDM
637 nextinsn = read_memory_integer (pc, 2);
638 if (P_PEA_FP == nextinsn
639 && P_MOVL_SP_FP == read_memory_integer (pc + 2, 2))
c906108c 640 {
89c3b6d3 641 /* pea %fp
c5aa993b 642 move.l %sp, %fp */
c906108c 643 next_addr = frame_info->frame;
89c3b6d3 644 pc += 4;
c906108c 645 }
89c3b6d3 646 else if (P_LINKL_FP == nextinsn)
c906108c
SS
647 /* link.l %fp */
648 /* Find the address above the saved
649 regs using the amount of storage from the link instruction. */
89c3b6d3
PDM
650 {
651 next_addr = (frame_info)->frame + read_memory_integer (pc + 2, 4);
652 pc += 6;
653 }
654 else if (P_LINKW_FP == nextinsn)
c906108c
SS
655 /* link.w %fp */
656 /* Find the address above the saved
657 regs using the amount of storage from the link instruction. */
89c3b6d3
PDM
658 {
659 next_addr = (frame_info)->frame + read_memory_integer (pc + 2, 2);
660 pc += 4;
661 }
c5aa993b
JM
662 else
663 goto lose;
664
665 /* If have an addal #-n, sp next, adjust next_addr. */
666 if ((0177777 & read_memory_integer (pc, 2)) == 0157774)
667 next_addr += read_memory_integer (pc += 2, 4), pc += 4;
668 }
c5aa993b 669
b5d78d39 670 for (;;)
c5aa993b 671 {
89c3b6d3 672 nextinsn = 0xffff & read_memory_integer (pc, 2);
c5aa993b 673 regmask = read_memory_integer (pc + 2, 2);
89c3b6d3
PDM
674 /* fmovemx to -(sp) */
675 if (0xf227 == nextinsn && (regmask & 0xff00) == 0xe000)
c906108c 676 {
89c3b6d3
PDM
677 /* Regmask's low bit is for register fp7, the first pushed */
678 for (regnum = FP0_REGNUM + 8; --regnum >= FP0_REGNUM; regmask >>= 1)
679 if (regmask & 1)
7f8e7424 680 frame_info->saved_regs[regnum] = (next_addr -= 12);
89c3b6d3
PDM
681 pc += 4;
682 }
683 /* fmovemx to (fp + displacement) */
684 else if (0171056 == nextinsn && (regmask & 0xff00) == 0xf000)
685 {
686 register CORE_ADDR addr;
687
688 addr = (frame_info)->frame + read_memory_integer (pc + 4, 2);
689 /* Regmask's low bit is for register fp7, the first pushed */
690 for (regnum = FP0_REGNUM + 8; --regnum >= FP0_REGNUM; regmask >>= 1)
691 if (regmask & 1)
692 {
7f8e7424 693 frame_info->saved_regs[regnum] = addr;
89c3b6d3
PDM
694 addr += 12;
695 }
696 pc += 6;
697 }
698 /* moveml to (sp) */
699 else if (0044327 == nextinsn)
700 {
701 /* Regmask's low bit is for register 0, the first written */
702 for (regnum = 0; regnum < 16; regnum++, regmask >>= 1)
703 if (regmask & 1)
704 {
7f8e7424 705 frame_info->saved_regs[regnum] = next_addr;
89c3b6d3
PDM
706 next_addr += 4;
707 }
708 pc += 4;
709 }
710 /* moveml to (fp + displacement) */
711 else if (0044356 == nextinsn)
712 {
713 register CORE_ADDR addr;
714
715 addr = (frame_info)->frame + read_memory_integer (pc + 4, 2);
716 /* Regmask's low bit is for register 0, the first written */
717 for (regnum = 0; regnum < 16; regnum++, regmask >>= 1)
718 if (regmask & 1)
719 {
7f8e7424 720 frame_info->saved_regs[regnum] = addr;
89c3b6d3
PDM
721 addr += 4;
722 }
723 pc += 6;
724 }
725 /* moveml to -(sp) */
726 else if (0044347 == nextinsn)
727 {
728 /* Regmask's low bit is for register 15, the first pushed */
729 for (regnum = 16; --regnum >= 0; regmask >>= 1)
730 if (regmask & 1)
7f8e7424 731 frame_info->saved_regs[regnum] = (next_addr -= 4);
89c3b6d3
PDM
732 pc += 4;
733 }
734 /* movl r,-(sp) */
735 else if (0x2f00 == (0xfff0 & nextinsn))
736 {
737 regnum = 0xf & nextinsn;
7f8e7424 738 frame_info->saved_regs[regnum] = (next_addr -= 4);
89c3b6d3 739 pc += 2;
c906108c 740 }
89c3b6d3
PDM
741 /* fmovemx to index of sp */
742 else if (0xf236 == nextinsn && (regmask & 0xff00) == 0xf000)
743 {
744 /* Regmask's low bit is for register fp0, the first written */
745 for (regnum = FP0_REGNUM + 8; --regnum >= FP0_REGNUM; regmask >>= 1)
746 if (regmask & 1)
747 {
7f8e7424 748 frame_info->saved_regs[regnum] = next_addr;
89c3b6d3
PDM
749 next_addr += 12;
750 }
751 pc += 10;
752 }
753 /* clrw -(sp); movw ccr,-(sp) */
754 else if (0x4267 == nextinsn && 0x42e7 == regmask)
755 {
7f8e7424 756 frame_info->saved_regs[PS_REGNUM] = (next_addr -= 4);
89c3b6d3
PDM
757 pc += 4;
758 }
759 else
760 break;
c906108c 761 }
c5aa993b 762lose:;
7f8e7424
GS
763 frame_info->saved_regs[SP_REGNUM] = (frame_info)->frame + 8;
764 frame_info->saved_regs[FP_REGNUM] = (frame_info)->frame;
765 frame_info->saved_regs[PC_REGNUM] = (frame_info)->frame + 4;
c906108c
SS
766#ifdef SIG_SP_FP_OFFSET
767 /* Adjust saved SP_REGNUM for fake _sigtramp frames. */
5a203e44 768 if ((get_frame_type (frame_info) == SIGTRAMP_FRAME) && frame_info->next)
7f8e7424
GS
769 frame_info->saved_regs[SP_REGNUM] =
770 frame_info->next->frame + SIG_SP_FP_OFFSET;
c906108c
SS
771#endif
772}
773
774
c5aa993b 775#ifdef USE_PROC_FS /* Target dependent support for /proc */
c906108c
SS
776
777#include <sys/procfs.h>
778
c60c0f5f
MS
779/* Prototypes for supply_gregset etc. */
780#include "gregset.h"
781
c906108c 782/* The /proc interface divides the target machine's register set up into
c5aa993b
JM
783 two different sets, the general register set (gregset) and the floating
784 point register set (fpregset). For each set, there is an ioctl to get
785 the current register set and another ioctl to set the current values.
c906108c 786
c5aa993b
JM
787 The actual structure passed through the ioctl interface is, of course,
788 naturally machine dependent, and is different for each set of registers.
789 For the m68k for example, the general register set is typically defined
790 by:
c906108c 791
c5aa993b 792 typedef int gregset_t[18];
c906108c 793
c5aa993b
JM
794 #define R_D0 0
795 ...
796 #define R_PS 17
c906108c 797
c5aa993b 798 and the floating point set by:
c906108c 799
c5aa993b
JM
800 typedef struct fpregset {
801 int f_pcr;
802 int f_psr;
803 int f_fpiaddr;
804 int f_fpregs[8][3]; (8 regs, 96 bits each)
805 } fpregset_t;
c906108c 806
c5aa993b
JM
807 These routines provide the packing and unpacking of gregset_t and
808 fpregset_t formatted data.
c906108c
SS
809
810 */
811
812/* Atari SVR4 has R_SR but not R_PS */
813
814#if !defined (R_PS) && defined (R_SR)
815#define R_PS R_SR
816#endif
817
818/* Given a pointer to a general register set in /proc format (gregset_t *),
c5aa993b
JM
819 unpack the register contents and supply them as gdb's idea of the current
820 register values. */
c906108c
SS
821
822void
fba45db2 823supply_gregset (gregset_t *gregsetp)
c906108c
SS
824{
825 register int regi;
826 register greg_t *regp = (greg_t *) gregsetp;
827
c5aa993b 828 for (regi = 0; regi < R_PC; regi++)
c906108c
SS
829 {
830 supply_register (regi, (char *) (regp + regi));
831 }
832 supply_register (PS_REGNUM, (char *) (regp + R_PS));
833 supply_register (PC_REGNUM, (char *) (regp + R_PC));
834}
835
836void
fba45db2 837fill_gregset (gregset_t *gregsetp, int regno)
c906108c
SS
838{
839 register int regi;
840 register greg_t *regp = (greg_t *) gregsetp;
c906108c 841
c5aa993b 842 for (regi = 0; regi < R_PC; regi++)
c906108c
SS
843 {
844 if ((regno == -1) || (regno == regi))
845 {
524d7c18 846 *(regp + regi) = *(int *) &deprecated_registers[REGISTER_BYTE (regi)];
c906108c
SS
847 }
848 }
849 if ((regno == -1) || (regno == PS_REGNUM))
850 {
524d7c18 851 *(regp + R_PS) = *(int *) &deprecated_registers[REGISTER_BYTE (PS_REGNUM)];
c906108c
SS
852 }
853 if ((regno == -1) || (regno == PC_REGNUM))
854 {
524d7c18 855 *(regp + R_PC) = *(int *) &deprecated_registers[REGISTER_BYTE (PC_REGNUM)];
c906108c
SS
856 }
857}
858
859#if defined (FP0_REGNUM)
860
861/* Given a pointer to a floating point register set in /proc format
c5aa993b
JM
862 (fpregset_t *), unpack the register contents and supply them as gdb's
863 idea of the current floating point register values. */
c906108c 864
c5aa993b 865void
fba45db2 866supply_fpregset (fpregset_t *fpregsetp)
c906108c
SS
867{
868 register int regi;
869 char *from;
c5aa993b 870
103a1597 871 for (regi = FP0_REGNUM; regi < E_FPC_REGNUM; regi++)
c906108c 872 {
c5aa993b 873 from = (char *) &(fpregsetp->f_fpregs[regi - FP0_REGNUM][0]);
c906108c
SS
874 supply_register (regi, from);
875 }
103a1597
GS
876 supply_register (E_FPC_REGNUM, (char *) &(fpregsetp->f_pcr));
877 supply_register (E_FPS_REGNUM, (char *) &(fpregsetp->f_psr));
878 supply_register (E_FPI_REGNUM, (char *) &(fpregsetp->f_fpiaddr));
c906108c
SS
879}
880
881/* Given a pointer to a floating point register set in /proc format
c5aa993b
JM
882 (fpregset_t *), update the register specified by REGNO from gdb's idea
883 of the current floating point register set. If REGNO is -1, update
884 them all. */
c906108c
SS
885
886void
fba45db2 887fill_fpregset (fpregset_t *fpregsetp, int regno)
c906108c
SS
888{
889 int regi;
890 char *to;
891 char *from;
c906108c 892
103a1597 893 for (regi = FP0_REGNUM; regi < E_FPC_REGNUM; regi++)
c906108c
SS
894 {
895 if ((regno == -1) || (regno == regi))
896 {
524d7c18 897 from = (char *) &deprecated_registers[REGISTER_BYTE (regi)];
c5aa993b 898 to = (char *) &(fpregsetp->f_fpregs[regi - FP0_REGNUM][0]);
c906108c
SS
899 memcpy (to, from, REGISTER_RAW_SIZE (regi));
900 }
901 }
103a1597 902 if ((regno == -1) || (regno == E_FPC_REGNUM))
c906108c 903 {
524d7c18 904 fpregsetp->f_pcr = *(int *) &deprecated_registers[REGISTER_BYTE (E_FPC_REGNUM)];
c906108c 905 }
103a1597 906 if ((regno == -1) || (regno == E_FPS_REGNUM))
c906108c 907 {
524d7c18 908 fpregsetp->f_psr = *(int *) &deprecated_registers[REGISTER_BYTE (E_FPS_REGNUM)];
c906108c 909 }
103a1597 910 if ((regno == -1) || (regno == E_FPI_REGNUM))
c906108c 911 {
524d7c18 912 fpregsetp->f_fpiaddr = *(int *) &deprecated_registers[REGISTER_BYTE (E_FPI_REGNUM)];
c906108c
SS
913 }
914}
915
c5aa993b 916#endif /* defined (FP0_REGNUM) */
c906108c 917
c5aa993b 918#endif /* USE_PROC_FS */
c906108c 919
c906108c
SS
920/* Figure out where the longjmp will land. Slurp the args out of the stack.
921 We expect the first arg to be a pointer to the jmp_buf structure from which
922 we extract the pc (JB_PC) that we will land at. The pc is copied into PC.
923 This routine returns true on success. */
924
2765b798
AC
925/* NOTE: cagney/2000-11-08: For this function to be fully multi-arched
926 the macro's JB_PC and JB_ELEMENT_SIZE would need to be moved into
927 the ``struct gdbarch_tdep'' object and then set on a target ISA/ABI
928 dependant basis. */
929
c906108c 930int
f4281f55 931m68k_get_longjmp_target (CORE_ADDR *pc)
c906108c 932{
2765b798 933#if defined (JB_PC) && defined (JB_ELEMENT_SIZE)
35fc8285 934 char *buf;
c906108c
SS
935 CORE_ADDR sp, jb_addr;
936
35fc8285 937 buf = alloca (TARGET_PTR_BIT / TARGET_CHAR_BIT);
c5aa993b 938 sp = read_register (SP_REGNUM);
c906108c 939
b5d78d39
GS
940 if (target_read_memory (sp + SP_ARG0, /* Offset of first arg on stack */
941 buf, TARGET_PTR_BIT / TARGET_CHAR_BIT))
c906108c
SS
942 return 0;
943
944 jb_addr = extract_address (buf, TARGET_PTR_BIT / TARGET_CHAR_BIT);
945
946 if (target_read_memory (jb_addr + JB_PC * JB_ELEMENT_SIZE, buf,
947 TARGET_PTR_BIT / TARGET_CHAR_BIT))
948 return 0;
949
950 *pc = extract_address (buf, TARGET_PTR_BIT / TARGET_CHAR_BIT);
951
952 return 1;
2765b798 953#else
8e65ff28
AC
954 internal_error (__FILE__, __LINE__,
955 "m68k_get_longjmp_target: not implemented");
2765b798
AC
956 return 0;
957#endif
c906108c 958}
c906108c
SS
959
960/* Immediately after a function call, return the saved pc before the frame
961 is setup. For sun3's, we check for the common case of being inside of a
962 system call, and if so, we know that Sun pushes the call # on the stack
963 prior to doing the trap. */
964
965CORE_ADDR
fba45db2 966m68k_saved_pc_after_call (struct frame_info *frame)
c906108c
SS
967{
968#ifdef SYSCALL_TRAP
969 int op;
970
971 op = read_memory_integer (frame->pc - SYSCALL_TRAP_OFFSET, 2);
972
973 if (op == SYSCALL_TRAP)
974 return read_memory_integer (read_register (SP_REGNUM) + 4, 4);
975 else
976#endif /* SYSCALL_TRAP */
977 return read_memory_integer (read_register (SP_REGNUM), 4);
978}
979
152d9db6
GS
980/* Function: m68k_gdbarch_init
981 Initializer function for the m68k gdbarch vector.
982 Called by gdbarch. Sets up the gdbarch vector(s) for this target. */
983
984static struct gdbarch *
985m68k_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
986{
a2c6a6d5
GS
987 static LONGEST call_dummy_words[7] = { 0xf227e0ff, 0x48e7fffc, 0x426742e7,
988 0x4eb93232, 0x3232dffc, 0x69696969,
989 (0x4e404e71 | (BPT_VECTOR << 16))
990 };
152d9db6
GS
991 struct gdbarch_tdep *tdep = NULL;
992 struct gdbarch *gdbarch;
993
994 /* find a candidate among the list of pre-declared architectures. */
995 arches = gdbarch_list_lookup_by_info (arches, &info);
996 if (arches != NULL)
997 return (arches->gdbarch);
998
999#if 0
1000 tdep = (struct gdbarch_tdep *) xmalloc (sizeof (struct gdbarch_tdep));
1001#endif
6300c360 1002
152d9db6
GS
1003 gdbarch = gdbarch_alloc (&info, 0);
1004
5d3ed2e3
GS
1005 set_gdbarch_long_double_format (gdbarch, &floatformat_m68881_ext);
1006 set_gdbarch_long_double_bit (gdbarch, 96);
1007
1008 set_gdbarch_function_start_offset (gdbarch, 0);
1009
1010 set_gdbarch_skip_prologue (gdbarch, m68k_skip_prologue);
1011 set_gdbarch_saved_pc_after_call (gdbarch, m68k_saved_pc_after_call);
103a1597 1012 set_gdbarch_breakpoint_from_pc (gdbarch, m68k_local_breakpoint_from_pc);
5d3ed2e3
GS
1013
1014 /* Stack grows down. */
1015 set_gdbarch_inner_than (gdbarch, core_addr_lessthan);
1016 set_gdbarch_stack_align (gdbarch, m68k_stack_align);
1017
6300c360
GS
1018
1019 set_gdbarch_believe_pcc_promotion (gdbarch, 1);
942dc0e9
GS
1020 set_gdbarch_decr_pc_after_break (gdbarch, 2);
1021
1022 set_gdbarch_store_struct_return (gdbarch, m68k_store_struct_return);
1023 set_gdbarch_deprecated_extract_return_value (gdbarch,
1024 m68k_deprecated_extract_return_value);
ebba8386 1025 set_gdbarch_deprecated_store_return_value (gdbarch, m68k_store_return_value);
942dc0e9
GS
1026
1027 set_gdbarch_frame_chain (gdbarch, m68k_frame_chain);
6300c360 1028 set_gdbarch_frame_chain_valid (gdbarch, generic_func_frame_chain_valid);
942dc0e9
GS
1029 set_gdbarch_frame_saved_pc (gdbarch, m68k_frame_saved_pc);
1030 set_gdbarch_frame_init_saved_regs (gdbarch, m68k_frame_init_saved_regs);
1031 set_gdbarch_frameless_function_invocation (gdbarch,
1032 m68k_frameless_function_invocation);
6300c360
GS
1033 /* OK to default this value to 'unknown'. */
1034 set_gdbarch_frame_num_args (gdbarch, frame_num_args_unknown);
1035 set_gdbarch_frame_args_skip (gdbarch, 8);
942dc0e9 1036
5d3ed2e3
GS
1037 set_gdbarch_register_raw_size (gdbarch, m68k_register_raw_size);
1038 set_gdbarch_register_virtual_size (gdbarch, m68k_register_virtual_size);
1039 set_gdbarch_max_register_raw_size (gdbarch, 12);
1040 set_gdbarch_max_register_virtual_size (gdbarch, 12);
1041 set_gdbarch_register_virtual_type (gdbarch, m68k_register_virtual_type);
1042 set_gdbarch_register_name (gdbarch, m68k_register_name);
1043 set_gdbarch_register_size (gdbarch, 4);
1044 set_gdbarch_register_byte (gdbarch, m68k_register_byte);
942dc0e9
GS
1045 set_gdbarch_num_regs (gdbarch, 29);
1046 set_gdbarch_register_bytes_ok (gdbarch, m68k_register_bytes_ok);
1047 set_gdbarch_register_bytes (gdbarch, (16 * 4 + 8 + 8 * 12 + 3 * 4));
6300c360
GS
1048 set_gdbarch_sp_regnum (gdbarch, E_SP_REGNUM);
1049 set_gdbarch_fp_regnum (gdbarch, E_FP_REGNUM);
1050 set_gdbarch_pc_regnum (gdbarch, E_PC_REGNUM);
1051 set_gdbarch_ps_regnum (gdbarch, E_PS_REGNUM);
1052 set_gdbarch_fp0_regnum (gdbarch, E_FP0_REGNUM);
a2c6a6d5 1053
7f8e7424
GS
1054 set_gdbarch_use_generic_dummy_frames (gdbarch, 0);
1055 set_gdbarch_call_dummy_location (gdbarch, ON_STACK);
1056 set_gdbarch_call_dummy_breakpoint_offset_p (gdbarch, 1);
a2c6a6d5 1057 set_gdbarch_call_dummy_breakpoint_offset (gdbarch, 24);
7f8e7424
GS
1058 set_gdbarch_pc_in_call_dummy (gdbarch, pc_in_call_dummy_on_stack);
1059 set_gdbarch_call_dummy_p (gdbarch, 1);
1060 set_gdbarch_call_dummy_stack_adjust_p (gdbarch, 0);
1061 set_gdbarch_call_dummy_length (gdbarch, 28);
1062 set_gdbarch_call_dummy_start_offset (gdbarch, 12);
a2c6a6d5 1063
7f8e7424
GS
1064 set_gdbarch_call_dummy_words (gdbarch, call_dummy_words);
1065 set_gdbarch_sizeof_call_dummy_words (gdbarch, sizeof (call_dummy_words));
1066 set_gdbarch_call_dummy_stack_adjust_p (gdbarch, 0);
1067 set_gdbarch_fix_call_dummy (gdbarch, m68k_fix_call_dummy);
1068 set_gdbarch_push_dummy_frame (gdbarch, m68k_push_dummy_frame);
1069 set_gdbarch_pop_frame (gdbarch, m68k_pop_frame);
a2c6a6d5 1070
152d9db6
GS
1071 return gdbarch;
1072}
1073
1074
1075static void
1076m68k_dump_tdep (struct gdbarch *current_gdbarch, struct ui_file *file)
1077{
1078
1079}
2acceee2 1080
c906108c 1081void
fba45db2 1082_initialize_m68k_tdep (void)
c906108c 1083{
152d9db6 1084 gdbarch_register (bfd_arch_m68k, m68k_gdbarch_init, m68k_dump_tdep);
c906108c
SS
1085 tm_print_insn = print_insn_m68k;
1086}
This page took 0.325452 seconds and 4 git commands to generate.