1 /* Target dependent code for the NS32000, for GDB.
3 Copyright 1986, 1988, 1991, 1992, 1994, 1995, 1998, 1999, 2000,
4 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
6 This file is part of GDB.
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2 of the License, or
11 (at your option) any later version.
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software
20 Foundation, Inc., 59 Temple Place - Suite 330,
21 Boston, MA 02111-1307, USA. */
30 #include "arch-utils.h"
34 #include "ns32k-tdep.h"
35 #include "gdb_string.h"
37 static int sign_extend (int value, int bits);
38 static CORE_ADDR ns32k_get_enter_addr (CORE_ADDR);
39 static int ns32k_localcount (CORE_ADDR enter_pc);
40 static void flip_bytes (void *, int);
43 ns32k_register_name_32082 (int regno)
45 static char *register_names[] =
47 "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
48 "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7",
49 "sp", "fp", "pc", "ps",
50 "l0", "l1", "l2", "l3", "xx",
55 if (regno >= sizeof (register_names) / sizeof (*register_names))
58 return (register_names[regno]);
62 ns32k_register_name_32382 (int regno)
64 static char *register_names[] =
66 "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
67 "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7",
68 "sp", "fp", "pc", "ps",
70 "l0", "l1", "l2", "l3", "l4", "l5", "l6", "l7", "xx",
75 if (regno >= sizeof (register_names) / sizeof (*register_names))
78 return (register_names[regno]);
82 ns32k_register_byte_32082 (int regno)
84 if (regno >= NS32K_LP0_REGNUM)
85 return (NS32K_LP0_REGNUM * 4) + ((regno - NS32K_LP0_REGNUM) * 8);
91 ns32k_register_byte_32382 (int regno)
93 /* This is a bit yuk. The even numbered double precision floating
94 point long registers occupy the same space as the even:odd numbered
95 single precision floating point registers, but the extra 32381 FPU
96 registers are at the end. Doing it this way is compatible for both
97 32081 and 32381 equipped machines. */
99 return ((regno < NS32K_LP0_REGNUM ? regno
100 : (regno - NS32K_LP0_REGNUM) & 1 ? regno - 1
101 : (regno - NS32K_LP0_REGNUM + FP0_REGNUM)) * 4);
105 ns32k_register_raw_size (int regno)
107 /* All registers are 4 bytes, except for the doubled floating
110 return ((regno >= NS32K_LP0_REGNUM) ? 8 : 4);
114 ns32k_register_virtual_size (int regno)
116 return ((regno >= NS32K_LP0_REGNUM) ? 8 : 4);
120 ns32k_register_virtual_type (int regno)
122 if (regno < FP0_REGNUM)
123 return (builtin_type_int);
125 if (regno < FP0_REGNUM + 8)
126 return (builtin_type_float);
128 if (regno < NS32K_LP0_REGNUM)
129 return (builtin_type_int);
131 return (builtin_type_double);
134 /* Immediately after a function call, return the saved PC. Can't
135 always go through the frames for this because on some systems,
136 the new frame is not set up until the new function executes some
140 ns32k_saved_pc_after_call (struct frame_info *frame)
142 return (read_memory_integer (read_register (SP_REGNUM), 4));
145 /* Advance PC across any function entry prologue instructions
146 to reach some "real" code. */
149 umax_skip_prologue (CORE_ADDR pc)
151 unsigned char op = read_memory_integer (pc, 1);
154 op = read_memory_integer (pc + 2, 1);
155 if ((op & 0x80) == 0)
157 else if ((op & 0xc0) == 0x80)
165 static const unsigned char *
166 ns32k_breakpoint_from_pc (CORE_ADDR *pcp, int *lenp)
168 static const unsigned char breakpoint_insn[] = { 0xf2 };
170 *lenp = sizeof (breakpoint_insn);
171 return breakpoint_insn;
174 /* Return number of args passed to a frame.
175 Can return -1, meaning no way to tell.
176 Encore's C compiler often reuses same area on stack for args,
177 so this will often not work properly. If the arg names
178 are known, it's likely most of them will be printed. */
181 umax_frame_num_args (struct frame_info *fi)
185 CORE_ADDR enter_addr;
187 unsigned int addr_mode;
191 enter_addr = ns32k_get_enter_addr (get_frame_pc (fi));
194 pc = ((enter_addr == 1)
195 ? DEPRECATED_SAVED_PC_AFTER_CALL (fi)
196 : DEPRECATED_FRAME_SAVED_PC (fi));
197 insn = read_memory_integer (pc, 2);
198 addr_mode = (insn >> 11) & 0x1f;
200 if ((insn & 0x7fc) == 0x57c
201 && addr_mode == 0x14) /* immediate */
203 if (insn == 0x57c) /* adjspb */
205 else if (insn == 0x57d) /* adjspw */
207 else if (insn == 0x57f) /* adjspd */
210 internal_error (__FILE__, __LINE__, "bad else");
211 numargs = read_memory_integer (pc + 2, width);
213 flip_bytes (&numargs, width);
214 numargs = -sign_extend (numargs, width * 8) / 4;
221 sign_extend (int value, int bits)
223 value = value & ((1 << bits) - 1);
224 return (value & (1 << (bits - 1))
225 ? value | (~((1 << bits) - 1))
230 flip_bytes (void *p, int count)
238 ptr[0] = ptr[count - 1];
239 ptr[count - 1] = tmp;
245 /* Return the number of locals in the current frame given a
246 pc pointing to the enter instruction. This is used by
247 ns32k_frame_init_saved_regs. */
250 ns32k_localcount (CORE_ADDR enter_pc)
252 unsigned char localtype;
255 localtype = read_memory_integer (enter_pc + 2, 1);
256 if ((localtype & 0x80) == 0)
257 localcount = localtype;
258 else if ((localtype & 0xc0) == 0x80)
259 localcount = (((localtype & 0x3f) << 8)
260 | (read_memory_integer (enter_pc + 3, 1) & 0xff));
262 localcount = (((localtype & 0x3f) << 24)
263 | ((read_memory_integer (enter_pc + 3, 1) & 0xff) << 16)
264 | ((read_memory_integer (enter_pc + 4, 1) & 0xff) << 8)
265 | (read_memory_integer (enter_pc + 5, 1) & 0xff));
270 /* Nonzero if instruction at PC is a return instruction. */
273 ns32k_about_to_return (CORE_ADDR pc)
275 return (read_memory_integer (pc, 1) == 0x12);
278 /* Get the address of the enter opcode for this function, if it is active.
279 Returns positive address > 1 if pc is between enter/exit,
280 1 if pc before enter or after exit, 0 otherwise. */
282 ns32k_get_enter_addr (CORE_ADDR pc)
284 CORE_ADDR enter_addr;
290 if (ns32k_about_to_return (pc))
291 return 1; /* after exit */
293 enter_addr = get_pc_function_start (pc);
295 if (pc == enter_addr)
296 return 1; /* before enter */
298 op = read_memory_integer (enter_addr, 1);
301 return 0; /* function has no enter/exit */
303 return enter_addr; /* pc is between enter and exit */
307 ns32k_frame_chain (struct frame_info *frame)
309 /* In the case of the NS32000 series, the frame's nominal address is the
310 FP value, and that address is saved at the previous FP value as a
312 return (read_memory_integer (get_frame_base (frame), 4));
317 ns32k_sigtramp_saved_pc (struct frame_info *frame)
319 CORE_ADDR sigcontext_addr;
321 int ptrbytes = TYPE_LENGTH (builtin_type_void_func_ptr);
322 int sigcontext_offs = (2 * TARGET_INT_BIT) / TARGET_CHAR_BIT;
324 buf = alloca (ptrbytes);
325 /* Get sigcontext address, it is the third parameter on the stack. */
326 if (get_next_frame (frame))
327 sigcontext_addr = read_memory_typed_address
328 (DEPRECATED_FRAME_ARGS_ADDRESS (get_next_frame (frame)) + FRAME_ARGS_SKIP + sigcontext_offs,
329 builtin_type_void_data_ptr);
331 sigcontext_addr = read_memory_typed_address
332 (read_register (SP_REGNUM) + sigcontext_offs, builtin_type_void_data_ptr);
334 /* Don't cause a memory_error when accessing sigcontext in case the stack
335 layout has changed or the stack is corrupt. */
336 target_read_memory (sigcontext_addr + SIGCONTEXT_PC_OFFSET, buf, ptrbytes);
337 return extract_typed_address (buf, builtin_type_void_func_ptr);
341 ns32k_frame_saved_pc (struct frame_info *frame)
343 if ((get_frame_type (frame) == SIGTRAMP_FRAME))
344 return (ns32k_sigtramp_saved_pc (frame)); /* XXXJRT */
346 return (read_memory_integer (get_frame_base (frame) + 4, 4));
350 ns32k_frame_args_address (struct frame_info *frame)
352 if (ns32k_get_enter_addr (get_frame_pc (frame)) > 1)
353 return (get_frame_base (frame));
355 return (read_register (SP_REGNUM) - 4);
358 /* Code to initialize the addresses of the saved registers of frame described
359 by FRAME_INFO. This includes special registers such as pc and fp saved in
360 special ways in the stack frame. sp is even more special: the address we
361 return for it IS the sp for the next frame. */
364 ns32k_frame_init_saved_regs (struct frame_info *frame)
368 CORE_ADDR enter_addr, next_addr;
370 if (deprecated_get_frame_saved_regs (frame))
373 frame_saved_regs_zalloc (frame);
375 enter_addr = ns32k_get_enter_addr (get_frame_pc (frame));
378 regmask = read_memory_integer (enter_addr + 1, 1) & 0xff;
379 localcount = ns32k_localcount (enter_addr);
380 next_addr = get_frame_base (frame) + localcount;
382 for (regnum = 0; regnum < 8; regnum++)
384 if (regmask & (1 << regnum))
385 deprecated_get_frame_saved_regs (frame)[regnum] = next_addr -= 4;
388 deprecated_get_frame_saved_regs (frame)[SP_REGNUM] = get_frame_base (frame) + 4;
389 deprecated_get_frame_saved_regs (frame)[PC_REGNUM] = get_frame_base (frame) + 4;
390 deprecated_get_frame_saved_regs (frame)[DEPRECATED_FP_REGNUM] = read_memory_integer (get_frame_base (frame), 4);
392 else if (enter_addr == 1)
394 CORE_ADDR sp = read_register (SP_REGNUM);
395 deprecated_get_frame_saved_regs (frame)[PC_REGNUM] = sp;
396 deprecated_get_frame_saved_regs (frame)[SP_REGNUM] = sp + 4;
401 ns32k_push_dummy_frame (void)
403 CORE_ADDR sp = read_register (SP_REGNUM);
406 sp = push_word (sp, read_register (PC_REGNUM));
407 sp = push_word (sp, read_register (DEPRECATED_FP_REGNUM));
408 write_register (DEPRECATED_FP_REGNUM, sp);
410 for (regnum = 0; regnum < 8; regnum++)
411 sp = push_word (sp, read_register (regnum));
413 write_register (SP_REGNUM, sp);
417 ns32k_pop_frame (void)
419 struct frame_info *frame = get_current_frame ();
423 fp = get_frame_base (frame);
424 DEPRECATED_FRAME_INIT_SAVED_REGS (frame);
426 for (regnum = 0; regnum < 8; regnum++)
427 if (deprecated_get_frame_saved_regs (frame)[regnum])
428 write_register (regnum,
429 read_memory_integer (deprecated_get_frame_saved_regs (frame)[regnum], 4));
431 write_register (DEPRECATED_FP_REGNUM, read_memory_integer (fp, 4));
432 write_register (PC_REGNUM, read_memory_integer (fp + 4, 4));
433 write_register (SP_REGNUM, fp + 8);
434 flush_cached_frames ();
437 /* The NS32000 call dummy sequence:
439 enter 0xff,0 82 ff 00
440 jsr @0x00010203 7f ae c0 01 02 03
441 adjspd 0x69696969 7f a5 01 02 03 04
444 It is 16 bytes long. */
446 static LONGEST ns32k_call_dummy_words[] =
453 static int sizeof_ns32k_call_dummy_words = sizeof (ns32k_call_dummy_words);
455 #define NS32K_CALL_DUMMY_ADDR 5
456 #define NS32K_CALL_DUMMY_NARGS 11
459 ns32k_fix_call_dummy (char *dummy, CORE_ADDR pc, CORE_ADDR fun, int nargs,
460 struct value **args, struct type *type, int gcc_p)
464 flipped = fun | 0xc0000000;
465 flip_bytes (&flipped, 4);
466 store_unsigned_integer (dummy + NS32K_CALL_DUMMY_ADDR, 4, flipped);
468 flipped = - nargs * 4;
469 flip_bytes (&flipped, 4);
470 store_unsigned_integer (dummy + NS32K_CALL_DUMMY_NARGS, 4, flipped);
474 ns32k_store_struct_return (CORE_ADDR addr, CORE_ADDR sp)
476 /* On this machine, this is a no-op (Encore Umax didn't use GCC). */
480 ns32k_extract_return_value (struct type *valtype, char *regbuf, char *valbuf)
483 regbuf + DEPRECATED_REGISTER_BYTE (TYPE_CODE (valtype) == TYPE_CODE_FLT ?
484 FP0_REGNUM : 0), TYPE_LENGTH (valtype));
488 ns32k_store_return_value (struct type *valtype, char *valbuf)
490 deprecated_write_register_bytes (TYPE_CODE (valtype) == TYPE_CODE_FLT
491 ? FP0_REGNUM : 0, valbuf,
492 TYPE_LENGTH (valtype));
496 ns32k_gdbarch_init_32082 (struct gdbarch *gdbarch)
498 set_gdbarch_num_regs (gdbarch, NS32K_NUM_REGS_32082);
500 set_gdbarch_register_name (gdbarch, ns32k_register_name_32082);
501 set_gdbarch_deprecated_register_bytes (gdbarch, NS32K_REGISTER_BYTES_32082);
502 set_gdbarch_deprecated_register_byte (gdbarch, ns32k_register_byte_32082);
506 ns32k_gdbarch_init_32382 (struct gdbarch *gdbarch)
508 set_gdbarch_num_regs (gdbarch, NS32K_NUM_REGS_32382);
510 set_gdbarch_register_name (gdbarch, ns32k_register_name_32382);
511 set_gdbarch_deprecated_register_bytes (gdbarch, NS32K_REGISTER_BYTES_32382);
512 set_gdbarch_deprecated_register_byte (gdbarch, ns32k_register_byte_32382);
515 /* Initialize the current architecture based on INFO. If possible, re-use an
516 architecture from ARCHES, which is a list of architectures already created
517 during this debugging session.
519 Called e.g. at program startup, when reading a core file, and when reading
522 static struct gdbarch *
523 ns32k_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
525 struct gdbarch *gdbarch;
527 /* If there is already a candidate, use it. */
528 arches = gdbarch_list_lookup_by_info (arches, &info);
530 return arches->gdbarch;
532 gdbarch = gdbarch_alloc (&info, NULL);
534 /* NOTE: cagney/2002-12-06: This can be deleted when this arch is
535 ready to unwind the PC first (see frame.c:get_prev_frame()). */
536 set_gdbarch_deprecated_init_frame_pc (gdbarch, deprecated_init_frame_pc_default);
539 ns32k_gdbarch_init_32082 (gdbarch);
540 set_gdbarch_num_regs (gdbarch, NS32K_SP_REGNUM);
541 set_gdbarch_num_regs (gdbarch, NS32K_FP_REGNUM);
542 set_gdbarch_num_regs (gdbarch, NS32K_PC_REGNUM);
543 set_gdbarch_num_regs (gdbarch, NS32K_PS_REGNUM);
545 set_gdbarch_deprecated_register_size (gdbarch, NS32K_REGISTER_SIZE);
546 set_gdbarch_deprecated_register_raw_size (gdbarch, ns32k_register_raw_size);
547 set_gdbarch_deprecated_max_register_raw_size (gdbarch, NS32K_MAX_REGISTER_RAW_SIZE);
548 set_gdbarch_deprecated_register_virtual_size (gdbarch, ns32k_register_virtual_size);
549 set_gdbarch_deprecated_max_register_virtual_size (gdbarch,
550 NS32K_MAX_REGISTER_VIRTUAL_SIZE);
551 set_gdbarch_deprecated_register_virtual_type (gdbarch, ns32k_register_virtual_type);
553 /* Frame and stack info */
554 set_gdbarch_skip_prologue (gdbarch, umax_skip_prologue);
555 set_gdbarch_deprecated_saved_pc_after_call (gdbarch, ns32k_saved_pc_after_call);
557 set_gdbarch_frame_num_args (gdbarch, umax_frame_num_args);
558 set_gdbarch_frameless_function_invocation (gdbarch,
559 generic_frameless_function_invocation_not);
561 set_gdbarch_deprecated_frame_chain (gdbarch, ns32k_frame_chain);
562 set_gdbarch_deprecated_frame_saved_pc (gdbarch, ns32k_frame_saved_pc);
564 set_gdbarch_deprecated_frame_args_address (gdbarch, ns32k_frame_args_address);
566 set_gdbarch_deprecated_frame_init_saved_regs (gdbarch, ns32k_frame_init_saved_regs);
568 set_gdbarch_frame_args_skip (gdbarch, 8);
570 set_gdbarch_inner_than (gdbarch, core_addr_lessthan);
572 /* Return value info */
573 set_gdbarch_deprecated_store_struct_return (gdbarch, ns32k_store_struct_return);
574 set_gdbarch_deprecated_extract_return_value (gdbarch, ns32k_extract_return_value);
575 set_gdbarch_deprecated_store_return_value (gdbarch, ns32k_store_return_value);
577 /* Call dummy info */
578 set_gdbarch_deprecated_push_dummy_frame (gdbarch, ns32k_push_dummy_frame);
579 set_gdbarch_deprecated_pop_frame (gdbarch, ns32k_pop_frame);
580 set_gdbarch_call_dummy_location (gdbarch, ON_STACK);
581 set_gdbarch_deprecated_call_dummy_words (gdbarch, ns32k_call_dummy_words);
582 set_gdbarch_deprecated_sizeof_call_dummy_words (gdbarch, sizeof_ns32k_call_dummy_words);
583 set_gdbarch_deprecated_fix_call_dummy (gdbarch, ns32k_fix_call_dummy);
584 set_gdbarch_deprecated_call_dummy_start_offset (gdbarch, 3);
585 set_gdbarch_deprecated_call_dummy_breakpoint_offset (gdbarch, 15);
586 set_gdbarch_deprecated_use_generic_dummy_frames (gdbarch, 0);
587 set_gdbarch_deprecated_pc_in_call_dummy (gdbarch, deprecated_pc_in_call_dummy_on_stack);
589 /* Breakpoint info */
590 set_gdbarch_breakpoint_from_pc (gdbarch, ns32k_breakpoint_from_pc);
592 /* Should be using push_dummy_call. */
593 set_gdbarch_deprecated_dummy_write_sp (gdbarch, deprecated_write_sp);
595 set_gdbarch_print_insn (gdbarch, print_insn_ns32k);
597 /* Hook in OS ABI-specific overrides, if they have been registered. */
598 gdbarch_init_osabi (info, gdbarch);
603 extern initialize_file_ftype _initialize_ns32k_tdep; /* -Wmissing-prototypes */
606 _initialize_ns32k_tdep (void)
608 gdbarch_register (bfd_arch_ns32k, ns32k_gdbarch_init, NULL);