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