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