OpenCores
URL https://opencores.org/ocsvn/or1k/or1k/trunk

Subversion Repositories or1k

[/] [or1k/] [trunk/] [insight/] [gdb/] [arc-tdep.c] - Blame information for rev 1765

Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.