Minor cleanup.
[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)
37
195e46ea
SC
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:
560x6df6 push r6
570x0d76 mov.w r7,r6
580x6dfn push reg
590x7905 nnnn mov.w #n,r5 or 0x1b87 subs #2,sp
600x1957 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
76int minimum_mode = 1;
77CORE_ADDR examine_prologue ();
78
79void frame_find_saved_regs ();
ccf1e898
SG
80
81int 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
195e46ea
SC
85CORE_ADDR
86h8500_skip_prologue (start_pc)
87 CORE_ADDR start_pc;
88
89{
90 short int w;
91
195e46ea
SC
92 w = read_memory_integer (start_pc, 1);
93 if (w == LINK_8)
94 {
ccf1e898 95 start_pc += 2;
195e46ea
SC
96 w = read_memory_integer (start_pc,1);
97 }
98
99 if (w == LINK_16)
100 {
ccf1e898 101 start_pc += 3;
195e46ea
SC
102 w = read_memory_integer (start_pc,2);
103 }
104
195e46ea 105 return start_pc;
195e46ea
SC
106}
107
108int
109print_insn (memaddr, stream)
110 CORE_ADDR memaddr;
111 FILE *stream;
112{
195e46ea 113 disassemble_info info;
195e46ea 114 GDB_INIT_DISASSEMBLE_INFO(info, stream);
5d0734a7 115 return print_insn_h8500 (memaddr, &info);
195e46ea
SC
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
125FRAME_ADDR
ccf1e898 126h8500_frame_chain (thisframe)
195e46ea
SC
127 FRAME thisframe;
128{
195e46ea 129
ccf1e898 130 if (!inside_entry_file (thisframe->pc))
ccced87a 131 return (read_memory_integer(thisframe->frame, 2) & 0xffff)
ccf1e898
SG
132 | (read_register(SEG_T_REGNUM) << 16);
133 else
134 return 0;
195e46ea
SC
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
147void
148frame_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
193CORE_ADDR
194NEXT_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
217static CORE_ADDR
218examine_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
195e46ea
SC
330
331/* Return the saved PC from this frame. */
332
333CORE_ADDR
334frame_saved_pc (frame)
335 FRAME frame;
336{
ccf1e898 337 return read_memory_integer ((frame)->frame + 2, PTR_SIZE);
195e46ea
SC
338}
339
340CORE_ADDR
341frame_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
350CORE_ADDR
351frame_args_address (fi)
352 struct frame_info *fi;
353{
ccf1e898 354 return fi->frame;
195e46ea
SC
355}
356
357void
358h8300_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
384void
385print_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
ccf1e898
SG
430int
431h8500_register_size (regno)
432 int regno;
195e46ea 433{
ccf1e898
SG
434 if (regno <= PC_REGNUM)
435 return 2;
436 else
437 return 1;
195e46ea
SC
438}
439
440struct type *
ccf1e898
SG
441h8500_register_virtual_type (regno)
442 int regno;
195e46ea 443{
ccf1e898 444 switch (regno)
195e46ea 445 {
ccf1e898
SG
446 case SEG_C_REGNUM:
447 case SEG_E_REGNUM:
448 case SEG_D_REGNUM:
449 case SEG_T_REGNUM:
195e46ea 450 return builtin_type_unsigned_char;
ccf1e898
SG
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:
195e46ea
SC
460 case CCR_REGNUM:
461 return builtin_type_unsigned_short;
195e46ea
SC
462 default:
463 abort();
464 }
465}
466
195e46ea
SC
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
473void
474frame_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
552saved_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
563about_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
590void
591h8500_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
613struct cmd_list_element *setmemorylist;
614
615
616static void
617segmented_command (args, from_tty)
618 char *args;
619 int from_tty;
620{
621 h8500_set_pointer_size (32);
622}
623
624static void
625unsegmented_command (args, from_tty)
626 char *args;
627 int from_tty;
628{
629 h8500_set_pointer_size (16);
630}
631
632static void
633set_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
ccf1e898 641/* See if variable name is ppc or pr[0-7] */
195e46ea 642
ccf1e898
SG
643int
644h8500_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
662PTR
663h8500_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
704void
705h8500_set_trapped_internalvar (var, newval, bitpos, bitsize, offset)
706 struct internalvar *var;
707 int offset, bitpos, bitsize;
708 value newval;
195e46ea 709{
ccf1e898
SG
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);
195e46ea 724
ccf1e898
SG
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{
195e46ea
SC
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.055037 seconds and 4 git commands to generate.