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