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