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