]> Git Repo - binutils.git/blob - gdb/h8500-tdep.c
added nlmstub.def to Things-to-keep
[binutils.git] / gdb / h8500-tdep.c
1 /* Target-machine dependent code for Hitachi H8/500, for GDB.
2    Copyright (C) 1993, 1994 Free Software Foundation, Inc.
3
4 This file is part of GDB.
5
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
10
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
19
20 /*
21  Contributed by Steve Chamberlain
22                 [email protected]
23  */
24
25 #include "defs.h"
26 #include "frame.h"
27 #include "obstack.h"
28 #include "symtab.h"
29 #include "gdbtypes.h"
30 #include "gdbcmd.h"
31 #include "value.h"
32 #include "dis-asm.h"
33 #include "../opcodes/h8500-opc.h"
34 ;
35
36 #define UNSIGNED_SHORT(X) ((X) & 0xffff)
37 int code_size = 2;
38 int data_size = 2;
39
40 /* Shape of an H8/500 frame :
41
42
43    arg-n
44    ..
45    arg-2
46    arg-1
47    return address <2 or 4 bytes>
48    old fp         <2 bytes>
49    auto-n
50    ..
51    auto-1
52    saved registers
53
54 */
55
56
57 /* an easy to debug H8 stack frame looks like:
58 0x6df6          push    r6
59 0x0d76          mov.w   r7,r6
60 0x6dfn          push    reg
61 0x7905 nnnn     mov.w  #n,r5    or   0x1b87  subs #2,sp
62 0x1957          sub.w  r5,sp
63
64  */
65
66 #define IS_PUSH(x) (((x) & 0xff00)==0x6d00)
67 #define IS_LINK_8(x) ((x) == 0x17)
68 #define IS_LINK_16(x) ((x) == 0x1f)
69 #define IS_MOVE_FP(x) ((x) == 0x0d76)
70 #define IS_MOV_SP_FP(x) ((x) == 0x0d76)
71 #define IS_SUB2_SP(x) ((x) == 0x1b87)
72 #define IS_MOVK_R5(x) ((x) == 0x7905)
73 #define IS_SUB_R5SP(x) ((x) == 0x1957)
74
75 #define LINK_8 0x17
76 #define LINK_16 0x1f
77
78 int minimum_mode = 1;
79 CORE_ADDR examine_prologue ();
80
81 void frame_find_saved_regs ();
82
83
84 CORE_ADDR
85 h8500_skip_prologue (start_pc)
86      CORE_ADDR start_pc;
87
88 {
89   short int w;
90
91  w = read_memory_integer (start_pc, 1);
92   if (w == LINK_8)
93     {
94       start_pc += 2;
95       w = read_memory_integer (start_pc, 1);
96     }
97
98   if (w == LINK_16)
99     {
100       start_pc += 3;
101       w = read_memory_integer (start_pc, 2);
102     }
103
104   return start_pc;
105 }
106
107 int
108 print_insn (memaddr, stream)
109      CORE_ADDR memaddr;
110      GDB_FILE *stream;
111 {
112   disassemble_info info;
113   GDB_INIT_DISASSEMBLE_INFO (info, stream);
114   return print_insn_h8500 (memaddr, &info);
115 }
116
117 /* Given a GDB frame, determine the address of the calling function's frame.
118    This will be used to create a new GDB frame struct, and then
119    INIT_EXTRA_FRAME_INFO and INIT_FRAME_PC will be called for the new frame.
120
121    For us, the frame address is its stack pointer value, so we look up
122    the function prologue to determine the caller's sp value, and return it.  */
123
124 CORE_ADDR
125 h8500_frame_chain (thisframe)
126      struct frame_info *thisframe;
127 {
128   if (!inside_entry_file (thisframe->pc))
129     return (read_memory_integer (FRAME_FP (thisframe), PTR_SIZE));
130   else
131     return 0;
132 }
133
134
135 /* Fetch the instruction at ADDR, returning 0 if ADDR is beyond LIM or
136    is not the address of a valid instruction, the address of the next
137    instruction beyond ADDR otherwise.  *PWORD1 receives the first word
138    of the instruction.*/
139
140 CORE_ADDR
141 NEXT_PROLOGUE_INSN (addr, lim, pword1)
142      CORE_ADDR addr;
143      CORE_ADDR lim;
144      char *pword1;
145 {
146   if (addr < lim + 8)
147     {
148       read_memory (addr, pword1, 1);
149       read_memory (addr, pword1 + 1, 1);
150       return 1;
151     }
152   return 0;
153 }
154
155 /* Examine the prologue of a function.  `ip' points to the first instruction.
156    `limit' is the limit of the prologue (e.g. the addr of the first
157    linenumber, or perhaps the program counter if we're stepping through).
158    `frame_sp' is the stack pointer value in use in this frame.
159    `fsr' is a pointer to a frame_saved_regs structure into which we put
160    info about the registers saved by this frame.
161    `fi' is a struct frame_info pointer; we fill in various fields in it
162    to reflect the offsets of the arg pointer and the locals pointer.  */
163
164
165 /* Return the saved PC from this frame. */
166
167 CORE_ADDR
168 frame_saved_pc (frame)
169      struct frame_info *frame;
170 {
171   return read_memory_integer (FRAME_FP (frame) + 2, PTR_SIZE);
172 }
173
174 CORE_ADDR
175 frame_locals_address (fi)
176      struct frame_info *fi;
177 {
178   return fi->frame;
179 }
180
181 /* Return the address of the argument block for the frame
182    described by FI.  Returns 0 if the address is unknown.  */
183
184 CORE_ADDR
185 frame_args_address (fi)
186      struct frame_info *fi;
187 {
188   return fi->frame;
189 }
190
191 void
192 h8300_pop_frame ()
193 {
194   unsigned regnum;
195   struct frame_saved_regs fsr;
196   struct frame_info *frame = get_current_frame ();
197
198   get_frame_saved_regs (frame, &fsr);
199
200   for (regnum = 0; regnum < 8; regnum++)
201     {
202       if (fsr.regs[regnum])
203           write_register (regnum, read_memory_short (fsr.regs[regnum]));
204
205       flush_cached_frames ();
206     }
207
208 }
209
210 void
211 print_register_hook (regno)
212 {
213   if (regno == CCR_REGNUM)
214     {
215       /* CCR register */
216
217       int C, Z, N, V;
218       unsigned char b[2];
219       unsigned char l;
220
221       read_relative_register_raw_bytes (regno, b);
222       l = b[1];
223       printf_unfiltered ("\t");
224       printf_unfiltered ("I-%d - ", (l & 0x80) != 0);
225       N = (l & 0x8) != 0;
226       Z = (l & 0x4) != 0;
227       V = (l & 0x2) != 0;
228       C = (l & 0x1) != 0;
229       printf_unfiltered ("N-%d ", N);
230       printf_unfiltered ("Z-%d ", Z);
231       printf_unfiltered ("V-%d ", V);
232       printf_unfiltered ("C-%d ", C);
233       if ((C | Z) == 0)
234         printf_unfiltered ("u> ");
235       if ((C | Z) == 1)
236         printf_unfiltered ("u<= ");
237       if ((C == 0))
238         printf_unfiltered ("u>= ");
239       if (C == 1)
240         printf_unfiltered ("u< ");
241       if (Z == 0)
242         printf_unfiltered ("!= ");
243       if (Z == 1)
244         printf_unfiltered ("== ");
245       if ((N ^ V) == 0)
246         printf_unfiltered (">= ");
247       if ((N ^ V) == 1)
248         printf_unfiltered ("< ");
249       if ((Z | (N ^ V)) == 0)
250         printf_unfiltered ("> ");
251       if ((Z | (N ^ V)) == 1)
252         printf_unfiltered ("<= ");
253     }
254 }
255
256 int
257 h8500_register_size (regno)
258      int regno;
259 {
260   switch (regno) {
261   case SEG_C_REGNUM:
262   case SEG_D_REGNUM:
263   case SEG_E_REGNUM:
264   case SEG_T_REGNUM:
265     return 1;
266   case R0_REGNUM:
267   case R1_REGNUM:
268   case R2_REGNUM:
269   case R3_REGNUM:
270   case R4_REGNUM:
271   case R5_REGNUM:
272   case R6_REGNUM:
273   case R7_REGNUM:
274   case CCR_REGNUM:
275     return 2;
276
277   case PR0_REGNUM:
278   case PR1_REGNUM:
279   case PR2_REGNUM:
280   case PR3_REGNUM:
281   case PR4_REGNUM:
282   case PR5_REGNUM:
283   case PR6_REGNUM:
284   case PR7_REGNUM:
285   case PC_REGNUM:
286     return 4;
287   }
288 }
289
290 struct type *
291 h8500_register_virtual_type (regno)
292      int regno;
293 {
294   switch (regno)
295     {
296     case SEG_C_REGNUM:
297     case SEG_E_REGNUM:
298     case SEG_D_REGNUM:
299     case SEG_T_REGNUM:
300       return builtin_type_unsigned_char;
301     case R0_REGNUM:
302     case R1_REGNUM:
303     case R2_REGNUM:
304     case R3_REGNUM:
305     case R4_REGNUM:
306     case R5_REGNUM:
307     case R6_REGNUM:
308     case R7_REGNUM:
309     case CCR_REGNUM:
310       return builtin_type_unsigned_short;
311     case PR0_REGNUM:
312     case PR1_REGNUM:
313     case PR2_REGNUM:
314     case PR3_REGNUM:
315     case PR4_REGNUM:
316     case PR5_REGNUM:
317     case PR6_REGNUM:
318     case PR7_REGNUM:
319     case PC_REGNUM:
320       return builtin_type_unsigned_long;
321     default:
322       abort ();
323     }
324 }
325
326 /* Put here the code to store, into a struct frame_saved_regs,
327    the addresses of the saved registers of frame described by FRAME_INFO.
328    This includes special registers such as pc and fp saved in special
329    ways in the stack frame.  sp is even more special:
330    the address we return for it IS the sp for the next frame.  */
331
332 void
333 frame_find_saved_regs (frame_info, frame_saved_regs)
334      struct frame_info *frame_info;
335      struct frame_saved_regs *frame_saved_regs;
336
337 {
338   register int regnum;
339   register int regmask;
340   register CORE_ADDR next_addr;
341   register CORE_ADDR pc;
342   unsigned char thebyte;
343
344   memset (frame_saved_regs, '\0', sizeof *frame_saved_regs);
345
346   if ((frame_info)->pc >= (frame_info)->frame - CALL_DUMMY_LENGTH - FP_REGNUM * 4 - 4
347       && (frame_info)->pc <= (frame_info)->frame)
348     {
349       next_addr = (frame_info)->frame;
350       pc = (frame_info)->frame - CALL_DUMMY_LENGTH - FP_REGNUM * 4 - 4;
351     }
352   else
353     {
354       pc = get_pc_function_start ((frame_info)->pc);
355       /* Verify we have a link a6 instruction next;
356          if not we lose.  If we win, find the address above the saved
357          regs using the amount of storage from the link instruction.
358          */
359
360       thebyte = read_memory_integer (pc, 1);
361       if (0x1f == thebyte)
362         next_addr = (frame_info)->frame + read_memory_integer (pc += 1, 2), pc += 2;
363       else if (0x17 == thebyte)
364         next_addr = (frame_info)->frame + read_memory_integer (pc += 1, 1), pc += 1;
365       else
366         goto lose;
367 #if 0
368       /* FIXME steve */
369       /* If have an add:g.waddal #-n, sp next, adjust next_addr.  */
370       if ((0x0c0177777 & read_memory_integer (pc, 2)) == 0157774)
371         next_addr += read_memory_integer (pc += 2, 4), pc += 4;
372 #endif
373     }
374
375   thebyte = read_memory_integer (pc, 1);
376   if (thebyte == 0x12)
377     {
378       /* Got stm */
379       pc++;
380       regmask = read_memory_integer (pc, 1);
381       pc++;
382       for (regnum = 0; regnum < 8; regnum++, regmask >>= 1)
383         {
384           if (regmask & 1)
385             {
386               (frame_saved_regs)->regs[regnum] = (next_addr += 2) - 2;
387             }
388         }
389       thebyte = read_memory_integer (pc, 1);
390     }
391   /* Maybe got a load of pushes */
392   while (thebyte == 0xbf)
393     {
394       pc++;
395       regnum = read_memory_integer (pc, 1) & 0x7;
396       pc++;
397       (frame_saved_regs)->regs[regnum] = (next_addr += 2) - 2;
398       thebyte = read_memory_integer (pc, 1);
399     }
400
401 lose:;
402
403   /* Remember the address of the frame pointer */
404   (frame_saved_regs)->regs[FP_REGNUM] = (frame_info)->frame;
405
406   /* This is where the old sp is hidden */
407   (frame_saved_regs)->regs[SP_REGNUM] = (frame_info)->frame;
408
409   /* And the PC - remember the pushed FP is always two bytes long */
410   (frame_saved_regs)->regs[PC_REGNUM] = (frame_info)->frame + 2;
411 }
412
413 saved_pc_after_call (frame)
414 {
415   int x;
416   int a = read_register (SP_REGNUM);
417   x = read_memory_integer (a, code_size);
418   if (code_size == 2)
419     {
420       /* Stick current code segement onto top */
421       x &= 0xffff;
422       x |= read_register (SEG_C_REGNUM) << 16;
423     }
424   x &= 0xffffff;
425   return x;
426 }
427
428
429 /* Nonzero if instruction at PC is a return instruction.  */
430
431 about_to_return (pc)
432 {
433   int b1 = read_memory_integer (pc, 1);
434
435   switch (b1)
436     {
437     case 0x14:                  /* rtd #8 */
438     case 0x1c:                  /* rtd #16 */
439     case 0x19:                  /* rts */
440     case 0x1a:                  /* rte */
441       return 1;
442     case 0x11:
443       {
444         int b2 = read_memory_integer (pc + 1, 1);
445         switch (b2)
446           {
447           case 0x18:            /* prts */
448           case 0x14:            /* prtd #8 */
449           case 0x16:            /* prtd #16 */
450             return 1;
451           }
452       }
453     }
454   return 0;
455 }
456
457
458 void
459 h8500_set_pointer_size (newsize)
460      int newsize;
461 {
462   static int oldsize = 0;
463
464   if (oldsize != newsize)
465     {
466       printf_unfiltered ("pointer size set to %d bits\n", newsize);
467       oldsize = newsize;
468       if (newsize == 32)
469         {
470           minimum_mode = 0;
471         }
472       else
473         {
474           minimum_mode = 1;
475         }
476       _initialize_gdbtypes ();
477     }
478 }
479
480
481 struct cmd_list_element *setmemorylist;
482
483
484 #define C(name,a,b,c) name () { h8500_set_pointer_size(a); code_size = b; data_size = c; }
485
486 C(big_command, 32,4,4);
487 C(medium_command, 32, 4,2);
488 C(compact_command, 32,2,4);
489 C(small_command, 16,2,2);
490
491 static void
492 set_memory (args, from_tty)
493      char *args;
494      int from_tty;
495 {
496   printf_unfiltered ("\"set memory\" must be followed by the name of a memory subcommand.\n");
497   help_list (setmemorylist, "set memory ", -1, gdb_stdout);
498 }
499
500 /* See if variable name is ppc or pr[0-7] */
501
502 int
503 h8500_is_trapped_internalvar (name)
504      char *name;
505 {
506   if (name[0] != 'p')
507     return 0;
508
509   if (strcmp (name + 1, "pc") == 0)
510     return 1;
511
512   if (name[1] == 'r'
513       && name[2] >= '0'
514       && name[2] <= '7'
515       && name[3] == '\000')
516     return 1;
517   else
518     return 0;
519 }
520
521 value_ptr
522 h8500_value_of_trapped_internalvar (var)
523      struct internalvar *var;
524 {
525   LONGEST regval;
526   unsigned char regbuf[4];
527   int page_regnum, regnum;
528
529   regnum = var->name[2] == 'c' ? PC_REGNUM : var->name[2] - '0';
530
531   switch (var->name[2])
532     {
533     case 'c':
534       page_regnum = SEG_C_REGNUM;
535       break;
536     case '0':
537     case '1':
538     case '2':
539     case '3':
540       page_regnum = SEG_D_REGNUM;
541       break;
542     case '4':
543     case '5':
544       page_regnum = SEG_E_REGNUM;
545       break;
546     case '6':
547     case '7':
548       page_regnum = SEG_T_REGNUM;
549       break;
550     }
551
552   get_saved_register (regbuf, NULL, NULL, selected_frame, page_regnum, NULL);
553   regval = regbuf[0] << 16;
554
555   get_saved_register (regbuf, NULL, NULL, selected_frame, regnum, NULL);
556   regval |= regbuf[0] << 8 | regbuf[1]; /* XXX host/target byte order */
557
558   free (var->value);            /* Free up old value */
559
560   var->value = value_from_longest (builtin_type_unsigned_long, regval);
561   release_value (var->value);   /* Unchain new value */
562
563   VALUE_LVAL (var->value) = lval_internalvar;
564   VALUE_INTERNALVAR (var->value) = var;
565   return var->value;
566 }
567
568 void
569 h8500_set_trapped_internalvar (var, newval, bitpos, bitsize, offset)
570      struct internalvar *var;
571      int offset, bitpos, bitsize;
572      value_ptr newval;
573 {
574   char *page_regnum, *regnum;
575   char expression[100];
576   unsigned new_regval;
577   struct type *type;
578   enum type_code newval_type_code;
579
580   type = VALUE_TYPE (newval);
581   newval_type_code = TYPE_CODE (type);
582
583   if ((newval_type_code != TYPE_CODE_INT
584        && newval_type_code != TYPE_CODE_PTR)
585       || TYPE_LENGTH (type) != sizeof (new_regval))
586     error ("Illegal type (%s) for assignment to $%s\n",
587            TYPE_NAME (type), var->name);
588
589   new_regval = *(long *) VALUE_CONTENTS_RAW (newval);
590
591   regnum = var->name + 1;
592
593   switch (var->name[2])
594     {
595     case 'c':
596       page_regnum = "cp";
597       break;
598     case '0':
599     case '1':
600     case '2':
601     case '3':
602       page_regnum = "dp";
603       break;
604     case '4':
605     case '5':
606       page_regnum = "ep";
607       break;
608     case '6':
609     case '7':
610       page_regnum = "tp";
611       break;
612     }
613
614   sprintf (expression, "$%s=%d", page_regnum, new_regval >> 16);
615   parse_and_eval (expression);
616
617   sprintf (expression, "$%s=%d", regnum, new_regval & 0xffff);
618   parse_and_eval (expression);
619 }
620
621 void
622 _initialize_h8500_tdep ()
623 {
624   add_prefix_cmd ("memory", no_class, set_memory,
625                   "set the memory model", &setmemorylist, "set memory ", 0,
626                   &setlist);
627
628   add_cmd ("small", class_support, small_command,
629            "Set small memory model. (16 bit code, 16 bit data)", &setmemorylist);
630
631   add_cmd ("big", class_support, big_command,
632            "Set big memory model. (32 bit code, 32 bit data)", &setmemorylist);
633
634   add_cmd ("medium", class_support, medium_command,
635            "Set medium memory model. (32 bit code, 16 bit data)", &setmemorylist);
636
637   add_cmd ("compact", class_support, compact_command,
638            "Set compact memory model. (16 bit code, 32 bit data)", &setmemorylist);
639
640 }
641
642 CORE_ADDR
643 h8500_read_sp ()
644 {
645   return read_register (PR7_REGNUM);
646 }
647
648 void
649 h8500_write_sp (v)
650      CORE_ADDR v;
651 {
652   write_register (PR7_REGNUM, v);
653 }
654
655 CORE_ADDR
656 h8500_read_pc (pid)
657      int pid;
658 {
659   return read_register (PC_REGNUM);
660 }
661
662 void
663 h8500_write_pc (v, pid)
664      CORE_ADDR v;
665      int pid;
666 {
667   write_register (PC_REGNUM, v);
668 }
669
670 CORE_ADDR
671 h8500_read_fp ()
672 {
673   return read_register (PR6_REGNUM);
674 }
675
676 void
677 h8500_write_fp (v)
678      CORE_ADDR v;
679 {
680   write_register (PR6_REGNUM, v);
681 }
682
This page took 0.062416 seconds and 4 git commands to generate.