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

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-old/] [gdb-7.1/] [sim/] [mcore/] [interp.c] - Blame information for rev 824

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

Line No. Rev Author Line
1 227 jeremybenn
/* Simulator for Motorola's MCore processor
2
   Copyright (C) 1999, 2000, 2002, 2003, 2007, 2008, 2009, 2010
3
   Free Software Foundation, Inc.
4
   Contributed by Cygnus Solutions.
5
 
6
This file is part of GDB, the GNU debugger.
7
 
8
This program is free software; you can redistribute it and/or modify
9
it under the terms of the GNU General Public License as published by
10
the Free Software Foundation; either version 3 of the License, or
11
(at your option) any later version.
12
 
13
This program is distributed in the hope that it will be useful,
14
but WITHOUT ANY WARRANTY; without even the implied warranty of
15
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16
GNU General Public License for more details.
17
 
18
You should have received a copy of the GNU General Public License
19
along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
20
 
21
#include <signal.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
#ifndef NUM_ELEM
32
#define NUM_ELEM(A) (sizeof (A) / sizeof (A)[0])
33
#endif
34
 
35
 
36
typedef long int           word;
37
typedef unsigned long int  uword;
38
 
39
static int            target_big_endian = 0;
40
static unsigned long  heap_ptr = 0;
41
host_callback *       callback;
42
 
43
 
44
unsigned long
45
mcore_extract_unsigned_integer (addr, len)
46
     unsigned char * addr;
47
     int len;
48
{
49
  unsigned long retval;
50
  unsigned char * p;
51
  unsigned char * startaddr = (unsigned char *)addr;
52
  unsigned char * endaddr = startaddr + len;
53
 
54
  if (len > (int) sizeof (unsigned long))
55
    printf ("That operation is not available on integers of more than %d bytes.",
56
            sizeof (unsigned long));
57
 
58
  /* Start at the most significant end of the integer, and work towards
59
     the least significant.  */
60
  retval = 0;
61
 
62
  if (! target_big_endian)
63
    {
64
      for (p = endaddr; p > startaddr;)
65
        retval = (retval << 8) | * -- p;
66
    }
67
  else
68
    {
69
      for (p = startaddr; p < endaddr;)
70
        retval = (retval << 8) | * p ++;
71
    }
72
 
73
  return retval;
74
}
75
 
76
void
77
mcore_store_unsigned_integer (addr, len, val)
78
     unsigned char * addr;
79
     int len;
80
     unsigned long val;
81
{
82
  unsigned char * p;
83
  unsigned char * startaddr = (unsigned char *)addr;
84
  unsigned char * endaddr = startaddr + len;
85
 
86
  if (! target_big_endian)
87
    {
88
      for (p = startaddr; p < endaddr;)
89
        {
90
          * p ++ = val & 0xff;
91
          val >>= 8;
92
        }
93
    }
94
  else
95
    {
96
      for (p = endaddr; p > startaddr;)
97
        {
98
          * -- p = val & 0xff;
99
          val >>= 8;
100
        }
101
    }
102
}
103
 
104
/* The machine state.
105
   This state is maintained in host byte order.  The
106
   fetch/store register functions must translate between host
107
   byte order and the target processor byte order.
108
   Keeping this data in target byte order simplifies the register
109
   read/write functions.  Keeping this data in native order improves
110
   the performance of the simulator.  Simulation speed is deemed more
111
   important.  */
112
 
113
/* The ordering of the mcore_regset structure is matched in the
114
   gdb/config/mcore/tm-mcore.h file in the REGISTER_NAMES macro.  */
115
struct mcore_regset
116
{
117
  word            gregs [16];           /* primary registers */
118
  word            alt_gregs [16];       /* alt register file */
119
  word            cregs [32];           /* control registers */
120
  word            pc;                   /* the pc */
121
  int             ticks;
122
  int             stalls;
123
  int             cycles;
124
  int             insts;
125
  int             exception;
126
  unsigned long   msize;
127
  unsigned char * memory;
128
  word *          active_gregs;
129
};
130
 
131
union
132
{
133
  struct mcore_regset asregs;
134
  word asints [1];              /* but accessed larger... */
135
} cpu;
136
 
137
#define LAST_VALID_CREG 32              /* only 0..12 implemented */
138
#define NUM_MCORE_REGS  (16 + 16 + LAST_VALID_CREG + 1)
139
 
140
int memcycles = 1;
141
 
142
static SIM_OPEN_KIND sim_kind;
143
static char * myname;
144
 
145
static int issue_messages = 0;
146
 
147
#define gr      asregs.active_gregs
148
#define cr      asregs.cregs
149
#define sr      asregs.cregs[0]
150
#define vbr     asregs.cregs[1]
151
#define esr     asregs.cregs[2]
152
#define fsr     asregs.cregs[3]
153
#define epc     asregs.cregs[4]
154
#define fpc     asregs.cregs[5]
155
#define ss0     asregs.cregs[6]
156
#define ss1     asregs.cregs[7]
157
#define ss2     asregs.cregs[8]
158
#define ss3     asregs.cregs[9]
159
#define ss4     asregs.cregs[10]
160
#define gcr     asregs.cregs[11]
161
#define gsr     asregs.cregs[12]
162
#define mem     asregs.memory
163
 
164
/* maniuplate the carry bit */
165
#define C_ON()   (cpu.sr & 1)
166
#define C_VALUE() (cpu.sr & 1)
167
#define C_OFF()  ((cpu.sr & 1) == 0)
168
#define SET_C()  {cpu.sr |= 1;}
169
#define CLR_C()  {cpu.sr &= 0xfffffffe;}
170
#define NEW_C(v) {CLR_C(); cpu.sr |= ((v) & 1);}
171
 
172
#define SR_AF() ((cpu.sr >> 1) & 1)
173
 
174
#define TRAPCODE        1       /* r1 holds which function we want */
175
#define PARM1   2               /* first parameter  */
176
#define PARM2   3
177
#define PARM3   4
178
#define PARM4   5
179
#define RET1    2               /* register for return values. */
180
 
181
long
182
int_sbrk (inc_bytes)
183
     int inc_bytes;
184
{
185
  long addr;
186
 
187
  addr = heap_ptr;
188
 
189
  heap_ptr += inc_bytes;
190
 
191
  if (issue_messages && heap_ptr>cpu.gr[0])
192
    fprintf (stderr, "Warning: heap_ptr overlaps stack!\n");
193
 
194
  return addr;
195
}
196
 
197
static void INLINE
198
wbat (x, v)
199
     word x, v;
200
{
201
  if (((uword)x) >= cpu.asregs.msize)
202
    {
203
      if (issue_messages)
204
        fprintf (stderr, "byte write to 0x%x outside memory range\n", x);
205
 
206
      cpu.asregs.exception = SIGSEGV;
207
    }
208
  else
209
    {
210
      unsigned char *p = cpu.mem + x;
211
      p[0] = v;
212
    }
213
}
214
 
215
static void INLINE
216
wlat (x, v)
217
     word x, v;
218
{
219
  if (((uword)x) >= cpu.asregs.msize)
220
    {
221
      if (issue_messages)
222
        fprintf (stderr, "word write to 0x%x outside memory range\n", x);
223
 
224
      cpu.asregs.exception = SIGSEGV;
225
    }
226
  else
227
    {
228
      if ((x & 3) != 0)
229
        {
230
          if (issue_messages)
231
            fprintf (stderr, "word write to unaligned memory address: 0x%x\n", x);
232
 
233
          cpu.asregs.exception = SIGBUS;
234
        }
235
      else if (! target_big_endian)
236
        {
237
          unsigned char * p = cpu.mem + x;
238
          p[3] = v >> 24;
239
          p[2] = v >> 16;
240
          p[1] = v >> 8;
241
          p[0] = v;
242
        }
243
      else
244
        {
245
          unsigned char * p = cpu.mem + x;
246
          p[0] = v >> 24;
247
          p[1] = v >> 16;
248
          p[2] = v >> 8;
249
          p[3] = v;
250
        }
251
    }
252
}
253
 
254
static void INLINE
255
what (x, v)
256
     word x, v;
257
{
258
  if (((uword)x) >= cpu.asregs.msize)
259
    {
260
      if (issue_messages)
261
        fprintf (stderr, "short write to 0x%x outside memory range\n", x);
262
 
263
      cpu.asregs.exception = SIGSEGV;
264
    }
265
  else
266
    {
267
      if ((x & 1) != 0)
268
        {
269
          if (issue_messages)
270
            fprintf (stderr, "short write to unaligned memory address: 0x%x\n",
271
                     x);
272
 
273
          cpu.asregs.exception = SIGBUS;
274
        }
275
      else if (! target_big_endian)
276
        {
277
          unsigned char * p = cpu.mem + x;
278
          p[1] = v >> 8;
279
          p[0] = v;
280
        }
281
      else
282
        {
283
          unsigned char * p = cpu.mem + x;
284
          p[0] = v >> 8;
285
          p[1] = v;
286
        }
287
    }
288
}
289
 
290
/* Read functions.  */
291
static int INLINE
292
rbat (x)
293
     word x;
294
{
295
  if (((uword)x) >= cpu.asregs.msize)
296
    {
297
      if (issue_messages)
298
        fprintf (stderr, "byte read from 0x%x outside memory range\n", x);
299
 
300
      cpu.asregs.exception = SIGSEGV;
301
      return 0;
302
    }
303
  else
304
    {
305
      unsigned char * p = cpu.mem + x;
306
      return p[0];
307
    }
308
}
309
 
310
static int INLINE
311
rlat (x)
312
     word x;
313
{
314
  if (((uword) x) >= cpu.asregs.msize)
315
    {
316
      if (issue_messages)
317
        fprintf (stderr, "word read from 0x%x outside memory range\n", x);
318
 
319
      cpu.asregs.exception = SIGSEGV;
320
      return 0;
321
    }
322
  else
323
    {
324
      if ((x & 3) != 0)
325
        {
326
          if (issue_messages)
327
            fprintf (stderr, "word read from unaligned address: 0x%x\n", x);
328
 
329
          cpu.asregs.exception = SIGBUS;
330
          return 0;
331
        }
332
      else if (! target_big_endian)
333
        {
334
          unsigned char * p = cpu.mem + x;
335
          return (p[3] << 24) | (p[2] << 16) | (p[1] << 8) | p[0];
336
        }
337
      else
338
        {
339
          unsigned char * p = cpu.mem + x;
340
          return (p[0] << 24) | (p[1] << 16) | (p[2] << 8) | p[3];
341
        }
342
    }
343
}
344
 
345
static int INLINE
346
rhat (x)
347
     word x;
348
{
349
  if (((uword)x) >= cpu.asregs.msize)
350
    {
351
      if (issue_messages)
352
        fprintf (stderr, "short read from 0x%x outside memory range\n", x);
353
 
354
      cpu.asregs.exception = SIGSEGV;
355
      return 0;
356
    }
357
  else
358
    {
359
      if ((x & 1) != 0)
360
        {
361
          if (issue_messages)
362
            fprintf (stderr, "short read from unaligned address: 0x%x\n", x);
363
 
364
          cpu.asregs.exception = SIGBUS;
365
          return 0;
366
        }
367
      else if (! target_big_endian)
368
        {
369
          unsigned char * p = cpu.mem + x;
370
          return (p[1] << 8) | p[0];
371
        }
372
      else
373
        {
374
          unsigned char * p = cpu.mem + x;
375
          return (p[0] << 8) | p[1];
376
        }
377
    }
378
}
379
 
380
 
381
#define SEXTB(x)        (((x & 0xff) ^ (~ 0x7f)) + 0x80)
382
#define SEXTW(y)        ((int)((short)y))
383
 
384
static int
385
IOMEM (addr, write, value)
386
     int addr;
387
     int write;
388
     int value;
389
{
390
}
391
 
392
/* Default to a 8 Mbyte (== 2^23) memory space.  */
393
static int sim_memory_size = 23;
394
 
395
#define MEM_SIZE_FLOOR  64
396
void
397
sim_size (power)
398
     int power;
399
{
400
  sim_memory_size = power;
401
  cpu.asregs.msize = 1 << sim_memory_size;
402
 
403
  if (cpu.mem)
404
    free (cpu.mem);
405
 
406
  /* Watch out for the '0 count' problem. There's probably a better
407
     way.. e.g., why do we use 64 here?  */
408
  if (cpu.asregs.msize < 64)    /* Ensure a boundary.  */
409
    cpu.mem = (unsigned char *) calloc (64, (64 + cpu.asregs.msize) / 64);
410
  else
411
    cpu.mem = (unsigned char *) calloc (64, cpu.asregs.msize / 64);
412
 
413
  if (!cpu.mem)
414
    {
415
      if (issue_messages)
416
        fprintf (stderr,
417
                 "Not enough VM for simulation of %d bytes of RAM\n",
418
                 cpu.asregs.msize);
419
 
420
      cpu.asregs.msize = 1;
421
      cpu.mem = (unsigned char *) calloc (1, 1);
422
    }
423
}
424
 
425
static void
426
init_pointers ()
427
{
428
  if (cpu.asregs.msize != (1 << sim_memory_size))
429
    sim_size (sim_memory_size);
430
}
431
 
432
static void
433
set_initial_gprs ()
434
{
435
  int i;
436
  long space;
437
  unsigned long memsize;
438
 
439
  init_pointers ();
440
 
441
  /* Set up machine just out of reset.  */
442
  cpu.asregs.pc = 0;
443
  cpu.sr = 0;
444
 
445
  memsize = cpu.asregs.msize / (1024 * 1024);
446
 
447
  if (issue_messages > 1)
448
    fprintf (stderr, "Simulated memory of %d Mbytes (0x0 .. 0x%08x)\n",
449
             memsize, cpu.asregs.msize - 1);
450
 
451
  /* Clean out the GPRs and alternate GPRs.  */
452
  for (i = 0; i < 16; i++)
453
    {
454
      cpu.asregs.gregs[i] = 0;
455
      cpu.asregs.alt_gregs[i] = 0;
456
    }
457
 
458
  /* Make our register set point to the right place.  */
459
  if (SR_AF())
460
    cpu.asregs.active_gregs = &cpu.asregs.alt_gregs[0];
461
  else
462
    cpu.asregs.active_gregs = &cpu.asregs.gregs[0];
463
 
464
  /* ABI specifies initial values for these registers.  */
465
  cpu.gr[0] = cpu.asregs.msize - 4;
466
 
467
  /* dac fix, the stack address must be 8-byte aligned! */
468
  cpu.gr[0] = cpu.gr[0] - cpu.gr[0] % 8;
469
  cpu.gr[PARM1] = 0;
470
  cpu.gr[PARM2] = 0;
471
  cpu.gr[PARM3] = 0;
472
  cpu.gr[PARM4] = cpu.gr[0];
473
}
474
 
475
static void
476
interrupt ()
477
{
478
  cpu.asregs.exception = SIGINT;
479
}
480
 
481
/* Functions so that trapped open/close don't interfere with the
482
   parent's functions.  We say that we can't close the descriptors
483
   that we didn't open.  exit() and cleanup() get in trouble here,
484
   to some extent.  That's the price of emulation.  */
485
 
486
unsigned char opened[100];
487
 
488
static void
489
log_open (fd)
490
    int fd;
491
{
492
  if (fd < 0 || fd > NUM_ELEM (opened))
493
    return;
494
 
495
  opened[fd] = 1;
496
}
497
 
498
static void
499
log_close (fd)
500
     int fd;
501
{
502
  if (fd < 0 || fd > NUM_ELEM (opened))
503
    return;
504
 
505
  opened[fd] = 0;
506
}
507
 
508
static int
509
is_opened (fd)
510
    int fd;
511
{
512
  if (fd < 0 || fd > NUM_ELEM (opened))
513
    return 0;
514
 
515
  return opened[fd];
516
}
517
 
518
static void
519
handle_trap1 ()
520
{
521
  unsigned long a[3];
522
 
523
  switch ((unsigned long) (cpu.gr [TRAPCODE]))
524
    {
525
    case 3:
526
      a[0] = (unsigned long) (cpu.gr[PARM1]);
527
      a[1] = (unsigned long) (cpu.mem + cpu.gr[PARM2]);
528
      a[2] = (unsigned long) (cpu.gr[PARM3]);
529
      cpu.gr[RET1] = callback->read (callback, a[0], (char *) a[1], a[2]);
530
      break;
531
 
532
    case 4:
533
      a[0] = (unsigned long) (cpu.gr[PARM1]);
534
      a[1] = (unsigned long) (cpu.mem + cpu.gr[PARM2]);
535
      a[2] = (unsigned long) (cpu.gr[PARM3]);
536
      cpu.gr[RET1] = (int)callback->write (callback, a[0], (char *) a[1], a[2]);
537
      break;
538
 
539
    case 5:
540
      a[0] = (unsigned long) (cpu.mem + cpu.gr[PARM1]);
541
      a[1] = (unsigned long) (cpu.gr[PARM2]);
542
      /* a[2] = (unsigned long) (cpu.gr[PARM3]); */
543
      cpu.gr[RET1] = callback->open (callback, (char *) a[0], a[1]);
544
      log_open (cpu.gr[RET1]);
545
      break;
546
 
547
    case 6:
548
      a[0] = (unsigned long) (cpu.gr[PARM1]);
549
      /* Watch out for debugger's files. */
550
      if (is_opened (a[0]))
551
        {
552
          log_close (a[0]);
553
          cpu.gr[RET1] = callback->close (callback, a[0]);
554
        }
555
      else
556
        {
557
          /* Don't let him close it.  */
558
          cpu.gr[RET1] = (-1);
559
        }
560
      break;
561
 
562
    case 9:
563
      a[0] = (unsigned long) (cpu.mem + cpu.gr[PARM1]);
564
      a[1] = (unsigned long) (cpu.mem + cpu.gr[PARM2]);
565
      cpu.gr[RET1] = link ((char *) a[0], (char *) a[1]);
566
      break;
567
 
568
    case 10:
569
      a[0] = (unsigned long) (cpu.mem + cpu.gr[PARM1]);
570
      cpu.gr[RET1] = callback->unlink (callback, (char *) a[0]);
571
      break;
572
 
573
    case 13:
574
      /* handle time(0) vs time(&var) */
575
      a[0] = (unsigned long) (cpu.gr[PARM1]);
576
      if (a[0])
577
        a[0] += (unsigned long) cpu.mem;
578
      cpu.gr[RET1] = callback->time (callback, (time_t *) a[0]);
579
      break;
580
 
581
    case 19:
582
      a[0] = (unsigned long) (cpu.gr[PARM1]);
583
      a[1] = (unsigned long) (cpu.gr[PARM2]);
584
      a[2] = (unsigned long) (cpu.gr[PARM3]);
585
      cpu.gr[RET1] = callback->lseek (callback, a[0], a[1], a[2]);
586
      break;
587
 
588
    case 33:
589
      a[0] = (unsigned long) (cpu.mem + cpu.gr[PARM1]);
590
      a[1] = (unsigned long) (cpu.gr[PARM2]);
591
      cpu.gr[RET1] = access ((char *) a[0], a[1]);
592
      break;
593
 
594
    case 43:
595
      a[0] = (unsigned long) (cpu.mem + cpu.gr[PARM1]);
596
#if 0
597
      cpu.gr[RET1] = times ((char *)a[0]);
598
#else
599
      {
600
        /* Give him simulated cycles for utime
601
           and an instruction count for stime. */
602
        struct tms
603
        {
604
          time_t tms_utime;
605
          time_t tms_stime;
606
          time_t tms_cutime;
607
          time_t tms_cstime;
608
        } t;
609
 
610
        t.tms_utime = cpu.asregs.cycles;
611
        t.tms_stime = cpu.asregs.insts;
612
        t.tms_cutime = t.tms_utime;
613
        t.tms_cstime = t.tms_stime;
614
 
615
        memcpy ((struct tms *)(a[0]), &t, sizeof (t));
616
 
617
        cpu.gr[RET1] = cpu.asregs.cycles;
618
      }
619
#endif
620
      break;
621
 
622
    case 69:
623
      a[0] = (unsigned long) (cpu.gr[PARM1]);
624
      cpu.gr[RET1] = int_sbrk (a[0]);
625
      break;
626
 
627
    default:
628
      if (issue_messages)
629
        fprintf (stderr, "WARNING: sys call %d unimplemented\n",
630
                 cpu.gr[TRAPCODE]);
631
      break;
632
    }
633
}
634
 
635
static void
636
process_stub (what)
637
     int what;
638
{
639
  /* These values should match those in libgloss/mcore/syscalls.s.  */
640
  switch (what)
641
    {
642
    case 3:  /* _read */
643
    case 4:  /* _write */
644
    case 5:  /* _open */
645
    case 6:  /* _close */
646
    case 10: /* _unlink */
647
    case 19: /* _lseek */
648
    case 43: /* _times */
649
      cpu.gr [TRAPCODE] = what;
650
      handle_trap1 ();
651
      break;
652
 
653
    default:
654
      if (issue_messages)
655
        fprintf (stderr, "Unhandled stub opcode: %d\n", what);
656
      break;
657
    }
658
}
659
 
660
static void
661
util (what)
662
     unsigned what;
663
{
664
  switch (what)
665
    {
666
    case 0:      /* exit */
667
      cpu.asregs.exception = SIGQUIT;
668
      break;
669
 
670
    case 1:     /* printf */
671
      {
672
        unsigned long a[6];
673
        unsigned char *s;
674
        int i;
675
 
676
        a[0] = (unsigned long)(cpu.mem + cpu.gr[PARM1]);
677
 
678
        for (s = (unsigned char *)a[0], i = 1 ; *s && i < 6 ; s++)
679
          {
680
            if (*s == '%')
681
              {
682
                if (*++s == 's')
683
                  a[i] = (unsigned long)(cpu.mem + cpu.gr[PARM1+i]);
684
                else
685
                  a[i] = cpu.gr[i+PARM1];
686
                i++;
687
              }
688
          }
689
 
690
        cpu.gr[RET1] = printf ((char *)a[0], a[1], a[2], a[3], a[4], a[5]);
691
      }
692
      break;
693
 
694
    case 2:     /* scanf */
695
      if (issue_messages)
696
        fprintf (stderr, "WARNING: scanf unimplemented\n");
697
      break;
698
 
699
    case 3:     /* utime */
700
      cpu.gr[RET1] = cpu.asregs.insts;
701
      break;
702
 
703
    case 0xFF:
704
      process_stub (cpu.gr[1]);
705
      break;
706
 
707
    default:
708
      if (issue_messages)
709
        fprintf (stderr, "Unhandled util code: %x\n", what);
710
      break;
711
    }
712
}
713
 
714
/* For figuring out whether we carried; addc/subc use this. */
715
static int
716
iu_carry (a, b, cin)
717
     unsigned long a;
718
     unsigned long b;
719
     int cin;
720
{
721
  unsigned long x;
722
 
723
  x = (a & 0xffff) + (b & 0xffff) + cin;
724
  x = (x >> 16) + (a >> 16) + (b >> 16);
725
  x >>= 16;
726
 
727
  return (x != 0);
728
}
729
 
730
#define WATCHFUNCTIONS 1
731
#ifdef WATCHFUNCTIONS
732
 
733
#define MAXWL 80
734
word WL[MAXWL];
735
char * WLstr[MAXWL];
736
 
737
int ENDWL=0;
738
int WLincyc;
739
int WLcyc[MAXWL];
740
int WLcnts[MAXWL];
741
int WLmax[MAXWL];
742
int WLmin[MAXWL];
743
word WLendpc;
744
int WLbcyc;
745
int WLW;
746
#endif
747
 
748
#define RD      (inst        & 0xF)
749
#define RS      ((inst >> 4) & 0xF)
750
#define RX      ((inst >> 8) & 0xF)
751
#define IMM5    ((inst >> 4) & 0x1F)
752
#define IMM4    ((inst) & 0xF)
753
 
754
static int tracing = 0;
755
 
756
void
757
sim_resume (sd, step, siggnal)
758
     SIM_DESC sd;
759
     int step, siggnal;
760
{
761
  int needfetch;
762
  word ibuf;
763
  word pc;
764
  unsigned short inst;
765
  void (* sigsave)();
766
  int memops;
767
  int bonus_cycles;
768
  int insts;
769
  int w;
770
  int cycs;
771
  word WLhash;
772
 
773
  sigsave = signal (SIGINT, interrupt);
774
  cpu.asregs.exception = step ? SIGTRAP: 0;
775
  pc = cpu.asregs.pc;
776
 
777
  /* Fetch the initial instructions that we'll decode. */
778
  ibuf = rlat (pc & 0xFFFFFFFC);
779
  needfetch = 0;
780
 
781
  memops = 0;
782
  bonus_cycles = 0;
783
  insts = 0;
784
 
785
  /* make our register set point to the right place */
786
  if (SR_AF ())
787
    cpu.asregs.active_gregs = & cpu.asregs.alt_gregs[0];
788
  else
789
    cpu.asregs.active_gregs = & cpu.asregs.gregs[0];
790
 
791
  /* make a hash to speed exec loop, hope it's nonzero */
792
  WLhash = 0xFFFFFFFF;
793
 
794
  for (w = 1; w <= ENDWL; w++)
795
    WLhash = WLhash & WL[w];
796
 
797
  do
798
    {
799
      word oldpc;
800
 
801
      insts ++;
802
 
803
      if (pc & 02)
804
        {
805
          if (! target_big_endian)
806
            inst = ibuf >> 16;
807
          else
808
            inst = ibuf & 0xFFFF;
809
          needfetch = 1;
810
        }
811
      else
812
        {
813
          if (! target_big_endian)
814
            inst = ibuf & 0xFFFF;
815
          else
816
            inst = ibuf >> 16;
817
        }
818
 
819
#ifdef WATCHFUNCTIONS
820
      /* now scan list of watch addresses, if match, count it and
821
         note return address and count cycles until pc=return address */
822
 
823
      if ((WLincyc == 1) && (pc == WLendpc))
824
        {
825
          cycs = (cpu.asregs.cycles + (insts + bonus_cycles +
826
                                       (memops * memcycles)) - WLbcyc);
827
 
828
          if (WLcnts[WLW] == 1)
829
            {
830
              WLmax[WLW] = cycs;
831
              WLmin[WLW] = cycs;
832
              WLcyc[WLW] = 0;
833
            }
834
 
835
          if (cycs > WLmax[WLW])
836
            {
837
              WLmax[WLW] = cycs;
838
            }
839
 
840
          if (cycs < WLmin[WLW])
841
            {
842
              WLmin[WLW] = cycs;
843
            }
844
 
845
          WLcyc[WLW] += cycs;
846
          WLincyc = 0;
847
          WLendpc = 0;
848
        }
849
 
850
      /* Optimize with a hash to speed loop.  */
851
      if (WLincyc == 0)
852
        {
853
          if ((WLhash == 0) || ((WLhash & pc) != 0))
854
            {
855
              for (w=1; w <= ENDWL; w++)
856
                {
857
                  if (pc == WL[w])
858
                    {
859
                      WLcnts[w]++;
860
                      WLbcyc = cpu.asregs.cycles + insts
861
                        + bonus_cycles + (memops * memcycles);
862
                      WLendpc = cpu.gr[15];
863
                      WLincyc = 1;
864
                      WLW = w;
865
                      break;
866
                    }
867
                }
868
            }
869
        }
870
#endif
871
 
872
      if (tracing)
873
        fprintf (stderr, "%.4x: inst = %.4x ", pc, inst);
874
 
875
      oldpc = pc;
876
 
877
      pc += 2;
878
 
879
      switch (inst >> 8)
880
        {
881
        case 0x00:
882
          switch RS
883
            {
884
            case 0x0:
885
              switch RD
886
                {
887
                case 0x0:                               /* bkpt */
888
                  cpu.asregs.exception = SIGTRAP;
889
                  pc -= 2;
890
                  break;
891
 
892
                case 0x1:                               /* sync */
893
                  break;
894
 
895
                case 0x2:                               /* rte */
896
                  pc = cpu.epc;
897
                  cpu.sr = cpu.esr;
898
                  needfetch = 1;
899
 
900
                  if (SR_AF ())
901
                    cpu.asregs.active_gregs = & cpu.asregs.alt_gregs[0];
902
                  else
903
                    cpu.asregs.active_gregs = & cpu.asregs.gregs[0];
904
                  break;
905
 
906
                case 0x3:                               /* rfi */
907
                  pc = cpu.fpc;
908
                  cpu.sr = cpu.fsr;
909
                  needfetch = 1;
910
 
911
                  if (SR_AF ())
912
                    cpu.asregs.active_gregs = &cpu.asregs.alt_gregs[0];
913
                  else
914
                    cpu.asregs.active_gregs = &cpu.asregs.gregs[0];
915
                  break;
916
 
917
                case 0x4:                               /* stop */
918
                  if (issue_messages)
919
                    fprintf (stderr, "WARNING: stop unimplemented\n");
920
                  break;
921
 
922
                case 0x5:                               /* wait */
923
                  if (issue_messages)
924
                    fprintf (stderr, "WARNING: wait unimplemented\n");
925
                  break;
926
 
927
                case 0x6:                               /* doze */
928
                  if (issue_messages)
929
                    fprintf (stderr, "WARNING: doze unimplemented\n");
930
                  break;
931
 
932
                case 0x7:
933
                  cpu.asregs.exception = SIGILL;        /* illegal */
934
                  break;
935
 
936
                case 0x8:                               /* trap 0 */
937
                case 0xA:                               /* trap 2 */
938
                case 0xB:                               /* trap 3 */
939
                  cpu.asregs.exception = SIGTRAP;
940
                  break;
941
 
942
                case 0xC:                               /* trap 4 */
943
                case 0xD:                               /* trap 5 */
944
                case 0xE:                               /* trap 6 */
945
                  cpu.asregs.exception = SIGILL;        /* illegal */
946
                  break;
947
 
948
                case 0xF:                               /* trap 7 */
949
                  cpu.asregs.exception = SIGTRAP;       /* integer div-by-0 */
950
                  break;
951
 
952
                case 0x9:                               /* trap 1 */
953
                  handle_trap1 ();
954
                  break;
955
                }
956
              break;
957
 
958
            case 0x1:
959
              cpu.asregs.exception = SIGILL;            /* illegal */
960
              break;
961
 
962
            case 0x2:                                   /* mvc */
963
              cpu.gr[RD] = C_VALUE();
964
              break;
965
            case 0x3:                                   /* mvcv */
966
              cpu.gr[RD] = C_OFF();
967
              break;
968
            case 0x4:                                   /* ldq */
969
              {
970
                char *addr = (char *)cpu.gr[RD];
971
                int regno = 4;                  /* always r4-r7 */
972
 
973
                bonus_cycles++;
974
                memops += 4;
975
                do
976
                  {
977
                    cpu.gr[regno] = rlat(addr);
978
                    addr += 4;
979
                    regno++;
980
                  }
981
                while ((regno&0x3) != 0);
982
              }
983
              break;
984
            case 0x5:                                   /* stq */
985
              {
986
                char *addr = (char *)cpu.gr[RD];
987
                int regno = 4;                  /* always r4-r7 */
988
 
989
                memops += 4;
990
                bonus_cycles++;
991
                do
992
                  {
993
                    wlat(addr, cpu.gr[regno]);
994
                    addr += 4;
995
                    regno++;
996
                  }
997
                while ((regno & 0x3) != 0);
998
              }
999
              break;
1000
            case 0x6:                                   /* ldm */
1001
              {
1002
                char *addr = (char *)cpu.gr[0];
1003
                int regno = RD;
1004
 
1005
                /* bonus cycle is really only needed if
1006
                   the next insn shifts the last reg loaded.
1007
 
1008
                   bonus_cycles++;
1009
                */
1010
                memops += 16-regno;
1011
                while (regno <= 0xF)
1012
                  {
1013
                    cpu.gr[regno] = rlat(addr);
1014
                    addr += 4;
1015
                    regno++;
1016
                  }
1017
              }
1018
              break;
1019
            case 0x7:                                   /* stm */
1020
              {
1021
                char *addr = (char *)cpu.gr[0];
1022
                int regno = RD;
1023
 
1024
                /* this should be removed! */
1025
                /*  bonus_cycles ++; */
1026
 
1027
                memops += 16 - regno;
1028
                while (regno <= 0xF)
1029
                  {
1030
                    wlat(addr, cpu.gr[regno]);
1031
                    addr += 4;
1032
                    regno++;
1033
                  }
1034
              }
1035
              break;
1036
 
1037
            case 0x8:                                   /* dect */
1038
              cpu.gr[RD] -= C_VALUE();
1039
              break;
1040
            case 0x9:                                   /* decf */
1041
              cpu.gr[RD] -= C_OFF();
1042
              break;
1043
            case 0xA:                                   /* inct */
1044
              cpu.gr[RD] += C_VALUE();
1045
              break;
1046
            case 0xB:                                   /* incf */
1047
              cpu.gr[RD] += C_OFF();
1048
              break;
1049
            case 0xC:                                   /* jmp */
1050
              pc = cpu.gr[RD];
1051
              if (tracing && RD == 15)
1052
                fprintf (stderr, "Func return, r2 = %x, r3 = %x\n",
1053
                         cpu.gr[2], cpu.gr[3]);
1054
              bonus_cycles++;
1055
              needfetch = 1;
1056
              break;
1057
            case 0xD:                                   /* jsr */
1058
              cpu.gr[15] = pc;
1059
              pc = cpu.gr[RD];
1060
              bonus_cycles++;
1061
              needfetch = 1;
1062
              break;
1063
            case 0xE:                                   /* ff1 */
1064
              {
1065
                word tmp, i;
1066
                tmp = cpu.gr[RD];
1067
                for (i = 0; !(tmp & 0x80000000) && i < 32; i++)
1068
                  tmp <<= 1;
1069
                cpu.gr[RD] = i;
1070
              }
1071
              break;
1072
            case 0xF:                                   /* brev */
1073
              {
1074
                word tmp;
1075
                tmp = cpu.gr[RD];
1076
                tmp = ((tmp & 0xaaaaaaaa) >>  1) | ((tmp & 0x55555555) <<  1);
1077
                tmp = ((tmp & 0xcccccccc) >>  2) | ((tmp & 0x33333333) <<  2);
1078
                tmp = ((tmp & 0xf0f0f0f0) >>  4) | ((tmp & 0x0f0f0f0f) <<  4);
1079
                tmp = ((tmp & 0xff00ff00) >>  8) | ((tmp & 0x00ff00ff) <<  8);
1080
                cpu.gr[RD] = ((tmp & 0xffff0000) >> 16) | ((tmp & 0x0000ffff) << 16);
1081
              }
1082
              break;
1083
            }
1084
          break;
1085
        case 0x01:
1086
          switch RS
1087
            {
1088
            case 0x0:                                   /* xtrb3 */
1089
              cpu.gr[1] = (cpu.gr[RD]) & 0xFF;
1090
              NEW_C (cpu.gr[RD] != 0);
1091
              break;
1092
            case 0x1:                                   /* xtrb2 */
1093
              cpu.gr[1] = (cpu.gr[RD]>>8) & 0xFF;
1094
              NEW_C (cpu.gr[RD] != 0);
1095
              break;
1096
            case 0x2:                                   /* xtrb1 */
1097
              cpu.gr[1] = (cpu.gr[RD]>>16) & 0xFF;
1098
              NEW_C (cpu.gr[RD] != 0);
1099
              break;
1100
            case 0x3:                                   /* xtrb0 */
1101
              cpu.gr[1] = (cpu.gr[RD]>>24) & 0xFF;
1102
              NEW_C (cpu.gr[RD] != 0);
1103
              break;
1104
            case 0x4:                                   /* zextb */
1105
              cpu.gr[RD] &= 0x000000FF;
1106
              break;
1107
            case 0x5:                                   /* sextb */
1108
              {
1109
                long tmp;
1110
                tmp = cpu.gr[RD];
1111
                tmp <<= 24;
1112
                tmp >>= 24;
1113
                cpu.gr[RD] = tmp;
1114
              }
1115
              break;
1116
            case 0x6:                                   /* zexth */
1117
              cpu.gr[RD] &= 0x0000FFFF;
1118
              break;
1119
            case 0x7:                                   /* sexth */
1120
              {
1121
                long tmp;
1122
                tmp = cpu.gr[RD];
1123
                tmp <<= 16;
1124
                tmp >>= 16;
1125
                cpu.gr[RD] = tmp;
1126
              }
1127
              break;
1128
            case 0x8:                                   /* declt */
1129
              --cpu.gr[RD];
1130
              NEW_C ((long)cpu.gr[RD] < 0);
1131
              break;
1132
            case 0x9:                                   /* tstnbz */
1133
              {
1134
                word tmp = cpu.gr[RD];
1135
                NEW_C ((tmp & 0xFF000000) != 0 &&
1136
                       (tmp & 0x00FF0000) != 0 && (tmp & 0x0000FF00) != 0 &&
1137
                       (tmp & 0x000000FF) != 0);
1138
              }
1139
              break;
1140
            case 0xA:                                   /* decgt */
1141
              --cpu.gr[RD];
1142
              NEW_C ((long)cpu.gr[RD] > 0);
1143
              break;
1144
            case 0xB:                                   /* decne */
1145
              --cpu.gr[RD];
1146
              NEW_C ((long)cpu.gr[RD] != 0);
1147
              break;
1148
            case 0xC:                                   /* clrt */
1149
              if (C_ON())
1150
                cpu.gr[RD] = 0;
1151
              break;
1152
            case 0xD:                                   /* clrf */
1153
              if (C_OFF())
1154
                cpu.gr[RD] = 0;
1155
              break;
1156
            case 0xE:                                   /* abs */
1157
              if (cpu.gr[RD] & 0x80000000)
1158
                cpu.gr[RD] = ~cpu.gr[RD] + 1;
1159
              break;
1160
            case 0xF:                                   /* not */
1161
              cpu.gr[RD] = ~cpu.gr[RD];
1162
              break;
1163
            }
1164
          break;
1165
        case 0x02:                                      /* movt */
1166
          if (C_ON())
1167
            cpu.gr[RD] = cpu.gr[RS];
1168
          break;
1169
        case 0x03:                                      /* mult */
1170
          /* consume 2 bits per cycle from rs, until rs is 0 */
1171
          {
1172
            unsigned int t = cpu.gr[RS];
1173
            int ticks;
1174
            for (ticks = 0; t != 0 ; t >>= 2)
1175
              ticks++;
1176
            bonus_cycles += ticks;
1177
          }
1178
          bonus_cycles += 2;  /* min. is 3, so add 2, plus ticks above */
1179
          if (tracing)
1180
            fprintf (stderr, "  mult %x by %x to give %x",
1181
                     cpu.gr[RD], cpu.gr[RS], cpu.gr[RD] * cpu.gr[RS]);
1182
          cpu.gr[RD] = cpu.gr[RD] * cpu.gr[RS];
1183
          break;
1184
        case 0x04:                                      /* loopt */
1185
          if (C_ON())
1186
            {
1187
              pc += (IMM4 << 1) - 32;
1188
              bonus_cycles ++;
1189
              needfetch = 1;
1190
            }
1191
          --cpu.gr[RS];                         /* not RD! */
1192
          NEW_C (((long)cpu.gr[RS]) > 0);
1193
          break;
1194
        case 0x05:                                      /* subu */
1195
          cpu.gr[RD] -= cpu.gr[RS];
1196
          break;
1197
        case 0x06:                                      /* addc */
1198
          {
1199
            unsigned long tmp, a, b;
1200
            a = cpu.gr[RD];
1201
            b = cpu.gr[RS];
1202
            cpu.gr[RD] = a + b + C_VALUE ();
1203
            tmp = iu_carry (a, b, C_VALUE ());
1204
            NEW_C (tmp);
1205
          }
1206
          break;
1207
        case 0x07:                                      /* subc */
1208
          {
1209
            unsigned long tmp, a, b;
1210
            a = cpu.gr[RD];
1211
            b = cpu.gr[RS];
1212
            cpu.gr[RD] = a - b + C_VALUE () - 1;
1213
            tmp = iu_carry (a,~b, C_VALUE ());
1214
            NEW_C (tmp);
1215
          }
1216
          break;
1217
        case 0x08:                                      /* illegal */
1218
        case 0x09:                                      /* illegal*/
1219
          cpu.asregs.exception = SIGILL;
1220
          break;
1221
        case 0x0A:                                      /* movf */
1222
          if (C_OFF())
1223
            cpu.gr[RD] = cpu.gr[RS];
1224
          break;
1225
        case 0x0B:                                      /* lsr */
1226
          {
1227
            unsigned long dst, src;
1228
            dst = cpu.gr[RD];
1229
            src = cpu.gr[RS];
1230
            /* We must not rely solely upon the native shift operations, since they
1231
               may not match the M*Core's behaviour on boundary conditions.  */
1232
            dst = src > 31 ? 0 : dst >> src;
1233
            cpu.gr[RD] = dst;
1234
          }
1235
          break;
1236
        case 0x0C:                                      /* cmphs */
1237
          NEW_C ((unsigned long )cpu.gr[RD] >=
1238
                 (unsigned long)cpu.gr[RS]);
1239
          break;
1240
        case 0x0D:                                      /* cmplt */
1241
          NEW_C ((long)cpu.gr[RD] < (long)cpu.gr[RS]);
1242
          break;
1243
        case 0x0E:                                      /* tst */
1244
          NEW_C ((cpu.gr[RD] & cpu.gr[RS]) != 0);
1245
          break;
1246
        case 0x0F:                                      /* cmpne */
1247
          NEW_C (cpu.gr[RD] != cpu.gr[RS]);
1248
          break;
1249
        case 0x10: case 0x11:                           /* mfcr */
1250
          {
1251
            unsigned r;
1252
            r = IMM5;
1253
            if (r <= LAST_VALID_CREG)
1254
              cpu.gr[RD] = cpu.cr[r];
1255
            else
1256
              cpu.asregs.exception = SIGILL;
1257
          }
1258
          break;
1259
 
1260
        case 0x12:                                      /* mov */
1261
          cpu.gr[RD] = cpu.gr[RS];
1262
          if (tracing)
1263
            fprintf (stderr, "MOV %x into reg %d", cpu.gr[RD], RD);
1264
          break;
1265
 
1266
        case 0x13:                                      /* bgenr */
1267
          if (cpu.gr[RS] & 0x20)
1268
            cpu.gr[RD] = 0;
1269
          else
1270
            cpu.gr[RD] = 1 << (cpu.gr[RS] & 0x1F);
1271
          break;
1272
 
1273
        case 0x14:                                      /* rsub */
1274
          cpu.gr[RD] = cpu.gr[RS] - cpu.gr[RD];
1275
          break;
1276
 
1277
        case 0x15:                                      /* ixw */
1278
          cpu.gr[RD] += cpu.gr[RS]<<2;
1279
          break;
1280
 
1281
        case 0x16:                                      /* and */
1282
          cpu.gr[RD] &= cpu.gr[RS];
1283
          break;
1284
 
1285
        case 0x17:                                      /* xor */
1286
          cpu.gr[RD] ^= cpu.gr[RS];
1287
          break;
1288
 
1289
        case 0x18: case 0x19:                           /* mtcr */
1290
          {
1291
            unsigned r;
1292
            r = IMM5;
1293
            if (r <= LAST_VALID_CREG)
1294
              cpu.cr[r] = cpu.gr[RD];
1295
            else
1296
              cpu.asregs.exception = SIGILL;
1297
 
1298
            /* we might have changed register sets... */
1299
            if (SR_AF ())
1300
              cpu.asregs.active_gregs = & cpu.asregs.alt_gregs[0];
1301
            else
1302
              cpu.asregs.active_gregs = & cpu.asregs.gregs[0];
1303
          }
1304
          break;
1305
 
1306
        case 0x1A:                                      /* asr */
1307
          /* We must not rely solely upon the native shift operations, since they
1308
             may not match the M*Core's behaviour on boundary conditions.  */
1309
          if (cpu.gr[RS] > 30)
1310
            cpu.gr[RD] = ((long) cpu.gr[RD]) < 0 ? -1 : 0;
1311
          else
1312
            cpu.gr[RD] = (long) cpu.gr[RD] >> cpu.gr[RS];
1313
          break;
1314
 
1315
        case 0x1B:                                      /* lsl */
1316
          /* We must not rely solely upon the native shift operations, since they
1317
             may not match the M*Core's behaviour on boundary conditions.  */
1318
          cpu.gr[RD] = cpu.gr[RS] > 31 ? 0 : cpu.gr[RD] << cpu.gr[RS];
1319
          break;
1320
 
1321
        case 0x1C:                                      /* addu */
1322
          cpu.gr[RD] += cpu.gr[RS];
1323
          break;
1324
 
1325
        case 0x1D:                                      /* ixh */
1326
          cpu.gr[RD] += cpu.gr[RS] << 1;
1327
          break;
1328
 
1329
        case 0x1E:                                      /* or */
1330
          cpu.gr[RD] |= cpu.gr[RS];
1331
          break;
1332
 
1333
        case 0x1F:                                      /* andn */
1334
          cpu.gr[RD] &= ~cpu.gr[RS];
1335
          break;
1336
        case 0x20: case 0x21:                           /* addi */
1337
          cpu.gr[RD] =
1338
            cpu.gr[RD] + (IMM5 + 1);
1339
          break;
1340
        case 0x22: case 0x23:                           /* cmplti */
1341
          {
1342
            int tmp = (IMM5 + 1);
1343
            if (cpu.gr[RD] < tmp)
1344
              {
1345
                SET_C();
1346
              }
1347
            else
1348
              {
1349
                CLR_C();
1350
              }
1351
          }
1352
          break;
1353
        case 0x24: case 0x25:                           /* subi */
1354
          cpu.gr[RD] =
1355
            cpu.gr[RD] - (IMM5 + 1);
1356
          break;
1357
        case 0x26: case 0x27:                           /* illegal */
1358
          cpu.asregs.exception = SIGILL;
1359
          break;
1360
        case 0x28: case 0x29:                           /* rsubi */
1361
          cpu.gr[RD] =
1362
            IMM5 - cpu.gr[RD];
1363
          break;
1364
        case 0x2A: case 0x2B:                           /* cmpnei */
1365
          if (cpu.gr[RD] != IMM5)
1366
            {
1367
              SET_C();
1368
            }
1369
          else
1370
            {
1371
              CLR_C();
1372
            }
1373
          break;
1374
 
1375
        case 0x2C: case 0x2D:                           /* bmaski, divu */
1376
          {
1377
            unsigned imm = IMM5;
1378
 
1379
            if (imm == 1)
1380
              {
1381
                int exe;
1382
                int rxnlz, r1nlz;
1383
                unsigned int rx, r1;
1384
 
1385
                rx = cpu.gr[RD];
1386
                r1 = cpu.gr[1];
1387
                exe = 0;
1388
 
1389
                /* unsigned divide */
1390
                cpu.gr[RD] = (word) ((unsigned int) cpu.gr[RD] / (unsigned int)cpu.gr[1] );
1391
 
1392
                /* compute bonus_cycles for divu */
1393
                for (r1nlz = 0; ((r1 & 0x80000000) == 0) && (r1nlz < 32); r1nlz ++)
1394
                  r1 = r1 << 1;
1395
 
1396
                for (rxnlz = 0; ((rx & 0x80000000) == 0) && (rxnlz < 32); rxnlz ++)
1397
                  rx = rx << 1;
1398
 
1399
                if (r1nlz < rxnlz)
1400
                  exe += 4;
1401
                else
1402
                  exe += 5 + r1nlz - rxnlz;
1403
 
1404
                if (exe >= (2 * memcycles - 1))
1405
                  {
1406
                    bonus_cycles += exe - (2 * memcycles) + 1;
1407
                  }
1408
              }
1409
            else if (imm == 0 || imm >= 8)
1410
              {
1411
                /* bmaski */
1412
                if (imm == 0)
1413
                  cpu.gr[RD] = -1;
1414
                else
1415
                  cpu.gr[RD] = (1 << imm) - 1;
1416
              }
1417
            else
1418
              {
1419
                /* illegal */
1420
                cpu.asregs.exception = SIGILL;
1421
              }
1422
          }
1423
          break;
1424
        case 0x2E: case 0x2F:                           /* andi */
1425
          cpu.gr[RD] = cpu.gr[RD] & IMM5;
1426
          break;
1427
        case 0x30: case 0x31:                           /* bclri */
1428
          cpu.gr[RD] = cpu.gr[RD] & ~(1<<IMM5);
1429
          break;
1430
        case 0x32: case 0x33:                           /* bgeni, divs */
1431
          {
1432
            unsigned imm = IMM5;
1433
            if (imm == 1)
1434
              {
1435
                int exe,sc;
1436
                int rxnlz, r1nlz;
1437
                signed int rx, r1;
1438
 
1439
                /* compute bonus_cycles for divu */
1440
                rx = cpu.gr[RD];
1441
                r1 = cpu.gr[1];
1442
                exe = 0;
1443
 
1444
                if (((rx < 0) && (r1 > 0)) || ((rx >= 0) && (r1 < 0)))
1445
                  sc = 1;
1446
                else
1447
                  sc = 0;
1448
 
1449
                rx = abs (rx);
1450
                r1 = abs (r1);
1451
 
1452
                /* signed divide, general registers are of type int, so / op is OK */
1453
                cpu.gr[RD] = cpu.gr[RD] / cpu.gr[1];
1454
 
1455
                for (r1nlz = 0; ((r1 & 0x80000000) == 0) && (r1nlz < 32) ; r1nlz ++ )
1456
                  r1 = r1 << 1;
1457
 
1458
                for (rxnlz = 0; ((rx & 0x80000000) == 0) && (rxnlz < 32) ; rxnlz ++ )
1459
                  rx = rx << 1;
1460
 
1461
                if (r1nlz < rxnlz)
1462
                  exe += 5;
1463
                else
1464
                  exe += 6 + r1nlz - rxnlz + sc;
1465
 
1466
                if (exe >= (2 * memcycles - 1))
1467
                  {
1468
                    bonus_cycles += exe - (2 * memcycles) + 1;
1469
                  }
1470
              }
1471
            else if (imm >= 7)
1472
              {
1473
                /* bgeni */
1474
                cpu.gr[RD] = (1 << IMM5);
1475
              }
1476
            else
1477
              {
1478
                /* illegal */
1479
                cpu.asregs.exception = SIGILL;
1480
              }
1481
            break;
1482
          }
1483
        case 0x34: case 0x35:                           /* bseti */
1484
          cpu.gr[RD] = cpu.gr[RD] | (1 << IMM5);
1485
          break;
1486
        case 0x36: case 0x37:                           /* btsti */
1487
          NEW_C (cpu.gr[RD] >> IMM5);
1488
          break;
1489
        case 0x38: case 0x39:                           /* xsr, rotli */
1490
          {
1491
            unsigned imm = IMM5;
1492
            unsigned long tmp = cpu.gr[RD];
1493
            if (imm == 0)
1494
              {
1495
                word cbit;
1496
                cbit = C_VALUE();
1497
                NEW_C (tmp);
1498
                cpu.gr[RD] = (cbit << 31) | (tmp >> 1);
1499
              }
1500
            else
1501
              cpu.gr[RD] = (tmp << imm) | (tmp >> (32 - imm));
1502
          }
1503
          break;
1504
        case 0x3A: case 0x3B:                           /* asrc, asri */
1505
          {
1506
            unsigned imm = IMM5;
1507
            long tmp = cpu.gr[RD];
1508
            if (imm == 0)
1509
              {
1510
                NEW_C (tmp);
1511
                cpu.gr[RD] = tmp >> 1;
1512
              }
1513
            else
1514
              cpu.gr[RD] = tmp >> imm;
1515
          }
1516
          break;
1517
        case 0x3C: case 0x3D:                           /* lslc, lsli */
1518
          {
1519
            unsigned imm = IMM5;
1520
            unsigned long tmp = cpu.gr[RD];
1521
            if (imm == 0)
1522
              {
1523
                NEW_C (tmp >> 31);
1524
                cpu.gr[RD] = tmp << 1;
1525
              }
1526
            else
1527
              cpu.gr[RD] = tmp << imm;
1528
          }
1529
          break;
1530
        case 0x3E: case 0x3F:                           /* lsrc, lsri */
1531
          {
1532
            unsigned imm = IMM5;
1533
            unsigned long tmp = cpu.gr[RD];
1534
            if (imm == 0)
1535
              {
1536
                NEW_C (tmp);
1537
                cpu.gr[RD] = tmp >> 1;
1538
              }
1539
            else
1540
              cpu.gr[RD] = tmp >> imm;
1541
          }
1542
          break;
1543
        case 0x40: case 0x41: case 0x42: case 0x43:
1544
        case 0x44: case 0x45: case 0x46: case 0x47:
1545
        case 0x48: case 0x49: case 0x4A: case 0x4B:
1546
        case 0x4C: case 0x4D: case 0x4E: case 0x4F:
1547
          cpu.asregs.exception = SIGILL;
1548
          break;
1549
        case 0x50:
1550
          util (inst & 0xFF);
1551
          break;
1552
        case 0x51: case 0x52: case 0x53:
1553
        case 0x54: case 0x55: case 0x56: case 0x57:
1554
        case 0x58: case 0x59: case 0x5A: case 0x5B:
1555
        case 0x5C: case 0x5D: case 0x5E: case 0x5F:
1556
          cpu.asregs.exception = SIGILL;
1557
          break;
1558
        case 0x60: case 0x61: case 0x62: case 0x63:     /* movi  */
1559
        case 0x64: case 0x65: case 0x66: case 0x67:
1560
          cpu.gr[RD] = (inst >> 4) & 0x7F;
1561
          break;
1562
        case 0x68: case 0x69: case 0x6A: case 0x6B:
1563
        case 0x6C: case 0x6D: case 0x6E: case 0x6F:     /* illegal */
1564
          cpu.asregs.exception = SIGILL;
1565
          break;
1566
        case 0x71: case 0x72: case 0x73:
1567
        case 0x74: case 0x75: case 0x76: case 0x77:
1568
        case 0x78: case 0x79: case 0x7A: case 0x7B:
1569
        case 0x7C: case 0x7D: case 0x7E:                /* lrw */
1570
          cpu.gr[RX] =  rlat ((pc + ((inst & 0xFF) << 2)) & 0xFFFFFFFC);
1571
          if (tracing)
1572
            fprintf (stderr, "LRW of 0x%x from 0x%x to reg %d",
1573
                     rlat ((pc + ((inst & 0xFF) << 2)) & 0xFFFFFFFC),
1574
                     (pc + ((inst & 0xFF) << 2)) & 0xFFFFFFFC, RX);
1575
          memops++;
1576
          break;
1577
        case 0x7F:                                      /* jsri */
1578
          cpu.gr[15] = pc;
1579
          if (tracing)
1580
            fprintf (stderr, "func call: r2 = %x r3 = %x r4 = %x r5 = %x r6 = %x r7 = %x\n",
1581
                     cpu.gr[2], cpu.gr[3], cpu.gr[4], cpu.gr[5], cpu.gr[6], cpu.gr[7]);
1582
        case 0x70:                                      /* jmpi */
1583
          pc = rlat ((pc + ((inst & 0xFF) << 2)) & 0xFFFFFFFC);
1584
          memops++;
1585
          bonus_cycles++;
1586
          needfetch = 1;
1587
          break;
1588
 
1589
        case 0x80: case 0x81: case 0x82: case 0x83:
1590
        case 0x84: case 0x85: case 0x86: case 0x87:
1591
        case 0x88: case 0x89: case 0x8A: case 0x8B:
1592
        case 0x8C: case 0x8D: case 0x8E: case 0x8F:     /* ld */
1593
          cpu.gr[RX] = rlat (cpu.gr[RD] + ((inst >> 2) & 0x003C));
1594
          if (tracing)
1595
            fprintf (stderr, "load reg %d from 0x%x with 0x%x",
1596
                     RX,
1597
                     cpu.gr[RD] + ((inst >> 2) & 0x003C), cpu.gr[RX]);
1598
          memops++;
1599
          break;
1600
        case 0x90: case 0x91: case 0x92: case 0x93:
1601
        case 0x94: case 0x95: case 0x96: case 0x97:
1602
        case 0x98: case 0x99: case 0x9A: case 0x9B:
1603
        case 0x9C: case 0x9D: case 0x9E: case 0x9F:     /* st */
1604
          wlat (cpu.gr[RD] + ((inst >> 2) & 0x003C), cpu.gr[RX]);
1605
          if (tracing)
1606
            fprintf (stderr, "store reg %d (containing 0x%x) to 0x%x",
1607
                     RX, cpu.gr[RX],
1608
                     cpu.gr[RD] + ((inst >> 2) & 0x003C));
1609
          memops++;
1610
          break;
1611
        case 0xA0: case 0xA1: case 0xA2: case 0xA3:
1612
        case 0xA4: case 0xA5: case 0xA6: case 0xA7:
1613
        case 0xA8: case 0xA9: case 0xAA: case 0xAB:
1614
        case 0xAC: case 0xAD: case 0xAE: case 0xAF:     /* ld.b */
1615
          cpu.gr[RX] = rbat (cpu.gr[RD] + RS);
1616
          memops++;
1617
          break;
1618
        case 0xB0: case 0xB1: case 0xB2: case 0xB3:
1619
        case 0xB4: case 0xB5: case 0xB6: case 0xB7:
1620
        case 0xB8: case 0xB9: case 0xBA: case 0xBB:
1621
        case 0xBC: case 0xBD: case 0xBE: case 0xBF:     /* st.b */
1622
          wbat (cpu.gr[RD] + RS, cpu.gr[RX]);
1623
          memops++;
1624
          break;
1625
        case 0xC0: case 0xC1: case 0xC2: case 0xC3:
1626
        case 0xC4: case 0xC5: case 0xC6: case 0xC7:
1627
        case 0xC8: case 0xC9: case 0xCA: case 0xCB:
1628
        case 0xCC: case 0xCD: case 0xCE: case 0xCF:     /* ld.h */
1629
          cpu.gr[RX] = rhat (cpu.gr[RD] + ((inst >> 3) & 0x001E));
1630
          memops++;
1631
          break;
1632
        case 0xD0: case 0xD1: case 0xD2: case 0xD3:
1633
        case 0xD4: case 0xD5: case 0xD6: case 0xD7:
1634
        case 0xD8: case 0xD9: case 0xDA: case 0xDB:
1635
        case 0xDC: case 0xDD: case 0xDE: case 0xDF:     /* st.h */
1636
          what (cpu.gr[RD] + ((inst >> 3) & 0x001E), cpu.gr[RX]);
1637
          memops++;
1638
          break;
1639
        case 0xE8: case 0xE9: case 0xEA: case 0xEB:
1640
        case 0xEC: case 0xED: case 0xEE: case 0xEF:     /* bf */
1641
          if (C_OFF())
1642
            {
1643
              int disp;
1644
              disp = inst & 0x03FF;
1645
              if (inst & 0x0400)
1646
                disp |= 0xFFFFFC00;
1647
              pc += disp<<1;
1648
              bonus_cycles++;
1649
              needfetch = 1;
1650
            }
1651
          break;
1652
        case 0xE0: case 0xE1: case 0xE2: case 0xE3:
1653
        case 0xE4: case 0xE5: case 0xE6: case 0xE7:     /* bt */
1654
          if (C_ON())
1655
            {
1656
              int disp;
1657
              disp = inst & 0x03FF;
1658
              if (inst & 0x0400)
1659
                disp |= 0xFFFFFC00;
1660
              pc += disp<<1;
1661
              bonus_cycles++;
1662
              needfetch = 1;
1663
            }
1664
          break;
1665
 
1666
        case 0xF8: case 0xF9: case 0xFA: case 0xFB:
1667
        case 0xFC: case 0xFD: case 0xFE: case 0xFF:     /* bsr */
1668
          cpu.gr[15] = pc;
1669
        case 0xF0: case 0xF1: case 0xF2: case 0xF3:
1670
        case 0xF4: case 0xF5: case 0xF6: case 0xF7:     /* br */
1671
          {
1672
            int disp;
1673
            disp = inst & 0x03FF;
1674
            if (inst & 0x0400)
1675
              disp |= 0xFFFFFC00;
1676
            pc += disp<<1;
1677
            bonus_cycles++;
1678
            needfetch = 1;
1679
          }
1680
          break;
1681
 
1682
        }
1683
 
1684
      if (tracing)
1685
        fprintf (stderr, "\n");
1686
 
1687
      if (needfetch)
1688
        {
1689
          /* Do not let him fetch from a bad address! */
1690
          if (((uword)pc) >= cpu.asregs.msize)
1691
            {
1692
              if (issue_messages)
1693
                fprintf (stderr, "PC loaded at 0x%x is outside of available memory! (0x%x)\n", oldpc, pc);
1694
 
1695
              cpu.asregs.exception = SIGSEGV;
1696
            }
1697
          else
1698
            {
1699
              ibuf = rlat (pc & 0xFFFFFFFC);
1700
              needfetch = 0;
1701
            }
1702
        }
1703
    }
1704
  while (!cpu.asregs.exception);
1705
 
1706
  /* Hide away the things we've cached while executing.  */
1707
  cpu.asregs.pc = pc;
1708
  cpu.asregs.insts += insts;            /* instructions done ... */
1709
  cpu.asregs.cycles += insts;           /* and each takes a cycle */
1710
  cpu.asregs.cycles += bonus_cycles;    /* and extra cycles for branches */
1711
  cpu.asregs.cycles += memops * memcycles;      /* and memop cycle delays */
1712
 
1713
  signal (SIGINT, sigsave);
1714
}
1715
 
1716
 
1717
int
1718
sim_write (sd, addr, buffer, size)
1719
     SIM_DESC sd;
1720
     SIM_ADDR addr;
1721
     unsigned char * buffer;
1722
     int size;
1723
{
1724
  int i;
1725
  init_pointers ();
1726
 
1727
  memcpy (& cpu.mem[addr], buffer, size);
1728
 
1729
  return size;
1730
}
1731
 
1732
int
1733
sim_read (sd, addr, buffer, size)
1734
     SIM_DESC sd;
1735
     SIM_ADDR addr;
1736
     unsigned char * buffer;
1737
     int size;
1738
{
1739
  int i;
1740
  init_pointers ();
1741
 
1742
  memcpy (buffer, & cpu.mem[addr], size);
1743
 
1744
  return size;
1745
}
1746
 
1747
 
1748
int
1749
sim_store_register (sd, rn, memory, length)
1750
     SIM_DESC sd;
1751
     int rn;
1752
     unsigned char * memory;
1753
     int length;
1754
{
1755
  init_pointers ();
1756
 
1757
  if (rn < NUM_MCORE_REGS && rn >= 0)
1758
    {
1759
      if (length == 4)
1760
        {
1761
          long ival;
1762
 
1763
          /* misalignment safe */
1764
          ival = mcore_extract_unsigned_integer (memory, 4);
1765
          cpu.asints[rn] = ival;
1766
        }
1767
 
1768
      return 4;
1769
    }
1770
  else
1771
    return 0;
1772
}
1773
 
1774
int
1775
sim_fetch_register (sd, rn, memory, length)
1776
     SIM_DESC sd;
1777
     int rn;
1778
     unsigned char * memory;
1779
     int length;
1780
{
1781
  init_pointers ();
1782
 
1783
  if (rn < NUM_MCORE_REGS && rn >= 0)
1784
    {
1785
      if (length == 4)
1786
        {
1787
          long ival = cpu.asints[rn];
1788
 
1789
          /* misalignment-safe */
1790
          mcore_store_unsigned_integer (memory, 4, ival);
1791
        }
1792
 
1793
      return 4;
1794
    }
1795
  else
1796
    return 0;
1797
}
1798
 
1799
 
1800
int
1801
sim_trace (sd)
1802
     SIM_DESC sd;
1803
{
1804
  tracing = 1;
1805
 
1806
  sim_resume (sd, 0, 0);
1807
 
1808
  tracing = 0;
1809
 
1810
  return 1;
1811
}
1812
 
1813
void
1814
sim_stop_reason (sd, reason, sigrc)
1815
     SIM_DESC sd;
1816
     enum sim_stop * reason;
1817
     int * sigrc;
1818
{
1819
  if (cpu.asregs.exception == SIGQUIT)
1820
    {
1821
      * reason = sim_exited;
1822
      * sigrc = cpu.gr[PARM1];
1823
    }
1824
  else
1825
    {
1826
      * reason = sim_stopped;
1827
      * sigrc = cpu.asregs.exception;
1828
    }
1829
}
1830
 
1831
 
1832
int
1833
sim_stop (sd)
1834
     SIM_DESC sd;
1835
{
1836
  cpu.asregs.exception = SIGINT;
1837
  return 1;
1838
}
1839
 
1840
 
1841
void
1842
sim_info (sd, verbose)
1843
     SIM_DESC sd;
1844
     int verbose;
1845
{
1846
#ifdef WATCHFUNCTIONS
1847
  int w, wcyc;
1848
#endif
1849
  double virttime = cpu.asregs.cycles / 36.0e6;
1850
 
1851
  callback->printf_filtered (callback, "\n\n# instructions executed  %10d\n",
1852
                             cpu.asregs.insts);
1853
  callback->printf_filtered (callback, "# cycles                 %10d\n",
1854
                             cpu.asregs.cycles);
1855
  callback->printf_filtered (callback, "# pipeline stalls        %10d\n",
1856
                             cpu.asregs.stalls);
1857
  callback->printf_filtered (callback, "# virtual time taken     %10.4f\n",
1858
                             virttime);
1859
 
1860
#ifdef WATCHFUNCTIONS
1861
  callback->printf_filtered (callback, "\nNumber of watched functions: %d\n",
1862
                             ENDWL);
1863
 
1864
  wcyc = 0;
1865
 
1866
  for (w = 1; w <= ENDWL; w++)
1867
    {
1868
      callback->printf_filtered (callback, "WL = %s %8x\n",WLstr[w],WL[w]);
1869
      callback->printf_filtered (callback, "  calls = %d, cycles = %d\n",
1870
                                 WLcnts[w],WLcyc[w]);
1871
 
1872
      if (WLcnts[w] != 0)
1873
        callback->printf_filtered (callback,
1874
                                   "  maxcpc = %d, mincpc = %d, avecpc = %d\n",
1875
                                   WLmax[w],WLmin[w],WLcyc[w]/WLcnts[w]);
1876
      wcyc += WLcyc[w];
1877
    }
1878
 
1879
  callback->printf_filtered (callback,
1880
                             "Total cycles for watched functions: %d\n",wcyc);
1881
#endif
1882
}
1883
 
1884
struct  aout
1885
{
1886
  unsigned char  sa_machtype[2];
1887
  unsigned char  sa_magic[2];
1888
  unsigned char  sa_tsize[4];
1889
  unsigned char  sa_dsize[4];
1890
  unsigned char  sa_bsize[4];
1891
  unsigned char  sa_syms[4];
1892
  unsigned char  sa_entry[4];
1893
  unsigned char  sa_trelo[4];
1894
  unsigned char  sa_drelo[4];
1895
} aout;
1896
 
1897
#define LONG(x)         (((x)[0]<<24)|((x)[1]<<16)|((x)[2]<<8)|(x)[3])
1898
#define SHORT(x)        (((x)[0]<<8)|(x)[1])
1899
 
1900
SIM_DESC
1901
sim_open (kind, cb, abfd, argv)
1902
     SIM_OPEN_KIND kind;
1903
     host_callback * cb;
1904
     struct bfd * abfd;
1905
     char ** argv;
1906
{
1907
  int osize = sim_memory_size;
1908
  myname = argv[0];
1909
  callback = cb;
1910
 
1911
  if (kind == SIM_OPEN_STANDALONE)
1912
    issue_messages = 1;
1913
 
1914
  /* Discard and reacquire memory -- start with a clean slate.  */
1915
  sim_size (1);         /* small */
1916
  sim_size (osize);     /* and back again */
1917
 
1918
  set_initial_gprs ();  /* Reset the GPR registers.  */
1919
 
1920
  /* Fudge our descriptor for now.  */
1921
  return (SIM_DESC) 1;
1922
}
1923
 
1924
void
1925
sim_close (sd, quitting)
1926
     SIM_DESC sd;
1927
     int quitting;
1928
{
1929
  /* nothing to do */
1930
}
1931
 
1932
SIM_RC
1933
sim_load (sd, prog, abfd, from_tty)
1934
     SIM_DESC sd;
1935
     char * prog;
1936
     bfd * abfd;
1937
     int from_tty;
1938
{
1939
  /* Do the right thing for ELF executables; this turns out to be
1940
     just about the right thing for any object format that:
1941
       - we crack using BFD routines
1942
       - follows the traditional UNIX text/data/bss layout
1943
       - calls the bss section ".bss".   */
1944
 
1945
  extern bfd * sim_load_file (); /* ??? Don't know where this should live.  */
1946
  bfd * prog_bfd;
1947
 
1948
  {
1949
    bfd * handle;
1950
    asection * s_bss;
1951
    handle = bfd_openr (prog, 0);        /* could be "mcore" */
1952
 
1953
    if (!handle)
1954
      {
1955
        printf("``%s'' could not be opened.\n", prog);
1956
        return SIM_RC_FAIL;
1957
      }
1958
 
1959
    /* Makes sure that we have an object file, also cleans gets the
1960
       section headers in place.  */
1961
    if (!bfd_check_format (handle, bfd_object))
1962
      {
1963
        /* wasn't an object file */
1964
        bfd_close (handle);
1965
        printf ("``%s'' is not appropriate object file.\n", prog);
1966
        return SIM_RC_FAIL;
1967
      }
1968
 
1969
    /* Look for that bss section.  */
1970
    s_bss = bfd_get_section_by_name (handle, ".bss");
1971
 
1972
    if (!s_bss)
1973
      {
1974
        printf("``%s'' has no bss section.\n", prog);
1975
        return SIM_RC_FAIL;
1976
      }
1977
 
1978
    /* Appropriately paranoid would check that we have
1979
       a traditional text/data/bss ordering within memory.  */
1980
 
1981
    /* figure the end of the bss section */
1982
#if 0
1983
    printf ("bss section at 0x%08x for 0x%08x bytes\n",
1984
            (unsigned long) bfd_get_section_vma (handle, s_bss),
1985
            (unsigned long) bfd_section_size (handle, s_bss));
1986
#endif
1987
    heap_ptr = ((unsigned long) bfd_get_section_vma (handle, s_bss)
1988
                + (unsigned long) bfd_section_size (handle, s_bss));
1989
 
1990
    /* Clean up after ourselves.  */
1991
    bfd_close (handle);
1992
 
1993
    /* XXX: do we need to free the s_bss and handle structures? */
1994
  }
1995
 
1996
  /* from sh -- dac */
1997
  prog_bfd = sim_load_file (sd, myname, callback, prog, abfd,
1998
                            sim_kind == SIM_OPEN_DEBUG,
1999
                            0, sim_write);
2000
  if (prog_bfd == NULL)
2001
    return SIM_RC_FAIL;
2002
 
2003
  target_big_endian = bfd_big_endian (prog_bfd);
2004
 
2005
  if (abfd == NULL)
2006
    bfd_close (prog_bfd);
2007
 
2008
  return SIM_RC_OK;
2009
}
2010
 
2011
SIM_RC
2012
sim_create_inferior (sd, prog_bfd, argv, env)
2013
     SIM_DESC sd;
2014
     struct bfd * prog_bfd;
2015
     char ** argv;
2016
     char ** env;
2017
{
2018
  char ** avp;
2019
  int nargs = 0;
2020
  int nenv = 0;
2021
  int s_length;
2022
  int l;
2023
  unsigned long strings;
2024
  unsigned long pointers;
2025
  unsigned long hi_stack;
2026
 
2027
 
2028
  /* Set the initial register set.  */
2029
  l = issue_messages;
2030
  issue_messages = 0;
2031
  set_initial_gprs ();
2032
  issue_messages = l;
2033
 
2034
  hi_stack = cpu.asregs.msize - 4;
2035
  cpu.asregs.pc = bfd_get_start_address (prog_bfd);
2036
 
2037
  /* Calculate the argument and environment strings.  */
2038
  s_length = 0;
2039
  nargs = 0;
2040
  avp = argv;
2041
  while (avp && *avp)
2042
    {
2043
      l = strlen (*avp) + 1;    /* include the null */
2044
      s_length += (l + 3) & ~3; /* make it a 4 byte boundary */
2045
      nargs++; avp++;
2046
    }
2047
 
2048
  nenv = 0;
2049
  avp = env;
2050
  while (avp && *avp)
2051
    {
2052
      l = strlen (*avp) + 1;    /* include the null */
2053
      s_length += (l + 3) & ~ 3;/* make it a 4 byte boundary */
2054
      nenv++; avp++;
2055
    }
2056
 
2057
  /* Claim some memory for the pointers and strings. */
2058
  pointers = hi_stack - sizeof(word) * (nenv+1+nargs+1);
2059
  pointers &= ~3;               /* must be 4-byte aligned */
2060
  cpu.gr[0] = pointers;
2061
 
2062
  strings = cpu.gr[0] - s_length;
2063
  strings &= ~3;                /* want to make it 4-byte aligned */
2064
  cpu.gr[0] = strings;
2065
  /* dac fix, the stack address must be 8-byte aligned! */
2066
  cpu.gr[0] = cpu.gr[0] - cpu.gr[0] % 8;
2067
 
2068
  /* Loop through the arguments and fill them in.  */
2069
  cpu.gr[PARM1] = nargs;
2070
  if (nargs == 0)
2071
    {
2072
      /* No strings to fill in.  */
2073
      cpu.gr[PARM2] = 0;
2074
    }
2075
  else
2076
    {
2077
      cpu.gr[PARM2] = pointers;
2078
      avp = argv;
2079
      while (avp && *avp)
2080
        {
2081
          /* Save where we're putting it.  */
2082
          wlat (pointers, strings);
2083
 
2084
          /* Copy the string.  */
2085
          l = strlen (* avp) + 1;
2086
          strcpy ((char *)(cpu.mem + strings), *avp);
2087
 
2088
          /* Bump the pointers.  */
2089
          avp++;
2090
          pointers += 4;
2091
          strings += l+1;
2092
        }
2093
 
2094
      /* A null to finish the list.  */
2095
      wlat (pointers, 0);
2096
      pointers += 4;
2097
    }
2098
 
2099
  /* Now do the environment pointers.  */
2100
  if (nenv == 0)
2101
    {
2102
      /* No strings to fill in.  */
2103
      cpu.gr[PARM3] = 0;
2104
    }
2105
  else
2106
    {
2107
      cpu.gr[PARM3] = pointers;
2108
      avp = env;
2109
 
2110
      while (avp && *avp)
2111
        {
2112
          /* Save where we're putting it.  */
2113
          wlat (pointers, strings);
2114
 
2115
          /* Copy the string.  */
2116
          l = strlen (* avp) + 1;
2117
          strcpy ((char *)(cpu.mem + strings), *avp);
2118
 
2119
          /* Bump the pointers.  */
2120
          avp++;
2121
          pointers += 4;
2122
          strings += l+1;
2123
        }
2124
 
2125
      /* A null to finish the list.  */
2126
      wlat (pointers, 0);
2127
      pointers += 4;
2128
    }
2129
 
2130
  return SIM_RC_OK;
2131
}
2132
 
2133
void
2134
sim_kill (sd)
2135
     SIM_DESC sd;
2136
{
2137
  /* nothing to do */
2138
}
2139
 
2140
void
2141
sim_do_command (sd, cmd)
2142
     SIM_DESC sd;
2143
     char * cmd;
2144
{
2145
  /* Nothing there yet; it's all an error.  */
2146
 
2147
  if (cmd != NULL)
2148
    {
2149
      char ** simargv = buildargv (cmd);
2150
 
2151
      if (strcmp (simargv[0], "watch") == 0)
2152
        {
2153
          if ((simargv[1] == NULL) || (simargv[2] == NULL))
2154
            {
2155
              fprintf (stderr, "Error: missing argument to watch cmd.\n");
2156
              return;
2157
            }
2158
 
2159
          ENDWL++;
2160
 
2161
          WL[ENDWL] = strtol (simargv[2], NULL, 0);
2162
          WLstr[ENDWL] = strdup (simargv[1]);
2163
          fprintf (stderr, "Added %s (%x) to watchlist, #%d\n",WLstr[ENDWL],
2164
                   WL[ENDWL], ENDWL);
2165
 
2166
        }
2167
      else if (strcmp (simargv[0], "dumpmem") == 0)
2168
        {
2169
          unsigned char * p;
2170
          FILE * dumpfile;
2171
 
2172
          if (simargv[1] == NULL)
2173
            fprintf (stderr, "Error: missing argument to dumpmem cmd.\n");
2174
 
2175
          fprintf (stderr, "Writing dumpfile %s...",simargv[1]);
2176
 
2177
          dumpfile = fopen (simargv[1], "w");
2178
          p = cpu.mem;
2179
          fwrite (p, cpu.asregs.msize-1, 1, dumpfile);
2180
          fclose (dumpfile);
2181
 
2182
          fprintf (stderr, "done.\n");
2183
        }
2184
      else if (strcmp (simargv[0], "clearstats") == 0)
2185
        {
2186
          cpu.asregs.cycles = 0;
2187
          cpu.asregs.insts = 0;
2188
          cpu.asregs.stalls = 0;
2189
          ENDWL = 0;
2190
        }
2191
      else if (strcmp (simargv[0], "verbose") == 0)
2192
        {
2193
          issue_messages = 2;
2194
        }
2195
      else
2196
        {
2197
          fprintf (stderr,"Error: \"%s\" is not a valid M.CORE simulator command.\n",
2198
                   cmd);
2199
        }
2200
    }
2201
  else
2202
    {
2203
      fprintf (stderr, "M.CORE sim commands: \n");
2204
      fprintf (stderr, "  watch <funcname> <addr>\n");
2205
      fprintf (stderr, "  dumpmem <filename>\n");
2206
      fprintf (stderr, "  clearstats\n");
2207
      fprintf (stderr, "  verbose\n");
2208
    }
2209
}
2210
 
2211
void
2212
sim_set_callbacks (ptr)
2213
     host_callback * ptr;
2214
{
2215
  callback = ptr;
2216
}

powered by: WebSVN 2.1.0

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