xref: /openbsd/gnu/usr.bin/binutils/gdb/ns32k-tdep.c (revision 63addd46)
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 *
ns32k_register_name_32082(int regno)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 *
ns32k_register_name_32382(int regno)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
ns32k_register_byte_32082(int regno)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
ns32k_register_byte_32382(int regno)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
ns32k_register_raw_size(int regno)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
ns32k_register_virtual_size(int regno)114 ns32k_register_virtual_size (int regno)
115 {
116   return ((regno >= NS32K_LP0_REGNUM) ? 8 : 4);
117 }
118 
119 static struct type *
ns32k_register_virtual_type(int regno)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
ns32k_saved_pc_after_call(struct frame_info * frame)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
umax_skip_prologue(CORE_ADDR pc)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 
165 static const unsigned char *
ns32k_breakpoint_from_pc(CORE_ADDR * pcp,int * lenp)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
umax_frame_num_args(struct frame_info * fi)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
sign_extend(int value,int bits)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
flip_bytes(void * p,int count)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
ns32k_localcount(CORE_ADDR enter_pc)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
ns32k_about_to_return(CORE_ADDR pc)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
ns32k_get_enter_addr(CORE_ADDR pc)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
ns32k_frame_chain(struct frame_info * frame)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   return (read_memory_integer (get_frame_base (frame), 4));
313 }
314 
315 
316 static CORE_ADDR
ns32k_sigtramp_saved_pc(struct frame_info * frame)317 ns32k_sigtramp_saved_pc (struct frame_info *frame)
318 {
319   CORE_ADDR sigcontext_addr;
320   char *buf;
321   int ptrbytes = TYPE_LENGTH (builtin_type_void_func_ptr);
322   int sigcontext_offs = (2 * TARGET_INT_BIT) / TARGET_CHAR_BIT;
323 
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);
330   else
331     sigcontext_addr = read_memory_typed_address
332       (read_register (SP_REGNUM) + sigcontext_offs, builtin_type_void_data_ptr);
333 
334   /* Offset to saved PC in sigcontext, from <machine/signal.h>.  Don't
335      cause a memory_error when accessing sigcontext in case the stack
336      layout has changed or the stack is corrupt.  */
337   target_read_memory (sigcontext_addr + 20, buf, ptrbytes);
338   return extract_typed_address (buf, builtin_type_void_func_ptr);
339 }
340 
341 static CORE_ADDR
ns32k_frame_saved_pc(struct frame_info * frame)342 ns32k_frame_saved_pc (struct frame_info *frame)
343 {
344   if ((get_frame_type (frame) == SIGTRAMP_FRAME))
345     return (ns32k_sigtramp_saved_pc (frame)); /* XXXJRT */
346 
347   return (read_memory_integer (get_frame_base (frame) + 4, 4));
348 }
349 
350 static CORE_ADDR
ns32k_frame_args_address(struct frame_info * frame)351 ns32k_frame_args_address (struct frame_info *frame)
352 {
353   if (ns32k_get_enter_addr (get_frame_pc (frame)) > 1)
354     return (get_frame_base (frame));
355 
356   return (read_register (SP_REGNUM) - 4);
357 }
358 
359 /* Code to initialize the addresses of the saved registers of frame described
360    by FRAME_INFO.  This includes special registers such as pc and fp saved in
361    special ways in the stack frame.  sp is even more special: the address we
362    return for it IS the sp for the next frame.  */
363 
364 static void
ns32k_frame_init_saved_regs(struct frame_info * frame)365 ns32k_frame_init_saved_regs (struct frame_info *frame)
366 {
367   int regmask, regnum;
368   int localcount;
369   CORE_ADDR enter_addr, next_addr;
370 
371   if (deprecated_get_frame_saved_regs (frame))
372     return;
373 
374   frame_saved_regs_zalloc (frame);
375 
376   enter_addr = ns32k_get_enter_addr (get_frame_pc (frame));
377   if (enter_addr > 1)
378     {
379       regmask = read_memory_integer (enter_addr + 1, 1) & 0xff;
380       localcount = ns32k_localcount (enter_addr);
381       next_addr = get_frame_base (frame) + localcount;
382 
383       for (regnum = 0; regnum < 8; regnum++)
384 	{
385           if (regmask & (1 << regnum))
386 	    deprecated_get_frame_saved_regs (frame)[regnum] = next_addr -= 4;
387 	}
388 
389       deprecated_get_frame_saved_regs (frame)[SP_REGNUM] = get_frame_base (frame) + 4;
390       deprecated_get_frame_saved_regs (frame)[PC_REGNUM] = get_frame_base (frame) + 4;
391       deprecated_get_frame_saved_regs (frame)[DEPRECATED_FP_REGNUM] = read_memory_integer (get_frame_base (frame), 4);
392     }
393   else if (enter_addr == 1)
394     {
395       CORE_ADDR sp = read_register (SP_REGNUM);
396       deprecated_get_frame_saved_regs (frame)[PC_REGNUM] = sp;
397       deprecated_get_frame_saved_regs (frame)[SP_REGNUM] = sp + 4;
398     }
399 }
400 
401 static void
ns32k_pop_frame(void)402 ns32k_pop_frame (void)
403 {
404   struct frame_info *frame = get_current_frame ();
405   CORE_ADDR fp;
406   int regnum;
407 
408   fp = get_frame_base (frame);
409   DEPRECATED_FRAME_INIT_SAVED_REGS (frame);
410 
411   for (regnum = 0; regnum < 8; regnum++)
412     if (deprecated_get_frame_saved_regs (frame)[regnum])
413       write_register (regnum,
414 		      read_memory_integer (deprecated_get_frame_saved_regs (frame)[regnum], 4));
415 
416   write_register (DEPRECATED_FP_REGNUM, read_memory_integer (fp, 4));
417   write_register (PC_REGNUM, read_memory_integer (fp + 4, 4));
418   write_register (SP_REGNUM, fp + 8);
419   flush_cached_frames ();
420 }
421 
422 static CORE_ADDR
ns32k_push_arguments(int nargs,struct value ** args,CORE_ADDR sp,int struct_return,CORE_ADDR struct_addr)423 ns32k_push_arguments (int nargs, struct value **args, CORE_ADDR sp,
424 		      int struct_return, CORE_ADDR struct_addr)
425 {
426   /* ASSERT ( !struct_return); */
427   int i;
428   for (i = nargs - 1; i >= 0; i--)
429     {
430       struct value *arg = args[i];
431       int len = TYPE_LENGTH (VALUE_ENCLOSING_TYPE (arg));
432       int container_len = len;
433       int offset;
434 
435       /* Are we going to put it at the high or low end of the
436 	 container?  */
437       if (TARGET_BYTE_ORDER == BFD_ENDIAN_BIG)
438 	offset = container_len - len;
439       else
440 	offset = 0;
441 
442       /* Stack grows downward.  */
443       sp -= container_len;
444       write_memory (sp + offset, VALUE_CONTENTS_ALL (arg), len);
445     }
446   return sp;
447 }
448 
449 
450 static void
ns32k_store_struct_return(CORE_ADDR addr,CORE_ADDR sp)451 ns32k_store_struct_return (CORE_ADDR addr, CORE_ADDR sp)
452 {
453   /* On this machine, this is a no-op (Encore Umax didn't use GCC).  */
454 }
455 
456 static void
ns32k_extract_return_value(struct type * valtype,char * regbuf,char * valbuf)457 ns32k_extract_return_value (struct type *valtype, char *regbuf, char *valbuf)
458 {
459   memcpy (valbuf,
460           regbuf + DEPRECATED_REGISTER_BYTE (TYPE_CODE (valtype) == TYPE_CODE_FLT ?
461 				  FP0_REGNUM : 0), TYPE_LENGTH (valtype));
462 }
463 
464 static void
ns32k_store_return_value(struct type * valtype,char * valbuf)465 ns32k_store_return_value (struct type *valtype, char *valbuf)
466 {
467   deprecated_write_register_bytes (TYPE_CODE (valtype) == TYPE_CODE_FLT
468 				   ? FP0_REGNUM : 0, valbuf,
469 				   TYPE_LENGTH (valtype));
470 }
471 
472 void
ns32k_gdbarch_init_32082(struct gdbarch * gdbarch)473 ns32k_gdbarch_init_32082 (struct gdbarch *gdbarch)
474 {
475   set_gdbarch_num_regs (gdbarch, NS32K_NUM_REGS_32082);
476 
477   set_gdbarch_register_name (gdbarch, ns32k_register_name_32082);
478   set_gdbarch_deprecated_register_byte (gdbarch, ns32k_register_byte_32082);
479 }
480 
481 void
ns32k_gdbarch_init_32382(struct gdbarch * gdbarch)482 ns32k_gdbarch_init_32382 (struct gdbarch *gdbarch)
483 {
484   set_gdbarch_num_regs (gdbarch, NS32K_NUM_REGS_32382);
485 
486   set_gdbarch_register_name (gdbarch, ns32k_register_name_32382);
487   set_gdbarch_deprecated_register_byte (gdbarch, ns32k_register_byte_32382);
488 }
489 
490 /* Initialize the current architecture based on INFO.  If possible, re-use an
491    architecture from ARCHES, which is a list of architectures already created
492    during this debugging session.
493 
494    Called e.g. at program startup, when reading a core file, and when reading
495    a binary file.  */
496 
497 static struct gdbarch *
ns32k_gdbarch_init(struct gdbarch_info info,struct gdbarch_list * arches)498 ns32k_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
499 {
500   struct gdbarch *gdbarch;
501 
502   /* If there is already a candidate, use it.  */
503   arches = gdbarch_list_lookup_by_info (arches, &info);
504   if (arches != NULL)
505     return arches->gdbarch;
506 
507   gdbarch = gdbarch_alloc (&info, NULL);
508 
509   /* NOTE: cagney/2002-12-06: This can be deleted when this arch is
510      ready to unwind the PC first (see frame.c:get_prev_frame()).  */
511   set_gdbarch_deprecated_init_frame_pc (gdbarch, deprecated_init_frame_pc_default);
512 
513   /* Register info */
514   ns32k_gdbarch_init_32082 (gdbarch);
515   set_gdbarch_num_regs (gdbarch, NS32K_SP_REGNUM);
516   set_gdbarch_num_regs (gdbarch, NS32K_FP_REGNUM);
517   set_gdbarch_num_regs (gdbarch, NS32K_PC_REGNUM);
518   set_gdbarch_num_regs (gdbarch, NS32K_PS_REGNUM);
519 
520   set_gdbarch_deprecated_register_size (gdbarch, NS32K_REGISTER_SIZE);
521   set_gdbarch_deprecated_register_raw_size (gdbarch, ns32k_register_raw_size);
522   set_gdbarch_deprecated_register_virtual_size (gdbarch, ns32k_register_virtual_size);
523   set_gdbarch_deprecated_register_virtual_type (gdbarch, ns32k_register_virtual_type);
524 
525   /* Frame and stack info */
526   set_gdbarch_skip_prologue (gdbarch, umax_skip_prologue);
527   set_gdbarch_deprecated_saved_pc_after_call (gdbarch, ns32k_saved_pc_after_call);
528 
529   set_gdbarch_frame_num_args (gdbarch, umax_frame_num_args);
530 
531   set_gdbarch_deprecated_frame_chain (gdbarch, ns32k_frame_chain);
532   set_gdbarch_deprecated_frame_saved_pc (gdbarch, ns32k_frame_saved_pc);
533 
534   set_gdbarch_deprecated_frame_args_address (gdbarch, ns32k_frame_args_address);
535 
536   set_gdbarch_deprecated_frame_init_saved_regs (gdbarch, ns32k_frame_init_saved_regs);
537 
538   set_gdbarch_frame_args_skip (gdbarch, 8);
539 
540   set_gdbarch_inner_than (gdbarch, core_addr_lessthan);
541 
542   /* Return value info */
543   set_gdbarch_deprecated_store_struct_return (gdbarch, ns32k_store_struct_return);
544   set_gdbarch_deprecated_extract_return_value (gdbarch, ns32k_extract_return_value);
545   set_gdbarch_deprecated_store_return_value (gdbarch, ns32k_store_return_value);
546 
547   /* Call dummy info */
548   set_gdbarch_deprecated_pop_frame (gdbarch, ns32k_pop_frame);
549   set_gdbarch_call_dummy_location (gdbarch, ON_STACK);
550   set_gdbarch_deprecated_push_arguments (gdbarch, ns32k_push_arguments);
551 
552   /* Breakpoint info */
553   set_gdbarch_breakpoint_from_pc (gdbarch, ns32k_breakpoint_from_pc);
554 
555   /* Should be using push_dummy_call.  */
556   set_gdbarch_deprecated_dummy_write_sp (gdbarch, deprecated_write_sp);
557 
558   set_gdbarch_print_insn (gdbarch, print_insn_ns32k);
559 
560   /* Hook in OS ABI-specific overrides, if they have been registered.  */
561   gdbarch_init_osabi (info, gdbarch);
562 
563   return (gdbarch);
564 }
565 
566 extern initialize_file_ftype _initialize_ns32k_tdep; /* -Wmissing-prototypes */
567 
568 void
_initialize_ns32k_tdep(void)569 _initialize_ns32k_tdep (void)
570 {
571   gdbarch_register (bfd_arch_ns32k, ns32k_gdbarch_init, NULL);
572 
573 }
574