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

Subversion Repositories openrisc_me

[/] [openrisc/] [trunk/] [gnu-src/] [gdb-7.1/] [sim/] [cr16/] [interp.c] - Blame information for rev 247

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

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

powered by: WebSVN 2.1.0

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