CARP: Delete ABOUT_TO_RETURN across all targets.
[deliverable/binutils-gdb.git] / gdb / h8500-tdep.c
CommitLineData
ec7b6fcf 1/* Target-dependent code for Hitachi H8/500, for GDB.
18b46e7c 2 Copyright 1993, 1994, 1995 Free Software Foundation, Inc.
195e46ea
SC
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
6c9638b4 18Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
195e46ea
SC
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 32#include "dis-asm.h"
ec7b6fcf 33#include "gdbcore.h"
195e46ea
SC
34
35#define UNSIGNED_SHORT(X) ((X) & 0xffff)
36
ec7b6fcf
SS
37static int code_size = 2;
38
39static int data_size = 2;
195e46ea 40
ec7b6fcf 41/* Shape of an H8/500 frame :
195e46ea
SC
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
195e46ea
SC
56/* an easy to debug H8 stack frame looks like:
570x6df6 push r6
580x0d76 mov.w r7,r6
590x6dfn push reg
600x7905 nnnn mov.w #n,r5 or 0x1b87 subs #2,sp
610x1957 sub.w r5,sp
62
63 */
64
d1445327 65#define IS_PUSH(x) (((x) & 0xff00)==0x6d00)
195e46ea
SC
66#define IS_LINK_8(x) ((x) == 0x17)
67#define IS_LINK_16(x) ((x) == 0x1f)
d1445327
FF
68#define IS_MOVE_FP(x) ((x) == 0x0d76)
69#define IS_MOV_SP_FP(x) ((x) == 0x0d76)
70#define IS_SUB2_SP(x) ((x) == 0x1b87)
71#define IS_MOVK_R5(x) ((x) == 0x7905)
72#define IS_SUB_R5SP(x) ((x) == 0x1957)
195e46ea
SC
73
74#define LINK_8 0x17
75#define LINK_16 0x1f
76
77int minimum_mode = 1;
ccf1e898 78
195e46ea
SC
79CORE_ADDR
80h8500_skip_prologue (start_pc)
81 CORE_ADDR start_pc;
195e46ea
SC
82{
83 short int w;
84
ec7b6fcf 85 w = read_memory_integer (start_pc, 1);
195e46ea
SC
86 if (w == LINK_8)
87 {
ccf1e898 88 start_pc += 2;
85e07872 89 w = read_memory_integer (start_pc, 1);
195e46ea
SC
90 }
91
92 if (w == LINK_16)
93 {
ccf1e898 94 start_pc += 3;
85e07872 95 w = read_memory_integer (start_pc, 2);
195e46ea
SC
96 }
97
195e46ea 98 return start_pc;
195e46ea
SC
99}
100
195e46ea
SC
101/* Given a GDB frame, determine the address of the calling function's frame.
102 This will be used to create a new GDB frame struct, and then
103 INIT_EXTRA_FRAME_INFO and INIT_FRAME_PC will be called for the new frame.
104
105 For us, the frame address is its stack pointer value, so we look up
106 the function prologue to determine the caller's sp value, and return it. */
107
669caa9c 108CORE_ADDR
ccf1e898 109h8500_frame_chain (thisframe)
669caa9c 110 struct frame_info *thisframe;
195e46ea 111{
ccf1e898 112 if (!inside_entry_file (thisframe->pc))
08c0d7b8 113 return (read_memory_integer (FRAME_FP (thisframe), PTR_SIZE));
ccf1e898
SG
114 else
115 return 0;
195e46ea
SC
116}
117
195e46ea
SC
118/* Fetch the instruction at ADDR, returning 0 if ADDR is beyond LIM or
119 is not the address of a valid instruction, the address of the next
120 instruction beyond ADDR otherwise. *PWORD1 receives the first word
121 of the instruction.*/
122
123CORE_ADDR
124NEXT_PROLOGUE_INSN (addr, lim, pword1)
125 CORE_ADDR addr;
126 CORE_ADDR lim;
127 char *pword1;
128{
129 if (addr < lim + 8)
130 {
131 read_memory (addr, pword1, 1);
132 read_memory (addr, pword1 + 1, 1);
133 return 1;
134 }
135 return 0;
136}
137
ec7b6fcf
SS
138/* Examine the prologue of a function. `ip' points to the first
139 instruction. `limit' is the limit of the prologue (e.g. the addr
140 of the first linenumber, or perhaps the program counter if we're
141 stepping through). `frame_sp' is the stack pointer value in use in
142 this frame. `fsr' is a pointer to a frame_saved_regs structure
143 into which we put info about the registers saved by this frame.
144 `fi' is a struct frame_info pointer; we fill in various fields in
145 it to reflect the offsets of the arg pointer and the locals
146 pointer. */
195e46ea
SC
147
148/* Return the saved PC from this frame. */
149
150CORE_ADDR
151frame_saved_pc (frame)
669caa9c 152 struct frame_info *frame;
195e46ea 153{
669caa9c 154 return read_memory_integer (FRAME_FP (frame) + 2, PTR_SIZE);
195e46ea
SC
155}
156
ec7b6fcf
SS
157void
158h8500_pop_frame ()
195e46ea
SC
159{
160 unsigned regnum;
161 struct frame_saved_regs fsr;
669caa9c 162 struct frame_info *frame = get_current_frame ();
195e46ea 163
669caa9c 164 get_frame_saved_regs (frame, &fsr);
195e46ea
SC
165
166 for (regnum = 0; regnum < 8; regnum++)
167 {
168 if (fsr.regs[regnum])
ec7b6fcf 169 write_register (regnum, read_memory_short (fsr.regs[regnum]));
195e46ea
SC
170
171 flush_cached_frames ();
195e46ea 172 }
195e46ea
SC
173}
174
175void
176print_register_hook (regno)
ec7b6fcf 177 int regno;
195e46ea
SC
178{
179 if (regno == CCR_REGNUM)
180 {
181 /* CCR register */
182
183 int C, Z, N, V;
184 unsigned char b[2];
185 unsigned char l;
186
187 read_relative_register_raw_bytes (regno, b);
188 l = b[1];
199b2450
TL
189 printf_unfiltered ("\t");
190 printf_unfiltered ("I-%d - ", (l & 0x80) != 0);
195e46ea
SC
191 N = (l & 0x8) != 0;
192 Z = (l & 0x4) != 0;
193 V = (l & 0x2) != 0;
194 C = (l & 0x1) != 0;
199b2450
TL
195 printf_unfiltered ("N-%d ", N);
196 printf_unfiltered ("Z-%d ", Z);
197 printf_unfiltered ("V-%d ", V);
198 printf_unfiltered ("C-%d ", C);
195e46ea 199 if ((C | Z) == 0)
199b2450 200 printf_unfiltered ("u> ");
195e46ea 201 if ((C | Z) == 1)
199b2450 202 printf_unfiltered ("u<= ");
195e46ea 203 if ((C == 0))
199b2450 204 printf_unfiltered ("u>= ");
195e46ea 205 if (C == 1)
199b2450 206 printf_unfiltered ("u< ");
195e46ea 207 if (Z == 0)
199b2450 208 printf_unfiltered ("!= ");
195e46ea 209 if (Z == 1)
199b2450 210 printf_unfiltered ("== ");
195e46ea 211 if ((N ^ V) == 0)
199b2450 212 printf_unfiltered (">= ");
195e46ea 213 if ((N ^ V) == 1)
199b2450 214 printf_unfiltered ("< ");
195e46ea 215 if ((Z | (N ^ V)) == 0)
199b2450 216 printf_unfiltered ("> ");
195e46ea 217 if ((Z | (N ^ V)) == 1)
199b2450 218 printf_unfiltered ("<= ");
195e46ea
SC
219 }
220}
221
ccf1e898
SG
222int
223h8500_register_size (regno)
224 int regno;
195e46ea 225{
ec7b6fcf
SS
226 switch (regno)
227 {
228 case SEG_C_REGNUM:
229 case SEG_D_REGNUM:
230 case SEG_E_REGNUM:
231 case SEG_T_REGNUM:
232 return 1;
233 case R0_REGNUM:
234 case R1_REGNUM:
235 case R2_REGNUM:
236 case R3_REGNUM:
237 case R4_REGNUM:
238 case R5_REGNUM:
239 case R6_REGNUM:
240 case R7_REGNUM:
241 case CCR_REGNUM:
242 return 2;
243
244 case PR0_REGNUM:
245 case PR1_REGNUM:
246 case PR2_REGNUM:
247 case PR3_REGNUM:
248 case PR4_REGNUM:
249 case PR5_REGNUM:
250 case PR6_REGNUM:
251 case PR7_REGNUM:
252 case PC_REGNUM:
253 return 4;
254 default:
255 abort ();
256 }
195e46ea
SC
257}
258
259struct type *
ccf1e898
SG
260h8500_register_virtual_type (regno)
261 int regno;
195e46ea 262{
ccf1e898 263 switch (regno)
195e46ea 264 {
ccf1e898
SG
265 case SEG_C_REGNUM:
266 case SEG_E_REGNUM:
267 case SEG_D_REGNUM:
268 case SEG_T_REGNUM:
195e46ea 269 return builtin_type_unsigned_char;
ccf1e898
SG
270 case R0_REGNUM:
271 case R1_REGNUM:
272 case R2_REGNUM:
273 case R3_REGNUM:
274 case R4_REGNUM:
275 case R5_REGNUM:
276 case R6_REGNUM:
277 case R7_REGNUM:
195e46ea
SC
278 case CCR_REGNUM:
279 return builtin_type_unsigned_short;
08c0d7b8
SC
280 case PR0_REGNUM:
281 case PR1_REGNUM:
282 case PR2_REGNUM:
283 case PR3_REGNUM:
284 case PR4_REGNUM:
285 case PR5_REGNUM:
286 case PR6_REGNUM:
287 case PR7_REGNUM:
288 case PC_REGNUM:
289 return builtin_type_unsigned_long;
195e46ea 290 default:
85e07872 291 abort ();
195e46ea
SC
292 }
293}
294
195e46ea
SC
295/* Put here the code to store, into a struct frame_saved_regs,
296 the addresses of the saved registers of frame described by FRAME_INFO.
297 This includes special registers such as pc and fp saved in special
298 ways in the stack frame. sp is even more special:
299 the address we return for it IS the sp for the next frame. */
300
301void
302frame_find_saved_regs (frame_info, frame_saved_regs)
303 struct frame_info *frame_info;
304 struct frame_saved_regs *frame_saved_regs;
195e46ea
SC
305{
306 register int regnum;
307 register int regmask;
308 register CORE_ADDR next_addr;
309 register CORE_ADDR pc;
310 unsigned char thebyte;
311
4ed97c9a 312 memset (frame_saved_regs, '\0', sizeof *frame_saved_regs);
195e46ea
SC
313
314 if ((frame_info)->pc >= (frame_info)->frame - CALL_DUMMY_LENGTH - FP_REGNUM * 4 - 4
315 && (frame_info)->pc <= (frame_info)->frame)
316 {
317 next_addr = (frame_info)->frame;
318 pc = (frame_info)->frame - CALL_DUMMY_LENGTH - FP_REGNUM * 4 - 4;
319 }
320 else
321 {
322 pc = get_pc_function_start ((frame_info)->pc);
323 /* Verify we have a link a6 instruction next;
324 if not we lose. If we win, find the address above the saved
325 regs using the amount of storage from the link instruction.
326 */
327
85e07872 328 thebyte = read_memory_integer (pc, 1);
195e46ea
SC
329 if (0x1f == thebyte)
330 next_addr = (frame_info)->frame + read_memory_integer (pc += 1, 2), pc += 2;
331 else if (0x17 == thebyte)
332 next_addr = (frame_info)->frame + read_memory_integer (pc += 1, 1), pc += 1;
333 else
334 goto lose;
335#if 0
d1445327 336 /* FIXME steve */
85e07872
SC
337 /* If have an add:g.waddal #-n, sp next, adjust next_addr. */
338 if ((0x0c0177777 & read_memory_integer (pc, 2)) == 0157774)
339 next_addr += read_memory_integer (pc += 2, 4), pc += 4;
195e46ea
SC
340#endif
341 }
342
85e07872
SC
343 thebyte = read_memory_integer (pc, 1);
344 if (thebyte == 0x12)
345 {
346 /* Got stm */
347 pc++;
348 regmask = read_memory_integer (pc, 1);
349 pc++;
350 for (regnum = 0; regnum < 8; regnum++, regmask >>= 1)
351 {
352 if (regmask & 1)
353 {
354 (frame_saved_regs)->regs[regnum] = (next_addr += 2) - 2;
355 }
356 }
357 thebyte = read_memory_integer (pc, 1);
358 }
195e46ea 359 /* Maybe got a load of pushes */
85e07872
SC
360 while (thebyte == 0xbf)
361 {
362 pc++;
363 regnum = read_memory_integer (pc, 1) & 0x7;
364 pc++;
365 (frame_saved_regs)->regs[regnum] = (next_addr += 2) - 2;
366 thebyte = read_memory_integer (pc, 1);
367 }
368
369lose:;
370
195e46ea
SC
371 /* Remember the address of the frame pointer */
372 (frame_saved_regs)->regs[FP_REGNUM] = (frame_info)->frame;
373
374 /* This is where the old sp is hidden */
375 (frame_saved_regs)->regs[SP_REGNUM] = (frame_info)->frame;
376
377 /* And the PC - remember the pushed FP is always two bytes long */
378 (frame_saved_regs)->regs[PC_REGNUM] = (frame_info)->frame + 2;
379}
380
ec7b6fcf
SS
381CORE_ADDR
382saved_pc_after_call ()
195e46ea
SC
383{
384 int x;
85e07872 385 int a = read_register (SP_REGNUM);
ec7b6fcf 386
edd01519
SC
387 x = read_memory_integer (a, code_size);
388 if (code_size == 2)
389 {
390 /* Stick current code segement onto top */
391 x &= 0xffff;
392 x |= read_register (SEG_C_REGNUM) << 16;
393 }
394 x &= 0xffffff;
195e46ea
SC
395 return x;
396}
397
195e46ea
SC
398void
399h8500_set_pointer_size (newsize)
400 int newsize;
401{
402 static int oldsize = 0;
403
404 if (oldsize != newsize)
405 {
199b2450 406 printf_unfiltered ("pointer size set to %d bits\n", newsize);
195e46ea
SC
407 oldsize = newsize;
408 if (newsize == 32)
409 {
410 minimum_mode = 0;
411 }
412 else
413 {
414 minimum_mode = 1;
415 }
416 _initialize_gdbtypes ();
417 }
418}
419
ec7b6fcf
SS
420static void
421big_command ()
422{
423 h8500_set_pointer_size (32);
424 code_size = 4;
425 data_size = 4;
426}
195e46ea 427
ec7b6fcf
SS
428static void
429medium_command ()
430{
431 h8500_set_pointer_size (32);
432 code_size = 4;
433 data_size = 2;
434}
195e46ea 435
ec7b6fcf
SS
436static void
437compact_command ()
438{
439 h8500_set_pointer_size (32);
440 code_size = 2;
441 data_size = 4;
442}
195e46ea 443
ec7b6fcf
SS
444static void
445small_command ()
446{
447 h8500_set_pointer_size (16);
448 code_size = 2;
449 data_size = 2;
450}
195e46ea 451
ec7b6fcf 452static struct cmd_list_element *setmemorylist;
195e46ea
SC
453
454static void
455set_memory (args, from_tty)
456 char *args;
457 int from_tty;
458{
199b2450
TL
459 printf_unfiltered ("\"set memory\" must be followed by the name of a memory subcommand.\n");
460 help_list (setmemorylist, "set memory ", -1, gdb_stdout);
195e46ea
SC
461}
462
ccf1e898 463/* See if variable name is ppc or pr[0-7] */
195e46ea 464
ccf1e898
SG
465int
466h8500_is_trapped_internalvar (name)
467 char *name;
468{
469 if (name[0] != 'p')
470 return 0;
471
85e07872 472 if (strcmp (name + 1, "pc") == 0)
ccf1e898
SG
473 return 1;
474
475 if (name[1] == 'r'
476 && name[2] >= '0'
477 && name[2] <= '7'
478 && name[3] == '\000')
479 return 1;
480 else
481 return 0;
482}
483
63eef03a 484value_ptr
ccf1e898
SG
485h8500_value_of_trapped_internalvar (var)
486 struct internalvar *var;
487{
488 LONGEST regval;
489 unsigned char regbuf[4];
490 int page_regnum, regnum;
491
492 regnum = var->name[2] == 'c' ? PC_REGNUM : var->name[2] - '0';
493
494 switch (var->name[2])
495 {
496 case 'c':
497 page_regnum = SEG_C_REGNUM;
498 break;
85e07872
SC
499 case '0':
500 case '1':
501 case '2':
502 case '3':
ccf1e898
SG
503 page_regnum = SEG_D_REGNUM;
504 break;
85e07872
SC
505 case '4':
506 case '5':
ccf1e898
SG
507 page_regnum = SEG_E_REGNUM;
508 break;
85e07872
SC
509 case '6':
510 case '7':
ccf1e898
SG
511 page_regnum = SEG_T_REGNUM;
512 break;
513 }
514
515 get_saved_register (regbuf, NULL, NULL, selected_frame, page_regnum, NULL);
516 regval = regbuf[0] << 16;
517
518 get_saved_register (regbuf, NULL, NULL, selected_frame, regnum, NULL);
519 regval |= regbuf[0] << 8 | regbuf[1]; /* XXX host/target byte order */
520
521 free (var->value); /* Free up old value */
522
523 var->value = value_from_longest (builtin_type_unsigned_long, regval);
524 release_value (var->value); /* Unchain new value */
525
526 VALUE_LVAL (var->value) = lval_internalvar;
527 VALUE_INTERNALVAR (var->value) = var;
528 return var->value;
529}
530
531void
532h8500_set_trapped_internalvar (var, newval, bitpos, bitsize, offset)
533 struct internalvar *var;
534 int offset, bitpos, bitsize;
63eef03a 535 value_ptr newval;
195e46ea 536{
ccf1e898
SG
537 char *page_regnum, *regnum;
538 char expression[100];
539 unsigned new_regval;
540 struct type *type;
541 enum type_code newval_type_code;
542
940d5967 543 type = check_typedef (VALUE_TYPE (newval));
ccf1e898
SG
544 newval_type_code = TYPE_CODE (type);
545
546 if ((newval_type_code != TYPE_CODE_INT
547 && newval_type_code != TYPE_CODE_PTR)
85e07872
SC
548 || TYPE_LENGTH (type) != sizeof (new_regval))
549 error ("Illegal type (%s) for assignment to $%s\n",
940d5967 550 TYPE_NAME (VALUE_TYPE (newval)), var->name);
195e46ea 551
85e07872 552 new_regval = *(long *) VALUE_CONTENTS_RAW (newval);
ccf1e898
SG
553
554 regnum = var->name + 1;
555
556 switch (var->name[2])
557 {
558 case 'c':
559 page_regnum = "cp";
560 break;
85e07872
SC
561 case '0':
562 case '1':
563 case '2':
564 case '3':
ccf1e898
SG
565 page_regnum = "dp";
566 break;
85e07872
SC
567 case '4':
568 case '5':
ccf1e898
SG
569 page_regnum = "ep";
570 break;
85e07872
SC
571 case '6':
572 case '7':
ccf1e898
SG
573 page_regnum = "tp";
574 break;
575 }
576
577 sprintf (expression, "$%s=%d", page_regnum, new_regval >> 16);
85e07872 578 parse_and_eval (expression);
ccf1e898
SG
579
580 sprintf (expression, "$%s=%d", regnum, new_regval & 0xffff);
85e07872 581 parse_and_eval (expression);
ccf1e898
SG
582}
583
85e07872 584CORE_ADDR
f4eb9968 585h8500_read_sp ()
85e07872 586{
08c0d7b8 587 return read_register (PR7_REGNUM);
85e07872
SC
588}
589
590void
f4eb9968 591h8500_write_sp (v)
85e07872
SC
592 CORE_ADDR v;
593{
08c0d7b8 594 write_register (PR7_REGNUM, v);
85e07872
SC
595}
596
597CORE_ADDR
f4eb9968
SS
598h8500_read_pc (pid)
599 int pid;
85e07872 600{
08c0d7b8 601 return read_register (PC_REGNUM);
85e07872
SC
602}
603
604void
f4eb9968 605h8500_write_pc (v, pid)
85e07872 606 CORE_ADDR v;
f4eb9968 607 int pid;
85e07872 608{
08c0d7b8 609 write_register (PC_REGNUM, v);
85e07872
SC
610}
611
612CORE_ADDR
f4eb9968 613h8500_read_fp ()
85e07872 614{
08c0d7b8 615 return read_register (PR6_REGNUM);
85e07872
SC
616}
617
618void
f4eb9968 619h8500_write_fp (v)
85e07872
SC
620 CORE_ADDR v;
621{
08c0d7b8 622 write_register (PR6_REGNUM, v);
85e07872 623}
1468bec9 624
18b46e7c
SS
625void
626_initialize_h8500_tdep ()
627{
ec7b6fcf
SS
628 tm_print_insn = print_insn_h8500;
629
630 add_prefix_cmd ("memory", no_class, set_memory,
631 "set the memory model", &setmemorylist, "set memory ", 0,
632 &setlist);
633
634 add_cmd ("small", class_support, small_command,
635 "Set small memory model. (16 bit code, 16 bit data)", &setmemorylist);
636
637 add_cmd ("big", class_support, big_command,
638 "Set big memory model. (32 bit code, 32 bit data)", &setmemorylist);
639
640 add_cmd ("medium", class_support, medium_command,
641 "Set medium memory model. (32 bit code, 16 bit data)", &setmemorylist);
642
643 add_cmd ("compact", class_support, compact_command,
644 "Set compact memory model. (16 bit code, 32 bit data)", &setmemorylist);
645
18b46e7c 646}
This page took 0.289826 seconds and 4 git commands to generate.