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