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