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