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