2004-01-18 Michael Chastain <mec.gnu@mindspring.com>
[deliverable/binutils-gdb.git] / gdb / ns32k-tdep.c
1 /* Target dependent code for the NS32000, for GDB.
2
3 Copyright 1986, 1988, 1991, 1992, 1994, 1995, 1998, 1999, 2000,
4 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
5
6 This file is part of GDB.
7
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.
12
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.
17
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. */
22
23 #include "defs.h"
24 #include "frame.h"
25 #include "gdbtypes.h"
26 #include "gdbcore.h"
27 #include "inferior.h"
28 #include "regcache.h"
29 #include "target.h"
30 #include "arch-utils.h"
31 #include "osabi.h"
32 #include "dis-asm.h"
33
34 #include "ns32k-tdep.h"
35 #include "gdb_string.h"
36
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);
41
42 static const char *
43 ns32k_register_name_32082 (int regno)
44 {
45 static char *register_names[] =
46 {
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",
51 };
52
53 if (regno < 0)
54 return NULL;
55 if (regno >= sizeof (register_names) / sizeof (*register_names))
56 return NULL;
57
58 return (register_names[regno]);
59 }
60
61 static const char *
62 ns32k_register_name_32382 (int regno)
63 {
64 static char *register_names[] =
65 {
66 "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
67 "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7",
68 "sp", "fp", "pc", "ps",
69 "fsr",
70 "l0", "l1", "l2", "l3", "l4", "l5", "l6", "l7", "xx",
71 };
72
73 if (regno < 0)
74 return NULL;
75 if (regno >= sizeof (register_names) / sizeof (*register_names))
76 return NULL;
77
78 return (register_names[regno]);
79 }
80
81 static int
82 ns32k_register_byte_32082 (int regno)
83 {
84 if (regno >= NS32K_LP0_REGNUM)
85 return (NS32K_LP0_REGNUM * 4) + ((regno - NS32K_LP0_REGNUM) * 8);
86
87 return (regno * 4);
88 }
89
90 static int
91 ns32k_register_byte_32382 (int regno)
92 {
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. */
98
99 return ((regno < NS32K_LP0_REGNUM ? regno
100 : (regno - NS32K_LP0_REGNUM) & 1 ? regno - 1
101 : (regno - NS32K_LP0_REGNUM + FP0_REGNUM)) * 4);
102 }
103
104 static int
105 ns32k_register_raw_size (int regno)
106 {
107 /* All registers are 4 bytes, except for the doubled floating
108 registers. */
109
110 return ((regno >= NS32K_LP0_REGNUM) ? 8 : 4);
111 }
112
113 static int
114 ns32k_register_virtual_size (int regno)
115 {
116 return ((regno >= NS32K_LP0_REGNUM) ? 8 : 4);
117 }
118
119 static struct type *
120 ns32k_register_virtual_type (int regno)
121 {
122 if (regno < FP0_REGNUM)
123 return (builtin_type_int);
124
125 if (regno < FP0_REGNUM + 8)
126 return (builtin_type_float);
127
128 if (regno < NS32K_LP0_REGNUM)
129 return (builtin_type_int);
130
131 return (builtin_type_double);
132 }
133
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
137 instructions. */
138
139 static CORE_ADDR
140 ns32k_saved_pc_after_call (struct frame_info *frame)
141 {
142 return (read_memory_integer (read_register (SP_REGNUM), 4));
143 }
144
145 /* Advance PC across any function entry prologue instructions
146 to reach some "real" code. */
147
148 static CORE_ADDR
149 umax_skip_prologue (CORE_ADDR pc)
150 {
151 unsigned char op = read_memory_integer (pc, 1);
152 if (op == 0x82)
153 {
154 op = read_memory_integer (pc + 2, 1);
155 if ((op & 0x80) == 0)
156 pc += 3;
157 else if ((op & 0xc0) == 0x80)
158 pc += 4;
159 else
160 pc += 6;
161 }
162 return pc;
163 }
164 \f
165 static const unsigned char *
166 ns32k_breakpoint_from_pc (CORE_ADDR *pcp, int *lenp)
167 {
168 static const unsigned char breakpoint_insn[] = { 0xf2 };
169
170 *lenp = sizeof (breakpoint_insn);
171 return breakpoint_insn;
172 }
173
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. */
179
180 static int
181 umax_frame_num_args (struct frame_info *fi)
182 {
183 int numargs;
184 CORE_ADDR pc;
185 CORE_ADDR enter_addr;
186 unsigned int insn;
187 unsigned int addr_mode;
188 int width;
189
190 numargs = -1;
191 enter_addr = ns32k_get_enter_addr (get_frame_pc (fi));
192 if (enter_addr > 0)
193 {
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;
199 insn = insn & 0x7ff;
200 if ((insn & 0x7fc) == 0x57c
201 && addr_mode == 0x14) /* immediate */
202 {
203 if (insn == 0x57c) /* adjspb */
204 width = 1;
205 else if (insn == 0x57d) /* adjspw */
206 width = 2;
207 else if (insn == 0x57f) /* adjspd */
208 width = 4;
209 else
210 internal_error (__FILE__, __LINE__, "bad else");
211 numargs = read_memory_integer (pc + 2, width);
212 if (width > 1)
213 flip_bytes (&numargs, width);
214 numargs = -sign_extend (numargs, width * 8) / 4;
215 }
216 }
217 return numargs;
218 }
219
220 static int
221 sign_extend (int value, int bits)
222 {
223 value = value & ((1 << bits) - 1);
224 return (value & (1 << (bits - 1))
225 ? value | (~((1 << bits) - 1))
226 : value);
227 }
228
229 static void
230 flip_bytes (void *p, int count)
231 {
232 char tmp;
233 char *ptr = 0;
234
235 while (count > 0)
236 {
237 tmp = *ptr;
238 ptr[0] = ptr[count - 1];
239 ptr[count - 1] = tmp;
240 ptr++;
241 count -= 2;
242 }
243 }
244
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. */
248
249 static int
250 ns32k_localcount (CORE_ADDR enter_pc)
251 {
252 unsigned char localtype;
253 int localcount;
254
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));
261 else
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));
266 return localcount;
267 }
268
269
270 /* Nonzero if instruction at PC is a return instruction. */
271
272 static int
273 ns32k_about_to_return (CORE_ADDR pc)
274 {
275 return (read_memory_integer (pc, 1) == 0x12);
276 }
277
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. */
281 static CORE_ADDR
282 ns32k_get_enter_addr (CORE_ADDR pc)
283 {
284 CORE_ADDR enter_addr;
285 unsigned char op;
286
287 if (pc == 0)
288 return 0;
289
290 if (ns32k_about_to_return (pc))
291 return 1; /* after exit */
292
293 enter_addr = get_pc_function_start (pc);
294
295 if (pc == enter_addr)
296 return 1; /* before enter */
297
298 op = read_memory_integer (enter_addr, 1);
299
300 if (op != 0x82)
301 return 0; /* function has no enter/exit */
302
303 return enter_addr; /* pc is between enter and exit */
304 }
305
306 static CORE_ADDR
307 ns32k_frame_chain (struct frame_info *frame)
308 {
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
311 4-byte word. */
312
313 if (deprecated_inside_entry_file (get_frame_pc (frame)))
314 return 0;
315
316 return (read_memory_integer (get_frame_base (frame), 4));
317 }
318
319
320 static CORE_ADDR
321 ns32k_sigtramp_saved_pc (struct frame_info *frame)
322 {
323 CORE_ADDR sigcontext_addr;
324 char *buf;
325 int ptrbytes = TYPE_LENGTH (builtin_type_void_func_ptr);
326 int sigcontext_offs = (2 * TARGET_INT_BIT) / TARGET_CHAR_BIT;
327
328 buf = alloca (ptrbytes);
329 /* Get sigcontext address, it is the third parameter on the stack. */
330 if (get_next_frame (frame))
331 sigcontext_addr = read_memory_typed_address
332 (DEPRECATED_FRAME_ARGS_ADDRESS (get_next_frame (frame)) + FRAME_ARGS_SKIP + sigcontext_offs,
333 builtin_type_void_data_ptr);
334 else
335 sigcontext_addr = read_memory_typed_address
336 (read_register (SP_REGNUM) + sigcontext_offs, builtin_type_void_data_ptr);
337
338 /* Don't cause a memory_error when accessing sigcontext in case the stack
339 layout has changed or the stack is corrupt. */
340 target_read_memory (sigcontext_addr + SIGCONTEXT_PC_OFFSET, buf, ptrbytes);
341 return extract_typed_address (buf, builtin_type_void_func_ptr);
342 }
343
344 static CORE_ADDR
345 ns32k_frame_saved_pc (struct frame_info *frame)
346 {
347 if ((get_frame_type (frame) == SIGTRAMP_FRAME))
348 return (ns32k_sigtramp_saved_pc (frame)); /* XXXJRT */
349
350 return (read_memory_integer (get_frame_base (frame) + 4, 4));
351 }
352
353 static CORE_ADDR
354 ns32k_frame_args_address (struct frame_info *frame)
355 {
356 if (ns32k_get_enter_addr (get_frame_pc (frame)) > 1)
357 return (get_frame_base (frame));
358
359 return (read_register (SP_REGNUM) - 4);
360 }
361
362 /* Code to initialize the addresses of the saved registers of frame described
363 by FRAME_INFO. This includes special registers such as pc and fp saved in
364 special ways in the stack frame. sp is even more special: the address we
365 return for it IS the sp for the next frame. */
366
367 static void
368 ns32k_frame_init_saved_regs (struct frame_info *frame)
369 {
370 int regmask, regnum;
371 int localcount;
372 CORE_ADDR enter_addr, next_addr;
373
374 if (deprecated_get_frame_saved_regs (frame))
375 return;
376
377 frame_saved_regs_zalloc (frame);
378
379 enter_addr = ns32k_get_enter_addr (get_frame_pc (frame));
380 if (enter_addr > 1)
381 {
382 regmask = read_memory_integer (enter_addr + 1, 1) & 0xff;
383 localcount = ns32k_localcount (enter_addr);
384 next_addr = get_frame_base (frame) + localcount;
385
386 for (regnum = 0; regnum < 8; regnum++)
387 {
388 if (regmask & (1 << regnum))
389 deprecated_get_frame_saved_regs (frame)[regnum] = next_addr -= 4;
390 }
391
392 deprecated_get_frame_saved_regs (frame)[SP_REGNUM] = get_frame_base (frame) + 4;
393 deprecated_get_frame_saved_regs (frame)[PC_REGNUM] = get_frame_base (frame) + 4;
394 deprecated_get_frame_saved_regs (frame)[DEPRECATED_FP_REGNUM] = read_memory_integer (get_frame_base (frame), 4);
395 }
396 else if (enter_addr == 1)
397 {
398 CORE_ADDR sp = read_register (SP_REGNUM);
399 deprecated_get_frame_saved_regs (frame)[PC_REGNUM] = sp;
400 deprecated_get_frame_saved_regs (frame)[SP_REGNUM] = sp + 4;
401 }
402 }
403
404 static void
405 ns32k_push_dummy_frame (void)
406 {
407 CORE_ADDR sp = read_register (SP_REGNUM);
408 int regnum;
409
410 sp = push_word (sp, read_register (PC_REGNUM));
411 sp = push_word (sp, read_register (DEPRECATED_FP_REGNUM));
412 write_register (DEPRECATED_FP_REGNUM, sp);
413
414 for (regnum = 0; regnum < 8; regnum++)
415 sp = push_word (sp, read_register (regnum));
416
417 write_register (SP_REGNUM, sp);
418 }
419
420 static void
421 ns32k_pop_frame (void)
422 {
423 struct frame_info *frame = get_current_frame ();
424 CORE_ADDR fp;
425 int regnum;
426
427 fp = get_frame_base (frame);
428 DEPRECATED_FRAME_INIT_SAVED_REGS (frame);
429
430 for (regnum = 0; regnum < 8; regnum++)
431 if (deprecated_get_frame_saved_regs (frame)[regnum])
432 write_register (regnum,
433 read_memory_integer (deprecated_get_frame_saved_regs (frame)[regnum], 4));
434
435 write_register (DEPRECATED_FP_REGNUM, read_memory_integer (fp, 4));
436 write_register (PC_REGNUM, read_memory_integer (fp + 4, 4));
437 write_register (SP_REGNUM, fp + 8);
438 flush_cached_frames ();
439 }
440 \f
441 /* The NS32000 call dummy sequence:
442
443 enter 0xff,0 82 ff 00
444 jsr @0x00010203 7f ae c0 01 02 03
445 adjspd 0x69696969 7f a5 01 02 03 04
446 bpt f2
447
448 It is 16 bytes long. */
449
450 static LONGEST ns32k_call_dummy_words[] =
451 {
452 0x7f00ff82,
453 0x0201c0ae,
454 0x01a57f03,
455 0xf2040302
456 };
457 static int sizeof_ns32k_call_dummy_words = sizeof (ns32k_call_dummy_words);
458
459 #define NS32K_CALL_DUMMY_ADDR 5
460 #define NS32K_CALL_DUMMY_NARGS 11
461
462 static void
463 ns32k_fix_call_dummy (char *dummy, CORE_ADDR pc, CORE_ADDR fun, int nargs,
464 struct value **args, struct type *type, int gcc_p)
465 {
466 int flipped;
467
468 flipped = fun | 0xc0000000;
469 flip_bytes (&flipped, 4);
470 store_unsigned_integer (dummy + NS32K_CALL_DUMMY_ADDR, 4, flipped);
471
472 flipped = - nargs * 4;
473 flip_bytes (&flipped, 4);
474 store_unsigned_integer (dummy + NS32K_CALL_DUMMY_NARGS, 4, flipped);
475 }
476 \f
477 static void
478 ns32k_store_struct_return (CORE_ADDR addr, CORE_ADDR sp)
479 {
480 /* On this machine, this is a no-op (Encore Umax didn't use GCC). */
481 }
482
483 static void
484 ns32k_extract_return_value (struct type *valtype, char *regbuf, char *valbuf)
485 {
486 memcpy (valbuf,
487 regbuf + DEPRECATED_REGISTER_BYTE (TYPE_CODE (valtype) == TYPE_CODE_FLT ?
488 FP0_REGNUM : 0), TYPE_LENGTH (valtype));
489 }
490
491 static void
492 ns32k_store_return_value (struct type *valtype, char *valbuf)
493 {
494 deprecated_write_register_bytes (TYPE_CODE (valtype) == TYPE_CODE_FLT
495 ? FP0_REGNUM : 0, valbuf,
496 TYPE_LENGTH (valtype));
497 }
498
499 void
500 ns32k_gdbarch_init_32082 (struct gdbarch *gdbarch)
501 {
502 set_gdbarch_num_regs (gdbarch, NS32K_NUM_REGS_32082);
503
504 set_gdbarch_register_name (gdbarch, ns32k_register_name_32082);
505 set_gdbarch_deprecated_register_bytes (gdbarch, NS32K_REGISTER_BYTES_32082);
506 set_gdbarch_deprecated_register_byte (gdbarch, ns32k_register_byte_32082);
507 }
508
509 void
510 ns32k_gdbarch_init_32382 (struct gdbarch *gdbarch)
511 {
512 set_gdbarch_num_regs (gdbarch, NS32K_NUM_REGS_32382);
513
514 set_gdbarch_register_name (gdbarch, ns32k_register_name_32382);
515 set_gdbarch_deprecated_register_bytes (gdbarch, NS32K_REGISTER_BYTES_32382);
516 set_gdbarch_deprecated_register_byte (gdbarch, ns32k_register_byte_32382);
517 }
518
519 /* Initialize the current architecture based on INFO. If possible, re-use an
520 architecture from ARCHES, which is a list of architectures already created
521 during this debugging session.
522
523 Called e.g. at program startup, when reading a core file, and when reading
524 a binary file. */
525
526 static struct gdbarch *
527 ns32k_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
528 {
529 struct gdbarch *gdbarch;
530
531 /* If there is already a candidate, use it. */
532 arches = gdbarch_list_lookup_by_info (arches, &info);
533 if (arches != NULL)
534 return arches->gdbarch;
535
536 gdbarch = gdbarch_alloc (&info, NULL);
537
538 /* NOTE: cagney/2002-12-06: This can be deleted when this arch is
539 ready to unwind the PC first (see frame.c:get_prev_frame()). */
540 set_gdbarch_deprecated_init_frame_pc (gdbarch, deprecated_init_frame_pc_default);
541
542 /* Register info */
543 ns32k_gdbarch_init_32082 (gdbarch);
544 set_gdbarch_num_regs (gdbarch, NS32K_SP_REGNUM);
545 set_gdbarch_num_regs (gdbarch, NS32K_FP_REGNUM);
546 set_gdbarch_num_regs (gdbarch, NS32K_PC_REGNUM);
547 set_gdbarch_num_regs (gdbarch, NS32K_PS_REGNUM);
548
549 set_gdbarch_deprecated_register_size (gdbarch, NS32K_REGISTER_SIZE);
550 set_gdbarch_deprecated_register_raw_size (gdbarch, ns32k_register_raw_size);
551 set_gdbarch_deprecated_max_register_raw_size (gdbarch, NS32K_MAX_REGISTER_RAW_SIZE);
552 set_gdbarch_deprecated_register_virtual_size (gdbarch, ns32k_register_virtual_size);
553 set_gdbarch_deprecated_max_register_virtual_size (gdbarch,
554 NS32K_MAX_REGISTER_VIRTUAL_SIZE);
555 set_gdbarch_deprecated_register_virtual_type (gdbarch, ns32k_register_virtual_type);
556
557 /* Frame and stack info */
558 set_gdbarch_skip_prologue (gdbarch, umax_skip_prologue);
559 set_gdbarch_deprecated_saved_pc_after_call (gdbarch, ns32k_saved_pc_after_call);
560
561 set_gdbarch_frame_num_args (gdbarch, umax_frame_num_args);
562 set_gdbarch_frameless_function_invocation (gdbarch,
563 generic_frameless_function_invocation_not);
564
565 set_gdbarch_deprecated_frame_chain (gdbarch, ns32k_frame_chain);
566 set_gdbarch_deprecated_frame_saved_pc (gdbarch, ns32k_frame_saved_pc);
567
568 set_gdbarch_deprecated_frame_args_address (gdbarch, ns32k_frame_args_address);
569
570 set_gdbarch_deprecated_frame_init_saved_regs (gdbarch, ns32k_frame_init_saved_regs);
571
572 set_gdbarch_frame_args_skip (gdbarch, 8);
573
574 set_gdbarch_inner_than (gdbarch, core_addr_lessthan);
575
576 /* Return value info */
577 set_gdbarch_deprecated_store_struct_return (gdbarch, ns32k_store_struct_return);
578 set_gdbarch_deprecated_extract_return_value (gdbarch, ns32k_extract_return_value);
579 set_gdbarch_deprecated_store_return_value (gdbarch, ns32k_store_return_value);
580
581 /* Call dummy info */
582 set_gdbarch_deprecated_push_dummy_frame (gdbarch, ns32k_push_dummy_frame);
583 set_gdbarch_deprecated_pop_frame (gdbarch, ns32k_pop_frame);
584 set_gdbarch_call_dummy_location (gdbarch, ON_STACK);
585 set_gdbarch_deprecated_call_dummy_words (gdbarch, ns32k_call_dummy_words);
586 set_gdbarch_deprecated_sizeof_call_dummy_words (gdbarch, sizeof_ns32k_call_dummy_words);
587 set_gdbarch_deprecated_fix_call_dummy (gdbarch, ns32k_fix_call_dummy);
588 set_gdbarch_deprecated_call_dummy_start_offset (gdbarch, 3);
589 set_gdbarch_deprecated_call_dummy_breakpoint_offset (gdbarch, 15);
590 set_gdbarch_deprecated_use_generic_dummy_frames (gdbarch, 0);
591 set_gdbarch_deprecated_pc_in_call_dummy (gdbarch, deprecated_pc_in_call_dummy_on_stack);
592
593 /* Breakpoint info */
594 set_gdbarch_breakpoint_from_pc (gdbarch, ns32k_breakpoint_from_pc);
595
596 /* Should be using push_dummy_call. */
597 set_gdbarch_deprecated_dummy_write_sp (gdbarch, deprecated_write_sp);
598
599 set_gdbarch_print_insn (gdbarch, print_insn_ns32k);
600
601 /* Hook in OS ABI-specific overrides, if they have been registered. */
602 gdbarch_init_osabi (info, gdbarch);
603
604 return (gdbarch);
605 }
606
607 extern initialize_file_ftype _initialize_ns32k_tdep; /* -Wmissing-prototypes */
608
609 void
610 _initialize_ns32k_tdep (void)
611 {
612 gdbarch_register (bfd_arch_ns32k, ns32k_gdbarch_init, NULL);
613
614 }
This page took 0.044085 seconds and 4 git commands to generate.