]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blame - gdb/arc-tdep.c
Update FSF address.
[thirdparty/binutils-gdb.git] / gdb / arc-tdep.c
CommitLineData
249abc98
KH
1/* ARC target-dependent stuff.
2 Copyright (C) 1995 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
6c9638b4 18Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
249abc98
KH
19
20#include "defs.h"
21#include "frame.h"
22#include "inferior.h"
23#include "gdbcore.h"
24#include "target.h"
25#include "floatformat.h"
26#include "symtab.h"
f0d795fa
DE
27#include "gdbcmd.h"
28
29/* Current CPU, set with the "set cpu" command. */
4f36d4ab 30static int arc_bfd_mach_type;
f0d795fa
DE
31char *arc_cpu_type;
32char *tmp_arc_cpu_type;
33
34/* Table of cpu names. */
35struct {
36 char *name;
37 int value;
38} arc_cpu_type_table[] = {
39 { "base", bfd_mach_arc_base },
40 { "host", bfd_mach_arc_host },
41 { "graphics", bfd_mach_arc_graphics },
42 { "audio", bfd_mach_arc_audio },
43 { NULL, 0 }
44};
45
46/* Used by simulator. */
47int display_pipeline_p;
48int cpu_timer;
49/* This one must have the same type as used in the emulator.
50 It's currently an enum so this should be ok for now. */
51int debug_pipeline_p;
52
53#define ARC_CALL_SAVED_REG(r) ((r) >= 16 && (r) < 24)
249abc98 54
f0d795fa
DE
55#define OPMASK 0xf8000000
56
4f36d4ab
DE
57/* Instruction field accessor macros.
58 See the Programmer's Reference Manual. */
f0d795fa
DE
59#define X_OP(i) (((i) >> 27) & 0x1f)
60#define X_A(i) (((i) >> 21) & 0x3f)
61#define X_B(i) (((i) >> 15) & 0x3f)
62#define X_C(i) (((i) >> 9) & 0x3f)
63#define X_D(i) ((((i) & 0x1ff) ^ 0x100) - 0x100)
64#define X_L(i) (((((i) >> 5) & 0x3ffffc) ^ 0x200000) - 0x200000)
65#define X_N(i) (((i) >> 5) & 3)
66#define X_Q(i) ((i) & 0x1f)
67
68/* Return non-zero if X is a short immediate data indicator. */
69#define SHIMM_P(x) ((x) == 61 || (x) == 63)
70
71/* Return non-zero if X is a "long" (32 bit) immediate data indicator. */
72#define LIMM_P(x) ((x) == 62)
73
74/* Build a simple instruction. */
75#define BUILD_INSN(op, a, b, c, d) \
76 ((((op) & 31) << 27) \
77 | (((a) & 63) << 21) \
78 | (((b) & 63) << 15) \
79 | (((c) & 63) << 9) \
80 | ((d) & 511))
81\f
82/* Codestream stuff. */
249abc98 83static void codestream_read PARAMS ((unsigned int *, int));
f0d795fa 84static void codestream_seek PARAMS ((CORE_ADDR));
249abc98
KH
85static unsigned int codestream_fill PARAMS ((int));
86
87#define CODESTREAM_BUFSIZ 16
88static CORE_ADDR codestream_next_addr;
89static CORE_ADDR codestream_addr;
90static unsigned int codestream_buf[CODESTREAM_BUFSIZ];
91static int codestream_off;
92static int codestream_cnt;
93
f0d795fa
DE
94#define codestream_tell() \
95 (codestream_addr + codestream_off * sizeof (codestream_buf[0]))
96#define codestream_peek() \
97 (codestream_cnt == 0 \
98 ? codestream_fill (1) \
99 : codestream_buf[codestream_off])
100#define codestream_get() \
101 (codestream_cnt-- == 0 \
102 ? codestream_fill (0) \
103 : codestream_buf[codestream_off++])
249abc98
KH
104
105static unsigned int
106codestream_fill (peek_flag)
107 int peek_flag;
108{
109 codestream_addr = codestream_next_addr;
f0d795fa 110 codestream_next_addr += CODESTREAM_BUFSIZ * sizeof (codestream_buf[0]);
249abc98
KH
111 codestream_off = 0;
112 codestream_cnt = CODESTREAM_BUFSIZ;
f0d795fa
DE
113 read_memory (codestream_addr, (char *) codestream_buf,
114 CODESTREAM_BUFSIZ * sizeof (codestream_buf[0]));
4f36d4ab
DE
115 /* FIXME: check return code? */
116
117 /* Handle byte order differences. */
118 if (HOST_BYTE_ORDER != TARGET_BYTE_ORDER)
119 {
120 register unsigned int i, j, n = sizeof (codestream_buf[0]);
121 register char tmp, *p;
122 for (i = 0, p = (char *) codestream_buf; i < CODESTREAM_BUFSIZ;
123 ++i, p += n)
124 for (j = 0; j < n / 2; ++j)
125 tmp = p[j], p[j] = p[n - 1 - j], p[n - 1 - j] = tmp;
126 }
249abc98
KH
127
128 if (peek_flag)
4f36d4ab 129 return codestream_peek ();
249abc98 130 else
4f36d4ab 131 return codestream_get ();
249abc98
KH
132}
133
134static void
135codestream_seek (place)
f0d795fa 136 CORE_ADDR place;
249abc98
KH
137{
138 codestream_next_addr = place / CODESTREAM_BUFSIZ;
139 codestream_next_addr *= CODESTREAM_BUFSIZ;
140 codestream_cnt = 0;
141 codestream_fill (1);
4f36d4ab 142 while (codestream_tell () != place)
249abc98
KH
143 codestream_get ();
144}
145
4f36d4ab
DE
146/* This function is currently unused but leave in for now. */
147
249abc98
KH
148static void
149codestream_read (buf, count)
150 unsigned int *buf;
151 int count;
152{
153 unsigned int *p;
154 int i;
155 p = buf;
156 for (i = 0; i < count; i++)
157 *p++ = codestream_get ();
158}
f0d795fa 159\f
4f36d4ab 160/* Set up prologue scanning and return the first insn. */
f0d795fa
DE
161
162static unsigned int
163setup_prologue_scan (pc)
164 CORE_ADDR pc;
165{
166 unsigned int insn;
167
168 codestream_seek (pc);
169 insn = codestream_get ();
170
f0d795fa
DE
171 return insn;
172}
249abc98
KH
173
174/*
f0d795fa
DE
175 * Find & return amount a local space allocated, and advance codestream to
176 * first register push (if any).
177 * If entry sequence doesn't make sense, return -1, and leave
178 * codestream pointer random.
249abc98
KH
179 */
180
181static long
182arc_get_frame_setup (pc)
f0d795fa 183 CORE_ADDR pc;
249abc98 184{
f0d795fa
DE
185 unsigned int insn;
186 /* Size of frame or -1 if unrecognizable prologue. */
4f36d4ab
DE
187 int frame_size = -1;
188 /* An initial "sub sp,sp,N" may or may not be for a stdarg fn. */
189 int maybe_stdarg_decr = -1;
249abc98 190
f0d795fa 191 insn = setup_prologue_scan (pc);
249abc98 192
4f36d4ab
DE
193 /* The authority for what appears here is the home-grown ABI.
194 The most recent version is 1.2. */
195
196 /* First insn may be "sub sp,sp,N" if stdarg fn. */
197 if ((insn & BUILD_INSN (-1, -1, -1, -1, 0))
198 == BUILD_INSN (10, SP_REGNUM, SP_REGNUM, SHIMM_REGNUM, 0))
199 {
200 maybe_stdarg_decr = X_D (insn);
201 insn = codestream_get ();
202 }
203
f0d795fa
DE
204 if ((insn & BUILD_INSN (-1, 0, -1, -1, -1)) /* st blink,[sp,4] */
205 == BUILD_INSN (2, 0, SP_REGNUM, BLINK_REGNUM, 4))
206 {
207 insn = codestream_get ();
208 /* Frame may not be necessary, even though blink is saved.
209 At least this is something we recognize. */
4f36d4ab 210 frame_size = 0;
f0d795fa
DE
211 }
212
213 if ((insn & BUILD_INSN (-1, 0, -1, -1, -1)) /* st fp,[sp] */
214 == BUILD_INSN (2, 0, SP_REGNUM, FP_REGNUM, 0))
249abc98
KH
215 {
216 insn = codestream_get ();
f0d795fa
DE
217 if ((insn & BUILD_INSN (-1, -1, -1, -1, 0))
218 != BUILD_INSN (12, FP_REGNUM, SP_REGNUM, SP_REGNUM, 0))
219 return -1;
249abc98 220
4f36d4ab 221 /* Check for stack adjustment sub sp,sp,N. */
249abc98 222 insn = codestream_peek ();
f0d795fa
DE
223 if ((insn & BUILD_INSN (-1, -1, -1, 0, 0))
224 == BUILD_INSN (10, SP_REGNUM, SP_REGNUM, 0, 0))
249abc98 225 {
f0d795fa 226 if (LIMM_P (X_C (insn)))
4f36d4ab 227 frame_size = codestream_get ();
f0d795fa 228 else if (SHIMM_P (X_C (insn)))
4f36d4ab 229 frame_size = X_D (insn);
f0d795fa
DE
230 else
231 return -1;
4f36d4ab 232 if (frame_size < 0)
f0d795fa
DE
233 return -1;
234
249abc98
KH
235 codestream_get ();
236
f0d795fa
DE
237 /* This sequence is used to get the address of the return
238 buffer for a function that returns a structure. */
249abc98
KH
239 insn = codestream_peek ();
240 if (insn & OPMASK == 0x60000000)
241 codestream_get ();
249abc98 242 }
f0d795fa 243 /* Frameless fn. */
249abc98
KH
244 else
245 {
4f36d4ab 246 frame_size = 0;
249abc98
KH
247 }
248 }
f0d795fa 249
4f36d4ab
DE
250 /* If we found a "sub sp,sp,N" and nothing else, it may or may not be a
251 stdarg fn. The stdarg decrement is not treated as part of the frame size,
252 so we have a dilemma: what do we return? For now, if we get a
253 "sub sp,sp,N" and nothing else assume this isn't a stdarg fn. One way
254 to fix this completely would be to add a bit to the function descriptor
255 that says the function is a stdarg function. */
256
257 if (frame_size < 0 && maybe_stdarg_decr > 0)
258 return maybe_stdarg_decr;
259 return frame_size;
249abc98
KH
260}
261
f0d795fa
DE
262/* Given a pc value, skip it forward past the function prologue by
263 disassembling instructions that appear to be a prologue.
264
265 If FRAMELESS_P is set, we are only testing to see if the function
266 is frameless. If it is a frameless function, return PC unchanged.
267 This allows a quicker answer. */
268
249abc98 269CORE_ADDR
f0d795fa
DE
270skip_prologue (pc, frameless_p)
271 CORE_ADDR pc;
272 int frameless_p;
249abc98
KH
273{
274 unsigned int insn;
f0d795fa
DE
275 int i, frame_size;
276
277 if ((frame_size = arc_get_frame_setup (pc)) < 0)
249abc98 278 return (pc);
f0d795fa
DE
279
280 if (frameless_p)
281 return frame_size == 0 ? pc : codestream_tell ();
282
283 /* Skip over register saves. */
284 for (i = 0; i < 8; i++)
249abc98
KH
285 {
286 insn = codestream_peek ();
f0d795fa
DE
287 if ((insn & BUILD_INSN (-1, 0, -1, 0, 0))
288 != BUILD_INSN (2, 0, SP_REGNUM, 0, 0))
289 break; /* not st insn */
290 if (! ARC_CALL_SAVED_REG (X_C (insn)))
249abc98
KH
291 break;
292 codestream_get ();
293 }
f0d795fa
DE
294
295 return codestream_tell ();
249abc98
KH
296}
297
f0d795fa
DE
298/* Return the return address for a frame.
299 This is used to implement FRAME_SAVED_PC.
300 This is taken from frameless_look_for_prologue. */
301
302CORE_ADDR
303arc_frame_saved_pc (frame)
304 struct frame_info *frame;
249abc98 305{
f0d795fa
DE
306 CORE_ADDR func_start;
307 unsigned int insn;
308
309 func_start = get_pc_function_start (frame->pc) + FUNCTION_START_OFFSET;
310 if (func_start == 0)
249abc98 311 {
f0d795fa
DE
312 /* Best guess. */
313 return ARC_PC_TO_REAL_ADDRESS (read_memory_integer (FRAME_FP (frame) + 4, 4));
249abc98 314 }
f0d795fa 315
4f36d4ab
DE
316 /* The authority for what appears here is the home-grown ABI.
317 The most recent version is 1.2. */
318
319 insn = setup_prologue_scan (func_start);
320
321 /* First insn may be "sub sp,sp,N" if stdarg fn. */
322 if ((insn & BUILD_INSN (-1, -1, -1, -1, 0))
323 == BUILD_INSN (10, SP_REGNUM, SP_REGNUM, SHIMM_REGNUM, 0))
324 insn = codestream_get ();
325
326 /* If the next insn is "st blink,[sp,4]" we can get blink from there.
f0d795fa
DE
327 Otherwise this is a leaf function and we can use blink. Note that
328 this still allows for the case where a leaf function saves/clobbers/
329 restores blink. */
330
f0d795fa
DE
331 if ((insn & BUILD_INSN (-1, 0, -1, -1, -1)) /* st blink,[sp,4] */
332 != BUILD_INSN (2, 0, SP_REGNUM, BLINK_REGNUM, 4))
333 return ARC_PC_TO_REAL_ADDRESS (read_register (BLINK_REGNUM));
249abc98 334 else
f0d795fa 335 return ARC_PC_TO_REAL_ADDRESS (read_memory_integer (FRAME_FP (frame) + 4, 4));
249abc98
KH
336}
337
338/*
f0d795fa 339 * Parse the first few instructions of the function to see
249abc98
KH
340 * what registers were stored.
341 *
342 * The startup sequence can be at the start of the function.
f0d795fa 343 * 'st blink,[sp+4], st fp,[sp], mov fp,sp'
249abc98 344 *
f0d795fa
DE
345 * Local space is allocated just below by sub sp,sp,nnn.
346 * Next, the registers used by this function are stored (as offsets from sp).
249abc98
KH
347 */
348
349void
350frame_find_saved_regs (fip, fsrp)
351 struct frame_info *fip;
352 struct frame_saved_regs *fsrp;
353{
354 long locals;
355 unsigned int insn;
356 CORE_ADDR dummy_bottom;
357 CORE_ADDR adr;
358 int i, regnum, offset;
f0d795fa 359
249abc98 360 memset (fsrp, 0, sizeof *fsrp);
f0d795fa
DE
361
362 /* If frame is the end of a dummy, compute where the beginning would be. */
249abc98 363 dummy_bottom = fip->frame - 4 - REGISTER_BYTES - CALL_DUMMY_LENGTH;
f0d795fa
DE
364
365 /* Check if the PC is in the stack, in a dummy frame. */
249abc98
KH
366 if (dummy_bottom <= fip->pc && fip->pc <= fip->frame)
367 {
368 /* all regs were saved by push_call_dummy () */
369 adr = fip->frame;
370 for (i = 0; i < NUM_REGS; i++)
371 {
372 adr -= REGISTER_RAW_SIZE (i);
373 fsrp->regs[i] = adr;
374 }
375 return;
376 }
f0d795fa 377
249abc98 378 locals = arc_get_frame_setup (get_pc_function_start (fip->pc));
f0d795fa 379
249abc98
KH
380 if (locals >= 0)
381 {
f0d795fa 382 /* Set `adr' to the value of `sp'. */
249abc98 383 adr = fip->frame - locals;
f0d795fa 384 for (i = 0; i < 8; i++)
249abc98
KH
385 {
386 insn = codestream_get ();
f0d795fa
DE
387 if ((insn & BUILD_INSN (-1, 0, -1, 0, 0))
388 != BUILD_INSN (2, 0, SP_REGNUM, 0, 0))
249abc98 389 break;
f0d795fa
DE
390 regnum = X_C (insn);
391 offset = X_D (insn);
249abc98
KH
392 fsrp->regs[regnum] = adr + offset;
393 }
394 }
f0d795fa 395
249abc98
KH
396 fsrp->regs[PC_REGNUM] = fip->frame + 4;
397 fsrp->regs[FP_REGNUM] = fip->frame;
398}
399
400void
401push_dummy_frame ()
402{
403 CORE_ADDR sp = read_register (SP_REGNUM);
404 int regnum;
405 char regbuf[MAX_REGISTER_RAW_SIZE];
406
407 read_register_gen (PC_REGNUM, regbuf);
408 write_memory (sp+4, regbuf, REGISTER_SIZE);
409 read_register_gen (FP_REGNUM, regbuf);
410 write_memory (sp, regbuf, REGISTER_SIZE);
411 write_register (FP_REGNUM, sp);
412 for (regnum = 0; regnum < NUM_REGS; regnum++)
413 {
414 read_register_gen (regnum, regbuf);
415 sp = push_bytes (sp, regbuf, REGISTER_RAW_SIZE (regnum));
416 }
417 sp += (2*REGISTER_SIZE);
418 write_register (SP_REGNUM, sp);
419}
420
421void
422pop_frame ()
423{
424 struct frame_info *frame = get_current_frame ();
425 CORE_ADDR fp;
426 int regnum;
427 struct frame_saved_regs fsr;
428 char regbuf[MAX_REGISTER_RAW_SIZE];
429
430 fp = FRAME_FP (frame);
431 get_frame_saved_regs (frame, &fsr);
432 for (regnum = 0; regnum < NUM_REGS; regnum++)
433 {
434 CORE_ADDR adr;
435 adr = fsr.regs[regnum];
436 if (adr)
437 {
438 read_memory (adr, regbuf, REGISTER_RAW_SIZE (regnum));
439 write_register_bytes (REGISTER_BYTE (regnum), regbuf,
440 REGISTER_RAW_SIZE (regnum));
441 }
442 }
443 write_register (FP_REGNUM, read_memory_integer (fp, 4));
444 write_register (PC_REGNUM, read_memory_integer (fp + 4, 4));
445 write_register (SP_REGNUM, fp + 8);
446 flush_cached_frames ();
447}
f0d795fa
DE
448\f
449/* Simulate single-step. */
450
451typedef enum
452{
453 NORMAL4, /* a normal 4 byte insn */
454 NORMAL8, /* a normal 8 byte insn */
455 BRANCH4, /* a 4 byte branch insn, including ones without delay slots */
456 BRANCH8, /* an 8 byte branch insn, including ones with delay slots */
457} insn_type;
458
459/* Return the type of INSN and store in TARGET the destination address of a
460 branch if this is one. */
461/* ??? Need to verify all cases are properly handled. */
462
463static insn_type
464get_insn_type (insn, pc, target)
465 unsigned long insn;
466 CORE_ADDR pc, *target;
467{
468 unsigned long limm;
469
470 switch (insn >> 27)
471 {
472 case 0 : case 1 : case 2 : /* load/store insns */
473 if (LIMM_P (X_A (insn))
474 || LIMM_P (X_B (insn))
475 || LIMM_P (X_C (insn)))
476 return NORMAL8;
477 return NORMAL4;
478 case 4 : case 5 : case 6 : /* branch insns */
479 *target = pc + 4 + X_L (insn);
480 /* ??? It isn't clear that this is always the right answer.
481 The problem occurs when the next insn is an 8 byte insn. If the
482 branch is conditional there's no worry as there shouldn't be an 8
483 byte insn following. The programmer may be cheating if s/he knows
484 the branch will never be taken, but we don't deal with that.
485 Note that the programmer is also allowed to play games by putting
486 an insn with long immediate data in the delay slot and then duplicate
487 the long immediate data at the branch target. Ugh! */
488 if (X_N (insn) == 0)
489 return BRANCH4;
490 return BRANCH8;
491 case 7 : /* jump insns */
492 if (LIMM_P (X_B (insn)))
493 {
494 limm = read_memory_integer (pc + 4, 4);
495 *target = ARC_PC_TO_REAL_ADDRESS (limm);
496 return BRANCH8;
497 }
498 if (SHIMM_P (X_B (insn)))
499 *target = ARC_PC_TO_REAL_ADDRESS (X_D (insn));
500 else
501 *target = ARC_PC_TO_REAL_ADDRESS (read_register (X_B (insn)));
502 if (X_Q (insn) == 0 && X_N (insn) == 0)
503 return BRANCH4;
504 return BRANCH8;
505 default : /* arithmetic insns, etc. */
506 if (LIMM_P (X_A (insn))
507 || LIMM_P (X_B (insn))
508 || LIMM_P (X_C (insn)))
509 return NORMAL8;
510 return NORMAL4;
511 }
512}
513
514/* Non-zero if we just simulated a single-step. This is needed because we
515 cannot remove the breakpoints in the inferior process until after the
516 `wait' in `wait_for_inferior'. */
517
518int one_stepped;
519
520/* single_step() is called just before we want to resume the inferior, if we
521 want to single-step it but there is no hardware or kernel single-step
522 support. We find all the possible targets of the coming instruction and
523 breakpoint them.
524
525 single_step is also called just after the inferior stops. If we had
526 set up a simulated single-step, we undo our damage. */
249abc98 527
f0d795fa
DE
528void
529single_step (ignore)
530 int ignore; /* sig, but we don't need it */
531{
532 static CORE_ADDR next_pc, target;
533 static int brktrg_p;
534 typedef char binsn_quantum[BREAKPOINT_MAX];
535 static binsn_quantum break_mem[2];
536
537 if (!one_stepped)
538 {
539 insn_type type;
540 CORE_ADDR pc;
541 unsigned long insn;
542
543 pc = read_register (PC_REGNUM);
544 insn = read_memory_integer (pc, 4);
545 type = get_insn_type (insn, pc, &target);
546
547 /* Always set a breakpoint for the insn after the branch. */
548 next_pc = pc + ((type == NORMAL8 || type == BRANCH8) ? 8 : 4);
549 target_insert_breakpoint (next_pc, break_mem[0]);
550
551 brktrg_p = 0;
552
553 if ((type == BRANCH4 || type == BRANCH8)
554 /* Watch out for branches to the following location.
555 We just stored a breakpoint there and another call to
556 target_insert_breakpoint will think the real insn is the
557 breakpoint we just stored there. */
558 && target != next_pc)
559 {
560 brktrg_p = 1;
561 target_insert_breakpoint (target, break_mem[1]);
562 }
563
564 /* We are ready to let it go. */
565 one_stepped = 1;
566 }
567 else
568 {
569 /* Remove breakpoints. */
570 target_remove_breakpoint (next_pc, break_mem[0]);
571
572 if (brktrg_p)
573 target_remove_breakpoint (target, break_mem[1]);
574
575 /* Fix the pc. */
576 stop_pc -= DECR_PC_AFTER_BREAK;
577 write_pc (stop_pc);
578
579 one_stepped = 0;
580 }
581}
582\f
249abc98
KH
583#ifdef GET_LONGJMP_TARGET
584/* Figure out where the longjmp will land. Slurp the args out of the stack.
585 We expect the first arg to be a pointer to the jmp_buf structure from which
586 we extract the pc (JB_PC) that we will land at. The pc is copied into PC.
587 This routine returns true on success. */
588
589int
590get_longjmp_target(pc)
591 CORE_ADDR *pc;
592{
593 char buf[TARGET_PTR_BIT / TARGET_CHAR_BIT];
594 CORE_ADDR sp, jb_addr;
595
596 sp = read_register (SP_REGNUM);
597
598 if (target_read_memory (sp + SP_ARG0, /* Offset of first arg on stack */
599 buf,
600 TARGET_PTR_BIT / TARGET_CHAR_BIT))
601 return 0;
602
603 jb_addr = extract_address (buf, TARGET_PTR_BIT / TARGET_CHAR_BIT);
604
605 if (target_read_memory (jb_addr + JB_PC * JB_ELEMENT_SIZE, buf,
606 TARGET_PTR_BIT / TARGET_CHAR_BIT))
607 return 0;
608
609 *pc = extract_address (buf, TARGET_PTR_BIT / TARGET_CHAR_BIT);
610
611 return 1;
612}
613#endif /* GET_LONGJMP_TARGET */
f0d795fa 614\f
4f36d4ab
DE
615/* Disassemble one instruction. */
616
617static int
618arc_print_insn (vma, info)
619 bfd_vma vma;
620 disassemble_info *info;
621{
622 static int current_mach;
623 static int current_endian;
624 static disassembler_ftype current_disasm;
625
626 if (current_disasm == NULL
627 || arc_bfd_mach_type != current_mach
628 || TARGET_BYTE_ORDER != current_endian)
629 {
630 current_mach = arc_bfd_mach_type;
631 current_endian = TARGET_BYTE_ORDER;
632 current_disasm = arc_get_disassembler (current_mach,
633 current_endian == BIG_ENDIAN);
634 }
635
636 return (*current_disasm) (vma, info);
637}
638\f
f0d795fa 639/* Command to set cpu type. */
249abc98 640
f0d795fa
DE
641void
642arc_set_cpu_type_command (args, from_tty)
643 char *args;
644 int from_tty;
645{
646 int i;
647
648 if (tmp_arc_cpu_type == NULL || *tmp_arc_cpu_type == '\0')
649 {
650 printf_unfiltered ("The known ARC cpu types are as follows:\n");
651 for (i = 0; arc_cpu_type_table[i].name != NULL; ++i)
652 printf_unfiltered ("%s\n", arc_cpu_type_table[i].name);
653
654 /* Restore the value. */
655 tmp_arc_cpu_type = strsave (arc_cpu_type);
656
657 return;
658 }
659
660 if (!arc_set_cpu_type (tmp_arc_cpu_type))
661 {
662 error ("Unknown cpu type `%s'.", tmp_arc_cpu_type);
663 /* Restore its value. */
664 tmp_arc_cpu_type = strsave (arc_cpu_type);
665 }
666}
667
668static void
669arc_show_cpu_type_command (args, from_tty)
670 char *args;
671 int from_tty;
672{
673}
674
675/* Modify the actual cpu type.
676 Result is a boolean indicating success. */
677
678int
679arc_set_cpu_type (str)
680 char *str;
681{
682 int i, j;
683
684 if (str == NULL)
685 return 0;
686
687 for (i = 0; arc_cpu_type_table[i].name != NULL; ++i)
688 {
689 if (strcasecmp (str, arc_cpu_type_table[i].name) == 0)
690 {
691 arc_cpu_type = str;
4f36d4ab 692 arc_bfd_mach_type = arc_cpu_type_table[i].value;
f0d795fa
DE
693 return 1;
694 }
695 }
696
697 return 0;
698}
699\f
9c4ecee6
SS
700void
701_initialize_arc_tdep ()
249abc98 702{
f0d795fa
DE
703 struct cmd_list_element *c;
704
705 c = add_set_cmd ("cpu", class_support, var_string_noescape,
706 (char *) &tmp_arc_cpu_type,
707 "Set the type of ARC cpu in use.\n\
708This command has two purposes. In a multi-cpu system it lets one\n\
709change the cpu being debugged. It also gives one access to\n\
710cpu-type-specific registers and recognize cpu-type-specific instructions.\
711",
712 &setlist);
713 c->function.cfunc = arc_set_cpu_type_command;
714 c = add_show_from_set (c, &showlist);
715 c->function.cfunc = arc_show_cpu_type_command;
716
717 /* We have to use strsave here because the `set' command frees it before
718 setting a new value. */
719 tmp_arc_cpu_type = strsave (DEFAULT_ARC_CPU_TYPE);
720 arc_set_cpu_type (tmp_arc_cpu_type);
721
722 c = add_set_cmd ("displaypipeline", class_support, var_zinteger,
723 (char *) &display_pipeline_p,
724 "Set pipeline display (simulator only).\n\
725When enabled, the state of the pipeline after each cycle is displayed.",
726 &setlist);
727 c = add_show_from_set (c, &showlist);
728
729 c = add_set_cmd ("debugpipeline", class_support, var_zinteger,
730 (char *) &debug_pipeline_p,
731 "Set pipeline debug display (simulator only).\n\
732When enabled, debugging information about the pipeline is displayed.",
733 &setlist);
734 c = add_show_from_set (c, &showlist);
735
736 c = add_set_cmd ("cputimer", class_support, var_zinteger,
737 (char *) &cpu_timer,
738 "Set maximum cycle count (simulator only).\n\
739Control will return to gdb if the timer expires.\n\
740A negative value disables the timer.",
741 &setlist);
742 c = add_show_from_set (c, &showlist);
743
4f36d4ab 744 tm_print_insn = arc_print_insn;
249abc98 745}