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

Subversion Repositories or1k

[/] [or1k/] [trunk/] [insight/] [sim/] [d10v/] [interp.c] - Blame information for rev 1774

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

Line No. Rev Author Line
1 578 markom
#include <signal.h>
2
#include "sysdep.h"
3
#include "bfd.h"
4
#include "callback.h"
5
#include "remote-sim.h"
6
 
7
#include "d10v_sim.h"
8
#include "sim-d10v.h"
9
 
10
enum _leftright { LEFT_FIRST, RIGHT_FIRST };
11
 
12
static char *myname;
13
static SIM_OPEN_KIND sim_kind;
14
int d10v_debug;
15
 
16
/* Set this to true to get the previous segment layout. */
17
 
18
int old_segment_mapping;
19
 
20
host_callback *d10v_callback;
21
unsigned long ins_type_counters[ (int)INS_MAX ];
22
 
23
uint16 OP[4];
24
 
25
static int init_text_p = 0;
26
/* non-zero if we opened prog_bfd */
27
static int prog_bfd_was_opened_p;
28
bfd *prog_bfd;
29
asection *text;
30
bfd_vma text_start;
31
bfd_vma text_end;
32
 
33
static long hash PARAMS ((long insn, int format));
34
static struct hash_entry *lookup_hash PARAMS ((uint32 ins, int size));
35
static void get_operands PARAMS ((struct simops *s, uint32 ins));
36
static void do_long PARAMS ((uint32 ins));
37
static void do_2_short PARAMS ((uint16 ins1, uint16 ins2, enum _leftright leftright));
38
static void do_parallel PARAMS ((uint16 ins1, uint16 ins2));
39
static char *add_commas PARAMS ((char *buf, int sizeof_buf, unsigned long value));
40
extern void sim_set_profile PARAMS ((int n));
41
extern void sim_set_profile_size PARAMS ((int n));
42
static INLINE uint8 *map_memory (unsigned phys_addr);
43
 
44
#ifdef NEED_UI_LOOP_HOOK
45
/* How often to run the ui_loop update, when in use */
46
#define UI_LOOP_POLL_INTERVAL 0x14000
47
 
48
/* Counter for the ui_loop_hook update */
49
static long ui_loop_hook_counter = UI_LOOP_POLL_INTERVAL;
50
 
51
/* Actual hook to call to run through gdb's gui event loop */
52
extern int (*ui_loop_hook) PARAMS ((int signo));
53
#endif /* NEED_UI_LOOP_HOOK */
54
 
55
#ifndef INLINE
56
#if defined(__GNUC__) && defined(__OPTIMIZE__)
57
#define INLINE __inline__
58
#else
59
#define INLINE
60
#endif
61
#endif
62
 
63
#define MAX_HASH  63
64
struct hash_entry
65
{
66
  struct hash_entry *next;
67
  uint32 opcode;
68
  uint32 mask;
69
  int size;
70
  struct simops *ops;
71
};
72
 
73
struct hash_entry hash_table[MAX_HASH+1];
74
 
75
INLINE static long
76
hash(insn, format)
77
     long insn;
78
     int format;
79
{
80
  if (format & LONG_OPCODE)
81
    return ((insn & 0x3F000000) >> 24);
82
  else
83
    return((insn & 0x7E00) >> 9);
84
}
85
 
86
INLINE static struct hash_entry *
87
lookup_hash (ins, size)
88
     uint32 ins;
89
     int size;
90
{
91
  struct hash_entry *h;
92
 
93
  if (size)
94
    h = &hash_table[(ins & 0x3F000000) >> 24];
95
  else
96
    h = &hash_table[(ins & 0x7E00) >> 9];
97
 
98
  while ((ins & h->mask) != h->opcode || h->size != size)
99
    {
100
      if (h->next == NULL)
101
        {
102
          State.exception = SIGILL;
103
          State.pc_changed = 1; /* Don't increment the PC. */
104
          return NULL;
105
        }
106
      h = h->next;
107
    }
108
  return (h);
109
}
110
 
111
INLINE static void
112
get_operands (struct simops *s, uint32 ins)
113
{
114
  int i, shift, bits, flags;
115
  uint32 mask;
116
  for (i=0; i < s->numops; i++)
117
    {
118
      shift = s->operands[3*i];
119
      bits = s->operands[3*i+1];
120
      flags = s->operands[3*i+2];
121
      mask = 0x7FFFFFFF >> (31 - bits);
122
      OP[i] = (ins >> shift) & mask;
123
    }
124
  /* FIXME: for tracing, update values that need to be updated each
125
     instruction decode cycle */
126
  State.trace.psw = PSW;
127
}
128
 
129
bfd_vma
130
decode_pc ()
131
{
132
  asection *s;
133
  if (!init_text_p && prog_bfd != NULL)
134
    {
135
      init_text_p = 1;
136
      for (s = prog_bfd->sections; s; s = s->next)
137
        if (strcmp (bfd_get_section_name (prog_bfd, s), ".text") == 0)
138
          {
139
            text = s;
140
            text_start = bfd_get_section_vma (prog_bfd, s);
141
            text_end = text_start + bfd_section_size (prog_bfd, s);
142
            break;
143
          }
144
    }
145
 
146
  return (PC << 2) + text_start;
147
}
148
 
149
static void
150
do_long (ins)
151
     uint32 ins;
152
{
153
  struct hash_entry *h;
154
#ifdef DEBUG
155
  if ((d10v_debug & DEBUG_INSTRUCTION) != 0)
156
    (*d10v_callback->printf_filtered) (d10v_callback, "do_long 0x%x\n", ins);
157
#endif
158
  h = lookup_hash (ins, 1);
159
  if (h == NULL)
160
    return;
161
  get_operands (h->ops, ins);
162
  State.ins_type = INS_LONG;
163
  ins_type_counters[ (int)State.ins_type ]++;
164
  (h->ops->func)();
165
}
166
 
167
static void
168
do_2_short (ins1, ins2, leftright)
169
     uint16 ins1, ins2;
170
     enum _leftright leftright;
171
{
172
  struct hash_entry *h;
173
  enum _ins_type first, second;
174
 
175
#ifdef DEBUG
176
  if ((d10v_debug & DEBUG_INSTRUCTION) != 0)
177
    (*d10v_callback->printf_filtered) (d10v_callback, "do_2_short 0x%x (%s) -> 0x%x\n",
178
                                       ins1, (leftright) ? "left" : "right", ins2);
179
#endif
180
 
181
  if (leftright == LEFT_FIRST)
182
    {
183
      first = INS_LEFT;
184
      second = INS_RIGHT;
185
      ins_type_counters[ (int)INS_LEFTRIGHT ]++;
186
    }
187
  else
188
    {
189
      first = INS_RIGHT;
190
      second = INS_LEFT;
191
      ins_type_counters[ (int)INS_RIGHTLEFT ]++;
192
    }
193
 
194
  /* Issue the first instruction */
195
  h = lookup_hash (ins1, 0);
196
  if (h == NULL)
197
    return;
198
  get_operands (h->ops, ins1);
199
  State.ins_type = first;
200
  ins_type_counters[ (int)State.ins_type ]++;
201
  (h->ops->func)();
202
 
203
  /* Issue the second instruction (if the PC hasn't changed) */
204
  if (!State.pc_changed && !State.exception)
205
    {
206
      /* finish any existing instructions */
207
      SLOT_FLUSH ();
208
      h = lookup_hash (ins2, 0);
209
      if (h == NULL)
210
        return;
211
      get_operands (h->ops, ins2);
212
      State.ins_type = second;
213
      ins_type_counters[ (int)State.ins_type ]++;
214
      ins_type_counters[ (int)INS_CYCLES ]++;
215
      (h->ops->func)();
216
    }
217
  else if (!State.exception)
218
    ins_type_counters[ (int)INS_COND_JUMP ]++;
219
}
220
 
221
static void
222
do_parallel (ins1, ins2)
223
     uint16 ins1, ins2;
224
{
225
  struct hash_entry *h1, *h2;
226
#ifdef DEBUG
227
  if ((d10v_debug & DEBUG_INSTRUCTION) != 0)
228
    (*d10v_callback->printf_filtered) (d10v_callback, "do_parallel 0x%x || 0x%x\n", ins1, ins2);
229
#endif
230
  ins_type_counters[ (int)INS_PARALLEL ]++;
231
  h1 = lookup_hash (ins1, 0);
232
  if (h1 == NULL)
233
    return;
234
  h2 = lookup_hash (ins2, 0);
235
  if (h2 == NULL)
236
    return;
237
 
238
  if (h1->ops->exec_type == PARONLY)
239
    {
240
      get_operands (h1->ops, ins1);
241
      State.ins_type = INS_LEFT_COND_TEST;
242
      ins_type_counters[ (int)State.ins_type ]++;
243
      (h1->ops->func)();
244
      if (State.exe)
245
        {
246
          ins_type_counters[ (int)INS_COND_TRUE ]++;
247
          get_operands (h2->ops, ins2);
248
          State.ins_type = INS_RIGHT_COND_EXE;
249
          ins_type_counters[ (int)State.ins_type ]++;
250
          (h2->ops->func)();
251
        }
252
      else
253
        ins_type_counters[ (int)INS_COND_FALSE ]++;
254
    }
255
  else if (h2->ops->exec_type == PARONLY)
256
    {
257
      get_operands (h2->ops, ins2);
258
      State.ins_type = INS_RIGHT_COND_TEST;
259
      ins_type_counters[ (int)State.ins_type ]++;
260
      (h2->ops->func)();
261
      if (State.exe)
262
        {
263
          ins_type_counters[ (int)INS_COND_TRUE ]++;
264
          get_operands (h1->ops, ins1);
265
          State.ins_type = INS_LEFT_COND_EXE;
266
          ins_type_counters[ (int)State.ins_type ]++;
267
          (h1->ops->func)();
268
        }
269
      else
270
        ins_type_counters[ (int)INS_COND_FALSE ]++;
271
    }
272
  else
273
    {
274
      get_operands (h1->ops, ins1);
275
      State.ins_type = INS_LEFT_PARALLEL;
276
      ins_type_counters[ (int)State.ins_type ]++;
277
      (h1->ops->func)();
278
      if (!State.exception)
279
        {
280
          get_operands (h2->ops, ins2);
281
          State.ins_type = INS_RIGHT_PARALLEL;
282
          ins_type_counters[ (int)State.ins_type ]++;
283
          (h2->ops->func)();
284
        }
285
    }
286
}
287
 
288
static char *
289
add_commas(buf, sizeof_buf, value)
290
     char *buf;
291
     int sizeof_buf;
292
     unsigned long value;
293
{
294
  int comma = 3;
295
  char *endbuf = buf + sizeof_buf - 1;
296
 
297
  *--endbuf = '\0';
298
  do {
299
    if (comma-- == 0)
300
      {
301
        *--endbuf = ',';
302
        comma = 2;
303
      }
304
 
305
    *--endbuf = (value % 10) + '0';
306
  } while ((value /= 10) != 0);
307
 
308
  return endbuf;
309
}
310
 
311
void
312
sim_size (power)
313
     int power;
314
 
315
{
316
  int i;
317
  for (i = 0; i < IMEM_SEGMENTS; i++)
318
    {
319
      if (State.mem.insn[i])
320
        free (State.mem.insn[i]);
321
    }
322
  for (i = 0; i < DMEM_SEGMENTS; i++)
323
    {
324
      if (State.mem.data[i])
325
        free (State.mem.data[i]);
326
    }
327
  for (i = 0; i < UMEM_SEGMENTS; i++)
328
    {
329
      if (State.mem.unif[i])
330
        free (State.mem.unif[i]);
331
    }
332
  /* Always allocate dmem segment 0.  This contains the IMAP and DMAP
333
     registers. */
334
  State.mem.data[0] = calloc (1, SEGMENT_SIZE);
335
}
336
 
337
/* For tracing - leave info on last access around. */
338
static char *last_segname = "invalid";
339
static char *last_from = "invalid";
340
static char *last_to = "invalid";
341
 
342
enum
343
  {
344
    IMAP0_OFFSET = 0xff00,
345
    DMAP0_OFFSET = 0xff08,
346
    DMAP2_SHADDOW = 0xff04,
347
    DMAP2_OFFSET = 0xff0c
348
  };
349
 
350
static void
351
set_dmap_register (int reg_nr, unsigned long value)
352
{
353
  uint8 *raw = map_memory (SIM_D10V_MEMORY_DATA
354
                           + DMAP0_OFFSET + 2 * reg_nr);
355
  WRITE_16 (raw, value);
356
#ifdef DEBUG
357
  if ((d10v_debug & DEBUG_MEMORY))
358
    {
359
      (*d10v_callback->printf_filtered)
360
        (d10v_callback, "mem: dmap%d=0x%04lx\n", reg_nr, value);
361
    }
362
#endif
363
}
364
 
365
static unsigned long
366
dmap_register (int reg_nr)
367
{
368
  uint8 *raw = map_memory (SIM_D10V_MEMORY_DATA
369
                           + DMAP0_OFFSET + 2 * reg_nr);
370
  return READ_16 (raw);
371
}
372
 
373
static void
374
set_imap_register (int reg_nr, unsigned long value)
375
{
376
  uint8 *raw = map_memory (SIM_D10V_MEMORY_DATA
377
                           + IMAP0_OFFSET + 2 * reg_nr);
378
  WRITE_16 (raw, value);
379
#ifdef DEBUG
380
  if ((d10v_debug & DEBUG_MEMORY))
381
    {
382
      (*d10v_callback->printf_filtered)
383
        (d10v_callback, "mem: imap%d=0x%04lx\n", reg_nr, value);
384
    }
385
#endif
386
}
387
 
388
static unsigned long
389
imap_register (int reg_nr)
390
{
391
  uint8 *raw = map_memory (SIM_D10V_MEMORY_DATA
392
                           + IMAP0_OFFSET + 2 * reg_nr);
393
  return READ_16 (raw);
394
}
395
 
396
enum
397
  {
398
    HELD_SPI_IDX = 0,
399
    HELD_SPU_IDX = 1
400
  };
401
 
402
static unsigned long
403
spu_register (void)
404
{
405
  if (PSW_SM)
406
    return GPR (SP_IDX);
407
  else
408
    return HELD_SP (HELD_SPU_IDX);
409
}
410
 
411
static unsigned long
412
spi_register (void)
413
{
414
  if (!PSW_SM)
415
    return GPR (SP_IDX);
416
  else
417
    return HELD_SP (HELD_SPI_IDX);
418
}
419
 
420
static void
421
set_spi_register (unsigned long value)
422
{
423
  if (!PSW_SM)
424
    SET_GPR (SP_IDX, value);
425
  SET_HELD_SP (HELD_SPI_IDX, value);
426
}
427
 
428
static void
429
set_spu_register  (unsigned long value)
430
{
431
  if (PSW_SM)
432
    SET_GPR (SP_IDX, value);
433
  SET_HELD_SP (HELD_SPU_IDX, value);
434
}
435
 
436
/* Given a virtual address in the DMAP address space, translate it
437
   into a physical address. */
438
 
439
unsigned long
440
sim_d10v_translate_dmap_addr (unsigned long offset,
441
                              int nr_bytes,
442
                              unsigned long *phys,
443
                              unsigned long (*dmap_register) (int reg_nr))
444
{
445
  short map;
446
  int regno;
447
  last_from = "logical-data";
448
  if (offset >= DMAP_BLOCK_SIZE * SIM_D10V_NR_DMAP_REGS)
449
    {
450
      /* Logical address out side of data segments, not supported */
451
      return 0;
452
    }
453
  regno = (offset / DMAP_BLOCK_SIZE);
454
  offset = (offset % DMAP_BLOCK_SIZE);
455
  if ((offset % DMAP_BLOCK_SIZE) + nr_bytes > DMAP_BLOCK_SIZE)
456
    {
457
      /* Don't cross a BLOCK boundary */
458
      nr_bytes = DMAP_BLOCK_SIZE - (offset % DMAP_BLOCK_SIZE);
459
    }
460
  map = dmap_register (regno);
461
  if (regno == 3)
462
    {
463
      /* Always maps to data memory */
464
      int iospi = (offset / 0x1000) % 4;
465
      int iosp = (map >> (4 * (3 - iospi))) % 0x10;
466
      last_to = "io-space";
467
      *phys = (SIM_D10V_MEMORY_DATA + (iosp * 0x10000) + 0xc000 + offset);
468
    }
469
  else
470
    {
471
      int sp = ((map & 0x3000) >> 12);
472
      int segno = (map & 0x3ff);
473
      switch (sp)
474
        {
475
        case 0: /* 00: Unified memory */
476
          *phys = SIM_D10V_MEMORY_UNIFIED + (segno * DMAP_BLOCK_SIZE) + offset;
477
          last_to = "unified";
478
          break;
479
        case 1: /* 01: Instruction Memory */
480
          *phys = SIM_D10V_MEMORY_INSN + (segno * DMAP_BLOCK_SIZE) + offset;
481
          last_to = "chip-insn";
482
          break;
483
        case 2: /* 10: Internal data memory */
484
          *phys = SIM_D10V_MEMORY_DATA + (segno << 16) + (regno * DMAP_BLOCK_SIZE) + offset;
485
          last_to = "chip-data";
486
          break;
487
        case 3: /* 11: Reserved */
488
          return 0;
489
        }
490
    }
491
  return nr_bytes;
492
}
493
 
494
/* Given a virtual address in the IMAP address space, translate it
495
   into a physical address. */
496
 
497
unsigned long
498
sim_d10v_translate_imap_addr (unsigned long offset,
499
                              int nr_bytes,
500
                              unsigned long *phys,
501
                              unsigned long (*imap_register) (int reg_nr))
502
{
503
  short map;
504
  int regno;
505
  int sp;
506
  int segno;
507
  last_from = "logical-insn";
508
  if (offset >= (IMAP_BLOCK_SIZE * SIM_D10V_NR_IMAP_REGS))
509
    {
510
      /* Logical address outside of IMAP segments, not supported */
511
      return 0;
512
    }
513
  regno = (offset / IMAP_BLOCK_SIZE);
514
  offset = (offset % IMAP_BLOCK_SIZE);
515
  if (offset + nr_bytes > IMAP_BLOCK_SIZE)
516
    {
517
      /* Don't cross a BLOCK boundary */
518
      nr_bytes = IMAP_BLOCK_SIZE - offset;
519
    }
520
  map = imap_register (regno);
521
  sp = (map & 0x3000) >> 12;
522
  segno = (map & 0x007f);
523
  switch (sp)
524
    {
525
    case 0: /* 00: unified memory */
526
      *phys = SIM_D10V_MEMORY_UNIFIED + (segno << 17) + offset;
527
      last_to = "unified";
528
      break;
529
    case 1: /* 01: instruction memory */
530
      *phys = SIM_D10V_MEMORY_INSN + (IMAP_BLOCK_SIZE * regno) + offset;
531
      last_to = "chip-insn";
532
      break;
533
    case 2: /*10*/
534
      /* Reserved. */
535
      return 0;
536
    case 3: /* 11: for testing  - instruction memory */
537
      offset = (offset % 0x800);
538
      *phys = SIM_D10V_MEMORY_INSN + offset;
539
      if (offset + nr_bytes > 0x800)
540
        /* don't cross VM boundary */
541
        nr_bytes = 0x800 - offset;
542
      last_to = "test-insn";
543
      break;
544
    }
545
  return nr_bytes;
546
}
547
 
548
unsigned long
549
sim_d10v_translate_addr (unsigned long memaddr,
550
                         int nr_bytes,
551
                         unsigned long *targ_addr,
552
                         unsigned long (*dmap_register) (int reg_nr),
553
                         unsigned long (*imap_register) (int reg_nr))
554
{
555
  unsigned long phys;
556
  unsigned long seg;
557
  unsigned long off;
558
 
559
  last_from = "unknown";
560
  last_to = "unknown";
561
 
562
  seg = (memaddr >> 24);
563
  off = (memaddr & 0xffffffL);
564
 
565
  /* However, if we've asked to use the previous generation of segment
566
     mapping, rearrange the segments as follows. */
567
 
568
  if (old_segment_mapping)
569
    {
570
      switch (seg)
571
        {
572
        case 0x00: /* DMAP translated memory */
573
          seg = 0x10;
574
          break;
575
        case 0x01: /* IMAP translated memory */
576
          seg = 0x11;
577
          break;
578
        case 0x10: /* On-chip data memory */
579
          seg = 0x02;
580
          break;
581
        case 0x11: /* On-chip insn memory */
582
          seg = 0x01;
583
          break;
584
        case 0x12: /* Unified memory */
585
          seg = 0x00;
586
          break;
587
        }
588
    }
589
 
590
  switch (seg)
591
    {
592
    case 0x00:                  /* Physical unified memory */
593
      last_from = "phys-unified";
594
      last_to = "unified";
595
      phys = SIM_D10V_MEMORY_UNIFIED + off;
596
      if ((off % SEGMENT_SIZE) + nr_bytes > SEGMENT_SIZE)
597
        nr_bytes = SEGMENT_SIZE - (off % SEGMENT_SIZE);
598
      break;
599
 
600
    case 0x01:                  /* Physical instruction memory */
601
      last_from = "phys-insn";
602
      last_to = "chip-insn";
603
      phys = SIM_D10V_MEMORY_INSN + off;
604
      if ((off % SEGMENT_SIZE) + nr_bytes > SEGMENT_SIZE)
605
        nr_bytes = SEGMENT_SIZE - (off % SEGMENT_SIZE);
606
      break;
607
 
608
    case 0x02:                  /* Physical data memory segment */
609
      last_from = "phys-data";
610
      last_to = "chip-data";
611
      phys = SIM_D10V_MEMORY_DATA + off;
612
      if ((off % SEGMENT_SIZE) + nr_bytes > SEGMENT_SIZE)
613
        nr_bytes = SEGMENT_SIZE - (off % SEGMENT_SIZE);
614
      break;
615
 
616
    case 0x10:                  /* in logical data address segment */
617
      nr_bytes = sim_d10v_translate_dmap_addr (off, nr_bytes, &phys,
618
                                               dmap_register);
619
      break;
620
 
621
    case 0x11:                  /* in logical instruction address segment */
622
      nr_bytes = sim_d10v_translate_imap_addr (off, nr_bytes, &phys,
623
                                               imap_register);
624
      break;
625
 
626
    default:
627
      return 0;
628
    }
629
 
630
  *targ_addr = phys;
631
  return nr_bytes;
632
}
633
 
634
/* Return a pointer into the raw buffer designated by phys_addr.  It
635
   is assumed that the client has already ensured that the access
636
   isn't going to cross a segment boundary. */
637
 
638
uint8 *
639
map_memory (unsigned phys_addr)
640
{
641
  uint8 **memory;
642
  uint8 *raw;
643
  unsigned offset;
644
  int segment = ((phys_addr >> 24) & 0xff);
645
 
646
  switch (segment)
647
    {
648
 
649
    case 0x00: /* Unified memory */
650
      {
651
        memory = &State.mem.unif[(phys_addr / SEGMENT_SIZE) % UMEM_SEGMENTS];
652
        last_segname = "umem";
653
        break;
654
      }
655
 
656
    case 0x01: /* On-chip insn memory */
657
      {
658
        memory = &State.mem.insn[(phys_addr / SEGMENT_SIZE) % IMEM_SEGMENTS];
659
        last_segname = "imem";
660
        break;
661
      }
662
 
663
    case 0x02: /* On-chip data memory */
664
      {
665
        if ((phys_addr & 0xff00) == 0xff00)
666
          {
667
            phys_addr = (phys_addr & 0xffff);
668
            if (phys_addr == DMAP2_SHADDOW)
669
              {
670
                phys_addr = DMAP2_OFFSET;
671
                last_segname = "dmap";
672
              }
673
            else
674
              last_segname = "reg";
675
          }
676
        else
677
          last_segname = "dmem";
678
        memory = &State.mem.data[(phys_addr / SEGMENT_SIZE) % DMEM_SEGMENTS];
679
        break;
680
      }
681
 
682
    default:
683
      /* OOPS! */
684
      last_segname = "scrap";
685
      return State.mem.fault;
686
    }
687
 
688
  if (*memory == NULL)
689
    {
690
      *memory = calloc (1, SEGMENT_SIZE);
691
      if (*memory == NULL)
692
        {
693
          (*d10v_callback->printf_filtered) (d10v_callback, "Malloc failed.\n");
694
          return State.mem.fault;
695
        }
696
    }
697
 
698
  offset = (phys_addr % SEGMENT_SIZE);
699
  raw = *memory + offset;
700
  return raw;
701
}
702
 
703
/* Transfer data to/from simulated memory.  Since a bug in either the
704
   simulated program or in gdb or the simulator itself may cause a
705
   bogus address to be passed in, we need to do some sanity checking
706
   on addresses to make sure they are within bounds.  When an address
707
   fails the bounds check, treat it as a zero length read/write rather
708
   than aborting the entire run. */
709
 
710
static int
711
xfer_mem (SIM_ADDR virt,
712
          unsigned char *buffer,
713
          int size,
714
          int write_p)
715
{
716
  int xfered = 0;
717
 
718
  while (xfered < size)
719
    {
720
      uint8 *memory;
721
      unsigned long phys;
722
      int phys_size;
723
      phys_size = sim_d10v_translate_addr (virt, size,
724
                                           &phys,
725
                                           dmap_register,
726
                                           imap_register);
727
      if (phys_size == 0)
728
        return xfered;
729
 
730
      memory = map_memory (phys);
731
 
732
#ifdef DEBUG
733
      if ((d10v_debug & DEBUG_INSTRUCTION) != 0)
734
        {
735
          (*d10v_callback->printf_filtered)
736
            (d10v_callback,
737
             "sim_%s %d bytes: 0x%08lx (%s) -> 0x%08lx (%s) -> 0x%08lx (%s)\n",
738
             (write_p ? "write" : "read"),
739
             phys_size, virt, last_from,
740
             phys, last_to,
741
             (long) memory, last_segname);
742
        }
743
#endif
744
 
745
      if (write_p)
746
        {
747
          memcpy (memory, buffer, phys_size);
748
        }
749
      else
750
        {
751
          memcpy (buffer, memory, phys_size);
752
        }
753
 
754
      virt += phys_size;
755
      buffer += phys_size;
756
      xfered += phys_size;
757
    }
758
 
759
  return size;
760
}
761
 
762
 
763
int
764
sim_write (sd, addr, buffer, size)
765
     SIM_DESC sd;
766
     SIM_ADDR addr;
767
     unsigned char *buffer;
768
     int size;
769
{
770
  /* FIXME: this should be performing a virtual transfer */
771
  return xfer_mem( addr, buffer, size, 1);
772
}
773
 
774
int
775
sim_read (sd, addr, buffer, size)
776
     SIM_DESC sd;
777
     SIM_ADDR addr;
778
     unsigned char *buffer;
779
     int size;
780
{
781
  /* FIXME: this should be performing a virtual transfer */
782
  return xfer_mem( addr, buffer, size, 0);
783
}
784
 
785
 
786
SIM_DESC
787
sim_open (kind, callback, abfd, argv)
788
     SIM_OPEN_KIND kind;
789
     host_callback *callback;
790
     struct _bfd *abfd;
791
     char **argv;
792
{
793
  struct simops *s;
794
  struct hash_entry *h;
795
  static int init_p = 0;
796
  char **p;
797
 
798
  sim_kind = kind;
799
  d10v_callback = callback;
800
  myname = argv[0];
801
  old_segment_mapping = 0;
802
 
803
  /* NOTE: This argument parsing is only effective when this function
804
     is called by GDB. Standalone argument parsing is handled by
805
     sim/common/run.c. */
806
  for (p = argv + 1; *p; ++p)
807
    {
808
      if (strcmp (*p, "-oldseg") == 0)
809
        old_segment_mapping = 1;
810
#ifdef DEBUG
811
      else if (strcmp (*p, "-t") == 0)
812
        d10v_debug = DEBUG;
813
      else if (strncmp (*p, "-t", 2) == 0)
814
        d10v_debug = atoi (*p + 2);
815
#endif
816
      else
817
        (*d10v_callback->printf_filtered) (d10v_callback, "ERROR: unsupported option(s): %s\n",*p);
818
    }
819
 
820
  /* put all the opcodes in the hash table */
821
  if (!init_p++)
822
    {
823
      for (s = Simops; s->func; s++)
824
        {
825
          h = &hash_table[hash(s->opcode,s->format)];
826
 
827
          /* go to the last entry in the chain */
828
          while (h->next)
829
            h = h->next;
830
 
831
          if (h->ops)
832
            {
833
              h->next = (struct hash_entry *) calloc(1,sizeof(struct hash_entry));
834
              if (!h->next)
835
                perror ("malloc failure");
836
 
837
              h = h->next;
838
            }
839
          h->ops = s;
840
          h->mask = s->mask;
841
          h->opcode = s->opcode;
842
          h->size = s->is_long;
843
        }
844
    }
845
 
846
  /* reset the processor state */
847
  if (!State.mem.data[0])
848
    sim_size (1);
849
  sim_create_inferior ((SIM_DESC) 1, NULL, NULL, NULL);
850
 
851
  /* Fudge our descriptor.  */
852
  return (SIM_DESC) 1;
853
}
854
 
855
 
856
void
857
sim_close (sd, quitting)
858
     SIM_DESC sd;
859
     int quitting;
860
{
861
  if (prog_bfd != NULL && prog_bfd_was_opened_p)
862
    {
863
      bfd_close (prog_bfd);
864
      prog_bfd = NULL;
865
      prog_bfd_was_opened_p = 0;
866
    }
867
}
868
 
869
void
870
sim_set_profile (n)
871
     int n;
872
{
873
  (*d10v_callback->printf_filtered) (d10v_callback, "sim_set_profile %d\n",n);
874
}
875
 
876
void
877
sim_set_profile_size (n)
878
     int n;
879
{
880
  (*d10v_callback->printf_filtered) (d10v_callback, "sim_set_profile_size %d\n",n);
881
}
882
 
883
uint8 *
884
dmem_addr (uint16 offset)
885
{
886
  unsigned long phys;
887
  uint8 *mem;
888
  int phys_size;
889
 
890
  /* Note: DMEM address range is 0..0x10000. Calling code can compute
891
     things like ``0xfffe + 0x0e60 == 0x10e5d''.  Since offset's type
892
     is uint16 this is modulo'ed onto 0x0e5d. */
893
 
894
  phys_size = sim_d10v_translate_dmap_addr (offset, 1, &phys,
895
                                            dmap_register);
896
  if (phys_size == 0)
897
    {
898
      mem = State.mem.fault;
899
    }
900
  else
901
    mem = map_memory (phys);
902
#ifdef DEBUG
903
  if ((d10v_debug & DEBUG_MEMORY))
904
    {
905
      (*d10v_callback->printf_filtered)
906
        (d10v_callback,
907
         "mem: 0x%08x (%s) -> 0x%08lx %d (%s) -> 0x%08lx (%s)\n",
908
         offset, last_from,
909
         phys, phys_size, last_to,
910
         (long) mem, last_segname);
911
    }
912
#endif
913
  return mem;
914
}
915
 
916
uint8 *
917
imem_addr (uint32 offset)
918
{
919
  unsigned long phys;
920
  uint8 *mem;
921
  int phys_size = sim_d10v_translate_imap_addr (offset, 1, &phys, imap_register);
922
  if (phys_size == 0)
923
    {
924
      return State.mem.fault;
925
    }
926
  mem = map_memory (phys);
927
#ifdef DEBUG
928
  if ((d10v_debug & DEBUG_MEMORY))
929
    {
930
      (*d10v_callback->printf_filtered)
931
        (d10v_callback,
932
         "mem: 0x%08x (%s) -> 0x%08lx %d (%s) -> 0x%08lx (%s)\n",
933
         offset, last_from,
934
         phys, phys_size, last_to,
935
         (long) mem, last_segname);
936
    }
937
#endif
938
  return mem;
939
}
940
 
941
static int stop_simulator = 0;
942
 
943
int
944
sim_stop (sd)
945
     SIM_DESC sd;
946
{
947
  stop_simulator = 1;
948
  return 1;
949
}
950
 
951
 
952
/* Run (or resume) the program.  */
953
void
954
sim_resume (sd, step, siggnal)
955
     SIM_DESC sd;
956
     int step, siggnal;
957
{
958
  uint32 inst;
959
  uint8 *iaddr;
960
 
961
/*   (*d10v_callback->printf_filtered) (d10v_callback, "sim_resume (%d,%d)  PC=0x%x\n",step,siggnal,PC); */
962
  State.exception = 0;
963
  if (step)
964
    sim_stop (sd);
965
 
966
  switch (siggnal)
967
    {
968
    case 0:
969
      break;
970
#ifdef SIGBUS
971
    case SIGBUS:
972
#endif
973
    case SIGSEGV:
974
      SET_BPC (PC);
975
      SET_BPSW (PSW);
976
      SET_HW_PSW ((PSW & (PSW_F0_BIT | PSW_F1_BIT | PSW_C_BIT)));
977
      JMP (AE_VECTOR_START);
978
      SLOT_FLUSH ();
979
      break;
980
    case SIGILL:
981
      SET_BPC (PC);
982
      SET_BPSW (PSW);
983
      SET_HW_PSW ((PSW & (PSW_F0_BIT | PSW_F1_BIT | PSW_C_BIT)));
984
      JMP (RIE_VECTOR_START);
985
      SLOT_FLUSH ();
986
      break;
987
    default:
988
      /* just ignore it */
989
      break;
990
    }
991
 
992
  do
993
    {
994
      iaddr = imem_addr ((uint32)PC << 2);
995
      if (iaddr == State.mem.fault)
996
        {
997
          State.exception = SIGBUS;
998
          break;
999
        }
1000
 
1001
      inst = get_longword( iaddr );
1002
 
1003
      State.pc_changed = 0;
1004
      ins_type_counters[ (int)INS_CYCLES ]++;
1005
 
1006
      switch (inst & 0xC0000000)
1007
        {
1008
        case 0xC0000000:
1009
          /* long instruction */
1010
          do_long (inst & 0x3FFFFFFF);
1011
          break;
1012
        case 0x80000000:
1013
          /* R -> L */
1014
          do_2_short ( inst & 0x7FFF, (inst & 0x3FFF8000) >> 15, RIGHT_FIRST);
1015
          break;
1016
        case 0x40000000:
1017
          /* L -> R */
1018
          do_2_short ((inst & 0x3FFF8000) >> 15, inst & 0x7FFF, LEFT_FIRST);
1019
          break;
1020
        case 0:
1021
          do_parallel ((inst & 0x3FFF8000) >> 15, inst & 0x7FFF);
1022
          break;
1023
        }
1024
 
1025
      /* If the PC of the current instruction matches RPT_E then
1026
         schedule a branch to the loop start.  If one of those
1027
         instructions happens to be a branch, than that instruction
1028
         will be ignored */
1029
      if (!State.pc_changed)
1030
        {
1031
          if (PSW_RP && PC == RPT_E)
1032
            {
1033
              /* Note: The behavour of a branch instruction at RPT_E
1034
                 is implementation dependant, this simulator takes the
1035
                 branch.  Branching to RPT_E is valid, the instruction
1036
                 must be executed before the loop is taken.  */
1037
              if (RPT_C == 1)
1038
                {
1039
                  SET_PSW_RP (0);
1040
                  SET_RPT_C (0);
1041
                  SET_PC (PC + 1);
1042
                }
1043
              else
1044
                {
1045
                  SET_RPT_C (RPT_C - 1);
1046
                  SET_PC (RPT_S);
1047
                }
1048
            }
1049
          else
1050
            SET_PC (PC + 1);
1051
        }
1052
 
1053
      /* Check for a breakpoint trap on this instruction.  This
1054
         overrides any pending branches or loops */
1055
      if (PSW_DB && PC == IBA)
1056
        {
1057
          SET_BPC (PC);
1058
          SET_BPSW (PSW);
1059
          SET_PSW (PSW & PSW_SM_BIT);
1060
          SET_PC (SDBT_VECTOR_START);
1061
        }
1062
 
1063
      /* Writeback all the DATA / PC changes */
1064
      SLOT_FLUSH ();
1065
 
1066
#ifdef NEED_UI_LOOP_HOOK
1067
      if (ui_loop_hook != NULL && ui_loop_hook_counter-- < 0)
1068
        {
1069
          ui_loop_hook_counter = UI_LOOP_POLL_INTERVAL;
1070
          ui_loop_hook (0);
1071
        }
1072
#endif /* NEED_UI_LOOP_HOOK */
1073
    }
1074
  while ( !State.exception && !stop_simulator);
1075
 
1076
  if (step && !State.exception)
1077
    State.exception = SIGTRAP;
1078
}
1079
 
1080
void
1081
sim_set_trace (void)
1082
{
1083
#ifdef DEBUG
1084
  d10v_debug = DEBUG;
1085
#endif
1086
}
1087
 
1088
void
1089
sim_info (sd, verbose)
1090
     SIM_DESC sd;
1091
     int verbose;
1092
{
1093
  char buf1[40];
1094
  char buf2[40];
1095
  char buf3[40];
1096
  char buf4[40];
1097
  char buf5[40];
1098
  unsigned long left            = ins_type_counters[ (int)INS_LEFT ] + ins_type_counters[ (int)INS_LEFT_COND_EXE ];
1099
  unsigned long left_nops       = ins_type_counters[ (int)INS_LEFT_NOPS ];
1100
  unsigned long left_parallel   = ins_type_counters[ (int)INS_LEFT_PARALLEL ];
1101
  unsigned long left_cond       = ins_type_counters[ (int)INS_LEFT_COND_TEST ];
1102
  unsigned long left_total      = left + left_parallel + left_cond + left_nops;
1103
 
1104
  unsigned long right           = ins_type_counters[ (int)INS_RIGHT ] + ins_type_counters[ (int)INS_RIGHT_COND_EXE ];
1105
  unsigned long right_nops      = ins_type_counters[ (int)INS_RIGHT_NOPS ];
1106
  unsigned long right_parallel  = ins_type_counters[ (int)INS_RIGHT_PARALLEL ];
1107
  unsigned long right_cond      = ins_type_counters[ (int)INS_RIGHT_COND_TEST ];
1108
  unsigned long right_total     = right + right_parallel + right_cond + right_nops;
1109
 
1110
  unsigned long unknown         = ins_type_counters[ (int)INS_UNKNOWN ];
1111
  unsigned long ins_long        = ins_type_counters[ (int)INS_LONG ];
1112
  unsigned long parallel        = ins_type_counters[ (int)INS_PARALLEL ];
1113
  unsigned long leftright       = ins_type_counters[ (int)INS_LEFTRIGHT ];
1114
  unsigned long rightleft       = ins_type_counters[ (int)INS_RIGHTLEFT ];
1115
  unsigned long cond_true       = ins_type_counters[ (int)INS_COND_TRUE ];
1116
  unsigned long cond_false      = ins_type_counters[ (int)INS_COND_FALSE ];
1117
  unsigned long cond_jump       = ins_type_counters[ (int)INS_COND_JUMP ];
1118
  unsigned long cycles          = ins_type_counters[ (int)INS_CYCLES ];
1119
  unsigned long total           = (unknown + left_total + right_total + ins_long);
1120
 
1121
  int size                      = strlen (add_commas (buf1, sizeof (buf1), total));
1122
  int parallel_size             = strlen (add_commas (buf1, sizeof (buf1),
1123
                                                      (left_parallel > right_parallel) ? left_parallel : right_parallel));
1124
  int cond_size                 = strlen (add_commas (buf1, sizeof (buf1), (left_cond > right_cond) ? left_cond : right_cond));
1125
  int nop_size                  = strlen (add_commas (buf1, sizeof (buf1), (left_nops > right_nops) ? left_nops : right_nops));
1126
  int normal_size               = strlen (add_commas (buf1, sizeof (buf1), (left > right) ? left : right));
1127
 
1128
  (*d10v_callback->printf_filtered) (d10v_callback,
1129
                                     "executed %*s left  instruction(s), %*s normal, %*s parallel, %*s EXExxx, %*s nops\n",
1130
                                     size, add_commas (buf1, sizeof (buf1), left_total),
1131
                                     normal_size, add_commas (buf2, sizeof (buf2), left),
1132
                                     parallel_size, add_commas (buf3, sizeof (buf3), left_parallel),
1133
                                     cond_size, add_commas (buf4, sizeof (buf4), left_cond),
1134
                                     nop_size, add_commas (buf5, sizeof (buf5), left_nops));
1135
 
1136
  (*d10v_callback->printf_filtered) (d10v_callback,
1137
                                     "executed %*s right instruction(s), %*s normal, %*s parallel, %*s EXExxx, %*s nops\n",
1138
                                     size, add_commas (buf1, sizeof (buf1), right_total),
1139
                                     normal_size, add_commas (buf2, sizeof (buf2), right),
1140
                                     parallel_size, add_commas (buf3, sizeof (buf3), right_parallel),
1141
                                     cond_size, add_commas (buf4, sizeof (buf4), right_cond),
1142
                                     nop_size, add_commas (buf5, sizeof (buf5), right_nops));
1143
 
1144
  if (ins_long)
1145
    (*d10v_callback->printf_filtered) (d10v_callback,
1146
                                       "executed %*s long instruction(s)\n",
1147
                                       size, add_commas (buf1, sizeof (buf1), ins_long));
1148
 
1149
  if (parallel)
1150
    (*d10v_callback->printf_filtered) (d10v_callback,
1151
                                       "executed %*s parallel instruction(s)\n",
1152
                                       size, add_commas (buf1, sizeof (buf1), parallel));
1153
 
1154
  if (leftright)
1155
    (*d10v_callback->printf_filtered) (d10v_callback,
1156
                                       "executed %*s instruction(s) encoded L->R\n",
1157
                                       size, add_commas (buf1, sizeof (buf1), leftright));
1158
 
1159
  if (rightleft)
1160
    (*d10v_callback->printf_filtered) (d10v_callback,
1161
                                       "executed %*s instruction(s) encoded R->L\n",
1162
                                       size, add_commas (buf1, sizeof (buf1), rightleft));
1163
 
1164
  if (unknown)
1165
    (*d10v_callback->printf_filtered) (d10v_callback,
1166
                                       "executed %*s unknown instruction(s)\n",
1167
                                       size, add_commas (buf1, sizeof (buf1), unknown));
1168
 
1169
  if (cond_true)
1170
    (*d10v_callback->printf_filtered) (d10v_callback,
1171
                                       "executed %*s instruction(s) due to EXExxx condition being true\n",
1172
                                       size, add_commas (buf1, sizeof (buf1), cond_true));
1173
 
1174
  if (cond_false)
1175
    (*d10v_callback->printf_filtered) (d10v_callback,
1176
                                       "skipped  %*s instruction(s) due to EXExxx condition being false\n",
1177
                                       size, add_commas (buf1, sizeof (buf1), cond_false));
1178
 
1179
  if (cond_jump)
1180
    (*d10v_callback->printf_filtered) (d10v_callback,
1181
                                       "skipped  %*s instruction(s) due to conditional branch succeeding\n",
1182
                                       size, add_commas (buf1, sizeof (buf1), cond_jump));
1183
 
1184
  (*d10v_callback->printf_filtered) (d10v_callback,
1185
                                     "executed %*s cycle(s)\n",
1186
                                     size, add_commas (buf1, sizeof (buf1), cycles));
1187
 
1188
  (*d10v_callback->printf_filtered) (d10v_callback,
1189
                                     "executed %*s total instructions\n",
1190
                                     size, add_commas (buf1, sizeof (buf1), total));
1191
}
1192
 
1193
SIM_RC
1194
sim_create_inferior (sd, abfd, argv, env)
1195
     SIM_DESC sd;
1196
     struct _bfd *abfd;
1197
     char **argv;
1198
     char **env;
1199
{
1200
  bfd_vma start_address;
1201
 
1202
  /* reset all state information */
1203
  memset (&State.regs, 0, (int)&State.mem - (int)&State.regs);
1204
 
1205
  if (argv)
1206
    {
1207
      /* a hack to set r0/r1 with argc/argv */
1208
      /* some high memory that won't be overwritten by the stack soon */
1209
      bfd_vma addr = 0x7C00;
1210
      int p = 20;
1211
      int i = 0;
1212
      while (argv[i])
1213
        {
1214
          int size = strlen (argv[i]) + 1;
1215
          SW (addr + 2*i, addr + p);
1216
          sim_write (sd, addr + 0, argv[i], size);
1217
          p += size;
1218
          i++;
1219
        }
1220
      SET_GPR (0, addr);
1221
      SET_GPR (1, i);
1222
    }
1223
 
1224
  /* set PC */
1225
  if (abfd != NULL)
1226
    start_address = bfd_get_start_address (abfd);
1227
  else
1228
    start_address = 0xffc0 << 2;
1229
#ifdef DEBUG
1230
  if (d10v_debug)
1231
    (*d10v_callback->printf_filtered) (d10v_callback, "sim_create_inferior:  PC=0x%lx\n", (long) start_address);
1232
#endif
1233
  SET_CREG (PC_CR, start_address >> 2);
1234
 
1235
  /* cpu resets imap0 to 0 and imap1 to 0x7f, but D10V-EVA board
1236
     initializes imap0 and imap1 to 0x1000 as part of its ROM
1237
     initialization. */
1238
  if (old_segment_mapping)
1239
    {
1240
      /* External memory startup.  This is the HARD reset state. */
1241
      set_imap_register (0, 0x0000);
1242
      set_imap_register (1, 0x007f);
1243
      set_dmap_register (0, 0x2000);
1244
      set_dmap_register (1, 0x2000);
1245
      set_dmap_register (2, 0x0000); /* Old DMAP */
1246
      set_dmap_register (3, 0x0000);
1247
    }
1248
  else
1249
    {
1250
      /* Internal memory startup. This is the ROM intialized state. */
1251
      set_imap_register (0, 0x1000);
1252
      set_imap_register (1, 0x1000);
1253
      set_dmap_register (0, 0x2000);
1254
      set_dmap_register (1, 0x2000);
1255
      set_dmap_register (2, 0x2000); /* DMAP2 initial internal value is
1256
                                        0x2000 on the new board. */
1257
      set_dmap_register (3, 0x0000);
1258
    }
1259
 
1260
  SLOT_FLUSH ();
1261
  return SIM_RC_OK;
1262
}
1263
 
1264
 
1265
void
1266
sim_set_callbacks (p)
1267
     host_callback *p;
1268
{
1269
  d10v_callback = p;
1270
}
1271
 
1272
void
1273
sim_stop_reason (sd, reason, sigrc)
1274
     SIM_DESC sd;
1275
     enum sim_stop *reason;
1276
     int *sigrc;
1277
{
1278
/*   (*d10v_callback->printf_filtered) (d10v_callback, "sim_stop_reason:  PC=0x%x\n",PC<<2); */
1279
 
1280
  switch (State.exception)
1281
    {
1282
    case SIG_D10V_STOP:                 /* stop instruction */
1283
      *reason = sim_exited;
1284
      *sigrc = 0;
1285
      break;
1286
 
1287
    case SIG_D10V_EXIT:                 /* exit trap */
1288
      *reason = sim_exited;
1289
      *sigrc = GPR (0);
1290
      break;
1291
 
1292
    case SIG_D10V_BUS:
1293
      *reason = sim_stopped;
1294
#ifdef SIGBUS
1295
      *sigrc = SIGBUS;
1296
#else
1297
      *sigrc = SIGSEGV;
1298
#endif
1299
      break;
1300
 
1301
    default:                            /* some signal */
1302
      *reason = sim_stopped;
1303
      if (stop_simulator && !State.exception)
1304
        *sigrc = SIGINT;
1305
      else
1306
        *sigrc = State.exception;
1307
      break;
1308
    }
1309
 
1310
  stop_simulator = 0;
1311
}
1312
 
1313
int
1314
sim_fetch_register (sd, rn, memory, length)
1315
     SIM_DESC sd;
1316
     int rn;
1317
     unsigned char *memory;
1318
     int length;
1319
{
1320
  int size;
1321
  if (rn < 0)
1322
    size = 0;
1323
  else if (rn >= SIM_D10V_R0_REGNUM
1324
           && rn < SIM_D10V_R0_REGNUM + SIM_D10V_NR_R_REGS)
1325
    {
1326
      WRITE_16 (memory, GPR (rn - SIM_D10V_R0_REGNUM));
1327
      size = 2;
1328
    }
1329
  else if (rn >= SIM_D10V_CR0_REGNUM
1330
           && rn < SIM_D10V_CR0_REGNUM + SIM_D10V_NR_CR_REGS)
1331
    {
1332
      WRITE_16 (memory, CREG (rn - SIM_D10V_CR0_REGNUM));
1333
      size = 2;
1334
    }
1335
  else if (rn >= SIM_D10V_A0_REGNUM
1336
           && rn < SIM_D10V_A0_REGNUM + SIM_D10V_NR_A_REGS)
1337
    {
1338
      WRITE_64 (memory, ACC (rn - SIM_D10V_A0_REGNUM));
1339
      size = 8;
1340
    }
1341
  else if (rn == SIM_D10V_SPI_REGNUM)
1342
    {
1343
      /* PSW_SM indicates that the current SP is the USER
1344
         stack-pointer. */
1345
      WRITE_16 (memory, spi_register ());
1346
      size = 2;
1347
    }
1348
  else if (rn == SIM_D10V_SPU_REGNUM)
1349
    {
1350
      /* PSW_SM indicates that the current SP is the USER
1351
         stack-pointer. */
1352
      WRITE_16 (memory, spu_register ());
1353
      size = 2;
1354
    }
1355
  else if (rn >= SIM_D10V_IMAP0_REGNUM
1356
           && rn < SIM_D10V_IMAP0_REGNUM + SIM_D10V_NR_IMAP_REGS)
1357
    {
1358
      WRITE_16 (memory, imap_register (rn - SIM_D10V_IMAP0_REGNUM));
1359
      size = 2;
1360
    }
1361
  else if (rn >= SIM_D10V_DMAP0_REGNUM
1362
           && rn < SIM_D10V_DMAP0_REGNUM + SIM_D10V_NR_DMAP_REGS)
1363
    {
1364
      WRITE_16 (memory, dmap_register (rn - SIM_D10V_DMAP0_REGNUM));
1365
      size = 2;
1366
    }
1367
  else
1368
    size = 0;
1369
  return size;
1370
}
1371
 
1372
int
1373
sim_store_register (sd, rn, memory, length)
1374
     SIM_DESC sd;
1375
     int rn;
1376
     unsigned char *memory;
1377
     int length;
1378
{
1379
  int size;
1380
  if (rn < 0)
1381
    size = 0;
1382
  else if (rn >= SIM_D10V_R0_REGNUM
1383
           && rn < SIM_D10V_R0_REGNUM + SIM_D10V_NR_R_REGS)
1384
    {
1385
      SET_GPR (rn - SIM_D10V_R0_REGNUM, READ_16 (memory));
1386
      size = 2;
1387
    }
1388
  else if (rn >= SIM_D10V_CR0_REGNUM
1389
           && rn < SIM_D10V_CR0_REGNUM + SIM_D10V_NR_CR_REGS)
1390
    {
1391
      SET_CREG (rn - SIM_D10V_CR0_REGNUM, READ_16 (memory));
1392
      size = 2;
1393
    }
1394
  else if (rn >= SIM_D10V_A0_REGNUM
1395
           && rn < SIM_D10V_A0_REGNUM + SIM_D10V_NR_A_REGS)
1396
    {
1397
      SET_ACC (rn - SIM_D10V_A0_REGNUM, READ_64 (memory) & MASK40);
1398
      size = 8;
1399
    }
1400
  else if (rn == SIM_D10V_SPI_REGNUM)
1401
    {
1402
      /* PSW_SM indicates that the current SP is the USER
1403
         stack-pointer. */
1404
      set_spi_register (READ_16 (memory));
1405
      size = 2;
1406
    }
1407
  else if (rn == SIM_D10V_SPU_REGNUM)
1408
    {
1409
      set_spu_register (READ_16 (memory));
1410
      size = 2;
1411
    }
1412
  else if (rn >= SIM_D10V_IMAP0_REGNUM
1413
           && rn < SIM_D10V_IMAP0_REGNUM + SIM_D10V_NR_IMAP_REGS)
1414
    {
1415
      set_imap_register (rn - SIM_D10V_IMAP0_REGNUM, READ_16(memory));
1416
      size = 2;
1417
    }
1418
  else if (rn >= SIM_D10V_DMAP0_REGNUM
1419
           && rn < SIM_D10V_DMAP0_REGNUM + SIM_D10V_NR_DMAP_REGS)
1420
    {
1421
      set_dmap_register (rn - SIM_D10V_DMAP0_REGNUM, READ_16(memory));
1422
      size = 2;
1423
    }
1424
  else
1425
    size = 0;
1426
  SLOT_FLUSH ();
1427
  return size;
1428
}
1429
 
1430
 
1431
void
1432
sim_do_command (sd, cmd)
1433
     SIM_DESC sd;
1434
     char *cmd;
1435
{
1436
  (*d10v_callback->printf_filtered) (d10v_callback, "sim_do_command: %s\n",cmd);
1437
}
1438
 
1439
SIM_RC
1440
sim_load (sd, prog, abfd, from_tty)
1441
     SIM_DESC sd;
1442
     char *prog;
1443
     bfd *abfd;
1444
     int from_tty;
1445
{
1446
  extern bfd *sim_load_file (); /* ??? Don't know where this should live.  */
1447
 
1448
  if (prog_bfd != NULL && prog_bfd_was_opened_p)
1449
    {
1450
      bfd_close (prog_bfd);
1451
      prog_bfd_was_opened_p = 0;
1452
    }
1453
  prog_bfd = sim_load_file (sd, myname, d10v_callback, prog, abfd,
1454
                            sim_kind == SIM_OPEN_DEBUG,
1455
                            1/*LMA*/, sim_write);
1456
  if (prog_bfd == NULL)
1457
    return SIM_RC_FAIL;
1458
  prog_bfd_was_opened_p = abfd == NULL;
1459
  return SIM_RC_OK;
1460
}

powered by: WebSVN 2.1.0

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