1 /* ARC target-dependent stuff.
2 Copyright (C) 1995 Free Software Foundation, Inc.
4 This file is part of GDB.
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.
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.
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., 675 Mass Ave, Cambridge, MA 02139, USA. */
25 #include "floatformat.h"
29 /* Current CPU, set with the "set cpu" command. */
31 char *tmp_arc_cpu_type
;
33 /* Table of cpu names. */
37 } arc_cpu_type_table
[] = {
38 { "base", bfd_mach_arc_base
},
39 { "host", bfd_mach_arc_host
},
40 { "graphics", bfd_mach_arc_graphics
},
41 { "audio", bfd_mach_arc_audio
},
45 /* Used by simulator. */
46 int display_pipeline_p
;
48 /* This one must have the same type as used in the emulator.
49 It's currently an enum so this should be ok for now. */
52 #define ARC_CALL_SAVED_REG(r) ((r) >= 16 && (r) < 24)
54 #define OPMASK 0xf8000000
56 /* Instruction field accessor macros. */
57 #define X_OP(i) (((i) >> 27) & 0x1f)
58 #define X_A(i) (((i) >> 21) & 0x3f)
59 #define X_B(i) (((i) >> 15) & 0x3f)
60 #define X_C(i) (((i) >> 9) & 0x3f)
61 #define X_D(i) ((((i) & 0x1ff) ^ 0x100) - 0x100)
62 #define X_L(i) (((((i) >> 5) & 0x3ffffc) ^ 0x200000) - 0x200000)
63 #define X_N(i) (((i) >> 5) & 3)
64 #define X_Q(i) ((i) & 0x1f)
66 /* Return non-zero if X is a short immediate data indicator. */
67 #define SHIMM_P(x) ((x) == 61 || (x) == 63)
69 /* Return non-zero if X is a "long" (32 bit) immediate data indicator. */
70 #define LIMM_P(x) ((x) == 62)
72 /* Build a simple instruction. */
73 #define BUILD_INSN(op, a, b, c, d) \
74 ((((op) & 31) << 27) \
75 | (((a) & 63) << 21) \
76 | (((b) & 63) << 15) \
80 /* Codestream stuff. */
81 static void codestream_read
PARAMS ((unsigned int *, int));
82 static void codestream_seek
PARAMS ((CORE_ADDR
));
83 static unsigned int codestream_fill
PARAMS ((int));
85 #define CODESTREAM_BUFSIZ 16
86 static CORE_ADDR codestream_next_addr
;
87 static CORE_ADDR codestream_addr
;
88 static unsigned int codestream_buf
[CODESTREAM_BUFSIZ
];
89 static int codestream_off
;
90 static int codestream_cnt
;
92 #define codestream_tell() \
93 (codestream_addr + codestream_off * sizeof (codestream_buf[0]))
94 #define codestream_peek() \
95 (codestream_cnt == 0 \
96 ? codestream_fill (1) \
97 : codestream_buf[codestream_off])
98 #define codestream_get() \
99 (codestream_cnt-- == 0 \
100 ? codestream_fill (0) \
101 : codestream_buf[codestream_off++])
104 codestream_fill (peek_flag
)
107 codestream_addr
= codestream_next_addr
;
108 codestream_next_addr
+= CODESTREAM_BUFSIZ
* sizeof (codestream_buf
[0]);
110 codestream_cnt
= CODESTREAM_BUFSIZ
;
111 /* FIXME: need to handle byte order differences. */
112 read_memory (codestream_addr
, (char *) codestream_buf
,
113 CODESTREAM_BUFSIZ
* sizeof (codestream_buf
[0]));
116 return (codestream_peek());
118 return (codestream_get());
122 codestream_seek (place
)
125 codestream_next_addr
= place
/ CODESTREAM_BUFSIZ
;
126 codestream_next_addr
*= CODESTREAM_BUFSIZ
;
129 while (codestream_tell() != place
)
134 codestream_read (buf
, count
)
141 for (i
= 0; i
< count
; i
++)
142 *p
++ = codestream_get ();
145 /* Set up prologue scanning and return the first insn,
146 not including the "sub sp,sp,32" of a stdarg function. */
149 setup_prologue_scan (pc
)
154 codestream_seek (pc
);
155 insn
= codestream_get ();
157 /* The authority for what appears here is the home-grown ABI. */
159 /* First insn may be "sub sp,sp,32" if stdarg fn. */
160 if (insn
== BUILD_INSN (10, SP_REGNUM
, SP_REGNUM
, SHIMM_REGNUM
, 32))
161 insn
= codestream_get ();
167 * Find & return amount a local space allocated, and advance codestream to
168 * first register push (if any).
169 * If entry sequence doesn't make sense, return -1, and leave
170 * codestream pointer random.
174 arc_get_frame_setup (pc
)
178 /* Size of frame or -1 if unrecognizable prologue. */
181 insn
= setup_prologue_scan (pc
);
183 if ((insn
& BUILD_INSN (-1, 0, -1, -1, -1)) /* st blink,[sp,4] */
184 == BUILD_INSN (2, 0, SP_REGNUM
, BLINK_REGNUM
, 4))
186 insn
= codestream_get ();
187 /* Frame may not be necessary, even though blink is saved.
188 At least this is something we recognize. */
192 if ((insn
& BUILD_INSN (-1, 0, -1, -1, -1)) /* st fp,[sp] */
193 == BUILD_INSN (2, 0, SP_REGNUM
, FP_REGNUM
, 0))
195 insn
= codestream_get ();
196 if ((insn
& BUILD_INSN (-1, -1, -1, -1, 0))
197 != BUILD_INSN (12, FP_REGNUM
, SP_REGNUM
, SP_REGNUM
, 0))
200 /* Check for stack adjustment sub sp,sp,nnn. */
201 insn
= codestream_peek ();
202 if ((insn
& BUILD_INSN (-1, -1, -1, 0, 0))
203 == BUILD_INSN (10, SP_REGNUM
, SP_REGNUM
, 0, 0))
205 if (LIMM_P (X_C (insn
)))
206 n
= codestream_get ();
207 else if (SHIMM_P (X_C (insn
)))
216 /* This sequence is used to get the address of the return
217 buffer for a function that returns a structure. */
218 insn
= codestream_peek ();
219 if (insn
& OPMASK
== 0x60000000)
232 /* Given a pc value, skip it forward past the function prologue by
233 disassembling instructions that appear to be a prologue.
235 If FRAMELESS_P is set, we are only testing to see if the function
236 is frameless. If it is a frameless function, return PC unchanged.
237 This allows a quicker answer. */
240 skip_prologue (pc
, frameless_p
)
247 if ((frame_size
= arc_get_frame_setup (pc
)) < 0)
251 return frame_size
== 0 ? pc
: codestream_tell ();
253 /* Skip over register saves. */
254 for (i
= 0; i
< 8; i
++)
256 insn
= codestream_peek ();
257 if ((insn
& BUILD_INSN (-1, 0, -1, 0, 0))
258 != BUILD_INSN (2, 0, SP_REGNUM
, 0, 0))
259 break; /* not st insn */
260 if (! ARC_CALL_SAVED_REG (X_C (insn
)))
265 return codestream_tell ();
268 /* Return the return address for a frame.
269 This is used to implement FRAME_SAVED_PC.
270 This is taken from frameless_look_for_prologue. */
273 arc_frame_saved_pc (frame
)
274 struct frame_info
*frame
;
276 CORE_ADDR func_start
;
279 func_start
= get_pc_function_start (frame
->pc
) + FUNCTION_START_OFFSET
;
283 return ARC_PC_TO_REAL_ADDRESS (read_memory_integer (FRAME_FP (frame
) + 4, 4));
286 /* If the first insn is "st blink,[sp,4]" we can get blink from there.
287 Otherwise this is a leaf function and we can use blink. Note that
288 this still allows for the case where a leaf function saves/clobbers/
291 insn
= setup_prologue_scan (func_start
);
293 if ((insn
& BUILD_INSN (-1, 0, -1, -1, -1)) /* st blink,[sp,4] */
294 != BUILD_INSN (2, 0, SP_REGNUM
, BLINK_REGNUM
, 4))
295 return ARC_PC_TO_REAL_ADDRESS (read_register (BLINK_REGNUM
));
297 return ARC_PC_TO_REAL_ADDRESS (read_memory_integer (FRAME_FP (frame
) + 4, 4));
301 * Parse the first few instructions of the function to see
302 * what registers were stored.
304 * The startup sequence can be at the start of the function.
305 * 'st blink,[sp+4], st fp,[sp], mov fp,sp'
307 * Local space is allocated just below by sub sp,sp,nnn.
308 * Next, the registers used by this function are stored (as offsets from sp).
312 frame_find_saved_regs (fip
, fsrp
)
313 struct frame_info
*fip
;
314 struct frame_saved_regs
*fsrp
;
318 CORE_ADDR dummy_bottom
;
320 int i
, regnum
, offset
;
322 memset (fsrp
, 0, sizeof *fsrp
);
324 /* If frame is the end of a dummy, compute where the beginning would be. */
325 dummy_bottom
= fip
->frame
- 4 - REGISTER_BYTES
- CALL_DUMMY_LENGTH
;
327 /* Check if the PC is in the stack, in a dummy frame. */
328 if (dummy_bottom
<= fip
->pc
&& fip
->pc
<= fip
->frame
)
330 /* all regs were saved by push_call_dummy () */
332 for (i
= 0; i
< NUM_REGS
; i
++)
334 adr
-= REGISTER_RAW_SIZE (i
);
340 locals
= arc_get_frame_setup (get_pc_function_start (fip
->pc
));
344 /* Set `adr' to the value of `sp'. */
345 adr
= fip
->frame
- locals
;
346 for (i
= 0; i
< 8; i
++)
348 insn
= codestream_get ();
349 if ((insn
& BUILD_INSN (-1, 0, -1, 0, 0))
350 != BUILD_INSN (2, 0, SP_REGNUM
, 0, 0))
354 fsrp
->regs
[regnum
] = adr
+ offset
;
358 fsrp
->regs
[PC_REGNUM
] = fip
->frame
+ 4;
359 fsrp
->regs
[FP_REGNUM
] = fip
->frame
;
365 CORE_ADDR sp
= read_register (SP_REGNUM
);
367 char regbuf
[MAX_REGISTER_RAW_SIZE
];
369 read_register_gen (PC_REGNUM
, regbuf
);
370 write_memory (sp
+4, regbuf
, REGISTER_SIZE
);
371 read_register_gen (FP_REGNUM
, regbuf
);
372 write_memory (sp
, regbuf
, REGISTER_SIZE
);
373 write_register (FP_REGNUM
, sp
);
374 for (regnum
= 0; regnum
< NUM_REGS
; regnum
++)
376 read_register_gen (regnum
, regbuf
);
377 sp
= push_bytes (sp
, regbuf
, REGISTER_RAW_SIZE (regnum
));
379 sp
+= (2*REGISTER_SIZE
);
380 write_register (SP_REGNUM
, sp
);
386 struct frame_info
*frame
= get_current_frame ();
389 struct frame_saved_regs fsr
;
390 char regbuf
[MAX_REGISTER_RAW_SIZE
];
392 fp
= FRAME_FP (frame
);
393 get_frame_saved_regs (frame
, &fsr
);
394 for (regnum
= 0; regnum
< NUM_REGS
; regnum
++)
397 adr
= fsr
.regs
[regnum
];
400 read_memory (adr
, regbuf
, REGISTER_RAW_SIZE (regnum
));
401 write_register_bytes (REGISTER_BYTE (regnum
), regbuf
,
402 REGISTER_RAW_SIZE (regnum
));
405 write_register (FP_REGNUM
, read_memory_integer (fp
, 4));
406 write_register (PC_REGNUM
, read_memory_integer (fp
+ 4, 4));
407 write_register (SP_REGNUM
, fp
+ 8);
408 flush_cached_frames ();
411 /* Simulate single-step. */
415 NORMAL4
, /* a normal 4 byte insn */
416 NORMAL8
, /* a normal 8 byte insn */
417 BRANCH4
, /* a 4 byte branch insn, including ones without delay slots */
418 BRANCH8
, /* an 8 byte branch insn, including ones with delay slots */
421 /* Return the type of INSN and store in TARGET the destination address of a
422 branch if this is one. */
423 /* ??? Need to verify all cases are properly handled. */
426 get_insn_type (insn
, pc
, target
)
428 CORE_ADDR pc
, *target
;
434 case 0 : case 1 : case 2 : /* load/store insns */
435 if (LIMM_P (X_A (insn
))
436 || LIMM_P (X_B (insn
))
437 || LIMM_P (X_C (insn
)))
440 case 4 : case 5 : case 6 : /* branch insns */
441 *target
= pc
+ 4 + X_L (insn
);
442 /* ??? It isn't clear that this is always the right answer.
443 The problem occurs when the next insn is an 8 byte insn. If the
444 branch is conditional there's no worry as there shouldn't be an 8
445 byte insn following. The programmer may be cheating if s/he knows
446 the branch will never be taken, but we don't deal with that.
447 Note that the programmer is also allowed to play games by putting
448 an insn with long immediate data in the delay slot and then duplicate
449 the long immediate data at the branch target. Ugh! */
453 case 7 : /* jump insns */
454 if (LIMM_P (X_B (insn
)))
456 limm
= read_memory_integer (pc
+ 4, 4);
457 *target
= ARC_PC_TO_REAL_ADDRESS (limm
);
460 if (SHIMM_P (X_B (insn
)))
461 *target
= ARC_PC_TO_REAL_ADDRESS (X_D (insn
));
463 *target
= ARC_PC_TO_REAL_ADDRESS (read_register (X_B (insn
)));
464 if (X_Q (insn
) == 0 && X_N (insn
) == 0)
467 default : /* arithmetic insns, etc. */
468 if (LIMM_P (X_A (insn
))
469 || LIMM_P (X_B (insn
))
470 || LIMM_P (X_C (insn
)))
476 /* Non-zero if we just simulated a single-step. This is needed because we
477 cannot remove the breakpoints in the inferior process until after the
478 `wait' in `wait_for_inferior'. */
482 /* single_step() is called just before we want to resume the inferior, if we
483 want to single-step it but there is no hardware or kernel single-step
484 support. We find all the possible targets of the coming instruction and
487 single_step is also called just after the inferior stops. If we had
488 set up a simulated single-step, we undo our damage. */
492 int ignore
; /* sig, but we don't need it */
494 static CORE_ADDR next_pc
, target
;
496 typedef char binsn_quantum
[BREAKPOINT_MAX
];
497 static binsn_quantum break_mem
[2];
505 pc
= read_register (PC_REGNUM
);
506 insn
= read_memory_integer (pc
, 4);
507 type
= get_insn_type (insn
, pc
, &target
);
509 /* Always set a breakpoint for the insn after the branch. */
510 next_pc
= pc
+ ((type
== NORMAL8
|| type
== BRANCH8
) ? 8 : 4);
511 target_insert_breakpoint (next_pc
, break_mem
[0]);
515 if ((type
== BRANCH4
|| type
== BRANCH8
)
516 /* Watch out for branches to the following location.
517 We just stored a breakpoint there and another call to
518 target_insert_breakpoint will think the real insn is the
519 breakpoint we just stored there. */
520 && target
!= next_pc
)
523 target_insert_breakpoint (target
, break_mem
[1]);
526 /* We are ready to let it go. */
531 /* Remove breakpoints. */
532 target_remove_breakpoint (next_pc
, break_mem
[0]);
535 target_remove_breakpoint (target
, break_mem
[1]);
538 stop_pc
-= DECR_PC_AFTER_BREAK
;
545 #ifdef GET_LONGJMP_TARGET
546 /* Figure out where the longjmp will land. Slurp the args out of the stack.
547 We expect the first arg to be a pointer to the jmp_buf structure from which
548 we extract the pc (JB_PC) that we will land at. The pc is copied into PC.
549 This routine returns true on success. */
552 get_longjmp_target(pc
)
555 char buf
[TARGET_PTR_BIT
/ TARGET_CHAR_BIT
];
556 CORE_ADDR sp
, jb_addr
;
558 sp
= read_register (SP_REGNUM
);
560 if (target_read_memory (sp
+ SP_ARG0
, /* Offset of first arg on stack */
562 TARGET_PTR_BIT
/ TARGET_CHAR_BIT
))
565 jb_addr
= extract_address (buf
, TARGET_PTR_BIT
/ TARGET_CHAR_BIT
);
567 if (target_read_memory (jb_addr
+ JB_PC
* JB_ELEMENT_SIZE
, buf
,
568 TARGET_PTR_BIT
/ TARGET_CHAR_BIT
))
571 *pc
= extract_address (buf
, TARGET_PTR_BIT
/ TARGET_CHAR_BIT
);
575 #endif /* GET_LONGJMP_TARGET */
577 /* Command to set cpu type. */
580 arc_set_cpu_type_command (args
, from_tty
)
586 if (tmp_arc_cpu_type
== NULL
|| *tmp_arc_cpu_type
== '\0')
588 printf_unfiltered ("The known ARC cpu types are as follows:\n");
589 for (i
= 0; arc_cpu_type_table
[i
].name
!= NULL
; ++i
)
590 printf_unfiltered ("%s\n", arc_cpu_type_table
[i
].name
);
592 /* Restore the value. */
593 tmp_arc_cpu_type
= strsave (arc_cpu_type
);
598 if (!arc_set_cpu_type (tmp_arc_cpu_type
))
600 error ("Unknown cpu type `%s'.", tmp_arc_cpu_type
);
601 /* Restore its value. */
602 tmp_arc_cpu_type
= strsave (arc_cpu_type
);
607 arc_show_cpu_type_command (args
, from_tty
)
613 /* Modify the actual cpu type.
614 Result is a boolean indicating success. */
617 arc_set_cpu_type (str
)
625 for (i
= 0; arc_cpu_type_table
[i
].name
!= NULL
; ++i
)
627 if (strcasecmp (str
, arc_cpu_type_table
[i
].name
) == 0)
630 tm_print_insn
= arc_get_disassembler (arc_cpu_type_table
[i
].value
,
631 TARGET_BYTE_ORDER
== BIG_ENDIAN
);
640 _initialize_arc_tdep ()
642 struct cmd_list_element
*c
;
644 c
= add_set_cmd ("cpu", class_support
, var_string_noescape
,
645 (char *) &tmp_arc_cpu_type
,
646 "Set the type of ARC cpu in use.\n\
647 This command has two purposes. In a multi-cpu system it lets one\n\
648 change the cpu being debugged. It also gives one access to\n\
649 cpu-type-specific registers and recognize cpu-type-specific instructions.\
652 c
->function
.cfunc
= arc_set_cpu_type_command
;
653 c
= add_show_from_set (c
, &showlist
);
654 c
->function
.cfunc
= arc_show_cpu_type_command
;
656 /* We have to use strsave here because the `set' command frees it before
657 setting a new value. */
658 tmp_arc_cpu_type
= strsave (DEFAULT_ARC_CPU_TYPE
);
659 arc_set_cpu_type (tmp_arc_cpu_type
);
661 c
= add_set_cmd ("displaypipeline", class_support
, var_zinteger
,
662 (char *) &display_pipeline_p
,
663 "Set pipeline display (simulator only).\n\
664 When enabled, the state of the pipeline after each cycle is displayed.",
666 c
= add_show_from_set (c
, &showlist
);
668 c
= add_set_cmd ("debugpipeline", class_support
, var_zinteger
,
669 (char *) &debug_pipeline_p
,
670 "Set pipeline debug display (simulator only).\n\
671 When enabled, debugging information about the pipeline is displayed.",
673 c
= add_show_from_set (c
, &showlist
);
675 c
= add_set_cmd ("cputimer", class_support
, var_zinteger
,
677 "Set maximum cycle count (simulator only).\n\
678 Control will return to gdb if the timer expires.\n\
679 A negative value disables the timer.",
681 c
= add_show_from_set (c
, &showlist
);
683 /* FIXME: must be done after for now. */
684 tm_print_insn
= arc_get_disassembler (bfd_mach_arc_base
, 1 /*FIXME*/);