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