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

Subversion Repositories or1k

[/] [or1k/] [trunk/] [gdb-5.0/] [gdb/] [arc-tdep.c] - Blame information for rev 1774

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 104 markom
/* ARC target-dependent stuff.
2
   Copyright (C) 1995, 1997 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
 
30
/* Local functions */
31
 
32
static int arc_set_cpu_type (char *str);
33
 
34
/* Current CPU, set with the "set cpu" command.  */
35
static int arc_bfd_mach_type;
36
char *arc_cpu_type;
37
char *tmp_arc_cpu_type;
38
 
39
/* Table of cpu names.  */
40
struct
41
  {
42
    char *name;
43
    int value;
44
  }
45
arc_cpu_type_table[] =
46
{
47
  {
48
    "base", bfd_mach_arc_base
49
  }
50
  ,
51
  {
52
    NULL, 0
53
  }
54
};
55
 
56
/* Used by simulator.  */
57
int display_pipeline_p;
58
int 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.  */
61
int 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
 
92
/* Codestream stuff.  */
93
static void codestream_read PARAMS ((unsigned int *, int));
94
static void codestream_seek PARAMS ((CORE_ADDR));
95
static unsigned int codestream_fill PARAMS ((int));
96
 
97
#define CODESTREAM_BUFSIZ 16
98
static CORE_ADDR codestream_next_addr;
99
static CORE_ADDR codestream_addr;
100
/* FIXME assumes sizeof (int) == 32? */
101
static unsigned int codestream_buf[CODESTREAM_BUFSIZ];
102
static int codestream_off;
103
static 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
 
116
static unsigned int
117
codestream_fill (peek_flag)
118
     int peek_flag;
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
 
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
  }
137
 
138
  if (peek_flag)
139
    return codestream_peek ();
140
  else
141
    return codestream_get ();
142
}
143
 
144
static void
145
codestream_seek (place)
146
     CORE_ADDR place;
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
 
158
static void
159
codestream_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
 
170
/* Set up prologue scanning and return the first insn.  */
171
 
172
static unsigned int
173
setup_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
 
191
static long
192
arc_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.
219
         At least this is something we recognize.  */
220
      frame_size = 0;
221
    }
222
 
223
  if ((insn & BUILD_INSN (-1, 0, -1, -1, -1))    /* st fp,[sp] */
224
      == BUILD_INSN (2, 0, SP_REGNUM, FP_REGNUM, 0))
225
    {
226
      insn = codestream_get ();
227
      if ((insn & BUILD_INSN (-1, -1, -1, -1, 0))
228
          != BUILD_INSN (12, FP_REGNUM, SP_REGNUM, SP_REGNUM, 0))
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
 
245
          codestream_get ();
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 ();
250
          if ((insn & OPMASK) == 0x60000000)
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
 
279
CORE_ADDR
280
arc_skip_prologue (pc, frameless_p)
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))
299
        break;                  /* not st insn */
300
      if (!ARC_CALL_SAVED_REG (X_C (insn)))
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
 
312
CORE_ADDR
313
arc_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
 
359
void
360
frame_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.  */
376
  if (dummy_bottom <= fip->pc && fip->pc <= fip->frame)
377
    {
378
      /* all regs were saved by push_call_dummy () */
379
      adr = fip->frame;
380
      for (i = 0; i < NUM_REGS; i++)
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
 
390
  if (locals >= 0)
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))
398
              != BUILD_INSN (2, 0, SP_REGNUM, 0, 0))
399
            break;
400
          regnum = X_C (insn);
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
 
410
void
411
arc_push_dummy_frame (void)
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);
418
  write_memory (sp + 4, regbuf, REGISTER_SIZE);
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
    }
427
  sp += (2 * REGISTER_SIZE);
428
  write_register (SP_REGNUM, sp);
429
}
430
 
431
void
432
arc_pop_frame (void)
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];
439
 
440
  fp = FRAME_FP (frame);
441
  get_frame_saved_regs (frame, &fsr);
442
  for (regnum = 0; regnum < NUM_REGS; regnum++)
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
 
459
/* Simulate single-step.  */
460
 
461
typedef enum
462
{
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
}
468
insn_type;
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
 
474
static insn_type
475
get_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
    {
483
    case 0:
484
    case 1:
485
    case 2:                     /* load/store insns */
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;
491
    case 4:
492
    case 5:
493
    case 6:                     /* branch insns */
494
      *target = pc + 4 + X_L (insn);
495
      /* ??? It isn't clear that this is always the right answer.
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!  */
503
      if (X_N (insn) == 0)
504
        return BRANCH4;
505
      return BRANCH8;
506
    case 7:                     /* jump insns */
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;
520
    default:                    /* arithmetic insns, etc. */
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
 
537
void
538
arc_software_single_step (ignore, insert_breakpoints_p)
539
     enum target_signal ignore; /* sig but we don't need it */
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)
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.  */
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
 
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
 
595
int
596
get_longjmp_target (pc)
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
 
604
  if (target_read_memory (sp + SP_ARG0,         /* Offset of first arg on stack */
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
 
621
/* Disassemble one instruction.  */
622
 
623
static int
624
arc_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
 
645
/* Command to set cpu type.  */
646
 
647
void
648
arc_set_cpu_type_command (char *args, int from_tty)
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
    }
663
 
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
 
672
static void
673
arc_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
 
682
static int
683
arc_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
 
704
void
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\
712
This command has two purposes.  In a multi-cpu system it lets one\n\
713
change the cpu being debugged.  It also gives one access to\n\
714
cpu-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\
729
When 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\
736
When 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\
743
Control will return to gdb if the timer expires.\n\
744
A negative value disables the timer.",
745
                   &setlist);
746
  c = add_show_from_set (c, &showlist);
747
 
748
  tm_print_insn = arc_print_insn;
749
}

powered by: WebSVN 2.1.0

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