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