]> Git Repo - binutils.git/blob - gdb/h8500-tdep.c
* core.c (dis_asm_read_memory): drop fourth arg which conflicts with
[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
38 /* Shape of an H8/500 frame : 
39
40
41    arg-n
42    ..
43    arg-2
44    arg-1
45    return address <2 or 4 bytes>
46    old fp         <2 bytes>
47    auto-n
48    ..
49    auto-1
50    saved registers
51
52 */
53
54
55 /* an easy to debug H8 stack frame looks like:
56 0x6df6          push    r6
57 0x0d76          mov.w   r7,r6
58 0x6dfn          push    reg
59 0x7905 nnnn     mov.w  #n,r5    or   0x1b87  subs #2,sp
60 0x1957          sub.w  r5,sp
61
62  */
63
64 #define IS_PUSH(x) ((x & 0xff00)==0x6d00)
65 #define IS_LINK_8(x) ((x) == 0x17)
66 #define IS_LINK_16(x) ((x) == 0x1f)
67 #define IS_MOVE_FP(x) (x == 0x0d76)
68 #define IS_MOV_SP_FP(x) (x == 0x0d76)
69 #define IS_SUB2_SP(x) (x==0x1b87)
70 #define IS_MOVK_R5(x) (x==0x7905)
71 #define IS_SUB_R5SP(x) (x==0x1957)
72
73 #define LINK_8 0x17
74 #define LINK_16 0x1f
75
76 int minimum_mode = 1;
77 CORE_ADDR examine_prologue ();
78
79 void frame_find_saved_regs ();
80
81 int regoff[NUM_REGS] = {0,  2,  4,  6,  8,  10,  12, 14, /* r0->r7 */
82                   16, 18, /* ccr, pc */
83                   20, 21, 22, 23}; /* cp, dp, ep, tp */
84
85 CORE_ADDR
86 h8500_skip_prologue (start_pc)
87      CORE_ADDR start_pc;
88
89 {
90   short int w;
91
92   w = read_memory_integer (start_pc, 1);
93   if (w == LINK_8)
94     {
95       start_pc += 2;
96       w = read_memory_integer (start_pc,1);
97     }
98
99   if (w == LINK_16)
100     {
101       start_pc += 3;
102       w = read_memory_integer (start_pc,2);
103     }
104
105   return start_pc;
106 }
107
108 int
109 print_insn (memaddr, stream)
110      CORE_ADDR memaddr;
111      FILE *stream;
112 {
113   disassemble_info info;
114   GDB_INIT_DISASSEMBLE_INFO(info, stream);
115   return print_insn_h8500 (memaddr, &info);
116 }
117
118 /* Given a GDB frame, determine the address of the calling function's frame.
119    This will be used to create a new GDB frame struct, and then
120    INIT_EXTRA_FRAME_INFO and INIT_FRAME_PC will be called for the new frame.
121
122    For us, the frame address is its stack pointer value, so we look up
123    the function prologue to determine the caller's sp value, and return it.  */
124
125 FRAME_ADDR
126 h8500_frame_chain (thisframe)
127      FRAME thisframe;
128 {
129
130   if (!inside_entry_file (thisframe->pc))
131       return read_memory_integer(thisframe->frame, 2)
132         | (read_register(SEG_T_REGNUM) << 16);
133   else
134     return 0;
135 }
136
137 /* Put here the code to store, into a struct frame_saved_regs,
138    the addresses of the saved registers of frame described by FRAME_INFO.
139    This includes special registers such as pc and fp saved in special
140    ways in the stack frame.  sp is even more special:
141    the address we return for it IS the sp for the next frame.
142
143    We cache the result of doing this in the frame_cache_obstack, since
144    it is fairly expensive.  */
145 #if 0
146
147 void
148 frame_find_saved_regs (fi, fsr)
149      struct frame_info *fi;
150      struct frame_saved_regs *fsr;
151 {
152   register CORE_ADDR next_addr;
153   register CORE_ADDR *saved_regs;
154   register int regnum;
155   register struct frame_saved_regs *cache_fsr;
156   extern struct obstack frame_cache_obstack;
157   CORE_ADDR ip;
158   struct symtab_and_line sal;
159   CORE_ADDR limit;
160
161   if (!fi->fsr)
162     {
163       cache_fsr = (struct frame_saved_regs *)
164         obstack_alloc (&frame_cache_obstack,
165                        sizeof (struct frame_saved_regs));
166       bzero (cache_fsr, sizeof (struct frame_saved_regs));
167
168       fi->fsr = cache_fsr;
169
170       /* Find the start and end of the function prologue.  If the PC
171          is in the function prologue, we only consider the part that
172          has executed already.  */
173
174       ip = get_pc_function_start (fi->pc);
175       sal = find_pc_line (ip, 0);
176       limit = (sal.end && sal.end < fi->pc) ? sal.end : fi->pc;
177
178       /* This will fill in fields in *fi as well as in cache_fsr.  */
179       examine_prologue (ip, limit, fi->frame, cache_fsr, fi);
180     }
181
182   if (fsr)
183     *fsr = *fi->fsr;
184 }
185
186 #endif
187
188 /* Fetch the instruction at ADDR, returning 0 if ADDR is beyond LIM or
189    is not the address of a valid instruction, the address of the next
190    instruction beyond ADDR otherwise.  *PWORD1 receives the first word
191    of the instruction.*/
192
193 CORE_ADDR
194 NEXT_PROLOGUE_INSN (addr, lim, pword1)
195      CORE_ADDR addr;
196      CORE_ADDR lim;
197      char *pword1;
198 {
199   if (addr < lim + 8)
200     {
201       read_memory (addr, pword1, 1);
202       read_memory (addr, pword1 + 1, 1);
203       return 1;
204     }
205   return 0;
206 }
207
208 /* Examine the prologue of a function.  `ip' points to the first instruction.
209    `limit' is the limit of the prologue (e.g. the addr of the first
210    linenumber, or perhaps the program counter if we're stepping through).
211    `frame_sp' is the stack pointer value in use in this frame.
212    `fsr' is a pointer to a frame_saved_regs structure into which we put
213    info about the registers saved by this frame.
214    `fi' is a struct frame_info pointer; we fill in various fields in it
215    to reflect the offsets of the arg pointer and the locals pointer.  */
216 #if 0
217 static CORE_ADDR
218 examine_prologue (ip, limit, after_prolog_fp, fsr, fi)
219      register CORE_ADDR ip;
220      register CORE_ADDR limit;
221      FRAME_ADDR after_prolog_fp;
222      struct frame_saved_regs *fsr;
223      struct frame_info *fi;
224 {
225   register CORE_ADDR next_ip;
226   int r;
227   int i;
228   int have_fp = 0;
229
230   register int src;
231   register struct pic_prologue_code *pcode;
232   char insn[2];
233   int size, offset;
234   unsigned int reg_save_depth = 2;      /* Number of things pushed onto
235                                       stack, starts at 2, 'cause the
236                                       PC is already there */
237
238   unsigned int auto_depth = 0;  /* Number of bytes of autos */
239
240   char in_frame[8];             /* One for each reg */
241
242   memset (in_frame, 1, 8);
243   for (r = 0; r < 8; r++)
244     {
245       fsr->regs[r] = 0;
246     }
247   if (after_prolog_fp == 0)
248     {
249       after_prolog_fp = read_register (SP_REGNUM);
250     }
251   if (ip == 0 || ip & ~0xffffff)
252     return 0;
253
254   ok = NEXT_PROLOGUE_INSN (ip, limit, &insn[0]);
255
256   /* Skip over any fp push instructions */
257   fsr->regs[6] = after_prolog_fp;
258
259   if (ok && IS_LINK_8 (insn[0]))
260     {
261       ip++;
262
263       in_frame[6] = reg_save_depth;
264       reg_save_depth += 2;
265     }
266
267   next_ip = NEXT_PROLOGUE_INSN (ip, limit, &insn_word);
268
269   /* Is this a move into the fp */
270   if (next_ip && IS_MOV_SP_FP (insn_word))
271     {
272       ip = next_ip;
273       next_ip = NEXT_PROLOGUE_INSN (ip, limit, &insn_word);
274       have_fp = 1;
275     }
276
277   /* Skip over any stack adjustment, happens either with a number of
278      sub#2,sp or a mov #x,r5 sub r5,sp */
279
280   if (next_ip && IS_SUB2_SP (insn_word))
281     {
282       while (next_ip && IS_SUB2_SP (insn_word))
283         {
284           auto_depth += 2;
285           ip = next_ip;
286           next_ip = NEXT_PROLOGUE_INSN (ip, limit, &insn_word);
287         }
288     }
289   else
290     {
291       if (next_ip && IS_MOVK_R5 (insn_word))
292         {
293           ip = next_ip;
294           next_ip = NEXT_PROLOGUE_INSN (ip, limit, &insn_word);
295           auto_depth += insn_word;
296
297           next_ip = NEXT_PROLOGUE_INSN (next_ip, limit, &insn_word);
298           auto_depth += insn_word;
299
300         }
301     }
302   /* Work out which regs are stored where */
303   while (next_ip && IS_PUSH (insn_word))
304     {
305       ip = next_ip;
306       next_ip = NEXT_PROLOGUE_INSN (ip, limit, &insn_word);
307       fsr->regs[r] = after_prolog_fp + auto_depth;
308       auto_depth += 2;
309     }
310
311   /* The args are always reffed based from the stack pointer */
312   fi->args_pointer = after_prolog_fp;
313   /* Locals are always reffed based from the fp */
314   fi->locals_pointer = after_prolog_fp;
315   /* The PC is at a known place */
316   fi->from_pc = read_memory_short (after_prolog_fp + 2);
317
318   /* Rememeber any others too */
319   in_frame[PC_REGNUM] = 0;
320
321   if (have_fp)
322     /* We keep the old FP in the SP spot */
323     fsr->regs[SP_REGNUM] = (read_memory_short (fsr->regs[6]));
324   else
325     fsr->regs[SP_REGNUM] = after_prolog_fp + auto_depth;
326
327   return (ip);
328 }
329 #endif
330
331 /* Return the saved PC from this frame. */
332
333 CORE_ADDR
334 frame_saved_pc (frame)
335      FRAME frame;
336 {
337   return read_memory_integer ((frame)->frame + 2, PTR_SIZE);
338 }
339
340 CORE_ADDR
341 frame_locals_address (fi)
342      struct frame_info *fi;
343 {
344   return fi->frame;
345 }
346
347 /* Return the address of the argument block for the frame
348    described by FI.  Returns 0 if the address is unknown.  */
349
350 CORE_ADDR
351 frame_args_address (fi)
352      struct frame_info *fi;
353 {
354   return fi->frame;
355 }
356
357 void
358 h8300_pop_frame ()
359 {
360   unsigned regnum;
361   struct frame_saved_regs fsr;
362   struct frame_info *fi;
363
364   FRAME frame = get_current_frame ();
365
366   fi = get_frame_info (frame);
367   get_frame_saved_regs (fi, &fsr);
368
369   for (regnum = 0; regnum < 8; regnum++)
370     {
371       if (fsr.regs[regnum])
372         {
373           write_register (regnum, read_memory_short (fsr.regs[regnum]));
374         }
375
376       flush_cached_frames ();
377       set_current_frame (create_new_frame (read_register (FP_REGNUM),
378                                            read_pc ()));
379
380     }
381
382 }
383
384 void
385 print_register_hook (regno)
386 {
387   if (regno == CCR_REGNUM)
388     {
389       /* CCR register */
390
391       int C, Z, N, V;
392       unsigned char b[2];
393       unsigned char l;
394
395       read_relative_register_raw_bytes (regno, b);
396       l = b[1];
397       printf ("\t");
398       printf ("I-%d - ", (l & 0x80) != 0);
399       N = (l & 0x8) != 0;
400       Z = (l & 0x4) != 0;
401       V = (l & 0x2) != 0;
402       C = (l & 0x1) != 0;
403       printf ("N-%d ", N);
404       printf ("Z-%d ", Z);
405       printf ("V-%d ", V);
406       printf ("C-%d ", C);
407       if ((C | Z) == 0)
408         printf ("u> ");
409       if ((C | Z) == 1)
410         printf ("u<= ");
411       if ((C == 0))
412         printf ("u>= ");
413       if (C == 1)
414         printf ("u< ");
415       if (Z == 0)
416         printf ("!= ");
417       if (Z == 1)
418         printf ("== ");
419       if ((N ^ V) == 0)
420         printf (">= ");
421       if ((N ^ V) == 1)
422         printf ("< ");
423       if ((Z | (N ^ V)) == 0)
424         printf ("> ");
425       if ((Z | (N ^ V)) == 1)
426         printf ("<= ");
427     }
428 }
429
430 int
431 h8500_register_size (regno)
432      int regno;
433 {
434   if (regno <= PC_REGNUM)
435     return 2;
436   else
437     return 1;
438 }
439
440 struct type *
441 h8500_register_virtual_type (regno)
442      int regno;
443 {
444   switch (regno)
445     {
446     case SEG_C_REGNUM:
447     case SEG_E_REGNUM:
448     case SEG_D_REGNUM:
449     case SEG_T_REGNUM:
450       return builtin_type_unsigned_char;
451     case R0_REGNUM:
452     case R1_REGNUM:
453     case R2_REGNUM:
454     case R3_REGNUM:
455     case R4_REGNUM:
456     case R5_REGNUM:
457     case R6_REGNUM:
458     case R7_REGNUM:
459     case PC_REGNUM:
460     case CCR_REGNUM:
461       return builtin_type_unsigned_short;
462     default:
463       abort();
464     }
465 }
466
467 /* Put here the code to store, into a struct frame_saved_regs,
468    the addresses of the saved registers of frame described by FRAME_INFO.
469    This includes special registers such as pc and fp saved in special
470    ways in the stack frame.  sp is even more special:
471    the address we return for it IS the sp for the next frame.  */
472
473 void
474 frame_find_saved_regs (frame_info, frame_saved_regs)
475      struct frame_info *frame_info;
476      struct frame_saved_regs *frame_saved_regs;
477
478 {
479   register int regnum;
480   register int regmask;
481   register CORE_ADDR next_addr;
482   register CORE_ADDR pc;
483   unsigned char thebyte;
484
485   bzero (frame_saved_regs, sizeof *frame_saved_regs);
486
487   if ((frame_info)->pc >= (frame_info)->frame - CALL_DUMMY_LENGTH - FP_REGNUM * 4 - 4
488       && (frame_info)->pc <= (frame_info)->frame)
489     {
490       next_addr = (frame_info)->frame;
491       pc = (frame_info)->frame - CALL_DUMMY_LENGTH - FP_REGNUM * 4 - 4;
492     }
493   else
494     {
495       pc = get_pc_function_start ((frame_info)->pc);
496       /* Verify we have a link a6 instruction next;
497          if not we lose.  If we win, find the address above the saved
498          regs using the amount of storage from the link instruction.
499          */
500
501       thebyte  = read_memory_integer(pc, 1);
502       if (0x1f == thebyte)
503         next_addr = (frame_info)->frame + read_memory_integer (pc += 1, 2), pc += 2;
504       else if (0x17 == thebyte)
505         next_addr = (frame_info)->frame + read_memory_integer (pc += 1, 1), pc += 1;
506       else
507         goto lose;
508 #if 0
509       fixme steve
510         /* If have an add:g.waddal #-n, sp next, adjust next_addr.  */
511         if ((0x0c0177777 & read_memory_integer (pc, 2)) == 0157774)
512           next_addr += read_memory_integer (pc += 2, 4), pc += 4;
513 #endif
514     }
515
516   thebyte = read_memory_integer(pc, 1);
517   if (thebyte == 0x12) {
518     /* Got stm */
519     pc++;
520     regmask = read_memory_integer(pc,1);
521     pc++;
522     for (regnum = 0; regnum < 8; regnum ++, regmask >>=1) 
523       {
524         if (regmask & 1) 
525           {
526             (frame_saved_regs)->regs[regnum] = (next_addr += 2) - 2;
527           }
528       }
529     thebyte = read_memory_integer(pc, 1);
530   }
531   /* Maybe got a load of pushes */
532   while (thebyte == 0xbf) {
533     pc++;
534     regnum = read_memory_integer(pc,1) & 0x7;
535     pc++;
536     (frame_saved_regs)->regs[regnum] = (next_addr += 2) - 2;    
537     thebyte = read_memory_integer(pc, 1);
538   }
539
540  lose:;
541   
542   /* Remember the address of the frame pointer */
543   (frame_saved_regs)->regs[FP_REGNUM] = (frame_info)->frame;
544
545   /* This is where the old sp is hidden */
546   (frame_saved_regs)->regs[SP_REGNUM] = (frame_info)->frame;
547
548   /* And the PC - remember the pushed FP is always two bytes long */
549   (frame_saved_regs)->regs[PC_REGNUM] = (frame_info)->frame + 2;
550 }
551
552 saved_pc_after_call(frame)
553 {
554   int x;
555   int a = read_register(SP_REGNUM);
556   x = read_memory_integer (a, PTR_SIZE);
557   return x;
558 }
559
560
561 /* Nonzero if instruction at PC is a return instruction.  */
562
563 about_to_return(pc)
564 {
565   int b1 = read_memory_integer(pc,1);
566
567   switch (b1) 
568     {
569     case 0x14:                  /* rtd #8 */
570     case 0x1c:                  /* rtd #16 */
571     case 0x19:                  /* rts */
572     case 0x1a:                  /* rte */
573       return 1;
574     case 0x11:
575       {
576         int b2 = read_memory_integer(pc+1,1);
577         switch (b2) 
578           {
579           case 0x18:            /* prts */
580           case 0x14:            /* prtd #8 */
581           case 0x16:            /* prtd #16 */
582             return 1;
583           }
584       }
585     }
586   return 0;
587 }
588
589
590 void
591 h8500_set_pointer_size (newsize)
592      int newsize;
593 {
594   static int oldsize = 0;
595
596   if (oldsize != newsize)
597     {
598       printf ("pointer size set to %d bits\n", newsize);
599       oldsize = newsize;
600       if (newsize == 32)
601         {
602           minimum_mode = 0;
603         }
604       else
605         {
606           minimum_mode = 1;
607         }
608       _initialize_gdbtypes ();
609     }
610 }
611
612
613 struct cmd_list_element *setmemorylist;
614
615
616 static void
617 segmented_command (args, from_tty)
618      char *args;
619      int from_tty;
620 {
621   h8500_set_pointer_size (32);
622 }
623
624 static void
625 unsegmented_command (args, from_tty)
626      char *args;
627      int from_tty;
628 {
629   h8500_set_pointer_size (16);
630 }
631
632 static void
633 set_memory (args, from_tty)
634      char *args;
635      int from_tty;
636 {
637   printf ("\"set memory\" must be followed by the name of a memory subcommand.\n");
638   help_list (setmemorylist, "set memory ", -1, stdout);
639 }
640
641 /* See if variable name is ppc or pr[0-7] */
642
643 int
644 h8500_is_trapped_internalvar (name)
645      char *name;
646 {
647   if (name[0] != 'p')
648     return 0;
649
650   if (strcmp(name+1, "pc") == 0)
651     return 1;
652
653   if (name[1] == 'r'
654       && name[2] >= '0'
655       && name[2] <= '7'
656       && name[3] == '\000')
657     return 1;
658   else
659     return 0;
660 }
661
662 PTR
663 h8500_value_of_trapped_internalvar (var)
664      struct internalvar *var;
665 {
666   LONGEST regval;
667   unsigned char regbuf[4];
668   int page_regnum, regnum;
669
670   regnum = var->name[2] == 'c' ? PC_REGNUM : var->name[2] - '0';
671
672   switch (var->name[2])
673     {
674     case 'c':
675       page_regnum = SEG_C_REGNUM;
676       break;
677     case '0': case '1': case '2': case '3':
678       page_regnum = SEG_D_REGNUM;
679       break;
680     case '4': case '5':
681       page_regnum = SEG_E_REGNUM;
682       break;
683     case '6': case '7':
684       page_regnum = SEG_T_REGNUM;
685       break;
686     }
687
688   get_saved_register (regbuf, NULL, NULL, selected_frame, page_regnum, NULL);
689   regval = regbuf[0] << 16;
690
691   get_saved_register (regbuf, NULL, NULL, selected_frame, regnum, NULL);
692   regval |= regbuf[0] << 8 | regbuf[1]; /* XXX host/target byte order */
693
694   free (var->value);            /* Free up old value */
695
696   var->value = value_from_longest (builtin_type_unsigned_long, regval);
697   release_value (var->value);   /* Unchain new value */
698
699   VALUE_LVAL (var->value) = lval_internalvar;
700   VALUE_INTERNALVAR (var->value) = var;
701   return var->value;
702 }
703
704 void
705 h8500_set_trapped_internalvar (var, newval, bitpos, bitsize, offset)
706      struct internalvar *var;
707      int offset, bitpos, bitsize;
708      value newval;
709 {
710   char *page_regnum, *regnum;
711   char expression[100];
712   unsigned new_regval;
713   struct type *type;
714   enum type_code newval_type_code;
715
716   type = VALUE_TYPE (newval);
717   newval_type_code = TYPE_CODE (type);
718
719   if ((newval_type_code != TYPE_CODE_INT
720        && newval_type_code != TYPE_CODE_PTR)
721       || TYPE_LENGTH (type) != sizeof(new_regval))
722     error("Illegal type (%s) for assignment to $%s\n",
723           TYPE_NAME (type), var->name);
724
725   new_regval = *(long *)VALUE_CONTENTS_RAW(newval);
726
727   regnum = var->name + 1;
728
729   switch (var->name[2])
730     {
731     case 'c':
732       page_regnum = "cp";
733       break;
734     case '0': case '1': case '2': case '3':
735       page_regnum = "dp";
736       break;
737     case '4': case '5':
738       page_regnum = "ep";
739       break;
740     case '6': case '7':
741       page_regnum = "tp";
742       break;
743     }
744
745   sprintf (expression, "$%s=%d", page_regnum, new_regval >> 16);
746   parse_and_eval(expression);
747
748   sprintf (expression, "$%s=%d", regnum, new_regval & 0xffff);
749   parse_and_eval(expression);
750 }
751
752 _initialize_h8500_tdep ()
753 {
754   add_prefix_cmd ("memory", no_class, set_memory,
755                   "set the memory model", &setmemorylist, "set memory ", 0,
756                   &setlist);
757   add_cmd ("segmented", class_support, segmented_command,
758            "Set segmented memory model.", &setmemorylist);
759   add_cmd ("unsegmented", class_support, unsegmented_command,
760            "Set unsegmented memory model.", &setmemorylist);
761
762 }
This page took 0.066644 seconds and 4 git commands to generate.