1 /* Target-machine dependent code for Hitachi H8/500, for GDB.
2 Copyright (C) 1993 Free Software Foundation, Inc.
4 This file is part of GDB.
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
21 Contributed by Steve Chamberlain
33 #include "../opcodes/h8500-opc.h"
36 #define UNSIGNED_SHORT(X) ((X) & 0xffff)
38 /* Shape of an H8/500 frame :
45 return address <2 or 4 bytes>
55 /* an easy to debug H8 stack frame looks like:
59 0x7905 nnnn mov.w #n,r5 or 0x1b87 subs #2,sp
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)
77 CORE_ADDR
examine_prologue ();
79 void frame_find_saved_regs ();
81 int regoff
[NUM_REGS
] =
82 {0, 2, 4, 6, 8, 10, 12, 14, /* r0->r7 */
84 20, 21, 22, 23}; /* cp, dp, ep, tp */
87 h8500_skip_prologue (start_pc
)
93 w
= read_memory_integer (start_pc
, 1);
97 w
= read_memory_integer (start_pc
, 1);
103 w
= read_memory_integer (start_pc
, 2);
110 print_insn (memaddr
, stream
)
114 disassemble_info info
;
115 GDB_INIT_DISASSEMBLE_INFO (info
, stream
);
116 return print_insn_h8500 (memaddr
, &info
);
119 /* Given a GDB frame, determine the address of the calling function's frame.
120 This will be used to create a new GDB frame struct, and then
121 INIT_EXTRA_FRAME_INFO and INIT_FRAME_PC will be called for the new frame.
123 For us, the frame address is its stack pointer value, so we look up
124 the function prologue to determine the caller's sp value, and return it. */
127 h8500_frame_chain (thisframe
)
131 if (!inside_entry_file (thisframe
->pc
))
132 return (read_memory_integer (thisframe
->frame
, 2) & 0xffff)
133 | (read_register (SEG_T_REGNUM
) << 16);
138 /* Put here the code to store, into a struct frame_saved_regs,
139 the addresses of the saved registers of frame described by FRAME_INFO.
140 This includes special registers such as pc and fp saved in special
141 ways in the stack frame. sp is even more special:
142 the address we return for it IS the sp for the next frame.
144 We cache the result of doing this in the frame_cache_obstack, since
145 it is fairly expensive. */
149 frame_find_saved_regs (fi
, fsr
)
150 struct frame_info
*fi
;
151 struct frame_saved_regs
*fsr
;
153 register CORE_ADDR next_addr
;
154 register CORE_ADDR
*saved_regs
;
156 register struct frame_saved_regs
*cache_fsr
;
157 extern struct obstack frame_cache_obstack
;
159 struct symtab_and_line sal
;
164 cache_fsr
= (struct frame_saved_regs
*)
165 obstack_alloc (&frame_cache_obstack
,
166 sizeof (struct frame_saved_regs
));
167 bzero (cache_fsr
, sizeof (struct frame_saved_regs
));
171 /* Find the start and end of the function prologue. If the PC
172 is in the function prologue, we only consider the part that
173 has executed already. */
175 ip
= get_pc_function_start (fi
->pc
);
176 sal
= find_pc_line (ip
, 0);
177 limit
= (sal
.end
&& sal
.end
< fi
->pc
) ? sal
.end
: fi
->pc
;
179 /* This will fill in fields in *fi as well as in cache_fsr. */
180 examine_prologue (ip
, limit
, fi
->frame
, cache_fsr
, fi
);
189 /* Fetch the instruction at ADDR, returning 0 if ADDR is beyond LIM or
190 is not the address of a valid instruction, the address of the next
191 instruction beyond ADDR otherwise. *PWORD1 receives the first word
192 of the instruction.*/
195 NEXT_PROLOGUE_INSN (addr
, lim
, pword1
)
202 read_memory (addr
, pword1
, 1);
203 read_memory (addr
, pword1
+ 1, 1);
209 /* Examine the prologue of a function. `ip' points to the first instruction.
210 `limit' is the limit of the prologue (e.g. the addr of the first
211 linenumber, or perhaps the program counter if we're stepping through).
212 `frame_sp' is the stack pointer value in use in this frame.
213 `fsr' is a pointer to a frame_saved_regs structure into which we put
214 info about the registers saved by this frame.
215 `fi' is a struct frame_info pointer; we fill in various fields in it
216 to reflect the offsets of the arg pointer and the locals pointer. */
219 examine_prologue (ip
, limit
, after_prolog_fp
, fsr
, fi
)
220 register CORE_ADDR ip
;
221 register CORE_ADDR limit
;
222 FRAME_ADDR after_prolog_fp
;
223 struct frame_saved_regs
*fsr
;
224 struct frame_info
*fi
;
226 register CORE_ADDR next_ip
;
232 register struct pic_prologue_code
*pcode
;
235 unsigned int reg_save_depth
= 2; /* Number of things pushed onto
236 stack, starts at 2, 'cause the
237 PC is already there */
239 unsigned int auto_depth
= 0; /* Number of bytes of autos */
241 char in_frame
[8]; /* One for each reg */
243 memset (in_frame
, 1, 8);
244 for (r
= 0; r
< 8; r
++)
248 if (after_prolog_fp
== 0)
250 after_prolog_fp
= read_register (SP_REGNUM
);
252 if (ip
== 0 || ip
& ~0xffffff)
255 ok
= NEXT_PROLOGUE_INSN (ip
, limit
, &insn
[0]);
257 /* Skip over any fp push instructions */
258 fsr
->regs
[6] = after_prolog_fp
;
260 if (ok
&& IS_LINK_8 (insn
[0]))
264 in_frame
[6] = reg_save_depth
;
268 next_ip
= NEXT_PROLOGUE_INSN (ip
, limit
, &insn_word
);
270 /* Is this a move into the fp */
271 if (next_ip
&& IS_MOV_SP_FP (insn_word
))
274 next_ip
= NEXT_PROLOGUE_INSN (ip
, limit
, &insn_word
);
278 /* Skip over any stack adjustment, happens either with a number of
279 sub#2,sp or a mov #x,r5 sub r5,sp */
281 if (next_ip
&& IS_SUB2_SP (insn_word
))
283 while (next_ip
&& IS_SUB2_SP (insn_word
))
287 next_ip
= NEXT_PROLOGUE_INSN (ip
, limit
, &insn_word
);
292 if (next_ip
&& IS_MOVK_R5 (insn_word
))
295 next_ip
= NEXT_PROLOGUE_INSN (ip
, limit
, &insn_word
);
296 auto_depth
+= insn_word
;
298 next_ip
= NEXT_PROLOGUE_INSN (next_ip
, limit
, &insn_word
);
299 auto_depth
+= insn_word
;
303 /* Work out which regs are stored where */
304 while (next_ip
&& IS_PUSH (insn_word
))
307 next_ip
= NEXT_PROLOGUE_INSN (ip
, limit
, &insn_word
);
308 fsr
->regs
[r
] = after_prolog_fp
+ auto_depth
;
312 /* The args are always reffed based from the stack pointer */
313 fi
->args_pointer
= after_prolog_fp
;
314 /* Locals are always reffed based from the fp */
315 fi
->locals_pointer
= after_prolog_fp
;
316 /* The PC is at a known place */
317 fi
->from_pc
= read_memory_short (after_prolog_fp
+ 2);
319 /* Rememeber any others too */
320 in_frame
[PC_REGNUM
] = 0;
323 /* We keep the old FP in the SP spot */
324 fsr
->regs
[SP_REGNUM
] = (read_memory_short (fsr
->regs
[6]));
326 fsr
->regs
[SP_REGNUM
] = after_prolog_fp
+ auto_depth
;
333 /* Return the saved PC from this frame. */
336 frame_saved_pc (frame
)
339 return read_memory_integer ((frame
)->frame
+ 2, PTR_SIZE
);
343 frame_locals_address (fi
)
344 struct frame_info
*fi
;
349 /* Return the address of the argument block for the frame
350 described by FI. Returns 0 if the address is unknown. */
353 frame_args_address (fi
)
354 struct frame_info
*fi
;
363 struct frame_saved_regs fsr
;
364 struct frame_info
*fi
;
366 FRAME frame
= get_current_frame ();
368 fi
= get_frame_info (frame
);
369 get_frame_saved_regs (fi
, &fsr
);
371 for (regnum
= 0; regnum
< 8; regnum
++)
373 if (fsr
.regs
[regnum
])
375 write_register (regnum
, read_memory_short (fsr
.regs
[regnum
]));
378 flush_cached_frames ();
379 set_current_frame (create_new_frame (read_register (FP_REGNUM
),
387 print_register_hook (regno
)
389 if (regno
== CCR_REGNUM
)
397 read_relative_register_raw_bytes (regno
, b
);
400 printf ("I-%d - ", (l
& 0x80) != 0);
425 if ((Z
| (N
^ V
)) == 0)
427 if ((Z
| (N
^ V
)) == 1)
433 h8500_register_size (regno
)
436 if (regno
<= PC_REGNUM
)
443 h8500_register_virtual_type (regno
)
452 return builtin_type_unsigned_char
;
463 return builtin_type_unsigned_short
;
469 /* Put here the code to store, into a struct frame_saved_regs,
470 the addresses of the saved registers of frame described by FRAME_INFO.
471 This includes special registers such as pc and fp saved in special
472 ways in the stack frame. sp is even more special:
473 the address we return for it IS the sp for the next frame. */
476 frame_find_saved_regs (frame_info
, frame_saved_regs
)
477 struct frame_info
*frame_info
;
478 struct frame_saved_regs
*frame_saved_regs
;
482 register int regmask
;
483 register CORE_ADDR next_addr
;
484 register CORE_ADDR pc
;
485 unsigned char thebyte
;
487 bzero (frame_saved_regs
, sizeof *frame_saved_regs
);
489 if ((frame_info
)->pc
>= (frame_info
)->frame
- CALL_DUMMY_LENGTH
- FP_REGNUM
* 4 - 4
490 && (frame_info
)->pc
<= (frame_info
)->frame
)
492 next_addr
= (frame_info
)->frame
;
493 pc
= (frame_info
)->frame
- CALL_DUMMY_LENGTH
- FP_REGNUM
* 4 - 4;
497 pc
= get_pc_function_start ((frame_info
)->pc
);
498 /* Verify we have a link a6 instruction next;
499 if not we lose. If we win, find the address above the saved
500 regs using the amount of storage from the link instruction.
503 thebyte
= read_memory_integer (pc
, 1);
505 next_addr
= (frame_info
)->frame
+ read_memory_integer (pc
+= 1, 2), pc
+= 2;
506 else if (0x17 == thebyte
)
507 next_addr
= (frame_info
)->frame
+ read_memory_integer (pc
+= 1, 1), pc
+= 1;
512 /* If have an add:g.waddal #-n, sp next, adjust next_addr. */
513 if ((0x0c0177777 & read_memory_integer (pc
, 2)) == 0157774)
514 next_addr
+= read_memory_integer (pc
+= 2, 4), pc
+= 4;
518 thebyte
= read_memory_integer (pc
, 1);
523 regmask
= read_memory_integer (pc
, 1);
525 for (regnum
= 0; regnum
< 8; regnum
++, regmask
>>= 1)
529 (frame_saved_regs
)->regs
[regnum
] = (next_addr
+= 2) - 2;
532 thebyte
= read_memory_integer (pc
, 1);
534 /* Maybe got a load of pushes */
535 while (thebyte
== 0xbf)
538 regnum
= read_memory_integer (pc
, 1) & 0x7;
540 (frame_saved_regs
)->regs
[regnum
] = (next_addr
+= 2) - 2;
541 thebyte
= read_memory_integer (pc
, 1);
546 /* Remember the address of the frame pointer */
547 (frame_saved_regs
)->regs
[FP_REGNUM
] = (frame_info
)->frame
;
549 /* This is where the old sp is hidden */
550 (frame_saved_regs
)->regs
[SP_REGNUM
] = (frame_info
)->frame
;
552 /* And the PC - remember the pushed FP is always two bytes long */
553 (frame_saved_regs
)->regs
[PC_REGNUM
] = (frame_info
)->frame
+ 2;
556 saved_pc_after_call (frame
)
559 int a
= read_register (SP_REGNUM
);
560 x
= read_memory_integer (a
, PTR_SIZE
);
565 /* Nonzero if instruction at PC is a return instruction. */
569 int b1
= read_memory_integer (pc
, 1);
573 case 0x14: /* rtd #8 */
574 case 0x1c: /* rtd #16 */
580 int b2
= read_memory_integer (pc
+ 1, 1);
583 case 0x18: /* prts */
584 case 0x14: /* prtd #8 */
585 case 0x16: /* prtd #16 */
595 h8500_set_pointer_size (newsize
)
598 static int oldsize
= 0;
600 if (oldsize
!= newsize
)
602 printf ("pointer size set to %d bits\n", newsize
);
612 _initialize_gdbtypes ();
617 struct cmd_list_element
*setmemorylist
;
621 segmented_command (args
, from_tty
)
625 h8500_set_pointer_size (32);
629 unsegmented_command (args
, from_tty
)
633 h8500_set_pointer_size (16);
637 set_memory (args
, from_tty
)
641 printf ("\"set memory\" must be followed by the name of a memory subcommand.\n");
642 help_list (setmemorylist
, "set memory ", -1, stdout
);
645 /* See if variable name is ppc or pr[0-7] */
648 h8500_is_trapped_internalvar (name
)
654 if (strcmp (name
+ 1, "pc") == 0)
660 && name
[3] == '\000')
667 h8500_value_of_trapped_internalvar (var
)
668 struct internalvar
*var
;
671 unsigned char regbuf
[4];
672 int page_regnum
, regnum
;
674 regnum
= var
->name
[2] == 'c' ? PC_REGNUM
: var
->name
[2] - '0';
676 switch (var
->name
[2])
679 page_regnum
= SEG_C_REGNUM
;
685 page_regnum
= SEG_D_REGNUM
;
689 page_regnum
= SEG_E_REGNUM
;
693 page_regnum
= SEG_T_REGNUM
;
697 get_saved_register (regbuf
, NULL
, NULL
, selected_frame
, page_regnum
, NULL
);
698 regval
= regbuf
[0] << 16;
700 get_saved_register (regbuf
, NULL
, NULL
, selected_frame
, regnum
, NULL
);
701 regval
|= regbuf
[0] << 8 | regbuf
[1]; /* XXX host/target byte order */
703 free (var
->value
); /* Free up old value */
705 var
->value
= value_from_longest (builtin_type_unsigned_long
, regval
);
706 release_value (var
->value
); /* Unchain new value */
708 VALUE_LVAL (var
->value
) = lval_internalvar
;
709 VALUE_INTERNALVAR (var
->value
) = var
;
714 h8500_set_trapped_internalvar (var
, newval
, bitpos
, bitsize
, offset
)
715 struct internalvar
*var
;
716 int offset
, bitpos
, bitsize
;
719 char *page_regnum
, *regnum
;
720 char expression
[100];
723 enum type_code newval_type_code
;
725 type
= VALUE_TYPE (newval
);
726 newval_type_code
= TYPE_CODE (type
);
728 if ((newval_type_code
!= TYPE_CODE_INT
729 && newval_type_code
!= TYPE_CODE_PTR
)
730 || TYPE_LENGTH (type
) != sizeof (new_regval
))
731 error ("Illegal type (%s) for assignment to $%s\n",
732 TYPE_NAME (type
), var
->name
);
734 new_regval
= *(long *) VALUE_CONTENTS_RAW (newval
);
736 regnum
= var
->name
+ 1;
738 switch (var
->name
[2])
759 sprintf (expression
, "$%s=%d", page_regnum
, new_regval
>> 16);
760 parse_and_eval (expression
);
762 sprintf (expression
, "$%s=%d", regnum
, new_regval
& 0xffff);
763 parse_and_eval (expression
);
766 _initialize_h8500_tdep ()
768 add_prefix_cmd ("memory", no_class
, set_memory
,
769 "set the memory model", &setmemorylist
, "set memory ", 0,
771 add_cmd ("segmented", class_support
, segmented_command
,
772 "Set segmented memory model.", &setmemorylist
);
773 add_cmd ("unsegmented", class_support
, unsegmented_command
,
774 "Set unsegmented memory model.", &setmemorylist
);
781 return (read_register (SEG_T_REGNUM
) << 16) | (read_register (SP_REGNUM
));
788 write_register (SEG_T_REGNUM
, v
>> 16);
789 write_register (SP_REGNUM
, v
& 0xffff);
795 return (read_register (SEG_C_REGNUM
) << 16) | (read_register (PC_REGNUM
));
802 write_register (SEG_C_REGNUM
, v
>> 16);
803 write_register (PC_REGNUM
, v
& 0xffff);
809 return (read_register (SEG_T_REGNUM
) << 16) | (read_register (FP_REGNUM
));
816 write_register (SEG_T_REGNUM
, v
>> 16);
817 write_register (FP_REGNUM
, v
& 0xffff);