]> Git Repo - binutils.git/blob - gdb/h8500-tdep.c
Modified Files:
[binutils.git] / gdb / h8500-tdep.c
1 /* Target-machine dependent code for Hitachi H8/500, for GDB.
2    Copyright (C) 1993 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 FRAME_ADDR
125 h8500_frame_chain (thisframe)
126      FRAME 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      FRAME frame;
170 {
171   return read_memory_integer ((frame)->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 *fi;
197
198   FRAME frame = get_current_frame ();
199
200   fi = get_frame_info (frame);
201   get_frame_saved_regs (fi, &fsr);
202
203   for (regnum = 0; regnum < 8; regnum++)
204     {
205       if (fsr.regs[regnum])
206         {
207           write_register (regnum, read_memory_short (fsr.regs[regnum]));
208         }
209
210       flush_cached_frames ();
211       set_current_frame (create_new_frame (read_register (FP_REGNUM),
212                                            read_pc ()));
213
214     }
215
216 }
217
218 void
219 print_register_hook (regno)
220 {
221   if (regno == CCR_REGNUM)
222     {
223       /* CCR register */
224
225       int C, Z, N, V;
226       unsigned char b[2];
227       unsigned char l;
228
229       read_relative_register_raw_bytes (regno, b);
230       l = b[1];
231       printf_unfiltered ("\t");
232       printf_unfiltered ("I-%d - ", (l & 0x80) != 0);
233       N = (l & 0x8) != 0;
234       Z = (l & 0x4) != 0;
235       V = (l & 0x2) != 0;
236       C = (l & 0x1) != 0;
237       printf_unfiltered ("N-%d ", N);
238       printf_unfiltered ("Z-%d ", Z);
239       printf_unfiltered ("V-%d ", V);
240       printf_unfiltered ("C-%d ", C);
241       if ((C | Z) == 0)
242         printf_unfiltered ("u> ");
243       if ((C | Z) == 1)
244         printf_unfiltered ("u<= ");
245       if ((C == 0))
246         printf_unfiltered ("u>= ");
247       if (C == 1)
248         printf_unfiltered ("u< ");
249       if (Z == 0)
250         printf_unfiltered ("!= ");
251       if (Z == 1)
252         printf_unfiltered ("== ");
253       if ((N ^ V) == 0)
254         printf_unfiltered (">= ");
255       if ((N ^ V) == 1)
256         printf_unfiltered ("< ");
257       if ((Z | (N ^ V)) == 0)
258         printf_unfiltered ("> ");
259       if ((Z | (N ^ V)) == 1)
260         printf_unfiltered ("<= ");
261     }
262 }
263
264 int
265 h8500_register_size (regno)
266      int regno;
267 {
268   switch (regno) {
269   case SEG_C_REGNUM:
270   case SEG_D_REGNUM:
271   case SEG_E_REGNUM:
272   case SEG_T_REGNUM:
273     return 1;
274   case R0_REGNUM:
275   case R1_REGNUM:
276   case R2_REGNUM:
277   case R3_REGNUM:
278   case R4_REGNUM:
279   case R5_REGNUM:
280   case R6_REGNUM:
281   case R7_REGNUM:
282   case CCR_REGNUM:
283     return 2;
284
285   case PR0_REGNUM:
286   case PR1_REGNUM:
287   case PR2_REGNUM:
288   case PR3_REGNUM:
289   case PR4_REGNUM:
290   case PR5_REGNUM:
291   case PR6_REGNUM:
292   case PR7_REGNUM:
293   case PC_REGNUM:
294     return 4;
295   }
296 }
297
298 struct type *
299 h8500_register_virtual_type (regno)
300      int regno;
301 {
302   switch (regno)
303     {
304     case SEG_C_REGNUM:
305     case SEG_E_REGNUM:
306     case SEG_D_REGNUM:
307     case SEG_T_REGNUM:
308       return builtin_type_unsigned_char;
309     case R0_REGNUM:
310     case R1_REGNUM:
311     case R2_REGNUM:
312     case R3_REGNUM:
313     case R4_REGNUM:
314     case R5_REGNUM:
315     case R6_REGNUM:
316     case R7_REGNUM:
317     case CCR_REGNUM:
318       return builtin_type_unsigned_short;
319     case PR0_REGNUM:
320     case PR1_REGNUM:
321     case PR2_REGNUM:
322     case PR3_REGNUM:
323     case PR4_REGNUM:
324     case PR5_REGNUM:
325     case PR6_REGNUM:
326     case PR7_REGNUM:
327     case PC_REGNUM:
328       return builtin_type_unsigned_long;
329     default:
330       abort ();
331     }
332 }
333
334 /* Put here the code to store, into a struct frame_saved_regs,
335    the addresses of the saved registers of frame described by FRAME_INFO.
336    This includes special registers such as pc and fp saved in special
337    ways in the stack frame.  sp is even more special:
338    the address we return for it IS the sp for the next frame.  */
339
340 void
341 frame_find_saved_regs (frame_info, frame_saved_regs)
342      struct frame_info *frame_info;
343      struct frame_saved_regs *frame_saved_regs;
344
345 {
346   register int regnum;
347   register int regmask;
348   register CORE_ADDR next_addr;
349   register CORE_ADDR pc;
350   unsigned char thebyte;
351
352   memset (frame_saved_regs, '\0', sizeof *frame_saved_regs);
353
354   if ((frame_info)->pc >= (frame_info)->frame - CALL_DUMMY_LENGTH - FP_REGNUM * 4 - 4
355       && (frame_info)->pc <= (frame_info)->frame)
356     {
357       next_addr = (frame_info)->frame;
358       pc = (frame_info)->frame - CALL_DUMMY_LENGTH - FP_REGNUM * 4 - 4;
359     }
360   else
361     {
362       pc = get_pc_function_start ((frame_info)->pc);
363       /* Verify we have a link a6 instruction next;
364          if not we lose.  If we win, find the address above the saved
365          regs using the amount of storage from the link instruction.
366          */
367
368       thebyte = read_memory_integer (pc, 1);
369       if (0x1f == thebyte)
370         next_addr = (frame_info)->frame + read_memory_integer (pc += 1, 2), pc += 2;
371       else if (0x17 == thebyte)
372         next_addr = (frame_info)->frame + read_memory_integer (pc += 1, 1), pc += 1;
373       else
374         goto lose;
375 #if 0
376       /* FIXME steve */
377       /* If have an add:g.waddal #-n, sp next, adjust next_addr.  */
378       if ((0x0c0177777 & read_memory_integer (pc, 2)) == 0157774)
379         next_addr += read_memory_integer (pc += 2, 4), pc += 4;
380 #endif
381     }
382
383   thebyte = read_memory_integer (pc, 1);
384   if (thebyte == 0x12)
385     {
386       /* Got stm */
387       pc++;
388       regmask = read_memory_integer (pc, 1);
389       pc++;
390       for (regnum = 0; regnum < 8; regnum++, regmask >>= 1)
391         {
392           if (regmask & 1)
393             {
394               (frame_saved_regs)->regs[regnum] = (next_addr += 2) - 2;
395             }
396         }
397       thebyte = read_memory_integer (pc, 1);
398     }
399   /* Maybe got a load of pushes */
400   while (thebyte == 0xbf)
401     {
402       pc++;
403       regnum = read_memory_integer (pc, 1) & 0x7;
404       pc++;
405       (frame_saved_regs)->regs[regnum] = (next_addr += 2) - 2;
406       thebyte = read_memory_integer (pc, 1);
407     }
408
409 lose:;
410
411   /* Remember the address of the frame pointer */
412   (frame_saved_regs)->regs[FP_REGNUM] = (frame_info)->frame;
413
414   /* This is where the old sp is hidden */
415   (frame_saved_regs)->regs[SP_REGNUM] = (frame_info)->frame;
416
417   /* And the PC - remember the pushed FP is always two bytes long */
418   (frame_saved_regs)->regs[PC_REGNUM] = (frame_info)->frame + 2;
419 }
420
421 saved_pc_after_call (frame)
422 {
423   int x;
424   int a = read_register (SP_REGNUM);
425   x = read_memory_integer (a, code_size);
426   if (code_size == 2)
427     {
428       /* Stick current code segement onto top */
429       x &= 0xffff;
430       x |= read_register (SEG_C_REGNUM) << 16;
431     }
432   x &= 0xffffff;
433   return x;
434 }
435
436
437 /* Nonzero if instruction at PC is a return instruction.  */
438
439 about_to_return (pc)
440 {
441   int b1 = read_memory_integer (pc, 1);
442
443   switch (b1)
444     {
445     case 0x14:                  /* rtd #8 */
446     case 0x1c:                  /* rtd #16 */
447     case 0x19:                  /* rts */
448     case 0x1a:                  /* rte */
449       return 1;
450     case 0x11:
451       {
452         int b2 = read_memory_integer (pc + 1, 1);
453         switch (b2)
454           {
455           case 0x18:            /* prts */
456           case 0x14:            /* prtd #8 */
457           case 0x16:            /* prtd #16 */
458             return 1;
459           }
460       }
461     }
462   return 0;
463 }
464
465
466 void
467 h8500_set_pointer_size (newsize)
468      int newsize;
469 {
470   static int oldsize = 0;
471
472   if (oldsize != newsize)
473     {
474       printf_unfiltered ("pointer size set to %d bits\n", newsize);
475       oldsize = newsize;
476       if (newsize == 32)
477         {
478           minimum_mode = 0;
479         }
480       else
481         {
482           minimum_mode = 1;
483         }
484       _initialize_gdbtypes ();
485     }
486 }
487
488
489 struct cmd_list_element *setmemorylist;
490
491
492 #define C(name,a,b,c) name () { h8500_set_pointer_size(a); code_size = b; data_size = c; }
493
494 C(big_command, 32,4,4);
495 C(medium_command, 32, 4,2);
496 C(compact_command, 32,2,4);
497 C(small_command, 16,2,2);
498
499 static void
500 set_memory (args, from_tty)
501      char *args;
502      int from_tty;
503 {
504   printf_unfiltered ("\"set memory\" must be followed by the name of a memory subcommand.\n");
505   help_list (setmemorylist, "set memory ", -1, gdb_stdout);
506 }
507
508 /* See if variable name is ppc or pr[0-7] */
509
510 int
511 h8500_is_trapped_internalvar (name)
512      char *name;
513 {
514   if (name[0] != 'p')
515     return 0;
516
517   if (strcmp (name + 1, "pc") == 0)
518     return 1;
519
520   if (name[1] == 'r'
521       && name[2] >= '0'
522       && name[2] <= '7'
523       && name[3] == '\000')
524     return 1;
525   else
526     return 0;
527 }
528
529 value_ptr
530 h8500_value_of_trapped_internalvar (var)
531      struct internalvar *var;
532 {
533   LONGEST regval;
534   unsigned char regbuf[4];
535   int page_regnum, regnum;
536
537   regnum = var->name[2] == 'c' ? PC_REGNUM : var->name[2] - '0';
538
539   switch (var->name[2])
540     {
541     case 'c':
542       page_regnum = SEG_C_REGNUM;
543       break;
544     case '0':
545     case '1':
546     case '2':
547     case '3':
548       page_regnum = SEG_D_REGNUM;
549       break;
550     case '4':
551     case '5':
552       page_regnum = SEG_E_REGNUM;
553       break;
554     case '6':
555     case '7':
556       page_regnum = SEG_T_REGNUM;
557       break;
558     }
559
560   get_saved_register (regbuf, NULL, NULL, selected_frame, page_regnum, NULL);
561   regval = regbuf[0] << 16;
562
563   get_saved_register (regbuf, NULL, NULL, selected_frame, regnum, NULL);
564   regval |= regbuf[0] << 8 | regbuf[1]; /* XXX host/target byte order */
565
566   free (var->value);            /* Free up old value */
567
568   var->value = value_from_longest (builtin_type_unsigned_long, regval);
569   release_value (var->value);   /* Unchain new value */
570
571   VALUE_LVAL (var->value) = lval_internalvar;
572   VALUE_INTERNALVAR (var->value) = var;
573   return var->value;
574 }
575
576 void
577 h8500_set_trapped_internalvar (var, newval, bitpos, bitsize, offset)
578      struct internalvar *var;
579      int offset, bitpos, bitsize;
580      value_ptr newval;
581 {
582   char *page_regnum, *regnum;
583   char expression[100];
584   unsigned new_regval;
585   struct type *type;
586   enum type_code newval_type_code;
587
588   type = VALUE_TYPE (newval);
589   newval_type_code = TYPE_CODE (type);
590
591   if ((newval_type_code != TYPE_CODE_INT
592        && newval_type_code != TYPE_CODE_PTR)
593       || TYPE_LENGTH (type) != sizeof (new_regval))
594     error ("Illegal type (%s) for assignment to $%s\n",
595            TYPE_NAME (type), var->name);
596
597   new_regval = *(long *) VALUE_CONTENTS_RAW (newval);
598
599   regnum = var->name + 1;
600
601   switch (var->name[2])
602     {
603     case 'c':
604       page_regnum = "cp";
605       break;
606     case '0':
607     case '1':
608     case '2':
609     case '3':
610       page_regnum = "dp";
611       break;
612     case '4':
613     case '5':
614       page_regnum = "ep";
615       break;
616     case '6':
617     case '7':
618       page_regnum = "tp";
619       break;
620     }
621
622   sprintf (expression, "$%s=%d", page_regnum, new_regval >> 16);
623   parse_and_eval (expression);
624
625   sprintf (expression, "$%s=%d", regnum, new_regval & 0xffff);
626   parse_and_eval (expression);
627 }
628
629 void
630 _initialize_h8500_tdep ()
631 {
632   add_prefix_cmd ("memory", no_class, set_memory,
633                   "set the memory model", &setmemorylist, "set memory ", 0,
634                   &setlist);
635
636   add_cmd ("small", class_support, small_command,
637            "Set small memory model. (16 bit code, 16 bit data)", &setmemorylist);
638
639   add_cmd ("big", class_support, big_command,
640            "Set big memory model. (32 bit code, 32 bit data)", &setmemorylist);
641
642   add_cmd ("medium", class_support, medium_command,
643            "Set medium memory model. (32 bit code, 16 bit data)", &setmemorylist);
644
645   add_cmd ("compact", class_support, compact_command,
646            "Set compact memory model. (16 bit code, 32 bit data)", &setmemorylist);
647
648 }
649
650 CORE_ADDR
651 target_read_sp ()
652 {
653   return read_register (PR7_REGNUM);
654 }
655
656 void
657 target_write_sp (v)
658      CORE_ADDR v;
659 {
660   write_register (PR7_REGNUM, v);
661 }
662
663 CORE_ADDR
664 target_read_pc ()
665 {
666   return read_register (PC_REGNUM);
667 }
668
669 void
670 target_write_pc (v)
671      CORE_ADDR v;
672 {
673   write_register (PC_REGNUM, v);
674 }
675
676 CORE_ADDR
677 target_read_fp ()
678 {
679   return read_register (PR6_REGNUM);
680 }
681
682 void
683 target_write_fp (v)
684      CORE_ADDR v;
685 {
686   write_register (PR6_REGNUM, v);
687 }
688
This page took 0.065805 seconds and 4 git commands to generate.