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