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