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