]> Git Repo - binutils.git/blob - gdb/ns32k-tdep.c
* gas/m68k/all.exp: xfail non-ELF targets on pcrel test.
[binutils.git] / gdb / ns32k-tdep.c
1 /* Target dependent code for the NS32000, for GDB.
2    Copyright 1986, 1988, 1991, 1992, 1994, 1995, 1998, 1999, 2000, 2001,
3    2002 Free Software Foundation, Inc.
4
5    This file is part of GDB.
6
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.
11
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.
16
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.  */
21
22 #include "defs.h"
23 #include "frame.h"
24 #include "gdbtypes.h"
25 #include "gdbcore.h"
26 #include "inferior.h"
27 #include "regcache.h"
28 #include "target.h"
29
30 #include "arch-utils.h"
31
32 #include "ns32k-tdep.h"
33
34 static int sign_extend (int value, int bits);
35 static CORE_ADDR ns32k_get_enter_addr (CORE_ADDR);
36 static int ns32k_localcount (CORE_ADDR enter_pc);
37 static void flip_bytes (void *, int);
38
39 static const char *
40 ns32k_register_name_32082 (int regno)
41 {
42   static char *register_names[] =
43   {
44     "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
45     "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7",
46     "sp", "fp", "pc", "ps",
47     "l0", "l1", "l2", "l3", "xx",
48   };
49
50   if (regno < 0)
51     return NULL;
52   if (regno >= sizeof (register_names) / sizeof (*register_names))
53     return NULL;
54
55   return (register_names[regno]);
56 }
57
58 static const char *
59 ns32k_register_name_32382 (int regno)
60 {
61   static char *register_names[] =
62   {
63     "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
64     "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7",
65     "sp", "fp", "pc", "ps",
66     "fsr",
67     "l0", "l1", "l2", "l3", "l4", "l5", "l6", "l7", "xx",
68   };
69
70   if (regno < 0)
71     return NULL;
72   if (regno >= sizeof (register_names) / sizeof (*register_names))
73     return NULL;
74
75   return (register_names[regno]);
76 }
77
78 static int
79 ns32k_register_byte_32082 (int regno)
80 {
81   if (regno >= NS32K_LP0_REGNUM)
82     return (NS32K_LP0_REGNUM * 4) + ((regno - NS32K_LP0_REGNUM) * 8);
83
84   return (regno * 4);
85 }
86
87 static int
88 ns32k_register_byte_32382 (int regno)
89 {
90   /* This is a bit yuk.  The even numbered double precision floating
91      point long registers occupy the same space as the even:odd numbered
92      single precision floating point registers, but the extra 32381 FPU
93      registers are at the end.  Doing it this way is compatible for both
94      32081 and 32381 equipped machines.  */
95
96   return ((regno < NS32K_LP0_REGNUM ? regno
97            : (regno - NS32K_LP0_REGNUM) & 1 ? regno - 1
98            : (regno - NS32K_LP0_REGNUM + FP0_REGNUM)) * 4);
99 }
100
101 static int
102 ns32k_register_raw_size (int regno)
103 {
104   /* All registers are 4 bytes, except for the doubled floating
105      registers.  */
106
107   return ((regno >= NS32K_LP0_REGNUM) ? 8 : 4);
108 }
109
110 static int
111 ns32k_register_virtual_size (int regno)
112 {
113   return ((regno >= NS32K_LP0_REGNUM) ? 8 : 4);
114 }
115
116 static struct type *
117 ns32k_register_virtual_type (int regno)
118 {
119   if (regno < FP0_REGNUM)
120     return (builtin_type_int);
121
122   if (regno < FP0_REGNUM + 8)
123     return (builtin_type_float);
124
125   if (regno < NS32K_LP0_REGNUM)
126     return (builtin_type_int); 
127
128   return (builtin_type_double);
129 }
130
131 /* Immediately after a function call, return the saved PC.  Can't
132    always go through the frames for this because on some systems,
133    the new frame is not set up until the new function executes some
134    instructions.  */
135
136 static CORE_ADDR
137 ns32k_saved_pc_after_call (struct frame_info *frame)
138 {
139   return (read_memory_integer (read_register (SP_REGNUM), 4));
140 }
141
142 /* Advance PC across any function entry prologue instructions
143    to reach some "real" code.  */
144
145 static CORE_ADDR
146 umax_skip_prologue (CORE_ADDR pc)
147 {
148   register unsigned char op = read_memory_integer (pc, 1);
149   if (op == 0x82)
150     {
151       op = read_memory_integer (pc + 2, 1);
152       if ((op & 0x80) == 0)
153         pc += 3;
154       else if ((op & 0xc0) == 0x80)
155         pc += 4;
156       else
157         pc += 6;
158     }
159   return pc;
160 }
161 \f
162 static const unsigned char *
163 ns32k_breakpoint_from_pc (CORE_ADDR *pcp, int *lenp)
164 {
165   static const unsigned char breakpoint_insn[] = { 0xf2 };
166
167   *lenp = sizeof (breakpoint_insn);
168   return breakpoint_insn;
169 }
170
171 /* Return number of args passed to a frame.
172    Can return -1, meaning no way to tell.
173    Encore's C compiler often reuses same area on stack for args,
174    so this will often not work properly.  If the arg names
175    are known, it's likely most of them will be printed. */
176
177 static int
178 umax_frame_num_args (struct frame_info *fi)
179 {
180   int numargs;
181   CORE_ADDR pc;
182   CORE_ADDR enter_addr;
183   unsigned int insn;
184   unsigned int addr_mode;
185   int width;
186
187   numargs = -1;
188   enter_addr = ns32k_get_enter_addr ((fi)->pc);
189   if (enter_addr > 0)
190     {
191       pc = ((enter_addr == 1)
192             ? SAVED_PC_AFTER_CALL (fi)
193             : FRAME_SAVED_PC (fi));
194       insn = read_memory_integer (pc, 2);
195       addr_mode = (insn >> 11) & 0x1f;
196       insn = insn & 0x7ff;
197       if ((insn & 0x7fc) == 0x57c
198           && addr_mode == 0x14) /* immediate */
199         {
200           if (insn == 0x57c)    /* adjspb */
201             width = 1;
202           else if (insn == 0x57d)       /* adjspw */
203             width = 2;
204           else if (insn == 0x57f)       /* adjspd */
205             width = 4;
206           else
207             internal_error (__FILE__, __LINE__, "bad else");
208           numargs = read_memory_integer (pc + 2, width);
209           if (width > 1)
210             flip_bytes (&numargs, width);
211           numargs = -sign_extend (numargs, width * 8) / 4;
212         }
213     }
214   return numargs;
215 }
216
217 static int
218 sign_extend (int value, int bits)
219 {
220   value = value & ((1 << bits) - 1);
221   return (value & (1 << (bits - 1))
222           ? value | (~((1 << bits) - 1))
223           : value);
224 }
225
226 static void
227 flip_bytes (void *p, int count)
228 {
229   char tmp;
230   char *ptr = 0;
231
232   while (count > 0)
233     {
234       tmp = *ptr;
235       ptr[0] = ptr[count - 1];
236       ptr[count - 1] = tmp;
237       ptr++;
238       count -= 2;
239     }
240 }
241
242 /* Return the number of locals in the current frame given a
243    pc pointing to the enter instruction.  This is used by
244    ns32k_frame_init_saved_regs.  */
245
246 static int
247 ns32k_localcount (CORE_ADDR enter_pc)
248 {
249   unsigned char localtype;
250   int localcount;
251
252   localtype = read_memory_integer (enter_pc + 2, 1);
253   if ((localtype & 0x80) == 0)
254     localcount = localtype;
255   else if ((localtype & 0xc0) == 0x80)
256     localcount = (((localtype & 0x3f) << 8)
257                   | (read_memory_integer (enter_pc + 3, 1) & 0xff));
258   else
259     localcount = (((localtype & 0x3f) << 24)
260                   | ((read_memory_integer (enter_pc + 3, 1) & 0xff) << 16)
261                   | ((read_memory_integer (enter_pc + 4, 1) & 0xff) << 8)
262                   | (read_memory_integer (enter_pc + 5, 1) & 0xff));
263   return localcount;
264 }
265
266
267 /* Nonzero if instruction at PC is a return instruction.  */
268
269 static int
270 ns32k_about_to_return (CORE_ADDR pc)
271 {
272   return (read_memory_integer (pc, 1) == 0x12);
273 }
274
275 /* Get the address of the enter opcode for this function, if it is active.
276    Returns positive address > 1 if pc is between enter/exit, 
277    1 if pc before enter or after exit, 0 otherwise. */
278 static CORE_ADDR
279 ns32k_get_enter_addr (CORE_ADDR pc)
280 {
281   CORE_ADDR enter_addr;
282   unsigned char op;
283
284   if (pc == 0)
285     return 0;
286
287   if (ns32k_about_to_return (pc))
288     return 1;                   /* after exit */
289
290   enter_addr = get_pc_function_start (pc);
291
292   if (pc == enter_addr)
293     return 1;                   /* before enter */
294
295   op = read_memory_integer (enter_addr, 1);
296
297   if (op != 0x82)
298     return 0;                   /* function has no enter/exit */
299
300   return enter_addr;            /* pc is between enter and exit */
301 }
302
303 static CORE_ADDR
304 ns32k_frame_chain (struct frame_info *frame)
305 {
306   /* In the case of the NS32000 series, the frame's nominal address is the
307      FP value, and that address is saved at the previous FP value as a
308      4-byte word.  */
309
310   if (inside_entry_file (frame->pc))
311     return 0;
312
313   return (read_memory_integer (frame->frame, 4));
314 }
315
316 static CORE_ADDR
317 ns32k_frame_saved_pc (struct frame_info *frame)
318 {
319   if (frame->signal_handler_caller)
320     return (sigtramp_saved_pc (frame)); /* XXXJRT */
321
322   return (read_memory_integer (frame->frame + 4, 4));
323 }
324
325 static CORE_ADDR
326 ns32k_frame_args_address (struct frame_info *frame)
327 {
328   if (ns32k_get_enter_addr (frame->pc) > 1)
329     return (frame->frame);
330
331   return (read_register (SP_REGNUM) - 4);
332 }
333
334 static CORE_ADDR
335 ns32k_frame_locals_address (struct frame_info *frame)
336 {
337   return (frame->frame);
338 }
339
340 /* Code to initialize the addresses of the saved registers of frame described
341    by FRAME_INFO.  This includes special registers such as pc and fp saved in
342    special ways in the stack frame.  sp is even more special: the address we
343    return for it IS the sp for the next frame.  */
344
345 static void
346 ns32k_frame_init_saved_regs (struct frame_info *frame)
347 {
348   int regmask, regnum;
349   int localcount;
350   CORE_ADDR enter_addr, next_addr;
351
352   if (frame->saved_regs)
353     return;
354
355   frame_saved_regs_zalloc (frame);
356
357   enter_addr = ns32k_get_enter_addr (frame->pc);
358   if (enter_addr > 1)
359     {
360       regmask = read_memory_integer (enter_addr + 1, 1) & 0xff;
361       localcount = ns32k_localcount (enter_addr);
362       next_addr = frame->frame + localcount;
363
364       for (regnum = 0; regnum < 8; regnum++)
365         {
366           if (regmask & (1 << regnum))
367             frame->saved_regs[regnum] = next_addr -= 4;
368         }
369
370       frame->saved_regs[SP_REGNUM] = frame->frame + 4;
371       frame->saved_regs[PC_REGNUM] = frame->frame + 4;
372       frame->saved_regs[FP_REGNUM] = read_memory_integer (frame->frame, 4);
373     }
374   else if (enter_addr == 1)
375     {
376       CORE_ADDR sp = read_register (SP_REGNUM);
377       frame->saved_regs[PC_REGNUM] = sp;
378       frame->saved_regs[SP_REGNUM] = sp + 4;
379     }
380 }
381
382 static void
383 ns32k_push_dummy_frame (void)
384 {
385   CORE_ADDR sp = read_register (SP_REGNUM);
386   int regnum;
387
388   sp = push_word (sp, read_register (PC_REGNUM));
389   sp = push_word (sp, read_register (FP_REGNUM));
390   write_register (FP_REGNUM, sp);
391
392   for (regnum = 0; regnum < 8; regnum++)
393     sp = push_word (sp, read_register (regnum));
394
395   write_register (SP_REGNUM, sp);
396 }
397
398 static void
399 ns32k_pop_frame (void)
400 {
401   struct frame_info *frame = get_current_frame ();
402   CORE_ADDR fp;
403   int regnum;
404
405   fp = frame->frame;
406   FRAME_INIT_SAVED_REGS (frame);
407
408   for (regnum = 0; regnum < 8; regnum++)
409     if (frame->saved_regs[regnum])
410       write_register (regnum,
411                       read_memory_integer (frame->saved_regs[regnum], 4));
412
413   write_register (FP_REGNUM, read_memory_integer (fp, 4));
414   write_register (PC_REGNUM, read_memory_integer (fp + 4, 4));
415   write_register (SP_REGNUM, fp + 8);
416   flush_cached_frames ();
417 }
418 \f
419 /* The NS32000 call dummy sequence:
420
421         enter   0xff,0                  82 ff 00
422         jsr     @0x00010203             7f ae c0 01 02 03
423         adjspd  0x69696969              7f a5 01 02 03 04
424         bpt                             f2
425
426    It is 16 bytes long.  */
427
428 static LONGEST ns32k_call_dummy_words[] =
429 {
430   0x7f00ff82,
431   0x0201c0ae,
432   0x01a57f03,
433   0xf2040302
434 };
435 static int sizeof_ns32k_call_dummy_words = sizeof (ns32k_call_dummy_words);
436
437 #define NS32K_CALL_DUMMY_ADDR         5
438 #define NS32K_CALL_DUMMY_NARGS        11
439
440 static void
441 ns32k_fix_call_dummy (char *dummy, CORE_ADDR pc, CORE_ADDR fun, int nargs,
442                       struct value **args, struct type *type, int gcc_p)
443 {
444   int flipped;
445
446   flipped = fun | 0xc0000000;
447   flip_bytes (&flipped, 4);
448   store_unsigned_integer (dummy + NS32K_CALL_DUMMY_ADDR, 4, flipped);
449
450   flipped = - nargs * 4;
451   flip_bytes (&flipped, 4);
452   store_unsigned_integer (dummy + NS32K_CALL_DUMMY_NARGS, 4, flipped);
453 }
454 \f
455 static void
456 ns32k_store_struct_return (CORE_ADDR addr, CORE_ADDR sp)
457 {
458   /* On this machine, this is a no-op (Encore Umax didn't use GCC).  */
459 }
460
461 static void
462 ns32k_extract_return_value (struct type *valtype, char *regbuf, char *valbuf)
463 {
464   memcpy (valbuf,
465           regbuf + REGISTER_BYTE (TYPE_CODE (valtype) == TYPE_CODE_FLT ?
466                                   FP0_REGNUM : 0), TYPE_LENGTH (valtype));
467 }
468
469 static void
470 ns32k_store_return_value (struct type *valtype, char *valbuf)
471 {
472   write_register_bytes (TYPE_CODE (valtype) == TYPE_CODE_FLT ?
473                         FP0_REGNUM : 0, valbuf, TYPE_LENGTH (valtype));
474 }
475
476 static CORE_ADDR
477 ns32k_extract_struct_value_address (char *regbuf)
478 {
479   return (extract_address (regbuf + REGISTER_BYTE (0), REGISTER_RAW_SIZE (0)));
480 }
481 \f
482 void
483 ns32k_gdbarch_init_32082 (struct gdbarch *gdbarch)
484 {
485   set_gdbarch_num_regs (gdbarch, NS32K_NUM_REGS_32082);
486
487   set_gdbarch_register_name (gdbarch, ns32k_register_name_32082);
488   set_gdbarch_register_bytes (gdbarch, NS32K_REGISTER_BYTES_32082);
489   set_gdbarch_register_byte (gdbarch, ns32k_register_byte_32082);
490 }
491
492 void
493 ns32k_gdbarch_init_32382 (struct gdbarch *gdbarch)
494 {
495   set_gdbarch_num_regs (gdbarch, NS32K_NUM_REGS_32382);
496
497   set_gdbarch_register_name (gdbarch, ns32k_register_name_32382);
498   set_gdbarch_register_bytes (gdbarch, NS32K_REGISTER_BYTES_32382);
499   set_gdbarch_register_byte (gdbarch, ns32k_register_byte_32382);
500 }
501
502 /* Initialize the current architecture based on INFO.  If possible, re-use an
503    architecture from ARCHES, which is a list of architectures already created
504    during this debugging session.
505
506    Called e.g. at program startup, when reading a core file, and when reading
507    a binary file.  */
508
509 static struct gdbarch *
510 ns32k_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
511 {
512   struct gdbarch_tdep *tdep;
513   struct gdbarch *gdbarch;
514   enum gdb_osabi osabi = GDB_OSABI_UNKNOWN;
515
516   /* Try to determine the OS ABI of the object we are loading.  */
517   if (info.abfd != NULL)
518     {
519       osabi = gdbarch_lookup_osabi (info.abfd);
520     }
521
522   /* Find a candidate among extant architectures.  */
523   for (arches = gdbarch_list_lookup_by_info (arches, &info);
524        arches != NULL;
525        arches = gdbarch_list_lookup_by_info (arches->next, &info))
526     {
527       /* Make sure the OS ABI selection matches.  */
528       tdep = gdbarch_tdep (arches->gdbarch);
529       if (tdep && tdep->osabi == osabi)
530         return arches->gdbarch;
531     }
532
533   tdep = xmalloc (sizeof (struct gdbarch_tdep));
534   gdbarch = gdbarch_alloc (&info, tdep);
535
536   tdep->osabi = osabi;
537
538   /* Register info */
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);
544
545   set_gdbarch_register_size (gdbarch, NS32K_REGISTER_SIZE);
546   set_gdbarch_register_raw_size (gdbarch, ns32k_register_raw_size);
547   set_gdbarch_max_register_raw_size (gdbarch, NS32K_MAX_REGISTER_RAW_SIZE);
548   set_gdbarch_register_virtual_size (gdbarch, ns32k_register_virtual_size);
549   set_gdbarch_max_register_virtual_size (gdbarch,
550                                          NS32K_MAX_REGISTER_VIRTUAL_SIZE);
551   set_gdbarch_register_virtual_type (gdbarch, ns32k_register_virtual_type);
552
553   /* Frame and stack info */
554   set_gdbarch_skip_prologue (gdbarch, umax_skip_prologue);
555   set_gdbarch_saved_pc_after_call (gdbarch, ns32k_saved_pc_after_call);
556
557   set_gdbarch_frame_num_args (gdbarch, umax_frame_num_args);
558   set_gdbarch_frameless_function_invocation (gdbarch,
559                                    generic_frameless_function_invocation_not);
560   
561   set_gdbarch_frame_chain (gdbarch, ns32k_frame_chain);
562   set_gdbarch_frame_chain_valid (gdbarch, func_frame_chain_valid);
563   set_gdbarch_frame_saved_pc (gdbarch, ns32k_frame_saved_pc);
564
565   set_gdbarch_frame_args_address (gdbarch, ns32k_frame_args_address);
566   set_gdbarch_frame_locals_address (gdbarch, ns32k_frame_locals_address);
567
568   set_gdbarch_frame_init_saved_regs (gdbarch, ns32k_frame_init_saved_regs);
569
570   set_gdbarch_frame_args_skip (gdbarch, 8);
571
572   set_gdbarch_inner_than (gdbarch, core_addr_lessthan);
573
574   /* Return value info */
575   set_gdbarch_store_struct_return (gdbarch, ns32k_store_struct_return);
576   set_gdbarch_deprecated_extract_return_value (gdbarch, ns32k_extract_return_value);
577   set_gdbarch_deprecated_store_return_value (gdbarch, ns32k_store_return_value);
578   set_gdbarch_deprecated_extract_struct_value_address (gdbarch,
579                                             ns32k_extract_struct_value_address);
580
581   /* Call dummy info */
582   set_gdbarch_push_dummy_frame (gdbarch, ns32k_push_dummy_frame);
583   set_gdbarch_pop_frame (gdbarch, ns32k_pop_frame);
584   set_gdbarch_call_dummy_location (gdbarch, ON_STACK);
585   set_gdbarch_call_dummy_p (gdbarch, 1);
586   set_gdbarch_call_dummy_words (gdbarch, ns32k_call_dummy_words);
587   set_gdbarch_sizeof_call_dummy_words (gdbarch, sizeof_ns32k_call_dummy_words);
588   set_gdbarch_fix_call_dummy (gdbarch, ns32k_fix_call_dummy);
589   set_gdbarch_call_dummy_start_offset (gdbarch, 3);
590   set_gdbarch_call_dummy_breakpoint_offset_p (gdbarch, 0);
591   set_gdbarch_use_generic_dummy_frames (gdbarch, 0);
592   set_gdbarch_pc_in_call_dummy (gdbarch, pc_in_call_dummy_on_stack);
593   set_gdbarch_call_dummy_stack_adjust_p (gdbarch, 0);
594
595   /* Breakpoint info */
596   set_gdbarch_decr_pc_after_break (gdbarch, 0);
597   set_gdbarch_breakpoint_from_pc (gdbarch, ns32k_breakpoint_from_pc);
598
599   /* Misc info */
600   set_gdbarch_function_start_offset (gdbarch, 0);
601
602   /* Hook in OS ABI-specific overrides, if they have been registered.  */
603   gdbarch_init_osabi (info, gdbarch, osabi);
604
605   return (gdbarch);
606 }
607
608 static void
609 ns32k_dump_tdep (struct gdbarch *current_gdbarch, struct ui_file *file)
610 {
611   struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch);
612
613   if (tdep == NULL)
614     return;
615
616   fprintf_unfiltered (file, "ns32k_dump_tdep: OS ABI = %s\n",
617                       gdbarch_osabi_name (tdep->osabi));
618 }
619
620 void
621 _initialize_ns32k_tdep (void)
622 {
623   gdbarch_register (bfd_arch_ns32k, ns32k_gdbarch_init, ns32k_dump_tdep);
624
625   tm_print_insn = print_insn_ns32k;
626 }
This page took 0.059338 seconds and 4 git commands to generate.