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

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-stable/] [gdb-7.2/] [sim/] [moxie/] [interp.c] - Blame information for rev 859

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

Line No. Rev Author Line
1 330 jeremybenn
/* Simulator for the moxie processor
2
   Copyright (C) 2008, 2009, 2010 Free Software Foundation, Inc.
3
   Contributed by Anthony Green
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 of the License, or
10
(at your option) 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 <stdlib.h>
22
#include "sysdep.h"
23
#include <sys/times.h>
24
#include <sys/param.h>
25
#include <netinet/in.h> /* for byte ordering macros */
26
#include "bfd.h"
27
#include "gdb/callback.h"
28
#include "libiberty.h"
29
#include "gdb/remote-sim.h"
30
 
31
#include "sim-main.h"
32
#include "sim-base.h"
33
 
34
typedef int word;
35
typedef unsigned int uword;
36
 
37
host_callback *       callback;
38
 
39
FILE *tracefile;
40
 
41
/* Extract the signed 10-bit offset from a 16-bit branch
42
   instruction.  */
43
#define INST2OFFSET(o) ((((signed short)((o & ((1<<10)-1))<<6))>>6)<<1)
44
 
45
#define EXTRACT_WORD(addr) \
46
  ((sim_core_read_aligned_1 (scpu, cia, read_map, addr) << 24) \
47
   + (sim_core_read_aligned_1 (scpu, cia, read_map, addr+1) << 16) \
48
   + (sim_core_read_aligned_1 (scpu, cia, read_map, addr+2) << 8) \
49
   + (sim_core_read_aligned_1 (scpu, cia, read_map, addr+3)))
50
 
51
unsigned long
52
moxie_extract_unsigned_integer (addr, len)
53
     unsigned char * addr;
54
     int len;
55
{
56
  unsigned long retval;
57
  unsigned char * p;
58
  unsigned char * startaddr = (unsigned char *)addr;
59
  unsigned char * endaddr = startaddr + len;
60
 
61
  if (len > (int) sizeof (unsigned long))
62
    printf ("That operation is not available on integers of more than %d bytes.",
63
            sizeof (unsigned long));
64
 
65
  /* Start at the most significant end of the integer, and work towards
66
     the least significant.  */
67
  retval = 0;
68
 
69
  for (p = endaddr; p > startaddr;)
70
    retval = (retval << 8) | * -- p;
71
 
72
  return retval;
73
}
74
 
75
void
76
moxie_store_unsigned_integer (addr, len, val)
77
     unsigned char * addr;
78
     int len;
79
     unsigned long val;
80
{
81
  unsigned char * p;
82
  unsigned char * startaddr = (unsigned char *)addr;
83
  unsigned char * endaddr = startaddr + len;
84
 
85
  for (p = endaddr; p > startaddr;)
86
    {
87
      * -- p = val & 0xff;
88
      val >>= 8;
89
    }
90
}
91
 
92
/* moxie register names.  */
93
static const char *reg_names[16] =
94
  { "$fp", "$sp", "$r0", "$r1", "$r2", "$r3", "$r4", "$r5",
95
    "$r6", "$r7", "$r8", "$r9", "$r10", "$r11", "$r12", "$r13" };
96
 
97
/* The machine state.
98
 
99
   This state is maintained in host byte order.  The fetch/store
100
   register functions must translate between host byte order and the
101
   target processor byte order.  Keeping this data in target byte
102
   order simplifies the register read/write functions.  Keeping this
103
   data in native order improves the performance of the simulator.
104
   Simulation speed is deemed more important.  */
105
 
106
#define NUM_MOXIE_REGS 17 /* Including PC */
107
#define NUM_MOXIE_SREGS 256 /* The special registers */
108
#define PC_REGNO     16
109
 
110
/* The ordering of the moxie_regset structure is matched in the
111
   gdb/config/moxie/tm-moxie.h file in the REGISTER_NAMES macro.  */
112
struct moxie_regset
113
{
114
  word            regs[NUM_MOXIE_REGS + 1]; /* primary registers */
115
  word            sregs[256];             /* special registers */
116
  word            cc;                   /* the condition code reg */
117
  int             exception;
118
  unsigned long long insts;                /* instruction counter */
119
};
120
 
121
#define CC_GT  1<<0
122
#define CC_LT  1<<1
123
#define CC_EQ  1<<2
124
#define CC_GTU 1<<3
125
#define CC_LTU 1<<4
126
 
127
union
128
{
129
  struct moxie_regset asregs;
130
  word asints [1];              /* but accessed larger... */
131
} cpu;
132
 
133
static char *myname;
134
static SIM_OPEN_KIND sim_kind;
135
static int issue_messages = 0;
136
 
137
void
138
sim_size (int s)
139
{
140
}
141
 
142
static void
143
set_initial_gprs ()
144
{
145
  int i;
146
  long space;
147
 
148
  /* Set up machine just out of reset.  */
149
  cpu.asregs.regs[PC_REGNO] = 0;
150
 
151
  /* Clean out the register contents.  */
152
  for (i = 0; i < NUM_MOXIE_REGS; i++)
153
    cpu.asregs.regs[i] = 0;
154
  for (i = 0; i < NUM_MOXIE_SREGS; i++)
155
    cpu.asregs.sregs[i] = 0;
156
}
157
 
158
static void
159
interrupt ()
160
{
161
  cpu.asregs.exception = SIGINT;
162
}
163
 
164
/* Write a 1 byte value to memory.  */
165
 
166
static void INLINE
167
wbat (sim_cpu *scpu, word pc, word x, word v)
168
{
169
  address_word cia = CIA_GET (scpu);
170
 
171
  sim_core_write_aligned_1 (scpu, cia, write_map, x, v);
172
}
173
 
174
/* Write a 2 byte value to memory.  */
175
 
176
static void INLINE
177
wsat (sim_cpu *scpu, word pc, word x, word v)
178
{
179
  address_word cia = CIA_GET (scpu);
180
 
181
  sim_core_write_aligned_2 (scpu, cia, write_map, x, v);
182
}
183
 
184
/* Write a 4 byte value to memory.  */
185
 
186
static void INLINE
187
wlat (sim_cpu *scpu, word pc, word x, word v)
188
{
189
  address_word cia = CIA_GET (scpu);
190
 
191
  sim_core_write_aligned_4 (scpu, cia, write_map, x, v);
192
}
193
 
194
/* Read 2 bytes from memory.  */
195
 
196
static int INLINE
197
rsat (sim_cpu *scpu, word pc, word x)
198
{
199
  address_word cia = CIA_GET (scpu);
200
 
201
  return (sim_core_read_aligned_2 (scpu, cia, read_map, x));
202
}
203
 
204
/* Read 1 byte from memory.  */
205
 
206
static int INLINE
207
rbat (sim_cpu *scpu, word pc, word x)
208
{
209
  address_word cia = CIA_GET (scpu);
210
 
211
  return (sim_core_read_aligned_1 (scpu, cia, read_map, x));
212
}
213
 
214
/* Read 4 bytes from memory.  */
215
 
216
static int INLINE
217
rlat (sim_cpu *scpu, word pc, word x)
218
{
219
  address_word cia = CIA_GET (scpu);
220
 
221
  return (sim_core_read_aligned_4 (scpu, cia, read_map, x));
222
}
223
 
224
#define CHECK_FLAG(T,H) if (tflags & T) { hflags |= H; tflags ^= T; }
225
 
226
unsigned int
227
convert_target_flags (unsigned int tflags)
228
{
229
  unsigned int hflags = 0x0;
230
 
231
  CHECK_FLAG(0x0001, O_WRONLY);
232
  CHECK_FLAG(0x0002, O_RDWR);
233
  CHECK_FLAG(0x0008, O_APPEND);
234
  CHECK_FLAG(0x0200, O_CREAT);
235
  CHECK_FLAG(0x0400, O_TRUNC);
236
  CHECK_FLAG(0x0800, O_EXCL);
237
  CHECK_FLAG(0x2000, O_SYNC);
238
 
239
  if (tflags != 0x0)
240
    fprintf (stderr,
241
             "Simulator Error: problem converting target open flags for host.  0x%x\n",
242
             tflags);
243
 
244
  return hflags;
245
}
246
 
247
#define TRACE(str) if (tracing) fprintf(tracefile,"0x%08x, %s, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x\n", opc, str, cpu.asregs.regs[0], cpu.asregs.regs[1], cpu.asregs.regs[2], cpu.asregs.regs[3], cpu.asregs.regs[4], cpu.asregs.regs[5], cpu.asregs.regs[6], cpu.asregs.regs[7], cpu.asregs.regs[8], cpu.asregs.regs[9], cpu.asregs.regs[10], cpu.asregs.regs[11], cpu.asregs.regs[12], cpu.asregs.regs[13], cpu.asregs.regs[14], cpu.asregs.regs[15]);
248
 
249
static int tracing = 0;
250
 
251
void
252
sim_resume (sd, step, siggnal)
253
     SIM_DESC sd;
254
     int step, siggnal;
255
{
256
  word pc, opc;
257
  unsigned long long insts;
258
  unsigned short inst;
259
  void (* sigsave)();
260
  sim_cpu *scpu = STATE_CPU (sd, 0); /* FIXME */
261
  address_word cia = CIA_GET (scpu);
262
 
263
  sigsave = signal (SIGINT, interrupt);
264
  cpu.asregs.exception = step ? SIGTRAP: 0;
265
  pc = cpu.asregs.regs[PC_REGNO];
266
  insts = cpu.asregs.insts;
267
 
268
  /* Run instructions here. */
269
  do
270
    {
271
      opc = pc;
272
 
273
      /* Fetch the instruction at pc.  */
274
      inst = (sim_core_read_aligned_1 (scpu, cia, read_map, pc) << 8)
275
        + sim_core_read_aligned_1 (scpu, cia, read_map, pc+1);
276
 
277
      /* Decode instruction.  */
278
      if (inst & (1 << 15))
279
        {
280
          if (inst & (1 << 14))
281
            {
282
              /* This is a Form 3 instruction.  */
283
              int opcode = (inst >> 10 & 0xf);
284
 
285
              switch (opcode)
286
                {
287
                case 0x00: /* beq */
288
                  {
289
                    TRACE("beq");
290
                    if (cpu.asregs.cc & CC_EQ)
291
                      pc += INST2OFFSET(inst) - 2;
292
                  }
293
                  break;
294
                case 0x01: /* bne */
295
                  {
296
                    TRACE("bne");
297
                    if (! (cpu.asregs.cc & CC_EQ))
298
                      pc += INST2OFFSET(inst) - 2;
299
                  }
300
                  break;
301
                case 0x02: /* blt */
302
                  {
303
                    TRACE("blt");
304
                    if (cpu.asregs.cc & CC_LT)
305
                      pc += INST2OFFSET(inst) - 2;
306
                  }               break;
307
                case 0x03: /* bgt */
308
                  {
309
                    TRACE("bgt");
310
                    if (cpu.asregs.cc & CC_GT)
311
                      pc += INST2OFFSET(inst) - 2;
312
                  }
313
                  break;
314
                case 0x04: /* bltu */
315
                  {
316
                    TRACE("bltu");
317
                    if (cpu.asregs.cc & CC_LTU)
318
                      pc += INST2OFFSET(inst) - 2;
319
                  }
320
                  break;
321
                case 0x05: /* bgtu */
322
                  {
323
                    TRACE("bgtu");
324
                    if (cpu.asregs.cc & CC_GTU)
325
                      pc += INST2OFFSET(inst) - 2;
326
                  }
327
                  break;
328
                case 0x06: /* bge */
329
                  {
330
                    TRACE("bge");
331
                    if (cpu.asregs.cc & (CC_GT | CC_EQ))
332
                      pc += INST2OFFSET(inst) - 2;
333
                  }
334
                  break;
335
                case 0x07: /* ble */
336
                  {
337
                    TRACE("ble");
338
                    if (cpu.asregs.cc & (CC_LT | CC_EQ))
339
                      pc += INST2OFFSET(inst) - 2;
340
                  }
341
                  break;
342
                case 0x08: /* bgeu */
343
                  {
344
                    TRACE("bgeu");
345
                    if (cpu.asregs.cc & (CC_GTU | CC_EQ))
346
                      pc += INST2OFFSET(inst) - 2;
347
                  }
348
                  break;
349
                case 0x09: /* bleu */
350
                  {
351
                    TRACE("bleu");
352
                    if (cpu.asregs.cc & (CC_LTU | CC_EQ))
353
                      pc += INST2OFFSET(inst) - 2;
354
                  }
355
                  break;
356
                default:
357
                  {
358
                    TRACE("SIGILL3");
359
                    cpu.asregs.exception = SIGILL;
360
                    break;
361
                  }
362
                }
363
            }
364
          else
365
            {
366
              /* This is a Form 2 instruction.  */
367
              int opcode = (inst >> 12 & 0x3);
368
              switch (opcode)
369
                {
370
                case 0x00: /* inc */
371
                  {
372
                    int a = (inst >> 8) & 0xf;
373
                    unsigned av = cpu.asregs.regs[a];
374
                    unsigned v = (inst & 0xff);
375
                    TRACE("inc");
376
                    cpu.asregs.regs[a] = av + v;
377
                  }
378
                  break;
379
                case 0x01: /* dec */
380
                  {
381
                    int a = (inst >> 8) & 0xf;
382
                    unsigned av = cpu.asregs.regs[a];
383
                    unsigned v = (inst & 0xff);
384
                    TRACE("dec");
385
                    cpu.asregs.regs[a] = av - v;
386
                  }
387
                  break;
388
                case 0x02: /* gsr */
389
                  {
390
                    int a = (inst >> 8) & 0xf;
391
                    unsigned v = (inst & 0xff);
392
                    TRACE("gsr");
393
                    cpu.asregs.regs[a] = cpu.asregs.sregs[v];
394
                  }
395
                  break;
396
                case 0x03: /* ssr */
397
                  {
398
                    int a = (inst >> 8) & 0xf;
399
                    unsigned v = (inst & 0xff);
400
                    TRACE("ssr");
401
                    cpu.asregs.sregs[v] = cpu.asregs.regs[a];
402
                  }
403
                  break;
404
                default:
405
                  TRACE("SIGILL2");
406
                  cpu.asregs.exception = SIGILL;
407
                  break;
408
                }
409
            }
410
        }
411
      else
412
        {
413
          /* This is a Form 1 instruction.  */
414
          int opcode = inst >> 8;
415
          switch (opcode)
416
            {
417
            case 0x00: /* bad */
418
              opc = opcode;
419
              TRACE("SIGILL0");
420
              cpu.asregs.exception = SIGILL;
421
              break;
422
            case 0x01: /* ldi.l (immediate) */
423
              {
424
                int reg = (inst >> 4) & 0xf;
425
                TRACE("ldi.l");
426
                unsigned int val = EXTRACT_WORD(pc+2);
427
                cpu.asregs.regs[reg] = val;
428
                pc += 4;
429
              }
430
              break;
431
            case 0x02: /* mov (register-to-register) */
432
              {
433
                int dest  = (inst >> 4) & 0xf;
434
                int src = (inst ) & 0xf;
435
                TRACE("mov");
436
                cpu.asregs.regs[dest] = cpu.asregs.regs[src];
437
              }
438
              break;
439
            case 0x03: /* jsra */
440
              {
441
                unsigned int fn = EXTRACT_WORD(pc+2);
442
                unsigned int sp = cpu.asregs.regs[1];
443
                TRACE("jsra");
444
                /* Save a slot for the static chain.  */
445
                sp -= 4;
446
 
447
                /* Push the return address.  */
448
                sp -= 4;
449
                wlat (scpu, opc, sp, pc + 6);
450
 
451
                /* Push the current frame pointer.  */
452
                sp -= 4;
453
                wlat (scpu, opc, sp, cpu.asregs.regs[0]);
454
 
455
                /* Uncache the stack pointer and set the pc and $fp.  */
456
                cpu.asregs.regs[1] = sp;
457
                cpu.asregs.regs[0] = sp;
458
                pc = fn - 2;
459
              }
460
              break;
461
            case 0x04: /* ret */
462
              {
463
                unsigned int sp = cpu.asregs.regs[0];
464
 
465
                TRACE("ret");
466
 
467
                /* Pop the frame pointer.  */
468
                cpu.asregs.regs[0] = rlat (scpu, opc, sp);
469
                sp += 4;
470
 
471
                /* Pop the return address.  */
472
                pc = rlat (scpu, opc, sp) - 2;
473
                sp += 4;
474
 
475
                /* Skip over the static chain slot.  */
476
                sp += 4;
477
 
478
                /* Uncache the stack pointer.  */
479
                cpu.asregs.regs[1] = sp;
480
              }
481
              break;
482
            case 0x05: /* add.l */
483
              {
484
                int a = (inst >> 4) & 0xf;
485
                int b = inst & 0xf;
486
                unsigned av = cpu.asregs.regs[a];
487
                unsigned bv = cpu.asregs.regs[b];
488
                TRACE("add.l");
489
                cpu.asregs.regs[a] = av + bv;
490
              }
491
              break;
492
            case 0x06: /* push */
493
              {
494
                int a = (inst >> 4) & 0xf;
495
                int b = inst & 0xf;
496
                int sp = cpu.asregs.regs[a] - 4;
497
                TRACE("push");
498
                wlat (scpu, opc, sp, cpu.asregs.regs[b]);
499
                cpu.asregs.regs[a] = sp;
500
              }
501
              break;
502
            case 0x07: /* pop */
503
              {
504
                int a = (inst >> 4) & 0xf;
505
                int b = inst & 0xf;
506
                int sp = cpu.asregs.regs[a];
507
                TRACE("pop");
508
                cpu.asregs.regs[b] = rlat (scpu, opc, sp);
509
                cpu.asregs.regs[a] = sp + 4;
510
              }
511
              break;
512
            case 0x08: /* lda.l */
513
              {
514
                int reg = (inst >> 4) & 0xf;
515
                unsigned int addr = EXTRACT_WORD(pc+2);
516
                TRACE("lda.l");
517
                cpu.asregs.regs[reg] = rlat (scpu, opc, addr);
518
                pc += 4;
519
              }
520
              break;
521
            case 0x09: /* sta.l */
522
              {
523
                int reg = (inst >> 4) & 0xf;
524
                unsigned int addr = EXTRACT_WORD(pc+2);
525
                TRACE("sta.l");
526
                wlat (scpu, opc, addr, cpu.asregs.regs[reg]);
527
                pc += 4;
528
              }
529
              break;
530
            case 0x0a: /* ld.l (register indirect) */
531
              {
532
                int src  = inst & 0xf;
533
                int dest = (inst >> 4) & 0xf;
534
                int xv;
535
                TRACE("ld.l");
536
                xv = cpu.asregs.regs[src];
537
                cpu.asregs.regs[dest] = rlat (scpu, opc, xv);
538
              }
539
              break;
540
            case 0x0b: /* st.l */
541
              {
542
                int dest = (inst >> 4) & 0xf;
543
                int val  = inst & 0xf;
544
                TRACE("st.l");
545
                wlat (scpu, opc, cpu.asregs.regs[dest], cpu.asregs.regs[val]);
546
              }
547
              break;
548
            case 0x0c: /* ldo.l */
549
              {
550
                unsigned int addr = EXTRACT_WORD(pc+2);
551
                int a = (inst >> 4) & 0xf;
552
                int b = inst & 0xf;
553
                TRACE("ldo.l");
554
                addr += cpu.asregs.regs[b];
555
                cpu.asregs.regs[a] = rlat (scpu, opc, addr);
556
                pc += 4;
557
              }
558
              break;
559
            case 0x0d: /* sto.l */
560
              {
561
                unsigned int addr = EXTRACT_WORD(pc+2);
562
                int a = (inst >> 4) & 0xf;
563
                int b = inst & 0xf;
564
                TRACE("sto.l");
565
                addr += cpu.asregs.regs[a];
566
                wlat (scpu, opc, addr, cpu.asregs.regs[b]);
567
                pc += 4;
568
              }
569
              break;
570
            case 0x0e: /* cmp */
571
              {
572
                int a  = (inst >> 4) & 0xf;
573
                int b  = inst & 0xf;
574
                int cc = 0;
575
                int va = cpu.asregs.regs[a];
576
                int vb = cpu.asregs.regs[b];
577
 
578
                TRACE("cmp");
579
 
580
                if (va == vb)
581
                  cc = CC_EQ;
582
                else
583
                  {
584
                    cc |= (va < vb ? CC_LT : 0);
585
                    cc |= (va > vb ? CC_GT : 0);
586
                    cc |= ((unsigned int) va < (unsigned int) vb ? CC_LTU : 0);
587
                    cc |= ((unsigned int) va > (unsigned int) vb ? CC_GTU : 0);
588
                  }
589
 
590
                cpu.asregs.cc = cc;
591
              }
592
              break;
593
            case 0x0f: /* nop */
594
              break;
595
            case 0x10: /* bad */
596
            case 0x11: /* bad */
597
            case 0x12: /* bad */
598
            case 0x13: /* bad */
599
            case 0x14: /* bad */
600
            case 0x15: /* bad */
601
            case 0x16: /* bad */
602
            case 0x17: /* bad */
603
            case 0x18: /* bad */
604
              {
605
                opc = opcode;
606
                TRACE("SIGILL0");
607
                cpu.asregs.exception = SIGILL;
608
                break;
609
              }
610
            case 0x19: /* jsr */
611
              {
612
                unsigned int fn = cpu.asregs.regs[(inst >> 4) & 0xf];
613
                unsigned int sp = cpu.asregs.regs[1];
614
 
615
                TRACE("jsr");
616
 
617
                /* Save a slot for the static chain.  */
618
                sp -= 4;
619
 
620
                /* Push the return address.  */
621
                sp -= 4;
622
                wlat (scpu, opc, sp, pc + 2);
623
 
624
                /* Push the current frame pointer.  */
625
                sp -= 4;
626
                wlat (scpu, opc, sp, cpu.asregs.regs[0]);
627
 
628
                /* Uncache the stack pointer and set the fp & pc.  */
629
                cpu.asregs.regs[1] = sp;
630
                cpu.asregs.regs[0] = sp;
631
                pc = fn - 2;
632
              }
633
              break;
634
            case 0x1a: /* jmpa */
635
              {
636
                unsigned int tgt = EXTRACT_WORD(pc+2);
637
                TRACE("jmpa");
638
                pc = tgt - 2;
639
              }
640
              break;
641
            case 0x1b: /* ldi.b (immediate) */
642
              {
643
                int reg = (inst >> 4) & 0xf;
644
 
645
                unsigned int val = EXTRACT_WORD(pc+2);
646
                TRACE("ldi.b");
647
                cpu.asregs.regs[reg] = val;
648
                pc += 4;
649
              }
650
              break;
651
            case 0x1c: /* ld.b (register indirect) */
652
              {
653
                int src  = inst & 0xf;
654
                int dest = (inst >> 4) & 0xf;
655
                int xv;
656
                TRACE("ld.b");
657
                xv = cpu.asregs.regs[src];
658
                cpu.asregs.regs[dest] = rbat (scpu, opc, xv);
659
              }
660
              break;
661
            case 0x1d: /* lda.b */
662
              {
663
                int reg = (inst >> 4) & 0xf;
664
                unsigned int addr = EXTRACT_WORD(pc+2);
665
                TRACE("lda.b");
666
                cpu.asregs.regs[reg] = rbat (scpu, opc, addr);
667
                pc += 4;
668
              }
669
              break;
670
            case 0x1e: /* st.b */
671
              {
672
                int dest = (inst >> 4) & 0xf;
673
                int val  = inst & 0xf;
674
                TRACE("st.b");
675
                wbat (scpu, opc, cpu.asregs.regs[dest], cpu.asregs.regs[val]);
676
              }
677
              break;
678
            case 0x1f: /* sta.b */
679
              {
680
                int reg = (inst >> 4) & 0xf;
681
                unsigned int addr = EXTRACT_WORD(pc+2);
682
                TRACE("sta.b");
683
                wbat (scpu, opc, addr, cpu.asregs.regs[reg]);
684
                pc += 4;
685
              }
686
              break;
687
            case 0x20: /* ldi.s (immediate) */
688
              {
689
                int reg = (inst >> 4) & 0xf;
690
 
691
                unsigned int val = EXTRACT_WORD(pc+2);
692
                TRACE("ldi.s");
693
                cpu.asregs.regs[reg] = val;
694
                pc += 4;
695
              }
696
              break;
697
            case 0x21: /* ld.s (register indirect) */
698
              {
699
                int src  = inst & 0xf;
700
                int dest = (inst >> 4) & 0xf;
701
                int xv;
702
                TRACE("ld.s");
703
                xv = cpu.asregs.regs[src];
704
                cpu.asregs.regs[dest] = rsat (scpu, opc, xv);
705
              }
706
              break;
707
            case 0x22: /* lda.s */
708
              {
709
                int reg = (inst >> 4) & 0xf;
710
                unsigned int addr = EXTRACT_WORD(pc+2);
711
                TRACE("lda.s");
712
                cpu.asregs.regs[reg] = rsat (scpu, opc, addr);
713
                pc += 4;
714
              }
715
              break;
716
            case 0x23: /* st.s */
717
              {
718
                int dest = (inst >> 4) & 0xf;
719
                int val  = inst & 0xf;
720
                TRACE("st.s");
721
                wsat (scpu, opc, cpu.asregs.regs[dest], cpu.asregs.regs[val]);
722
              }
723
              break;
724
            case 0x24: /* sta.s */
725
              {
726
                int reg = (inst >> 4) & 0xf;
727
                unsigned int addr = EXTRACT_WORD(pc+2);
728
                TRACE("sta.s");
729
                wsat (scpu, opc, addr, cpu.asregs.regs[reg]);
730
                pc += 4;
731
              }
732
              break;
733
            case 0x25: /* jmp */
734
              {
735
                int reg = (inst >> 4) & 0xf;
736
                TRACE("jmp");
737
                pc = cpu.asregs.regs[reg] - 2;
738
              }
739
              break;
740
            case 0x26: /* and */
741
              {
742
                int a = (inst >> 4) & 0xf;
743
                int b = inst & 0xf;
744
                int av, bv;
745
                TRACE("and");
746
                av = cpu.asregs.regs[a];
747
                bv = cpu.asregs.regs[b];
748
                cpu.asregs.regs[a] = av & bv;
749
              }
750
              break;
751
            case 0x27: /* lshr */
752
              {
753
                int a = (inst >> 4) & 0xf;
754
                int b = inst & 0xf;
755
                int av = cpu.asregs.regs[a];
756
                int bv = cpu.asregs.regs[b];
757
                TRACE("lshr");
758
                cpu.asregs.regs[a] = (unsigned) ((unsigned) av >> bv);
759
              }
760
              break;
761
            case 0x28: /* ashl */
762
              {
763
                int a = (inst >> 4) & 0xf;
764
                int b = inst & 0xf;
765
                int av = cpu.asregs.regs[a];
766
                int bv = cpu.asregs.regs[b];
767
                TRACE("ashl");
768
                cpu.asregs.regs[a] = av << bv;
769
              }
770
              break;
771
            case 0x29: /* sub.l */
772
              {
773
                int a = (inst >> 4) & 0xf;
774
                int b = inst & 0xf;
775
                unsigned av = cpu.asregs.regs[a];
776
                unsigned bv = cpu.asregs.regs[b];
777
                TRACE("sub.l");
778
                cpu.asregs.regs[a] = av - bv;
779
              }
780
              break;
781
            case 0x2a: /* neg */
782
              {
783
                int a  = (inst >> 4) & 0xf;
784
                int b  = inst & 0xf;
785
                int bv = cpu.asregs.regs[b];
786
                TRACE("neg");
787
                cpu.asregs.regs[a] = - bv;
788
              }
789
              break;
790
            case 0x2b: /* or */
791
              {
792
                int a = (inst >> 4) & 0xf;
793
                int b = inst & 0xf;
794
                int av, bv;
795
                TRACE("or");
796
                av = cpu.asregs.regs[a];
797
                bv = cpu.asregs.regs[b];
798
                cpu.asregs.regs[a] = av | bv;
799
              }
800
              break;
801
            case 0x2c: /* not */
802
              {
803
                int a = (inst >> 4) & 0xf;
804
                int b = inst & 0xf;
805
                int bv = cpu.asregs.regs[b];
806
                TRACE("not");
807
                cpu.asregs.regs[a] = 0xffffffff ^ bv;
808
              }
809
              break;
810
            case 0x2d: /* ashr */
811
              {
812
                int a  = (inst >> 4) & 0xf;
813
                int b  = inst & 0xf;
814
                int av = cpu.asregs.regs[a];
815
                int bv = cpu.asregs.regs[b];
816
                TRACE("ashr");
817
                cpu.asregs.regs[a] = av >> bv;
818
              }
819
              break;
820
            case 0x2e: /* xor */
821
              {
822
                int a = (inst >> 4) & 0xf;
823
                int b = inst & 0xf;
824
                int av, bv;
825
                TRACE("xor");
826
                av = cpu.asregs.regs[a];
827
                bv = cpu.asregs.regs[b];
828
                cpu.asregs.regs[a] = av ^ bv;
829
              }
830
              break;
831
            case 0x2f: /* mul.l */
832
              {
833
                int a = (inst >> 4) & 0xf;
834
                int b = inst & 0xf;
835
                unsigned av = cpu.asregs.regs[a];
836
                unsigned bv = cpu.asregs.regs[b];
837
                TRACE("mul.l");
838
                cpu.asregs.regs[a] = av * bv;
839
              }
840
              break;
841
            case 0x30: /* swi */
842
              {
843
                unsigned int inum = EXTRACT_WORD(pc+2);
844
                TRACE("swi");
845
                /* Set the special registers appropriately.  */
846
                cpu.asregs.sregs[2] = 3; /* MOXIE_EX_SWI */
847
                cpu.asregs.sregs[3] = inum;
848
                switch (inum)
849
                  {
850
                  case 0x1: /* SYS_exit */
851
                    {
852
                      cpu.asregs.exception = SIGQUIT;
853
                      break;
854
                    }
855
                  case 0x2: /* SYS_open */
856
                    {
857
                      char fname[1024];
858
                      int mode = (int) convert_target_flags ((unsigned) cpu.asregs.regs[3]);
859
                      int perm = (int) cpu.asregs.regs[4];
860
                      int fd = open (fname, mode, perm);
861
                      sim_core_read_buffer (sd, scpu, read_map, fname,
862
                                            cpu.asregs.regs[2], 1024);
863
                      /* FIXME - set errno */
864
                      cpu.asregs.regs[2] = fd;
865
                      break;
866
                    }
867
                  case 0x4: /* SYS_read */
868
                    {
869
                      int fd = cpu.asregs.regs[2];
870
                      unsigned len = (unsigned) cpu.asregs.regs[4];
871
                      char *buf = malloc (len);
872
                      cpu.asregs.regs[2] = read (fd, buf, len);
873
                      sim_core_write_buffer (sd, scpu, write_map, buf,
874
                                             cpu.asregs.regs[3], len);
875
                      free (buf);
876
                      break;
877
                    }
878
                  case 0x5: /* SYS_write */
879
                    {
880
                      char *str;
881
                      /* String length is at 0x12($fp) */
882
                      unsigned count, len = (unsigned) cpu.asregs.regs[4];
883
                      str = malloc (len);
884
                      sim_core_read_buffer (sd, scpu, read_map, str,
885
                                            cpu.asregs.regs[3], len);
886
                      count = write (cpu.asregs.regs[2], str, len);
887
                      free (str);
888
                      cpu.asregs.regs[2] = count;
889
                      break;
890
                    }
891
                  case 0xffffffff: /* Linux System Call */
892
                    {
893
                      unsigned int handler = cpu.asregs.sregs[1];
894
                      unsigned int sp = cpu.asregs.regs[1];
895
 
896
                      /* Save a slot for the static chain.  */
897
                      sp -= 4;
898
 
899
                      /* Push the return address.  */
900
                      sp -= 4;
901
                      wlat (scpu, opc, sp, pc + 6);
902
 
903
                      /* Push the current frame pointer.  */
904
                      sp -= 4;
905
                      wlat (scpu, opc, sp, cpu.asregs.regs[0]);
906
 
907
                      /* Uncache the stack pointer and set the fp & pc.  */
908
                      cpu.asregs.regs[1] = sp;
909
                      cpu.asregs.regs[0] = sp;
910
                      pc = handler - 6;
911
                    }
912
                  default:
913
                    break;
914
                  }
915
                pc += 4;
916
              }
917
              break;
918
            case 0x31: /* div.l */
919
              {
920
                int a = (inst >> 4) & 0xf;
921
                int b = inst & 0xf;
922
                int av = cpu.asregs.regs[a];
923
                int bv = cpu.asregs.regs[b];
924
                TRACE("div.l");
925
                cpu.asregs.regs[a] = av / bv;
926
              }
927
              break;
928
            case 0x32: /* udiv.l */
929
              {
930
                int a = (inst >> 4) & 0xf;
931
                int b = inst & 0xf;
932
                unsigned int av = cpu.asregs.regs[a];
933
                unsigned int bv = cpu.asregs.regs[b];
934
                TRACE("udiv.l");
935
                cpu.asregs.regs[a] = (av / bv);
936
              }
937
              break;
938
            case 0x33: /* mod.l */
939
              {
940
                int a = (inst >> 4) & 0xf;
941
                int b = inst & 0xf;
942
                int av = cpu.asregs.regs[a];
943
                int bv = cpu.asregs.regs[b];
944
                TRACE("mod.l");
945
                cpu.asregs.regs[a] = av % bv;
946
              }
947
              break;
948
            case 0x34: /* umod.l */
949
              {
950
                int a = (inst >> 4) & 0xf;
951
                int b = inst & 0xf;
952
                unsigned int av = cpu.asregs.regs[a];
953
                unsigned int bv = cpu.asregs.regs[b];
954
                TRACE("umod.l");
955
                cpu.asregs.regs[a] = (av % bv);
956
              }
957
              break;
958
            case 0x35: /* brk */
959
              TRACE("brk");
960
              cpu.asregs.exception = SIGTRAP;
961
              pc -= 2; /* Adjust pc */
962
              break;
963
            case 0x36: /* ldo.b */
964
              {
965
                unsigned int addr = EXTRACT_WORD(pc+2);
966
                int a = (inst >> 4) & 0xf;
967
                int b = inst & 0xf;
968
                TRACE("ldo.b");
969
                addr += cpu.asregs.regs[b];
970
                cpu.asregs.regs[a] = rbat (scpu, opc, addr);
971
                pc += 4;
972
              }
973
              break;
974
            case 0x37: /* sto.b */
975
              {
976
                unsigned int addr = EXTRACT_WORD(pc+2);
977
                int a = (inst >> 4) & 0xf;
978
                int b = inst & 0xf;
979
                TRACE("sto.b");
980
                addr += cpu.asregs.regs[a];
981
                wbat (scpu, opc, addr, cpu.asregs.regs[b]);
982
                pc += 4;
983
              }
984
              break;
985
            case 0x38: /* ldo.s */
986
              {
987
                unsigned int addr = EXTRACT_WORD(pc+2);
988
                int a = (inst >> 4) & 0xf;
989
                int b = inst & 0xf;
990
                TRACE("ldo.s");
991
                addr += cpu.asregs.regs[b];
992
                cpu.asregs.regs[a] = rsat (scpu, opc, addr);
993
                pc += 4;
994
              }
995
              break;
996
            case 0x39: /* sto.s */
997
              {
998
                unsigned int addr = EXTRACT_WORD(pc+2);
999
                int a = (inst >> 4) & 0xf;
1000
                int b = inst & 0xf;
1001
                TRACE("sto.s");
1002
                addr += cpu.asregs.regs[a];
1003
                wsat (scpu, opc, addr, cpu.asregs.regs[b]);
1004
                pc += 4;
1005
              }
1006
              break;
1007
            default:
1008
              opc = opcode;
1009
              TRACE("SIGILL1");
1010
              cpu.asregs.exception = SIGILL;
1011
              break;
1012
            }
1013
        }
1014
 
1015
      insts++;
1016
      pc += 2;
1017
 
1018
    } while (!cpu.asregs.exception);
1019
 
1020
  /* Hide away the things we've cached while executing.  */
1021
  cpu.asregs.regs[PC_REGNO] = pc;
1022
  cpu.asregs.insts += insts;            /* instructions done ... */
1023
 
1024
  signal (SIGINT, sigsave);
1025
}
1026
 
1027
int
1028
sim_write (sd, addr, buffer, size)
1029
     SIM_DESC sd;
1030
     SIM_ADDR addr;
1031
     const unsigned char * buffer;
1032
     int size;
1033
{
1034
  sim_cpu *scpu = STATE_CPU (sd, 0); /* FIXME */
1035
 
1036
  sim_core_write_buffer (sd, scpu, write_map, buffer, addr, size);
1037
 
1038
  return size;
1039
}
1040
 
1041
int
1042
sim_read (sd, addr, buffer, size)
1043
     SIM_DESC sd;
1044
     SIM_ADDR addr;
1045
     unsigned char * buffer;
1046
     int size;
1047
{
1048
  sim_cpu *scpu = STATE_CPU (sd, 0); /* FIXME */
1049
 
1050
  sim_core_read_buffer (sd, scpu, read_map, buffer, addr, size);
1051
 
1052
  return size;
1053
}
1054
 
1055
 
1056
int
1057
sim_store_register (sd, rn, memory, length)
1058
     SIM_DESC sd;
1059
     int rn;
1060
     unsigned char * memory;
1061
     int length;
1062
{
1063
  if (rn < NUM_MOXIE_REGS && rn >= 0)
1064
    {
1065
      if (length == 4)
1066
        {
1067
          long ival;
1068
 
1069
          /* misalignment safe */
1070
          ival = moxie_extract_unsigned_integer (memory, 4);
1071
          cpu.asints[rn] = ival;
1072
        }
1073
 
1074
      return 4;
1075
    }
1076
  else
1077
    return 0;
1078
}
1079
 
1080
int
1081
sim_fetch_register (sd, rn, memory, length)
1082
     SIM_DESC sd;
1083
     int rn;
1084
     unsigned char * memory;
1085
     int length;
1086
{
1087
  if (rn < NUM_MOXIE_REGS && rn >= 0)
1088
    {
1089
      if (length == 4)
1090
        {
1091
          long ival = cpu.asints[rn];
1092
 
1093
          /* misalignment-safe */
1094
          moxie_store_unsigned_integer (memory, 4, ival);
1095
        }
1096
 
1097
      return 4;
1098
    }
1099
  else
1100
    return 0;
1101
}
1102
 
1103
 
1104
int
1105
sim_trace (sd)
1106
     SIM_DESC sd;
1107
{
1108
  if (tracefile == 0)
1109
    tracefile = fopen("trace.csv", "wb");
1110
 
1111
  tracing = 1;
1112
 
1113
  sim_resume (sd, 0, 0);
1114
 
1115
  tracing = 0;
1116
 
1117
  return 1;
1118
}
1119
 
1120
void
1121
sim_stop_reason (sd, reason, sigrc)
1122
     SIM_DESC sd;
1123
     enum sim_stop * reason;
1124
     int * sigrc;
1125
{
1126
  if (cpu.asregs.exception == SIGQUIT)
1127
    {
1128
      * reason = sim_exited;
1129
      * sigrc = cpu.asregs.regs[2];
1130
    }
1131
  else
1132
    {
1133
      * reason = sim_stopped;
1134
      * sigrc = cpu.asregs.exception;
1135
    }
1136
}
1137
 
1138
 
1139
int
1140
sim_stop (sd)
1141
     SIM_DESC sd;
1142
{
1143
  cpu.asregs.exception = SIGINT;
1144
  return 1;
1145
}
1146
 
1147
 
1148
void
1149
sim_info (sd, verbose)
1150
     SIM_DESC sd;
1151
     int verbose;
1152
{
1153
  callback->printf_filtered (callback, "\n\n# instructions executed  %llu\n",
1154
                             cpu.asregs.insts);
1155
}
1156
 
1157
 
1158
SIM_DESC
1159
sim_open (kind, cb, abfd, argv)
1160
     SIM_OPEN_KIND kind;
1161
     host_callback * cb;
1162
     struct bfd * abfd;
1163
     char ** argv;
1164
{
1165
  SIM_DESC sd = sim_state_alloc (kind, cb);
1166
  printf ("0x%x 0x%x\n", sd, STATE_MAGIC(sd));
1167
  SIM_ASSERT (STATE_MAGIC (sd) == SIM_MAGIC_NUMBER);
1168
 
1169
  if (sim_pre_argv_init (sd, argv[0]) != SIM_RC_OK)
1170
    return 0;
1171
 
1172
  sim_do_command(sd," memory region 0x00000000,0x4000000") ;
1173
  sim_do_command(sd," memory region 0xE0000000,0x10000") ;
1174
 
1175
  myname = argv[0];
1176
  callback = cb;
1177
 
1178
  if (kind == SIM_OPEN_STANDALONE)
1179
    issue_messages = 1;
1180
 
1181
  set_initial_gprs ();  /* Reset the GPR registers.  */
1182
 
1183
  /* Configure/verify the target byte order and other runtime
1184
     configuration options.  */
1185
  if (sim_config (sd) != SIM_RC_OK)
1186
    {
1187
      sim_module_uninstall (sd);
1188
      return 0;
1189
    }
1190
 
1191
  if (sim_post_argv_init (sd) != SIM_RC_OK)
1192
    {
1193
      /* Uninstall the modules to avoid memory leaks,
1194
         file descriptor leaks, etc.  */
1195
      sim_module_uninstall (sd);
1196
      return 0;
1197
    }
1198
 
1199
  return sd;
1200
}
1201
 
1202
void
1203
sim_close (sd, quitting)
1204
     SIM_DESC sd;
1205
     int quitting;
1206
{
1207
  /* nothing to do */
1208
}
1209
 
1210
 
1211
/* Load the device tree blob.  */
1212
 
1213
static void
1214
load_dtb (SIM_DESC sd, const char *filename)
1215
{
1216
  int size = 0;
1217
  FILE *f = fopen (filename, "rb");
1218
  char *buf;
1219
  sim_cpu *scpu = STATE_CPU (sd, 0); /* FIXME */
1220
 if (f == NULL)
1221
    {
1222
      printf ("WARNING: ``%s'' could not be opened.\n", filename);
1223
      return;
1224
    }
1225
  fseek (f, 0, SEEK_END);
1226
  size = ftell(f);
1227
  fseek (f, 0, SEEK_SET);
1228
  buf = alloca (size);
1229
  if (size != fread (buf, 1, size, f))
1230
    {
1231
      printf ("ERROR: error reading ``%s''.\n", filename);
1232
      return;
1233
    }
1234
  sim_core_write_buffer (sd, scpu, write_map, buf, 0xE0000000, size);
1235
  cpu.asregs.sregs[9] = 0xE0000000;
1236
  fclose (f);
1237
}
1238
 
1239
SIM_RC
1240
sim_load (sd, prog, abfd, from_tty)
1241
     SIM_DESC sd;
1242
     char * prog;
1243
     bfd * abfd;
1244
     int from_tty;
1245
{
1246
 
1247
  /* Do the right thing for ELF executables; this turns out to be
1248
     just about the right thing for any object format that:
1249
       - we crack using BFD routines
1250
       - follows the traditional UNIX text/data/bss layout
1251
       - calls the bss section ".bss".   */
1252
 
1253
  extern bfd * sim_load_file (); /* ??? Don't know where this should live.  */
1254
  bfd * prog_bfd;
1255
 
1256
  {
1257
    bfd * handle;
1258
    handle = bfd_openr (prog, 0);        /* could be "moxie" */
1259
 
1260
    if (!handle)
1261
      {
1262
        printf("``%s'' could not be opened.\n", prog);
1263
        return SIM_RC_FAIL;
1264
      }
1265
 
1266
    /* Makes sure that we have an object file, also cleans gets the
1267
       section headers in place.  */
1268
    if (!bfd_check_format (handle, bfd_object))
1269
      {
1270
        /* wasn't an object file */
1271
        bfd_close (handle);
1272
        printf ("``%s'' is not appropriate object file.\n", prog);
1273
        return SIM_RC_FAIL;
1274
      }
1275
 
1276
    /* Clean up after ourselves.  */
1277
    bfd_close (handle);
1278
  }
1279
 
1280
  /* from sh -- dac */
1281
  prog_bfd = sim_load_file (sd, myname, callback, prog, abfd,
1282
                            sim_kind == SIM_OPEN_DEBUG,
1283
                            0, sim_write);
1284
  if (prog_bfd == NULL)
1285
    return SIM_RC_FAIL;
1286
 
1287
  if (abfd == NULL)
1288
    bfd_close (prog_bfd);
1289
 
1290
  return SIM_RC_OK;
1291
}
1292
 
1293
SIM_RC
1294
sim_create_inferior (sd, prog_bfd, argv, env)
1295
     SIM_DESC sd;
1296
     struct bfd * prog_bfd;
1297
     char ** argv;
1298
     char ** env;
1299
{
1300
  char ** avp;
1301
  int l, argc, i, tp;
1302
  sim_cpu *scpu = STATE_CPU (sd, 0); /* FIXME */
1303
 
1304
  /* Set the initial register set.  */
1305
  l = issue_messages;
1306
  issue_messages = 0;
1307
  set_initial_gprs ();
1308
  issue_messages = l;
1309
 
1310
  if (prog_bfd != NULL)
1311
    cpu.asregs.regs[PC_REGNO] = bfd_get_start_address (prog_bfd);
1312
 
1313
  /* Copy args into target memory.  */
1314
  avp = argv;
1315
  for (argc = 0; avp && *avp; avp++)
1316
    argc++;
1317
 
1318
  /* Target memory looks like this:
1319
     0x00000000 zero word
1320
     0x00000004 argc word
1321
     0x00000008 start of argv
1322
     .
1323
     0x0000???? end of argv
1324
     0x0000???? zero word
1325
     0x0000???? start of data pointed to by argv  */
1326
 
1327
  wlat (scpu, 0, 0, 0);
1328
  wlat (scpu, 0, 4, argc);
1329
 
1330
  /* tp is the offset of our first argv data.  */
1331
  tp = 4 + 4 + argc * 4 + 4;
1332
 
1333
  for (i = 0; i < argc; i++)
1334
    {
1335
      /* Set the argv value.  */
1336
      wlat (scpu, 0, 4 + 4 + i * 4, tp);
1337
 
1338
      /* Store the string.  */
1339
      sim_core_write_buffer (sd, scpu, write_map, argv[i],
1340
                             tp, strlen(argv[i])+1);
1341
      tp += strlen (argv[i]) + 1;
1342
    }
1343
 
1344
  wlat (scpu, 0, 4 + 4 + i * 4, 0);
1345
 
1346
  load_dtb (sd, DTB);
1347
 
1348
  return SIM_RC_OK;
1349
}
1350
 
1351
void
1352
sim_kill (sd)
1353
     SIM_DESC sd;
1354
{
1355
  if (tracefile)
1356
    fclose(tracefile);
1357
}
1358
 
1359
void
1360
sim_do_command (sd, cmd)
1361
     SIM_DESC sd;
1362
     char * cmd;
1363
{
1364
  if (sim_args_command (sd, cmd) != SIM_RC_OK)
1365
    sim_io_printf (sd,
1366
                   "Error: \"%s\" is not a valid moxie simulator command.\n",
1367
                   cmd);
1368
}
1369
 
1370
void
1371
sim_set_callbacks (ptr)
1372
     host_callback * ptr;
1373
{
1374
  callback = ptr;
1375
}

powered by: WebSVN 2.1.0

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