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

Subversion Repositories openrisc

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

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

Line No. Rev Author Line
1 330 jeremybenn
/* Simulator for the Renesas (formerly Hitachi) / SuperH Inc. SH architecture.
2
 
3
   Written by Steve Chamberlain of Cygnus Support.
4
   sac@cygnus.com
5
 
6
   This file is part of SH sim
7
 
8
 
9
                THIS SOFTWARE IS NOT COPYRIGHTED
10
 
11
   Cygnus offers the following for use in the public domain.  Cygnus
12
   makes no warranty with regard to the software or it's performance
13
   and the user accepts the software "AS IS" with all faults.
14
 
15
   CYGNUS DISCLAIMS ANY WARRANTIES, EXPRESS OR IMPLIED, WITH REGARD TO
16
   THIS SOFTWARE INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17
   MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
18
 
19
*/
20
 
21
#include "config.h"
22
 
23
#include <stdio.h>
24
#include <errno.h>
25
#include <signal.h>
26
#ifdef HAVE_UNISTD_H
27
#include <unistd.h>
28
#endif
29
#ifdef HAVE_MMAP
30
#include <sys/mman.h>
31
# ifndef MAP_FAILED
32
#  define MAP_FAILED -1
33
# endif
34
# if !defined (MAP_ANONYMOUS) && defined (MAP_ANON)
35
#  define MAP_ANONYMOUS MAP_ANON
36
# endif
37
#endif
38
 
39
#ifdef HAVE_STRING_H
40
#include <string.h>
41
#else
42
#ifdef HAVE_STRINGS_H
43
#include <strings.h>
44
#endif
45
#endif
46
 
47
#ifdef HAVE_STDLIB_H
48
#include <stdlib.h>
49
#endif
50
 
51
#ifdef HAVE_SYS_STAT_H
52
#include <sys/stat.h>
53
#endif
54
 
55
#include "bfd.h"
56
#include "gdb/callback.h"
57
#include "gdb/remote-sim.h"
58
#include "gdb/sim-sh.h"
59
 
60
/* This file is local - if newlib changes, then so should this.  */
61
#include "syscall.h"
62
 
63
#include <math.h>
64
 
65
#ifdef _WIN32
66
#include <float.h>              /* Needed for _isnan() */
67
#define isnan _isnan
68
#endif
69
 
70
#ifndef SIGBUS
71
#define SIGBUS SIGSEGV
72
#endif
73
 
74
#ifndef SIGQUIT
75
#define SIGQUIT SIGTERM
76
#endif
77
 
78
#ifndef SIGTRAP
79
#define SIGTRAP 5
80
#endif
81
 
82
extern unsigned short sh_jump_table[], sh_dsp_table[0x1000], ppi_table[];
83
 
84
int sim_write (SIM_DESC sd, SIM_ADDR addr, const unsigned char *buffer, int size);
85
 
86
#define O_RECOMPILE 85
87
#define DEFINE_TABLE
88
#define DISASSEMBLER_TABLE
89
 
90
/* Define the rate at which the simulator should poll the host
91
   for a quit. */
92
#define POLL_QUIT_INTERVAL 0x60000
93
 
94
typedef struct
95
{
96
  int regs[20];
97
} regstacktype;
98
 
99
typedef union
100
{
101
 
102
  struct
103
  {
104
    int regs[16];
105
    int pc;
106
 
107
    /* System registers.  For sh-dsp this also includes A0 / X0 / X1 / Y0 / Y1
108
       which are located in fregs, i.e. strictly speaking, these are
109
       out-of-bounds accesses of sregs.i .  This wart of the code could be
110
       fixed by making fregs part of sregs, and including pc too - to avoid
111
       alignment repercussions - but this would cause very onerous union /
112
       structure nesting, which would only be managable with anonymous
113
       unions and structs.  */
114
    union
115
      {
116
        struct
117
          {
118
            int mach;
119
            int macl;
120
            int pr;
121
            int dummy3, dummy4;
122
            int fpul; /* A1 for sh-dsp -  but only for movs etc.  */
123
            int fpscr; /* dsr for sh-dsp */
124
          } named;
125
        int i[7];
126
      } sregs;
127
 
128
    /* sh3e / sh-dsp */
129
    union fregs_u
130
      {
131
        float f[16];
132
        double d[8];
133
        int i[16];
134
      }
135
    fregs[2];
136
 
137
    /* Control registers; on the SH4, ldc / stc is privileged, except when
138
       accessing gbr.  */
139
    union
140
      {
141
        struct
142
          {
143
            int sr;
144
            int gbr;
145
            int vbr;
146
            int ssr;
147
            int spc;
148
            int mod;
149
            /* sh-dsp */
150
            int rs;
151
            int re;
152
            /* sh3 */
153
            int bank[8];
154
            int dbr;            /* debug base register */
155
            int sgr;            /* saved gr15 */
156
            int ldst;           /* load/store flag (boolean) */
157
            int tbr;
158
            int ibcr;           /* sh2a bank control register */
159
            int ibnr;           /* sh2a bank number register */
160
          } named;
161
        int i[16];
162
      } cregs;
163
 
164
    unsigned char *insn_end;
165
 
166
    int ticks;
167
    int stalls;
168
    int memstalls;
169
    int cycles;
170
    int insts;
171
 
172
    int prevlock;
173
    int thislock;
174
    int exception;
175
 
176
    int end_of_registers;
177
 
178
    int msize;
179
#define PROFILE_FREQ 1
180
#define PROFILE_SHIFT 2
181
    int profile;
182
    unsigned short *profile_hist;
183
    unsigned char *memory;
184
    int xyram_select, xram_start, yram_start;
185
    unsigned char *xmem;
186
    unsigned char *ymem;
187
    unsigned char *xmem_offset;
188
    unsigned char *ymem_offset;
189
    unsigned long bfd_mach;
190
    regstacktype *regstack;
191
  }
192
  asregs;
193
  int asints[40];
194
} saved_state_type;
195
 
196
saved_state_type saved_state;
197
 
198
struct loop_bounds { unsigned char *start, *end; };
199
 
200
/* These variables are at file scope so that functions other than
201
   sim_resume can use the fetch/store macros */
202
 
203
static int target_little_endian;
204
static int global_endianw, endianb;
205
static int target_dsp;
206
static int host_little_endian;
207
static char **prog_argv;
208
 
209
static int maskw = 0;
210
static int maskl = 0;
211
 
212
static SIM_OPEN_KIND sim_kind;
213
static char *myname;
214
static int   tracing = 0;
215
 
216
 
217
/* Short hand definitions of the registers */
218
 
219
#define SBIT(x) ((x)&sbit)
220
#define R0      saved_state.asregs.regs[0]
221
#define Rn      saved_state.asregs.regs[n]
222
#define Rm      saved_state.asregs.regs[m]
223
#define UR0     (unsigned int) (saved_state.asregs.regs[0])
224
#define UR      (unsigned int) R
225
#define UR      (unsigned int) R
226
#define SR0     saved_state.asregs.regs[0]
227
#define CREG(n) (saved_state.asregs.cregs.i[(n)])
228
#define GBR     saved_state.asregs.cregs.named.gbr
229
#define VBR     saved_state.asregs.cregs.named.vbr
230
#define DBR     saved_state.asregs.cregs.named.dbr
231
#define TBR     saved_state.asregs.cregs.named.tbr
232
#define IBCR    saved_state.asregs.cregs.named.ibcr
233
#define IBNR    saved_state.asregs.cregs.named.ibnr
234
#define BANKN   (saved_state.asregs.cregs.named.ibnr & 0x1ff)
235
#define ME      ((saved_state.asregs.cregs.named.ibnr >> 14) & 0x3)
236
#define SSR     saved_state.asregs.cregs.named.ssr
237
#define SPC     saved_state.asregs.cregs.named.spc
238
#define SGR     saved_state.asregs.cregs.named.sgr
239
#define SREG(n) (saved_state.asregs.sregs.i[(n)])
240
#define MACH    saved_state.asregs.sregs.named.mach
241
#define MACL    saved_state.asregs.sregs.named.macl
242
#define PR      saved_state.asregs.sregs.named.pr
243
#define FPUL    saved_state.asregs.sregs.named.fpul
244
 
245
#define PC insn_ptr
246
 
247
 
248
 
249
/* Alternate bank of registers r0-r7 */
250
 
251
/* Note: code controling SR handles flips between BANK0 and BANK1 */
252
#define Rn_BANK(n) (saved_state.asregs.cregs.named.bank[(n)])
253
#define SET_Rn_BANK(n, EXP) do { saved_state.asregs.cregs.named.bank[(n)] = (EXP); } while (0)
254
 
255
 
256
/* Manipulate SR */
257
 
258
#define SR_MASK_BO  (1 << 14)
259
#define SR_MASK_CS  (1 << 13)
260
#define SR_MASK_DMY (1 << 11)
261
#define SR_MASK_DMX (1 << 10)
262
#define SR_MASK_M (1 << 9)
263
#define SR_MASK_Q (1 << 8)
264
#define SR_MASK_I (0xf << 4)
265
#define SR_MASK_S (1 << 1)
266
#define SR_MASK_T (1 << 0)
267
 
268
#define SR_MASK_BL (1 << 28)
269
#define SR_MASK_RB (1 << 29)
270
#define SR_MASK_MD (1 << 30)
271
#define SR_MASK_RC 0x0fff0000
272
#define SR_RC_INCREMENT -0x00010000
273
 
274
#define BO      ((saved_state.asregs.cregs.named.sr & SR_MASK_BO) != 0)
275
#define CS      ((saved_state.asregs.cregs.named.sr & SR_MASK_CS) != 0)
276
#define M       ((saved_state.asregs.cregs.named.sr & SR_MASK_M) != 0)
277
#define Q       ((saved_state.asregs.cregs.named.sr & SR_MASK_Q) != 0)
278
#define S       ((saved_state.asregs.cregs.named.sr & SR_MASK_S) != 0)
279
#define T       ((saved_state.asregs.cregs.named.sr & SR_MASK_T) != 0)
280
#define LDST    ((saved_state.asregs.cregs.named.ldst) != 0)
281
 
282
#define SR_BL ((saved_state.asregs.cregs.named.sr & SR_MASK_BL) != 0)
283
#define SR_RB ((saved_state.asregs.cregs.named.sr & SR_MASK_RB) != 0)
284
#define SR_MD ((saved_state.asregs.cregs.named.sr & SR_MASK_MD) != 0)
285
#define SR_DMY ((saved_state.asregs.cregs.named.sr & SR_MASK_DMY) != 0)
286
#define SR_DMX ((saved_state.asregs.cregs.named.sr & SR_MASK_DMX) != 0)
287
#define SR_RC ((saved_state.asregs.cregs.named.sr & SR_MASK_RC))
288
 
289
/* Note: don't use this for privileged bits */
290
#define SET_SR_BIT(EXP, BIT) \
291
do { \
292
  if ((EXP) & 1) \
293
    saved_state.asregs.cregs.named.sr |= (BIT); \
294
  else \
295
    saved_state.asregs.cregs.named.sr &= ~(BIT); \
296
} while (0)
297
 
298
#define SET_SR_BO(EXP) SET_SR_BIT ((EXP), SR_MASK_BO)
299
#define SET_SR_CS(EXP) SET_SR_BIT ((EXP), SR_MASK_CS)
300
#define SET_BANKN(EXP) \
301
do { \
302
  IBNR = (IBNR & 0xfe00) | (EXP & 0x1f); \
303
} while (0)
304
#define SET_ME(EXP) \
305
do { \
306
  IBNR = (IBNR & 0x3fff) | ((EXP & 0x3) << 14); \
307
} while (0)
308
#define SET_SR_M(EXP) SET_SR_BIT ((EXP), SR_MASK_M)
309
#define SET_SR_Q(EXP) SET_SR_BIT ((EXP), SR_MASK_Q)
310
#define SET_SR_S(EXP) SET_SR_BIT ((EXP), SR_MASK_S)
311
#define SET_SR_T(EXP) SET_SR_BIT ((EXP), SR_MASK_T)
312
#define SET_LDST(EXP) (saved_state.asregs.cregs.named.ldst = ((EXP) != 0))
313
 
314
/* stc currently relies on being able to read SR without modifications.  */
315
#define GET_SR() (saved_state.asregs.cregs.named.sr - 0)
316
 
317
#define SET_SR(x) set_sr (x)
318
 
319
#define SET_RC(x) \
320
  (saved_state.asregs.cregs.named.sr \
321
   = saved_state.asregs.cregs.named.sr & 0xf000ffff | ((x) & 0xfff) << 16)
322
 
323
/* Manipulate FPSCR */
324
 
325
#define FPSCR_MASK_FR (1 << 21)
326
#define FPSCR_MASK_SZ (1 << 20)
327
#define FPSCR_MASK_PR (1 << 19)
328
 
329
#define FPSCR_FR  ((GET_FPSCR () & FPSCR_MASK_FR) != 0)
330
#define FPSCR_SZ  ((GET_FPSCR () & FPSCR_MASK_SZ) != 0)
331
#define FPSCR_PR  ((GET_FPSCR () & FPSCR_MASK_PR) != 0)
332
 
333
/* Count the number of arguments in an argv.  */
334
static int
335
count_argc (char **argv)
336
{
337
  int i;
338
 
339
  if (! argv)
340
    return -1;
341
 
342
  for (i = 0; argv[i] != NULL; ++i)
343
    continue;
344
  return i;
345
}
346
 
347
static void
348
set_fpscr1 (x)
349
        int x;
350
{
351
  int old = saved_state.asregs.sregs.named.fpscr;
352
  saved_state.asregs.sregs.named.fpscr = (x);
353
  /* swap the floating point register banks */
354
  if ((saved_state.asregs.sregs.named.fpscr ^ old) & FPSCR_MASK_FR
355
      /* Ignore bit change if simulating sh-dsp.  */
356
      && ! target_dsp)
357
    {
358
      union fregs_u tmpf = saved_state.asregs.fregs[0];
359
      saved_state.asregs.fregs[0] = saved_state.asregs.fregs[1];
360
      saved_state.asregs.fregs[1] = tmpf;
361
    }
362
}
363
 
364
/* sts relies on being able to read fpscr directly.  */
365
#define GET_FPSCR()  (saved_state.asregs.sregs.named.fpscr)
366
#define SET_FPSCR(x) \
367
do { \
368
  set_fpscr1 (x); \
369
} while (0)
370
 
371
#define DSR  (saved_state.asregs.sregs.named.fpscr)
372
 
373
int
374
fail ()
375
{
376
  abort ();
377
}
378
 
379
#define RAISE_EXCEPTION(x) \
380
  (saved_state.asregs.exception = x, saved_state.asregs.insn_end = 0)
381
 
382
#define RAISE_EXCEPTION_IF_IN_DELAY_SLOT() \
383
  if (in_delay_slot) RAISE_EXCEPTION (SIGILL)
384
 
385
/* This function exists mainly for the purpose of setting a breakpoint to
386
   catch simulated bus errors when running the simulator under GDB.  */
387
 
388
void
389
raise_exception (x)
390
     int x;
391
{
392
  RAISE_EXCEPTION (x);
393
}
394
 
395
void
396
raise_buserror ()
397
{
398
  raise_exception (SIGBUS);
399
}
400
 
401
#define PROCESS_SPECIAL_ADDRESS(addr, endian, ptr, bits_written, \
402
                                forbidden_addr_bits, data, retval) \
403
do { \
404
  if (addr & forbidden_addr_bits) \
405
    { \
406
      raise_buserror (); \
407
      return retval; \
408
    } \
409
  else if ((addr & saved_state.asregs.xyram_select) \
410
           == saved_state.asregs.xram_start) \
411
    ptr = (void *) &saved_state.asregs.xmem_offset[addr ^ endian]; \
412
  else if ((addr & saved_state.asregs.xyram_select) \
413
           == saved_state.asregs.yram_start) \
414
    ptr = (void *) &saved_state.asregs.ymem_offset[addr ^ endian]; \
415
  else if ((unsigned) addr >> 24 == 0xf0 \
416
           && bits_written == 32 && (data & 1) == 0) \
417
    /* This invalidates (if not associative) or might invalidate \
418
       (if associative) an instruction cache line.  This is used for \
419
       trampolines.  Since we don't simulate the cache, this is a no-op \
420
       as far as the simulator is concerned.  */ \
421
    return retval; \
422
  else \
423
    { \
424
      if (bits_written == 8 && addr > 0x5000000) \
425
        IOMEM (addr, 1, data); \
426
      /* We can't do anything useful with the other stuff, so fail.  */ \
427
      raise_buserror (); \
428
      return retval; \
429
    } \
430
} while (0)
431
 
432
/* FIXME: sim_resume should be renamed to sim_engine_run.  sim_resume
433
   being implemented by ../common/sim_resume.c and the below should
434
   make a call to sim_engine_halt */
435
 
436
#define BUSERROR(addr, mask) ((addr) & (mask))
437
 
438
#define WRITE_BUSERROR(addr, mask, data, addr_func) \
439
  do \
440
    { \
441
      if (addr & mask) \
442
        { \
443
          addr_func (addr, data); \
444
          return; \
445
        } \
446
    } \
447
  while (0)
448
 
449
#define READ_BUSERROR(addr, mask, addr_func) \
450
  do \
451
    { \
452
      if (addr & mask) \
453
        return addr_func (addr); \
454
    } \
455
  while (0)
456
 
457
/* Define this to enable register lifetime checking.
458
   The compiler generates "add #0,rn" insns to mark registers as invalid,
459
   the simulator uses this info to call fail if it finds a ref to an invalid
460
   register before a def
461
 
462
   #define PARANOID
463
*/
464
 
465
#ifdef PARANOID
466
int valid[16];
467
#define CREF(x)  if (!valid[x]) fail ();
468
#define CDEF(x)  valid[x] = 1;
469
#define UNDEF(x) valid[x] = 0;
470
#else
471
#define CREF(x)
472
#define CDEF(x)
473
#define UNDEF(x)
474
#endif
475
 
476
static void parse_and_set_memory_size PARAMS ((char *str));
477
static int IOMEM PARAMS ((int addr, int write, int value));
478
static struct loop_bounds get_loop_bounds PARAMS ((int, int, unsigned char *,
479
                                                   unsigned char *, int, int));
480
static void process_wlat_addr PARAMS ((int, int));
481
static void process_wwat_addr PARAMS ((int, int));
482
static void process_wbat_addr PARAMS ((int, int));
483
static int process_rlat_addr PARAMS ((int));
484
static int process_rwat_addr PARAMS ((int));
485
static int process_rbat_addr PARAMS ((int));
486
static void INLINE wlat_fast PARAMS ((unsigned char *, int, int, int));
487
static void INLINE wwat_fast PARAMS ((unsigned char *, int, int, int, int));
488
static void INLINE wbat_fast PARAMS ((unsigned char *, int, int, int));
489
static int INLINE rlat_fast PARAMS ((unsigned char *, int, int));
490
static int INLINE rwat_fast PARAMS ((unsigned char *, int, int, int));
491
static int INLINE rbat_fast PARAMS ((unsigned char *, int, int));
492
 
493
static host_callback *callback;
494
 
495
 
496
 
497
/* Floating point registers */
498
 
499
#define DR(n) (get_dr (n))
500
static double
501
get_dr (n)
502
     int n;
503
{
504
  n = (n & ~1);
505
  if (host_little_endian)
506
    {
507
      union
508
      {
509
        int i[2];
510
        double d;
511
      } dr;
512
      dr.i[1] = saved_state.asregs.fregs[0].i[n + 0];
513
      dr.i[0] = saved_state.asregs.fregs[0].i[n + 1];
514
      return dr.d;
515
    }
516
  else
517
    return (saved_state.asregs.fregs[0].d[n >> 1]);
518
}
519
 
520
#define SET_DR(n, EXP) set_dr ((n), (EXP))
521
static void
522
set_dr (n, exp)
523
     int n;
524
     double exp;
525
{
526
  n = (n & ~1);
527
  if (host_little_endian)
528
    {
529
      union
530
      {
531
        int i[2];
532
        double d;
533
      } dr;
534
      dr.d = exp;
535
      saved_state.asregs.fregs[0].i[n + 0] = dr.i[1];
536
      saved_state.asregs.fregs[0].i[n + 1] = dr.i[0];
537
    }
538
  else
539
    saved_state.asregs.fregs[0].d[n >> 1] = exp;
540
}
541
 
542
#define SET_FI(n,EXP) (saved_state.asregs.fregs[0].i[(n)] = (EXP))
543
#define FI(n) (saved_state.asregs.fregs[0].i[(n)])
544
 
545
#define FR(n) (saved_state.asregs.fregs[0].f[(n)])
546
#define SET_FR(n,EXP) (saved_state.asregs.fregs[0].f[(n)] = (EXP))
547
 
548
#define XD_TO_XF(n) ((((n) & 1) << 5) | ((n) & 0x1e))
549
#define XF(n) (saved_state.asregs.fregs[(n) >> 5].i[(n) & 0x1f])
550
#define SET_XF(n,EXP) (saved_state.asregs.fregs[(n) >> 5].i[(n) & 0x1f] = (EXP))
551
 
552
#define RS saved_state.asregs.cregs.named.rs
553
#define RE saved_state.asregs.cregs.named.re
554
#define MOD (saved_state.asregs.cregs.named.mod)
555
#define SET_MOD(i) \
556
(MOD = (i), \
557
 MOD_ME = (unsigned) MOD >> 16 | (SR_DMY ? ~0xffff : (SR_DMX ? 0 : 0x10000)), \
558
 MOD_DELTA = (MOD & 0xffff) - ((unsigned) MOD >> 16))
559
 
560
#define DSP_R(n) saved_state.asregs.sregs.i[(n)]
561
#define DSP_GRD(n) DSP_R ((n) + 8)
562
#define GET_DSP_GRD(n) ((n | 2) == 7 ? SEXT (DSP_GRD (n)) : SIGN32 (DSP_R (n)))
563
#define A1 DSP_R (5)
564
#define A0 DSP_R (7)
565
#define X0 DSP_R (8)
566
#define X1 DSP_R (9)
567
#define Y0 DSP_R (10)
568
#define Y1 DSP_R (11)
569
#define M0 DSP_R (12)
570
#define A1G DSP_R (13)
571
#define M1 DSP_R (14)
572
#define A0G DSP_R (15)
573
/* DSP_R (16) / DSP_GRD (16) are used as a fake destination for pcmp.  */
574
#define MOD_ME DSP_GRD (17)
575
#define MOD_DELTA DSP_GRD (18)
576
 
577
#define FP_OP(n, OP, m) \
578
{ \
579
  if (FPSCR_PR) \
580
    { \
581
      if (((n) & 1) || ((m) & 1)) \
582
        RAISE_EXCEPTION (SIGILL); \
583
      else \
584
        SET_DR (n, (DR (n) OP DR (m))); \
585
    } \
586
  else \
587
    SET_FR (n, (FR (n) OP FR (m))); \
588
} while (0)
589
 
590
#define FP_UNARY(n, OP) \
591
{ \
592
  if (FPSCR_PR) \
593
    { \
594
      if ((n) & 1) \
595
        RAISE_EXCEPTION (SIGILL); \
596
      else \
597
        SET_DR (n, (OP (DR (n)))); \
598
    } \
599
  else \
600
    SET_FR (n, (OP (FR (n)))); \
601
} while (0)
602
 
603
#define FP_CMP(n, OP, m) \
604
{ \
605
  if (FPSCR_PR) \
606
    { \
607
      if (((n) & 1) || ((m) & 1)) \
608
        RAISE_EXCEPTION (SIGILL); \
609
      else \
610
        SET_SR_T (DR (n) OP DR (m)); \
611
    } \
612
  else \
613
    SET_SR_T (FR (n) OP FR (m)); \
614
} while (0)
615
 
616
static void
617
set_sr (new_sr)
618
     int new_sr;
619
{
620
  /* do we need to swap banks */
621
  int old_gpr = SR_MD && SR_RB;
622
  int new_gpr = (new_sr & SR_MASK_MD) && (new_sr & SR_MASK_RB);
623
  if (old_gpr != new_gpr)
624
    {
625
      int i, tmp;
626
      for (i = 0; i < 8; i++)
627
        {
628
          tmp = saved_state.asregs.cregs.named.bank[i];
629
          saved_state.asregs.cregs.named.bank[i] = saved_state.asregs.regs[i];
630
          saved_state.asregs.regs[i] = tmp;
631
        }
632
    }
633
  saved_state.asregs.cregs.named.sr = new_sr;
634
  SET_MOD (MOD);
635
}
636
 
637
static void INLINE
638
wlat_fast (memory, x, value, maskl)
639
     unsigned char *memory;
640
{
641
  int v = value;
642
  unsigned int *p = (unsigned int *) (memory + x);
643
  WRITE_BUSERROR (x, maskl, v, process_wlat_addr);
644
  *p = v;
645
}
646
 
647
static void INLINE
648
wwat_fast (memory, x, value, maskw, endianw)
649
     unsigned char *memory;
650
{
651
  int v = value;
652
  unsigned short *p = (unsigned short *) (memory + (x ^ endianw));
653
  WRITE_BUSERROR (x, maskw, v, process_wwat_addr);
654
  *p = v;
655
}
656
 
657
static void INLINE
658
wbat_fast (memory, x, value, maskb)
659
     unsigned char *memory;
660
{
661
  unsigned char *p = memory + (x ^ endianb);
662
  WRITE_BUSERROR (x, maskb, value, process_wbat_addr);
663
 
664
  p[0] = value;
665
}
666
 
667
/* Read functions */
668
 
669
static int INLINE
670
rlat_fast (memory, x, maskl)
671
     unsigned char *memory;
672
{
673
  unsigned int *p = (unsigned int *) (memory + x);
674
  READ_BUSERROR (x, maskl, process_rlat_addr);
675
 
676
  return *p;
677
}
678
 
679
static int INLINE
680
rwat_fast (memory, x, maskw, endianw)
681
     unsigned char *memory;
682
     int x, maskw, endianw;
683
{
684
  unsigned short *p = (unsigned short *) (memory + (x ^ endianw));
685
  READ_BUSERROR (x, maskw, process_rwat_addr);
686
 
687
  return *p;
688
}
689
 
690
static int INLINE
691
riat_fast (insn_ptr, endianw)
692
     unsigned char *insn_ptr;
693
{
694
  unsigned short *p = (unsigned short *) ((size_t) insn_ptr ^ endianw);
695
 
696
  return *p;
697
}
698
 
699
static int INLINE
700
rbat_fast (memory, x, maskb)
701
     unsigned char *memory;
702
{
703
  unsigned char *p = memory + (x ^ endianb);
704
  READ_BUSERROR (x, maskb, process_rbat_addr);
705
 
706
  return *p;
707
}
708
 
709
#define RWAT(x)         (rwat_fast (memory, x, maskw, endianw))
710
#define RLAT(x)         (rlat_fast (memory, x, maskl))
711
#define RBAT(x)         (rbat_fast (memory, x, maskb))
712
#define RIAT(p)         (riat_fast ((p), endianw))
713
#define WWAT(x,v)       (wwat_fast (memory, x, v, maskw, endianw))
714
#define WLAT(x,v)       (wlat_fast (memory, x, v, maskl))
715
#define WBAT(x,v)       (wbat_fast (memory, x, v, maskb))
716
 
717
#define RUWAT(x)  (RWAT (x) & 0xffff)
718
#define RSWAT(x)  ((short) (RWAT (x)))
719
#define RSLAT(x)  ((long) (RLAT (x)))
720
#define RSBAT(x)  (SEXT (RBAT (x)))
721
 
722
#define RDAT(x, n) (do_rdat (memory, (x), (n), (maskl)))
723
static int
724
do_rdat (memory, x, n, maskl)
725
     char *memory;
726
     int x;
727
     int n;
728
     int maskl;
729
{
730
  int f0;
731
  int f1;
732
  int i = (n & 1);
733
  int j = (n & ~1);
734
  f0 = rlat_fast (memory, x + 0, maskl);
735
  f1 = rlat_fast (memory, x + 4, maskl);
736
  saved_state.asregs.fregs[i].i[(j + 0)] = f0;
737
  saved_state.asregs.fregs[i].i[(j + 1)] = f1;
738
  return 0;
739
}
740
 
741
#define WDAT(x, n) (do_wdat (memory, (x), (n), (maskl)))
742
static int
743
do_wdat (memory, x, n, maskl)
744
     char *memory;
745
     int x;
746
     int n;
747
     int maskl;
748
{
749
  int f0;
750
  int f1;
751
  int i = (n & 1);
752
  int j = (n & ~1);
753
  f0 = saved_state.asregs.fregs[i].i[(j + 0)];
754
  f1 = saved_state.asregs.fregs[i].i[(j + 1)];
755
  wlat_fast (memory, (x + 0), f0, maskl);
756
  wlat_fast (memory, (x + 4), f1, maskl);
757
  return 0;
758
}
759
 
760
static void
761
process_wlat_addr (addr, value)
762
     int addr;
763
     int value;
764
{
765
  unsigned int *ptr;
766
 
767
  PROCESS_SPECIAL_ADDRESS (addr, endianb, ptr, 32, 3, value, );
768
  *ptr = value;
769
}
770
 
771
static void
772
process_wwat_addr (addr, value)
773
     int addr;
774
     int value;
775
{
776
  unsigned short *ptr;
777
 
778
  PROCESS_SPECIAL_ADDRESS (addr, endianb, ptr, 16, 1, value, );
779
  *ptr = value;
780
}
781
 
782
static void
783
process_wbat_addr (addr, value)
784
     int addr;
785
     int value;
786
{
787
  unsigned char *ptr;
788
 
789
  PROCESS_SPECIAL_ADDRESS (addr, endianb, ptr, 8, 0, value, );
790
  *ptr = value;
791
}
792
 
793
static int
794
process_rlat_addr (addr)
795
     int addr;
796
{
797
  unsigned char *ptr;
798
 
799
  PROCESS_SPECIAL_ADDRESS (addr, endianb, ptr, -32, 3, -1, 0);
800
  return *ptr;
801
}
802
 
803
static int
804
process_rwat_addr (addr)
805
     int addr;
806
{
807
  unsigned char *ptr;
808
 
809
  PROCESS_SPECIAL_ADDRESS (addr, endianb, ptr, -16, 1, -1, 0);
810
  return *ptr;
811
}
812
 
813
static int
814
process_rbat_addr (addr)
815
     int addr;
816
{
817
  unsigned char *ptr;
818
 
819
  PROCESS_SPECIAL_ADDRESS (addr, endianb, ptr, -8, 0, -1, 0);
820
  return *ptr;
821
}
822
 
823
#define SEXT(x)         (((x &  0xff) ^ (~0x7f))+0x80)
824
#define SEXT12(x)       (((x & 0xfff) ^ 0x800) - 0x800)
825
#define SEXTW(y)        ((int) ((short) y))
826
#if 0
827
#define SEXT32(x)       ((int) ((x & 0xffffffff) ^ 0x80000000U) - 0x7fffffff - 1)
828
#else
829
#define SEXT32(x)       ((int) (x))
830
#endif
831
#define SIGN32(x)       (SEXT32 (x) >> 31)
832
 
833
/* convert pointer from target to host value.  */
834
#define PT2H(x) ((x) + memory)
835
/* convert pointer from host to target value.  */
836
#define PH2T(x) ((x) - memory)
837
 
838
#define SKIP_INSN(p) ((p) += ((RIAT (p) & 0xfc00) == 0xf800 ? 4 : 2))
839
 
840
#define SET_NIP(x) nip = (x); CHECK_INSN_PTR (nip);
841
 
842
static int in_delay_slot = 0;
843
#define Delay_Slot(TEMPPC)      iword = RIAT (TEMPPC); in_delay_slot = 1; goto top;
844
 
845
#define CHECK_INSN_PTR(p) \
846
do { \
847
  if (saved_state.asregs.exception || PH2T (p) & maskw) \
848
    saved_state.asregs.insn_end = 0; \
849
  else if (p < loop.end) \
850
    saved_state.asregs.insn_end = loop.end; \
851
  else \
852
    saved_state.asregs.insn_end = mem_end; \
853
} while (0)
854
 
855
#ifdef ACE_FAST
856
 
857
#define MA(n)
858
#define L(x)
859
#define TL(x)
860
#define TB(x)
861
 
862
#else
863
 
864
#define MA(n) \
865
  do { memstalls += ((((int) PC & 3) != 0) ? (n) : ((n) - 1)); } while (0)
866
 
867
#define L(x)   thislock = x;
868
#define TL(x)  if ((x) == prevlock) stalls++;
869
#define TB(x,y)  if ((x) == prevlock || (y) == prevlock) stalls++;
870
 
871
#endif
872
 
873
#if defined(__GO32__)
874
int sim_memory_size = 19;
875
#else
876
int sim_memory_size = 24;
877
#endif
878
 
879
static int sim_profile_size = 17;
880
static int nsamples;
881
 
882
#undef TB
883
#define TB(x,y)
884
 
885
#define SMR1 (0x05FFFEC8)       /* Channel 1  serial mode register */
886
#define BRR1 (0x05FFFEC9)       /* Channel 1  bit rate register */
887
#define SCR1 (0x05FFFECA)       /* Channel 1  serial control register */
888
#define TDR1 (0x05FFFECB)       /* Channel 1  transmit data register */
889
#define SSR1 (0x05FFFECC)       /* Channel 1  serial status register */
890
#define RDR1 (0x05FFFECD)       /* Channel 1  receive data register */
891
 
892
#define SCI_RDRF         0x40   /* Recieve data register full */
893
#define SCI_TDRE        0x80    /* Transmit data register empty */
894
 
895
static int
896
IOMEM (addr, write, value)
897
     int addr;
898
     int write;
899
     int value;
900
{
901
  if (write)
902
    {
903
      switch (addr)
904
        {
905
        case TDR1:
906
          if (value != '\r')
907
            {
908
              putchar (value);
909
              fflush (stdout);
910
            }
911
          break;
912
        }
913
    }
914
  else
915
    {
916
      switch (addr)
917
        {
918
        case RDR1:
919
          return getchar ();
920
        }
921
    }
922
  return 0;
923
}
924
 
925
static int
926
get_now ()
927
{
928
  return time ((long *) 0);
929
}
930
 
931
static int
932
now_persec ()
933
{
934
  return 1;
935
}
936
 
937
static FILE *profile_file;
938
 
939
static unsigned INLINE
940
swap (n)
941
     unsigned n;
942
{
943
  if (endianb)
944
    n = (n << 24 | (n & 0xff00) << 8
945
         | (n & 0xff0000) >> 8 | (n & 0xff000000) >> 24);
946
  return n;
947
}
948
 
949
static unsigned short INLINE
950
swap16 (n)
951
     unsigned short n;
952
{
953
  if (endianb)
954
    n = n << 8 | (n & 0xff00) >> 8;
955
  return n;
956
}
957
 
958
static void
959
swapout (n)
960
     int n;
961
{
962
  if (profile_file)
963
    {
964
      union { char b[4]; int n; } u;
965
      u.n = swap (n);
966
      fwrite (u.b, 4, 1, profile_file);
967
    }
968
}
969
 
970
static void
971
swapout16 (n)
972
     int n;
973
{
974
  union { char b[4]; int n; } u;
975
  u.n = swap16 (n);
976
  fwrite (u.b, 2, 1, profile_file);
977
}
978
 
979
/* Turn a pointer in a register into a pointer into real memory. */
980
 
981
static char *
982
ptr (x)
983
     int x;
984
{
985
  return (char *) (x + saved_state.asregs.memory);
986
}
987
 
988
/* STR points to a zero-terminated string in target byte order.  Return
989
   the number of bytes that need to be converted to host byte order in order
990
   to use this string as a zero-terminated string on the host.
991
   (Not counting the rounding up needed to operate on entire words.)  */
992
static int
993
strswaplen (str)
994
     int str;
995
{
996
  unsigned char *memory = saved_state.asregs.memory;
997
  int start, end;
998
  int endian = endianb;
999
 
1000
  if (! endian)
1001
    return 0;
1002
  end = str;
1003
  for (end = str; memory[end ^ endian]; end++) ;
1004
  return end - str + 1;
1005
}
1006
 
1007
static void
1008
strnswap (str, len)
1009
     int str;
1010
     int len;
1011
{
1012
  int *start, *end;
1013
 
1014
  if (! endianb || ! len)
1015
    return;
1016
  start = (int *) ptr (str & ~3);
1017
  end = (int *) ptr (str + len);
1018
  do
1019
    {
1020
      int old = *start;
1021
      *start = (old << 24 | (old & 0xff00) << 8
1022
                | (old & 0xff0000) >> 8 | (old & 0xff000000) >> 24);
1023
      start++;
1024
    }
1025
  while (start < end);
1026
}
1027
 
1028
/* Simulate a monitor trap, put the result into r0 and errno into r1
1029
   return offset by which to adjust pc.  */
1030
 
1031
static int
1032
trap (i, regs, insn_ptr, memory, maskl, maskw, endianw)
1033
     int i;
1034
     int *regs;
1035
     unsigned char *insn_ptr;
1036
     unsigned char *memory;
1037
{
1038
  switch (i)
1039
    {
1040
    case 1:
1041
      printf ("%c", regs[0]);
1042
      break;
1043
    case 2:
1044
      raise_exception (SIGQUIT);
1045
      break;
1046
    case 3:                     /* FIXME: for backwards compat, should be removed */
1047
    case 33:
1048
      {
1049
        unsigned int countp = * (unsigned int *) (insn_ptr + 4);
1050
 
1051
        WLAT (countp, RLAT (countp) + 1);
1052
        return 6;
1053
      }
1054
    case 34:
1055
      {
1056
        extern int errno;
1057
        int perrno = errno;
1058
        errno = 0;
1059
 
1060
        switch (regs[4])
1061
          {
1062
 
1063
#if !defined(__GO32__) && !defined(_WIN32)
1064
          case SYS_fork:
1065
            regs[0] = fork ();
1066
            break;
1067
/* This would work only if endianness matched between host and target.
1068
   Besides, it's quite dangerous.  */
1069
#if 0
1070
          case SYS_execve:
1071
            regs[0] = execve (ptr (regs[5]), (char **) ptr (regs[6]),
1072
                              (char **) ptr (regs[7]));
1073
            break;
1074
          case SYS_execv:
1075
            regs[0] = execve (ptr (regs[5]), (char **) ptr (regs[6]), 0);
1076
            break;
1077
#endif
1078
          case SYS_pipe:
1079
            {
1080
              regs[0] = (BUSERROR (regs[5], maskl)
1081
                         ? -EINVAL
1082
                         : pipe ((int *) ptr (regs[5])));
1083
            }
1084
            break;
1085
 
1086
          case SYS_wait:
1087
            regs[0] = wait (ptr (regs[5]));
1088
            break;
1089
#endif /* !defined(__GO32__) && !defined(_WIN32) */
1090
 
1091
          case SYS_read:
1092
            strnswap (regs[6], regs[7]);
1093
            regs[0]
1094
              = callback->read (callback, regs[5], ptr (regs[6]), regs[7]);
1095
            strnswap (regs[6], regs[7]);
1096
            break;
1097
          case SYS_write:
1098
            strnswap (regs[6], regs[7]);
1099
            if (regs[5] == 1)
1100
              regs[0] = (int) callback->write_stdout (callback,
1101
                                                      ptr (regs[6]), regs[7]);
1102
            else
1103
              regs[0] = (int) callback->write (callback, regs[5],
1104
                                               ptr (regs[6]), regs[7]);
1105
            strnswap (regs[6], regs[7]);
1106
            break;
1107
          case SYS_lseek:
1108
            regs[0] = callback->lseek (callback,regs[5], regs[6], regs[7]);
1109
            break;
1110
          case SYS_close:
1111
            regs[0] = callback->close (callback,regs[5]);
1112
            break;
1113
          case SYS_open:
1114
            {
1115
              int len = strswaplen (regs[5]);
1116
              strnswap (regs[5], len);
1117
              regs[0] = callback->open (callback, ptr (regs[5]), regs[6]);
1118
              strnswap (regs[5], len);
1119
              break;
1120
            }
1121
          case SYS_exit:
1122
            /* EXIT - caller can look in r5 to work out the reason */
1123
            raise_exception (SIGQUIT);
1124
            regs[0] = regs[5];
1125
            break;
1126
 
1127
          case SYS_stat:        /* added at hmsi */
1128
            /* stat system call */
1129
            {
1130
              struct stat host_stat;
1131
              int buf;
1132
              int len = strswaplen (regs[5]);
1133
 
1134
              strnswap (regs[5], len);
1135
              regs[0] = stat (ptr (regs[5]), &host_stat);
1136
              strnswap (regs[5], len);
1137
 
1138
              buf = regs[6];
1139
 
1140
              WWAT (buf, host_stat.st_dev);
1141
              buf += 2;
1142
              WWAT (buf, host_stat.st_ino);
1143
              buf += 2;
1144
              WLAT (buf, host_stat.st_mode);
1145
              buf += 4;
1146
              WWAT (buf, host_stat.st_nlink);
1147
              buf += 2;
1148
              WWAT (buf, host_stat.st_uid);
1149
              buf += 2;
1150
              WWAT (buf, host_stat.st_gid);
1151
              buf += 2;
1152
              WWAT (buf, host_stat.st_rdev);
1153
              buf += 2;
1154
              WLAT (buf, host_stat.st_size);
1155
              buf += 4;
1156
              WLAT (buf, host_stat.st_atime);
1157
              buf += 4;
1158
              WLAT (buf, 0);
1159
              buf += 4;
1160
              WLAT (buf, host_stat.st_mtime);
1161
              buf += 4;
1162
              WLAT (buf, 0);
1163
              buf += 4;
1164
              WLAT (buf, host_stat.st_ctime);
1165
              buf += 4;
1166
              WLAT (buf, 0);
1167
              buf += 4;
1168
              WLAT (buf, 0);
1169
              buf += 4;
1170
              WLAT (buf, 0);
1171
              buf += 4;
1172
            }
1173
            break;
1174
 
1175
#ifndef _WIN32
1176
          case SYS_chown:
1177
            {
1178
              int len = strswaplen (regs[5]);
1179
 
1180
              strnswap (regs[5], len);
1181
              regs[0] = chown (ptr (regs[5]), regs[6], regs[7]);
1182
              strnswap (regs[5], len);
1183
              break;
1184
            }
1185
#endif /* _WIN32 */
1186
          case SYS_chmod:
1187
            {
1188
              int len = strswaplen (regs[5]);
1189
 
1190
              strnswap (regs[5], len);
1191
              regs[0] = chmod (ptr (regs[5]), regs[6]);
1192
              strnswap (regs[5], len);
1193
              break;
1194
            }
1195
          case SYS_utime:
1196
            {
1197
              /* Cast the second argument to void *, to avoid type mismatch
1198
                 if a prototype is present.  */
1199
              int len = strswaplen (regs[5]);
1200
 
1201
              strnswap (regs[5], len);
1202
              regs[0] = utime (ptr (regs[5]), (void *) ptr (regs[6]));
1203
              strnswap (regs[5], len);
1204
              break;
1205
            }
1206
          case SYS_argc:
1207
            regs[0] = count_argc (prog_argv);
1208
            break;
1209
          case SYS_argnlen:
1210
            if (regs[5] < count_argc (prog_argv))
1211
              regs[0] = strlen (prog_argv[regs[5]]);
1212
            else
1213
              regs[0] = -1;
1214
            break;
1215
          case SYS_argn:
1216
            if (regs[5] < count_argc (prog_argv))
1217
              {
1218
                /* Include the termination byte.  */
1219
                int i = strlen (prog_argv[regs[5]]) + 1;
1220
                regs[0] = sim_write (0, regs[6], prog_argv[regs[5]], i);
1221
              }
1222
            else
1223
              regs[0] = -1;
1224
            break;
1225
          case SYS_time:
1226
            regs[0] = get_now ();
1227
            break;
1228
          case SYS_ftruncate:
1229
            regs[0] = callback->ftruncate (callback, regs[5], regs[6]);
1230
            break;
1231
          case SYS_truncate:
1232
            {
1233
              int len = strswaplen (regs[5]);
1234
              strnswap (regs[5], len);
1235
              regs[0] = callback->truncate (callback, ptr (regs[5]), regs[6]);
1236
              strnswap (regs[5], len);
1237
              break;
1238
            }
1239
          default:
1240
            regs[0] = -1;
1241
            break;
1242
          }
1243
        regs[1] = callback->get_errno (callback);
1244
        errno = perrno;
1245
      }
1246
      break;
1247
 
1248
    case 13:    /* Set IBNR */
1249
      IBNR = regs[0] & 0xffff;
1250
      break;
1251
    case 14:    /* Set IBCR */
1252
      IBCR = regs[0] & 0xffff;
1253
      break;
1254
    case 0xc3:
1255
    case 255:
1256
      raise_exception (SIGTRAP);
1257
      if (i == 0xc3)
1258
        return -2;
1259
      break;
1260
    }
1261
  return 0;
1262
}
1263
 
1264
void
1265
control_c (sig, code, scp, addr)
1266
     int sig;
1267
     int code;
1268
     char *scp;
1269
     char *addr;
1270
{
1271
  raise_exception (SIGINT);
1272
}
1273
 
1274
static int
1275
div1 (R, iRn2, iRn1/*, T*/)
1276
     int *R;
1277
     int iRn1;
1278
     int iRn2;
1279
     /* int T;*/
1280
{
1281
  unsigned long tmp0;
1282
  unsigned char old_q, tmp1;
1283
 
1284
  old_q = Q;
1285
  SET_SR_Q ((unsigned char) ((0x80000000 & R[iRn1]) != 0));
1286
  R[iRn1] <<= 1;
1287
  R[iRn1] |= (unsigned long) T;
1288
 
1289
  switch (old_q)
1290
    {
1291
    case 0:
1292
      switch (M)
1293
        {
1294
        case 0:
1295
          tmp0 = R[iRn1];
1296
          R[iRn1] -= R[iRn2];
1297
          tmp1 = (R[iRn1] > tmp0);
1298
          switch (Q)
1299
            {
1300
            case 0:
1301
              SET_SR_Q (tmp1);
1302
              break;
1303
            case 1:
1304
              SET_SR_Q ((unsigned char) (tmp1 == 0));
1305
              break;
1306
            }
1307
          break;
1308
        case 1:
1309
          tmp0 = R[iRn1];
1310
          R[iRn1] += R[iRn2];
1311
          tmp1 = (R[iRn1] < tmp0);
1312
          switch (Q)
1313
            {
1314
            case 0:
1315
              SET_SR_Q ((unsigned char) (tmp1 == 0));
1316
              break;
1317
            case 1:
1318
              SET_SR_Q (tmp1);
1319
              break;
1320
            }
1321
          break;
1322
        }
1323
      break;
1324
    case 1:
1325
      switch (M)
1326
        {
1327
        case 0:
1328
          tmp0 = R[iRn1];
1329
          R[iRn1] += R[iRn2];
1330
          tmp1 = (R[iRn1] < tmp0);
1331
          switch (Q)
1332
            {
1333
            case 0:
1334
              SET_SR_Q (tmp1);
1335
              break;
1336
            case 1:
1337
              SET_SR_Q ((unsigned char) (tmp1 == 0));
1338
              break;
1339
            }
1340
          break;
1341
        case 1:
1342
          tmp0 = R[iRn1];
1343
          R[iRn1] -= R[iRn2];
1344
          tmp1 = (R[iRn1] > tmp0);
1345
          switch (Q)
1346
            {
1347
            case 0:
1348
              SET_SR_Q ((unsigned char) (tmp1 == 0));
1349
              break;
1350
            case 1:
1351
              SET_SR_Q (tmp1);
1352
              break;
1353
            }
1354
          break;
1355
        }
1356
      break;
1357
    }
1358
  /*T = (Q == M);*/
1359
  SET_SR_T (Q == M);
1360
  /*return T;*/
1361
}
1362
 
1363
static void
1364
dmul (sign, rm, rn)
1365
     int sign;
1366
     unsigned int rm;
1367
     unsigned int rn;
1368
{
1369
  unsigned long RnL, RnH;
1370
  unsigned long RmL, RmH;
1371
  unsigned long temp0, temp1, temp2, temp3;
1372
  unsigned long Res2, Res1, Res0;
1373
 
1374
  RnL = rn & 0xffff;
1375
  RnH = (rn >> 16) & 0xffff;
1376
  RmL = rm & 0xffff;
1377
  RmH = (rm >> 16) & 0xffff;
1378
  temp0 = RmL * RnL;
1379
  temp1 = RmH * RnL;
1380
  temp2 = RmL * RnH;
1381
  temp3 = RmH * RnH;
1382
  Res2 = 0;
1383
  Res1 = temp1 + temp2;
1384
  if (Res1 < temp1)
1385
    Res2 += 0x00010000;
1386
  temp1 = (Res1 << 16) & 0xffff0000;
1387
  Res0 = temp0 + temp1;
1388
  if (Res0 < temp0)
1389
    Res2 += 1;
1390
  Res2 += ((Res1 >> 16) & 0xffff) + temp3;
1391
 
1392
  if (sign)
1393
    {
1394
      if (rn & 0x80000000)
1395
        Res2 -= rm;
1396
      if (rm & 0x80000000)
1397
        Res2 -= rn;
1398
    }
1399
 
1400
  MACH = Res2;
1401
  MACL = Res0;
1402
}
1403
 
1404
static void
1405
macw (regs, memory, n, m, endianw)
1406
     int *regs;
1407
     unsigned char *memory;
1408
     int m, n;
1409
     int endianw;
1410
{
1411
  long tempm, tempn;
1412
  long prod, macl, sum;
1413
 
1414
  tempm=RSWAT (regs[m]); regs[m]+=2;
1415
  tempn=RSWAT (regs[n]); regs[n]+=2;
1416
 
1417
  macl = MACL;
1418
  prod = (long) (short) tempm * (long) (short) tempn;
1419
  sum = prod + macl;
1420
  if (S)
1421
    {
1422
      if ((~(prod ^ macl) & (sum ^ prod)) < 0)
1423
        {
1424
          /* MACH's lsb is a sticky overflow bit.  */
1425
          MACH |= 1;
1426
          /* Store the smallest negative number in MACL if prod is
1427
             negative, and the largest positive number otherwise.  */
1428
          sum = 0x7fffffff + (prod < 0);
1429
        }
1430
    }
1431
  else
1432
    {
1433
      long mach;
1434
      /* Add to MACH the sign extended product, and carry from low sum.  */
1435
      mach = MACH + (-(prod < 0)) + ((unsigned long) sum < prod);
1436
      /* Sign extend at 10:th bit in MACH.  */
1437
      MACH = (mach & 0x1ff) | -(mach & 0x200);
1438
    }
1439
  MACL = sum;
1440
}
1441
 
1442
static void
1443
macl (regs, memory, n, m)
1444
     int *regs;
1445
     unsigned char *memory;
1446
     int m, n;
1447
{
1448
  long tempm, tempn;
1449
  long macl, mach;
1450
  long long ans;
1451
  long long mac64;
1452
 
1453
  tempm = RSLAT (regs[m]);
1454
  regs[m] += 4;
1455
 
1456
  tempn = RSLAT (regs[n]);
1457
  regs[n] += 4;
1458
 
1459
  mach = MACH;
1460
  macl = MACL;
1461
 
1462
  mac64 = ((long long) macl & 0xffffffff) |
1463
          ((long long) mach & 0xffffffff) << 32;
1464
 
1465
  ans = (long long) tempm * (long long) tempn; /* Multiply 32bit * 32bit */
1466
 
1467
  mac64 += ans; /* Accumulate 64bit + 64 bit */
1468
 
1469
  macl = (long) (mac64 & 0xffffffff);
1470
  mach = (long) ((mac64 >> 32) & 0xffffffff);
1471
 
1472
  if (S)  /* Store only 48 bits of the result */
1473
    {
1474
      if (mach < 0) /* Result is negative */
1475
        {
1476
          mach = mach & 0x0000ffff; /* Mask higher 16 bits */
1477
          mach |= 0xffff8000; /* Sign extend higher 16 bits */
1478
        }
1479
      else
1480
        mach = mach & 0x00007fff; /* Postive Result */
1481
    }
1482
 
1483
  MACL = macl;
1484
  MACH = mach;
1485
}
1486
 
1487
enum {
1488
  B_BCLR = 0,
1489
  B_BSET = 1,
1490
  B_BST  = 2,
1491
  B_BLD  = 3,
1492
  B_BAND = 4,
1493
  B_BOR  = 5,
1494
  B_BXOR = 6,
1495
  B_BLDNOT = 11,
1496
  B_BANDNOT = 12,
1497
  B_BORNOT = 13,
1498
 
1499
  MOVB_RM = 0x0000,
1500
  MOVW_RM = 0x1000,
1501
  MOVL_RM = 0x2000,
1502
  FMOV_RM = 0x3000,
1503
  MOVB_MR = 0x4000,
1504
  MOVW_MR = 0x5000,
1505
  MOVL_MR = 0x6000,
1506
  FMOV_MR = 0x7000,
1507
  MOVU_BMR = 0x8000,
1508
  MOVU_WMR = 0x9000,
1509
};
1510
 
1511
/* Do extended displacement move instructions.  */
1512
void
1513
do_long_move_insn (int op, int disp12, int m, int n, int *thatlock)
1514
{
1515
  int memstalls = 0;
1516
  int thislock = *thatlock;
1517
  int endianw = global_endianw;
1518
  int *R = &(saved_state.asregs.regs[0]);
1519
  unsigned char *memory = saved_state.asregs.memory;
1520
  int maskb = ~((saved_state.asregs.msize - 1) & ~0);
1521
  unsigned char *insn_ptr = PT2H (saved_state.asregs.pc);
1522
 
1523
  switch (op) {
1524
  case MOVB_RM:         /* signed */
1525
    WBAT (disp12 * 1 + R[n], R[m]);
1526
    break;
1527
  case MOVW_RM:
1528
    WWAT (disp12 * 2 + R[n], R[m]);
1529
    break;
1530
  case MOVL_RM:
1531
    WLAT (disp12 * 4 + R[n], R[m]);
1532
    break;
1533
  case FMOV_RM:         /* floating point */
1534
    if (FPSCR_SZ)
1535
      {
1536
        MA (1);
1537
        WDAT (R[n] + 8 * disp12, m);
1538
      }
1539
    else
1540
      WLAT (R[n] + 4 * disp12, FI (m));
1541
    break;
1542
  case MOVB_MR:
1543
    R[n] = RSBAT (disp12 * 1 + R[m]);
1544
    L (n);
1545
    break;
1546
  case MOVW_MR:
1547
    R[n] = RSWAT (disp12 * 2 + R[m]);
1548
    L (n);
1549
    break;
1550
  case MOVL_MR:
1551
    R[n] = RLAT (disp12 * 4 + R[m]);
1552
    L (n);
1553
    break;
1554
  case FMOV_MR:
1555
    if (FPSCR_SZ) {
1556
      MA (1);
1557
      RDAT (R[m] + 8 * disp12, n);
1558
    }
1559
    else
1560
      SET_FI (n, RLAT (R[m] + 4 * disp12));
1561
    break;
1562
  case MOVU_BMR:        /* unsigned */
1563
    R[n] = RBAT (disp12 * 1 + R[m]);
1564
    L (n);
1565
    break;
1566
  case MOVU_WMR:
1567
    R[n] = RWAT (disp12 * 2 + R[m]);
1568
    L (n);
1569
    break;
1570
  default:
1571
    RAISE_EXCEPTION (SIGINT);
1572
    exit (1);
1573
  }
1574
  saved_state.asregs.memstalls += memstalls;
1575
  *thatlock = thislock;
1576
}
1577
 
1578
/* Do binary logical bit-manipulation insns.  */
1579
void
1580
do_blog_insn (int imm, int addr, int binop,
1581
              unsigned char *memory, int maskb)
1582
{
1583
  int oldval = RBAT (addr);
1584
 
1585
  switch (binop) {
1586
  case B_BCLR:  /* bclr.b */
1587
    WBAT (addr, oldval & ~imm);
1588
    break;
1589
  case B_BSET:  /* bset.b */
1590
    WBAT (addr, oldval | imm);
1591
    break;
1592
  case B_BST:   /* bst.b */
1593
    if (T)
1594
      WBAT (addr, oldval | imm);
1595
    else
1596
      WBAT (addr, oldval & ~imm);
1597
    break;
1598
  case B_BLD:   /* bld.b */
1599
    SET_SR_T ((oldval & imm) != 0);
1600
    break;
1601
  case B_BAND:  /* band.b */
1602
    SET_SR_T (T && ((oldval & imm) != 0));
1603
    break;
1604
  case B_BOR:   /* bor.b */
1605
    SET_SR_T (T || ((oldval & imm) != 0));
1606
    break;
1607
  case B_BXOR:  /* bxor.b */
1608
    SET_SR_T (T ^ ((oldval & imm) != 0));
1609
    break;
1610
  case B_BLDNOT:        /* bldnot.b */
1611
    SET_SR_T ((oldval & imm) == 0);
1612
    break;
1613
  case B_BANDNOT:       /* bandnot.b */
1614
    SET_SR_T (T && ((oldval & imm) == 0));
1615
    break;
1616
  case B_BORNOT:        /* bornot.b */
1617
    SET_SR_T (T || ((oldval & imm) == 0));
1618
    break;
1619
  }
1620
}
1621
float
1622
fsca_s (int in, double (*f) (double))
1623
{
1624
  double rad = ldexp ((in & 0xffff), -15) * 3.141592653589793238462643383;
1625
  double result = (*f) (rad);
1626
  double error, upper, lower, frac;
1627
  int exp;
1628
 
1629
  /* Search the value with the maximum error that is still within the
1630
     architectural spec.  */
1631
  error = ldexp (1., -21);
1632
  /* compensate for calculation inaccuracy by reducing error.  */
1633
  error = error - ldexp (1., -50);
1634
  upper = result + error;
1635
  frac = frexp (upper, &exp);
1636
  upper = ldexp (floor (ldexp (frac, 24)), exp - 24);
1637
  lower = result - error;
1638
  frac = frexp (lower, &exp);
1639
  lower = ldexp (ceil (ldexp (frac, 24)), exp - 24);
1640
  return abs (upper - result) >= abs (lower - result) ? upper : lower;
1641
}
1642
 
1643
float
1644
fsrra_s (float in)
1645
{
1646
  double result = 1. / sqrt (in);
1647
  int exp;
1648
  double frac, upper, lower, error, eps;
1649
 
1650
  /* refine result */
1651
  result = result - (result * result * in - 1) * 0.5 * result;
1652
  /* Search the value with the maximum error that is still within the
1653
     architectural spec.  */
1654
  frac = frexp (result, &exp);
1655
  frac = ldexp (frac, 24);
1656
  error = 4.0; /* 1 << 24-1-21 */
1657
  /* use eps to compensate for possible 1 ulp error in our 'exact' result.  */
1658
  eps = ldexp (1., -29);
1659
  upper = floor (frac + error - eps);
1660
  if (upper > 16777216.)
1661
    upper = floor ((frac + error - eps) * 0.5) * 2.;
1662
  lower = ceil ((frac - error + eps) * 2) * .5;
1663
  if (lower > 8388608.)
1664
    lower = ceil (frac - error + eps);
1665
  upper = ldexp (upper, exp - 24);
1666
  lower = ldexp (lower, exp - 24);
1667
  return upper - result >= result - lower ? upper : lower;
1668
}
1669
 
1670
 
1671
/* GET_LOOP_BOUNDS {EXTENDED}
1672
   These two functions compute the actual starting and ending point
1673
   of the repeat loop, based on the RS and RE registers (repeat start,
1674
   repeat stop).  The extended version is called for LDRC, and the
1675
   regular version is called for SETRC.  The difference is that for
1676
   LDRC, the loop start and end instructions are literally the ones
1677
   pointed to by RS and RE -- for SETRC, they're not (see docs).  */
1678
 
1679
static struct loop_bounds
1680
get_loop_bounds_ext (rs, re, memory, mem_end, maskw, endianw)
1681
     int rs, re;
1682
     unsigned char *memory, *mem_end;
1683
     int maskw, endianw;
1684
{
1685
  struct loop_bounds loop;
1686
 
1687
  /* FIXME: should I verify RS < RE?  */
1688
  loop.start = PT2H (RS);       /* FIXME not using the params?  */
1689
  loop.end   = PT2H (RE & ~1);  /* Ignore bit 0 of RE.  */
1690
  SKIP_INSN (loop.end);
1691
  if (loop.end >= mem_end)
1692
    loop.end = PT2H (0);
1693
  return loop;
1694
}
1695
 
1696
static struct loop_bounds
1697
get_loop_bounds (rs, re, memory, mem_end, maskw, endianw)
1698
     int rs, re;
1699
     unsigned char *memory, *mem_end;
1700
     int maskw, endianw;
1701
{
1702
  struct loop_bounds loop;
1703
 
1704
  if (SR_RC)
1705
    {
1706
      if (RS >= RE)
1707
        {
1708
          loop.start = PT2H (RE - 4);
1709
          SKIP_INSN (loop.start);
1710
          loop.end = loop.start;
1711
          if (RS - RE == 0)
1712
            SKIP_INSN (loop.end);
1713
          if (RS - RE <= 2)
1714
            SKIP_INSN (loop.end);
1715
          SKIP_INSN (loop.end);
1716
        }
1717
      else
1718
        {
1719
          loop.start = PT2H (RS);
1720
          loop.end = PT2H (RE - 4);
1721
          SKIP_INSN (loop.end);
1722
          SKIP_INSN (loop.end);
1723
          SKIP_INSN (loop.end);
1724
          SKIP_INSN (loop.end);
1725
        }
1726
      if (loop.end >= mem_end)
1727
        loop.end = PT2H (0);
1728
    }
1729
  else
1730
    loop.end = PT2H (0);
1731
 
1732
  return loop;
1733
}
1734
 
1735
static void ppi_insn ();
1736
 
1737
#include "ppi.c"
1738
 
1739
/* Provide calloc / free versions that use an anonymous mmap.  This can
1740
   significantly cut the start-up time when a large simulator memory is
1741
   required, because pages are only zeroed on demand.  */
1742
#ifdef MAP_ANONYMOUS
1743
void *
1744
mcalloc (size_t nmemb, size_t size)
1745
{
1746
  void *page;
1747
 
1748
  if (nmemb != 1)
1749
    size *= nmemb;
1750
  return mmap (0, size, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS,
1751
               -1, 0);
1752
}
1753
 
1754
#define mfree(start,length) munmap ((start), (length))
1755
#else
1756
#define mcalloc calloc
1757
#define mfree(start,length) free(start)
1758
#endif
1759
 
1760
/* Set the memory size to the power of two provided. */
1761
 
1762
void
1763
sim_size (power)
1764
     int power;
1765
 
1766
{
1767
  sim_memory_size = power;
1768
 
1769
  if (saved_state.asregs.memory)
1770
    {
1771
      mfree (saved_state.asregs.memory, saved_state.asregs.msize);
1772
    }
1773
 
1774
  saved_state.asregs.msize = 1 << power;
1775
 
1776
  saved_state.asregs.memory =
1777
    (unsigned char *) mcalloc (1, saved_state.asregs.msize);
1778
 
1779
  if (!saved_state.asregs.memory)
1780
    {
1781
      fprintf (stderr,
1782
               "Not enough VM for simulation of %d bytes of RAM\n",
1783
               saved_state.asregs.msize);
1784
 
1785
      saved_state.asregs.msize = 1;
1786
      saved_state.asregs.memory = (unsigned char *) mcalloc (1, 1);
1787
    }
1788
}
1789
 
1790
static void
1791
init_dsp (abfd)
1792
     struct bfd *abfd;
1793
{
1794
  int was_dsp = target_dsp;
1795
  unsigned long mach = bfd_get_mach (abfd);
1796
 
1797
  if (mach == bfd_mach_sh_dsp  ||
1798
      mach == bfd_mach_sh4al_dsp ||
1799
      mach == bfd_mach_sh3_dsp)
1800
    {
1801
      int ram_area_size, xram_start, yram_start;
1802
      int new_select;
1803
 
1804
      target_dsp = 1;
1805
      if (mach == bfd_mach_sh_dsp)
1806
        {
1807
          /* SH7410 (orig. sh-sdp):
1808
             4KB each for X & Y memory;
1809
             On-chip X RAM 0x0800f000-0x0800ffff
1810
             On-chip Y RAM 0x0801f000-0x0801ffff  */
1811
          xram_start = 0x0800f000;
1812
          ram_area_size = 0x1000;
1813
        }
1814
      if (mach == bfd_mach_sh3_dsp || mach == bfd_mach_sh4al_dsp)
1815
        {
1816
          /* SH7612:
1817
             8KB each for X & Y memory;
1818
             On-chip X RAM 0x1000e000-0x1000ffff
1819
             On-chip Y RAM 0x1001e000-0x1001ffff  */
1820
          xram_start = 0x1000e000;
1821
          ram_area_size = 0x2000;
1822
        }
1823
      yram_start = xram_start + 0x10000;
1824
      new_select = ~(ram_area_size - 1);
1825
      if (saved_state.asregs.xyram_select != new_select)
1826
        {
1827
          saved_state.asregs.xyram_select = new_select;
1828
          free (saved_state.asregs.xmem);
1829
          free (saved_state.asregs.ymem);
1830
          saved_state.asregs.xmem =
1831
            (unsigned char *) calloc (1, ram_area_size);
1832
          saved_state.asregs.ymem =
1833
            (unsigned char *) calloc (1, ram_area_size);
1834
 
1835
          /* Disable use of X / Y mmeory if not allocated.  */
1836
          if (! saved_state.asregs.xmem || ! saved_state.asregs.ymem)
1837
            {
1838
              saved_state.asregs.xyram_select = 0;
1839
              if (saved_state.asregs.xmem)
1840
                free (saved_state.asregs.xmem);
1841
              if (saved_state.asregs.ymem)
1842
                free (saved_state.asregs.ymem);
1843
            }
1844
        }
1845
      saved_state.asregs.xram_start = xram_start;
1846
      saved_state.asregs.yram_start = yram_start;
1847
      saved_state.asregs.xmem_offset = saved_state.asregs.xmem - xram_start;
1848
      saved_state.asregs.ymem_offset = saved_state.asregs.ymem - yram_start;
1849
    }
1850
  else
1851
    {
1852
      target_dsp = 0;
1853
      if (saved_state.asregs.xyram_select)
1854
        {
1855
          saved_state.asregs.xyram_select = 0;
1856
          free (saved_state.asregs.xmem);
1857
          free (saved_state.asregs.ymem);
1858
        }
1859
    }
1860
 
1861
  if (! saved_state.asregs.xyram_select)
1862
    {
1863
      saved_state.asregs.xram_start = 1;
1864
      saved_state.asregs.yram_start = 1;
1865
    }
1866
 
1867
  if (saved_state.asregs.regstack == NULL)
1868
    saved_state.asregs.regstack =
1869
      calloc (512, sizeof *saved_state.asregs.regstack);
1870
 
1871
  if (target_dsp != was_dsp)
1872
    {
1873
      int i, tmp;
1874
 
1875
      for (i = (sizeof sh_dsp_table / sizeof sh_dsp_table[0]) - 1; i >= 0; i--)
1876
        {
1877
          tmp = sh_jump_table[0xf000 + i];
1878
          sh_jump_table[0xf000 + i] = sh_dsp_table[i];
1879
          sh_dsp_table[i] = tmp;
1880
        }
1881
    }
1882
}
1883
 
1884
static void
1885
init_pointers ()
1886
{
1887
  host_little_endian = 0;
1888
  * (char*) &host_little_endian = 1;
1889
  host_little_endian &= 1;
1890
 
1891
  if (saved_state.asregs.msize != 1 << sim_memory_size)
1892
    {
1893
      sim_size (sim_memory_size);
1894
    }
1895
 
1896
  if (saved_state.asregs.profile && !profile_file)
1897
    {
1898
      profile_file = fopen ("gmon.out", "wb");
1899
      /* Seek to where to put the call arc data */
1900
      nsamples = (1 << sim_profile_size);
1901
 
1902
      fseek (profile_file, nsamples * 2 + 12, 0);
1903
 
1904
      if (!profile_file)
1905
        {
1906
          fprintf (stderr, "Can't open gmon.out\n");
1907
        }
1908
      else
1909
        {
1910
          saved_state.asregs.profile_hist =
1911
            (unsigned short *) calloc (64, (nsamples * sizeof (short) / 64));
1912
        }
1913
    }
1914
}
1915
 
1916
static void
1917
dump_profile ()
1918
{
1919
  unsigned int minpc;
1920
  unsigned int maxpc;
1921
  unsigned short *p;
1922
  int i;
1923
 
1924
  p = saved_state.asregs.profile_hist;
1925
  minpc = 0;
1926
  maxpc = (1 << sim_profile_size);
1927
 
1928
  fseek (profile_file, 0L, 0);
1929
  swapout (minpc << PROFILE_SHIFT);
1930
  swapout (maxpc << PROFILE_SHIFT);
1931
  swapout (nsamples * 2 + 12);
1932
  for (i = 0; i < nsamples; i++)
1933
    swapout16 (saved_state.asregs.profile_hist[i]);
1934
 
1935
}
1936
 
1937
static void
1938
gotcall (from, to)
1939
     int from;
1940
     int to;
1941
{
1942
  swapout (from);
1943
  swapout (to);
1944
  swapout (1);
1945
}
1946
 
1947
#define MMASKB ((saved_state.asregs.msize -1) & ~0)
1948
 
1949
int
1950
sim_stop (sd)
1951
     SIM_DESC sd;
1952
{
1953
  raise_exception (SIGINT);
1954
  return 1;
1955
}
1956
 
1957
void
1958
sim_resume (sd, step, siggnal)
1959
     SIM_DESC sd;
1960
     int step, siggnal;
1961
{
1962
  register unsigned char *insn_ptr;
1963
  unsigned char *mem_end;
1964
  struct loop_bounds loop;
1965
  register int cycles = 0;
1966
  register int stalls = 0;
1967
  register int memstalls = 0;
1968
  register int insts = 0;
1969
  register int prevlock;
1970
#if 1
1971
  int thislock;
1972
#else
1973
  register int thislock;
1974
#endif
1975
  register unsigned int doprofile;
1976
  register int pollcount = 0;
1977
  /* endianw is used for every insn fetch, hence it makes sense to cache it.
1978
     endianb is used less often.  */
1979
  register int endianw = global_endianw;
1980
 
1981
  int tick_start = get_now ();
1982
  void (*prev) ();
1983
  void (*prev_fpe) ();
1984
 
1985
  register unsigned short *jump_table = sh_jump_table;
1986
 
1987
  register int *R = &(saved_state.asregs.regs[0]);
1988
  /*register int T;*/
1989
#ifndef PR
1990
  register int PR;
1991
#endif
1992
 
1993
  register int maskb = ~((saved_state.asregs.msize - 1) & ~0);
1994
  register int maskw = ~((saved_state.asregs.msize - 1) & ~1);
1995
  register int maskl = ~((saved_state.asregs.msize - 1) & ~3);
1996
  register unsigned char *memory;
1997
  register unsigned int sbit = ((unsigned int) 1 << 31);
1998
 
1999
  prev = signal (SIGINT, control_c);
2000
  prev_fpe = signal (SIGFPE, SIG_IGN);
2001
 
2002
  init_pointers ();
2003
  saved_state.asregs.exception = 0;
2004
 
2005
  memory = saved_state.asregs.memory;
2006
  mem_end = memory + saved_state.asregs.msize;
2007
 
2008
  if (RE & 1)
2009
    loop = get_loop_bounds_ext (RS, RE, memory, mem_end, maskw, endianw);
2010
  else
2011
    loop = get_loop_bounds     (RS, RE, memory, mem_end, maskw, endianw);
2012
 
2013
  insn_ptr = PT2H (saved_state.asregs.pc);
2014
  CHECK_INSN_PTR (insn_ptr);
2015
 
2016
#ifndef PR
2017
  PR = saved_state.asregs.sregs.named.pr;
2018
#endif
2019
  /*T = GET_SR () & SR_MASK_T;*/
2020
  prevlock = saved_state.asregs.prevlock;
2021
  thislock = saved_state.asregs.thislock;
2022
  doprofile = saved_state.asregs.profile;
2023
 
2024
  /* If profiling not enabled, disable it by asking for
2025
     profiles infrequently. */
2026
  if (doprofile == 0)
2027
    doprofile = ~0;
2028
 
2029
 loop:
2030
  if (step && insn_ptr < saved_state.asregs.insn_end)
2031
    {
2032
      if (saved_state.asregs.exception)
2033
        /* This can happen if we've already been single-stepping and
2034
           encountered a loop end.  */
2035
        saved_state.asregs.insn_end = insn_ptr;
2036
      else
2037
        {
2038
          saved_state.asregs.exception = SIGTRAP;
2039
          saved_state.asregs.insn_end = insn_ptr + 2;
2040
        }
2041
    }
2042
 
2043
  while (insn_ptr < saved_state.asregs.insn_end)
2044
    {
2045
      register unsigned int iword = RIAT (insn_ptr);
2046
      register unsigned int ult;
2047
      register unsigned char *nip = insn_ptr + 2;
2048
 
2049
#ifndef ACE_FAST
2050
      insts++;
2051
#endif
2052
    top:
2053
      if (tracing)
2054
        fprintf (stderr, "PC: %08x, insn: %04x\n", PH2T (insn_ptr), iword);
2055
 
2056
#include "code.c"
2057
 
2058
 
2059
      in_delay_slot = 0;
2060
      insn_ptr = nip;
2061
 
2062
      if (--pollcount < 0)
2063
        {
2064
          pollcount = POLL_QUIT_INTERVAL;
2065
          if ((*callback->poll_quit) != NULL
2066
              && (*callback->poll_quit) (callback))
2067
            {
2068
              sim_stop (sd);
2069
            }
2070
        }
2071
 
2072
#ifndef ACE_FAST
2073
      prevlock = thislock;
2074
      thislock = 30;
2075
      cycles++;
2076
 
2077
      if (cycles >= doprofile)
2078
        {
2079
 
2080
          saved_state.asregs.cycles += doprofile;
2081
          cycles -= doprofile;
2082
          if (saved_state.asregs.profile_hist)
2083
            {
2084
              int n = PH2T (insn_ptr) >> PROFILE_SHIFT;
2085
              if (n < nsamples)
2086
                {
2087
                  int i = saved_state.asregs.profile_hist[n];
2088
                  if (i < 65000)
2089
                    saved_state.asregs.profile_hist[n] = i + 1;
2090
                }
2091
 
2092
            }
2093
        }
2094
#endif
2095
    }
2096
  if (saved_state.asregs.insn_end == loop.end)
2097
    {
2098
      saved_state.asregs.cregs.named.sr += SR_RC_INCREMENT;
2099
      if (SR_RC)
2100
        insn_ptr = loop.start;
2101
      else
2102
        {
2103
          saved_state.asregs.insn_end = mem_end;
2104
          loop.end = PT2H (0);
2105
        }
2106
      goto loop;
2107
    }
2108
 
2109
  if (saved_state.asregs.exception == SIGILL
2110
      || saved_state.asregs.exception == SIGBUS)
2111
    {
2112
      insn_ptr -= 2;
2113
    }
2114
  /* Check for SIGBUS due to insn fetch.  */
2115
  else if (! saved_state.asregs.exception)
2116
    saved_state.asregs.exception = SIGBUS;
2117
 
2118
  saved_state.asregs.ticks += get_now () - tick_start;
2119
  saved_state.asregs.cycles += cycles;
2120
  saved_state.asregs.stalls += stalls;
2121
  saved_state.asregs.memstalls += memstalls;
2122
  saved_state.asregs.insts += insts;
2123
  saved_state.asregs.pc = PH2T (insn_ptr);
2124
#ifndef PR
2125
  saved_state.asregs.sregs.named.pr = PR;
2126
#endif
2127
 
2128
  saved_state.asregs.prevlock = prevlock;
2129
  saved_state.asregs.thislock = thislock;
2130
 
2131
  if (profile_file)
2132
    {
2133
      dump_profile ();
2134
    }
2135
 
2136
  signal (SIGFPE, prev_fpe);
2137
  signal (SIGINT, prev);
2138
}
2139
 
2140
int
2141
sim_write (sd, addr, buffer, size)
2142
     SIM_DESC sd;
2143
     SIM_ADDR addr;
2144
     const unsigned char *buffer;
2145
     int size;
2146
{
2147
  int i;
2148
 
2149
  init_pointers ();
2150
 
2151
  for (i = 0; i < size; i++)
2152
    {
2153
      saved_state.asregs.memory[(MMASKB & (addr + i)) ^ endianb] = buffer[i];
2154
    }
2155
  return size;
2156
}
2157
 
2158
int
2159
sim_read (sd, addr, buffer, size)
2160
     SIM_DESC sd;
2161
     SIM_ADDR addr;
2162
     unsigned char *buffer;
2163
     int size;
2164
{
2165
  int i;
2166
 
2167
  init_pointers ();
2168
 
2169
  for (i = 0; i < size; i++)
2170
    {
2171
      buffer[i] = saved_state.asregs.memory[(MMASKB & (addr + i)) ^ endianb];
2172
    }
2173
  return size;
2174
}
2175
 
2176
static int gdb_bank_number;
2177
enum {
2178
  REGBANK_MACH = 15,
2179
  REGBANK_IVN  = 16,
2180
  REGBANK_PR   = 17,
2181
  REGBANK_GBR  = 18,
2182
  REGBANK_MACL = 19
2183
};
2184
 
2185
int
2186
sim_store_register (sd, rn, memory, length)
2187
     SIM_DESC sd;
2188
     int rn;
2189
     unsigned char *memory;
2190
     int length;
2191
{
2192
  unsigned val;
2193
 
2194
  init_pointers ();
2195
  val = swap (* (int *) memory);
2196
  switch (rn)
2197
    {
2198
    case SIM_SH_R0_REGNUM: case SIM_SH_R1_REGNUM: case SIM_SH_R2_REGNUM:
2199
    case SIM_SH_R3_REGNUM: case SIM_SH_R4_REGNUM: case SIM_SH_R5_REGNUM:
2200
    case SIM_SH_R6_REGNUM: case SIM_SH_R7_REGNUM: case SIM_SH_R8_REGNUM:
2201
    case SIM_SH_R9_REGNUM: case SIM_SH_R10_REGNUM: case SIM_SH_R11_REGNUM:
2202
    case SIM_SH_R12_REGNUM: case SIM_SH_R13_REGNUM: case SIM_SH_R14_REGNUM:
2203
    case SIM_SH_R15_REGNUM:
2204
      saved_state.asregs.regs[rn] = val;
2205
      break;
2206
    case SIM_SH_PC_REGNUM:
2207
      saved_state.asregs.pc = val;
2208
      break;
2209
    case SIM_SH_PR_REGNUM:
2210
      PR = val;
2211
      break;
2212
    case SIM_SH_GBR_REGNUM:
2213
      GBR = val;
2214
      break;
2215
    case SIM_SH_VBR_REGNUM:
2216
      VBR = val;
2217
      break;
2218
    case SIM_SH_MACH_REGNUM:
2219
      MACH = val;
2220
      break;
2221
    case SIM_SH_MACL_REGNUM:
2222
      MACL = val;
2223
      break;
2224
    case SIM_SH_SR_REGNUM:
2225
      SET_SR (val);
2226
      break;
2227
    case SIM_SH_FPUL_REGNUM:
2228
      FPUL = val;
2229
      break;
2230
    case SIM_SH_FPSCR_REGNUM:
2231
      SET_FPSCR (val);
2232
      break;
2233
    case SIM_SH_FR0_REGNUM: case SIM_SH_FR1_REGNUM: case SIM_SH_FR2_REGNUM:
2234
    case SIM_SH_FR3_REGNUM: case SIM_SH_FR4_REGNUM: case SIM_SH_FR5_REGNUM:
2235
    case SIM_SH_FR6_REGNUM: case SIM_SH_FR7_REGNUM: case SIM_SH_FR8_REGNUM:
2236
    case SIM_SH_FR9_REGNUM: case SIM_SH_FR10_REGNUM: case SIM_SH_FR11_REGNUM:
2237
    case SIM_SH_FR12_REGNUM: case SIM_SH_FR13_REGNUM: case SIM_SH_FR14_REGNUM:
2238
    case SIM_SH_FR15_REGNUM:
2239
      SET_FI (rn - SIM_SH_FR0_REGNUM, val);
2240
      break;
2241
    case SIM_SH_DSR_REGNUM:
2242
      DSR = val;
2243
      break;
2244
    case SIM_SH_A0G_REGNUM:
2245
      A0G = val;
2246
      break;
2247
    case SIM_SH_A0_REGNUM:
2248
      A0 = val;
2249
      break;
2250
    case SIM_SH_A1G_REGNUM:
2251
      A1G = val;
2252
      break;
2253
    case SIM_SH_A1_REGNUM:
2254
      A1 = val;
2255
      break;
2256
    case SIM_SH_M0_REGNUM:
2257
      M0 = val;
2258
      break;
2259
    case SIM_SH_M1_REGNUM:
2260
      M1 = val;
2261
      break;
2262
    case SIM_SH_X0_REGNUM:
2263
      X0 = val;
2264
      break;
2265
    case SIM_SH_X1_REGNUM:
2266
      X1 = val;
2267
      break;
2268
    case SIM_SH_Y0_REGNUM:
2269
      Y0 = val;
2270
      break;
2271
    case SIM_SH_Y1_REGNUM:
2272
      Y1 = val;
2273
      break;
2274
    case SIM_SH_MOD_REGNUM:
2275
      SET_MOD (val);
2276
      break;
2277
    case SIM_SH_RS_REGNUM:
2278
      RS = val;
2279
      break;
2280
    case SIM_SH_RE_REGNUM:
2281
      RE = val;
2282
      break;
2283
    case SIM_SH_SSR_REGNUM:
2284
      SSR = val;
2285
      break;
2286
    case SIM_SH_SPC_REGNUM:
2287
      SPC = val;
2288
      break;
2289
    /* The rn_bank idiosyncracies are not due to hardware differences, but to
2290
       a weird aliasing naming scheme for sh3 / sh3e / sh4.  */
2291
    case SIM_SH_R0_BANK0_REGNUM: case SIM_SH_R1_BANK0_REGNUM:
2292
    case SIM_SH_R2_BANK0_REGNUM: case SIM_SH_R3_BANK0_REGNUM:
2293
    case SIM_SH_R4_BANK0_REGNUM: case SIM_SH_R5_BANK0_REGNUM:
2294
    case SIM_SH_R6_BANK0_REGNUM: case SIM_SH_R7_BANK0_REGNUM:
2295
      if (saved_state.asregs.bfd_mach == bfd_mach_sh2a)
2296
        {
2297
          rn -= SIM_SH_R0_BANK0_REGNUM;
2298
          saved_state.asregs.regstack[gdb_bank_number].regs[rn] = val;
2299
        }
2300
      else
2301
      if (SR_MD && SR_RB)
2302
        Rn_BANK (rn - SIM_SH_R0_BANK0_REGNUM) = val;
2303
      else
2304
        saved_state.asregs.regs[rn - SIM_SH_R0_BANK0_REGNUM] = val;
2305
      break;
2306
    case SIM_SH_R0_BANK1_REGNUM: case SIM_SH_R1_BANK1_REGNUM:
2307
    case SIM_SH_R2_BANK1_REGNUM: case SIM_SH_R3_BANK1_REGNUM:
2308
    case SIM_SH_R4_BANK1_REGNUM: case SIM_SH_R5_BANK1_REGNUM:
2309
    case SIM_SH_R6_BANK1_REGNUM: case SIM_SH_R7_BANK1_REGNUM:
2310
      if (saved_state.asregs.bfd_mach == bfd_mach_sh2a)
2311
        {
2312
          rn -= SIM_SH_R0_BANK1_REGNUM;
2313
          saved_state.asregs.regstack[gdb_bank_number].regs[rn + 8] = val;
2314
        }
2315
      else
2316
      if (SR_MD && SR_RB)
2317
        saved_state.asregs.regs[rn - SIM_SH_R0_BANK1_REGNUM] = val;
2318
      else
2319
        Rn_BANK (rn - SIM_SH_R0_BANK1_REGNUM) = val;
2320
      break;
2321
    case SIM_SH_R0_BANK_REGNUM: case SIM_SH_R1_BANK_REGNUM:
2322
    case SIM_SH_R2_BANK_REGNUM: case SIM_SH_R3_BANK_REGNUM:
2323
    case SIM_SH_R4_BANK_REGNUM: case SIM_SH_R5_BANK_REGNUM:
2324
    case SIM_SH_R6_BANK_REGNUM: case SIM_SH_R7_BANK_REGNUM:
2325
      SET_Rn_BANK (rn - SIM_SH_R0_BANK_REGNUM, val);
2326
      break;
2327
    case SIM_SH_TBR_REGNUM:
2328
      TBR = val;
2329
      break;
2330
    case SIM_SH_IBNR_REGNUM:
2331
      IBNR = val;
2332
      break;
2333
    case SIM_SH_IBCR_REGNUM:
2334
      IBCR = val;
2335
      break;
2336
    case SIM_SH_BANK_REGNUM:
2337
      /* This is a pseudo-register maintained just for gdb.
2338
         It tells us what register bank gdb would like to read/write.  */
2339
      gdb_bank_number = val;
2340
      break;
2341
    case SIM_SH_BANK_MACL_REGNUM:
2342
      saved_state.asregs.regstack[gdb_bank_number].regs[REGBANK_MACL] = val;
2343
      break;
2344
    case SIM_SH_BANK_GBR_REGNUM:
2345
      saved_state.asregs.regstack[gdb_bank_number].regs[REGBANK_GBR] = val;
2346
      break;
2347
    case SIM_SH_BANK_PR_REGNUM:
2348
      saved_state.asregs.regstack[gdb_bank_number].regs[REGBANK_PR] = val;
2349
      break;
2350
    case SIM_SH_BANK_IVN_REGNUM:
2351
      saved_state.asregs.regstack[gdb_bank_number].regs[REGBANK_IVN] = val;
2352
      break;
2353
    case SIM_SH_BANK_MACH_REGNUM:
2354
      saved_state.asregs.regstack[gdb_bank_number].regs[REGBANK_MACH] = val;
2355
      break;
2356
    default:
2357
      return 0;
2358
    }
2359
  return -1;
2360
}
2361
 
2362
int
2363
sim_fetch_register (sd, rn, memory, length)
2364
     SIM_DESC sd;
2365
     int rn;
2366
     unsigned char *memory;
2367
     int length;
2368
{
2369
  int val;
2370
 
2371
  init_pointers ();
2372
  switch (rn)
2373
    {
2374
    case SIM_SH_R0_REGNUM: case SIM_SH_R1_REGNUM: case SIM_SH_R2_REGNUM:
2375
    case SIM_SH_R3_REGNUM: case SIM_SH_R4_REGNUM: case SIM_SH_R5_REGNUM:
2376
    case SIM_SH_R6_REGNUM: case SIM_SH_R7_REGNUM: case SIM_SH_R8_REGNUM:
2377
    case SIM_SH_R9_REGNUM: case SIM_SH_R10_REGNUM: case SIM_SH_R11_REGNUM:
2378
    case SIM_SH_R12_REGNUM: case SIM_SH_R13_REGNUM: case SIM_SH_R14_REGNUM:
2379
    case SIM_SH_R15_REGNUM:
2380
      val = saved_state.asregs.regs[rn];
2381
      break;
2382
    case SIM_SH_PC_REGNUM:
2383
      val = saved_state.asregs.pc;
2384
      break;
2385
    case SIM_SH_PR_REGNUM:
2386
      val = PR;
2387
      break;
2388
    case SIM_SH_GBR_REGNUM:
2389
      val = GBR;
2390
      break;
2391
    case SIM_SH_VBR_REGNUM:
2392
      val = VBR;
2393
      break;
2394
    case SIM_SH_MACH_REGNUM:
2395
      val = MACH;
2396
      break;
2397
    case SIM_SH_MACL_REGNUM:
2398
      val = MACL;
2399
      break;
2400
    case SIM_SH_SR_REGNUM:
2401
      val = GET_SR ();
2402
      break;
2403
    case SIM_SH_FPUL_REGNUM:
2404
      val = FPUL;
2405
      break;
2406
    case SIM_SH_FPSCR_REGNUM:
2407
      val = GET_FPSCR ();
2408
      break;
2409
    case SIM_SH_FR0_REGNUM: case SIM_SH_FR1_REGNUM: case SIM_SH_FR2_REGNUM:
2410
    case SIM_SH_FR3_REGNUM: case SIM_SH_FR4_REGNUM: case SIM_SH_FR5_REGNUM:
2411
    case SIM_SH_FR6_REGNUM: case SIM_SH_FR7_REGNUM: case SIM_SH_FR8_REGNUM:
2412
    case SIM_SH_FR9_REGNUM: case SIM_SH_FR10_REGNUM: case SIM_SH_FR11_REGNUM:
2413
    case SIM_SH_FR12_REGNUM: case SIM_SH_FR13_REGNUM: case SIM_SH_FR14_REGNUM:
2414
    case SIM_SH_FR15_REGNUM:
2415
      val = FI (rn - SIM_SH_FR0_REGNUM);
2416
      break;
2417
    case SIM_SH_DSR_REGNUM:
2418
      val = DSR;
2419
      break;
2420
    case SIM_SH_A0G_REGNUM:
2421
      val = SEXT (A0G);
2422
      break;
2423
    case SIM_SH_A0_REGNUM:
2424
      val = A0;
2425
      break;
2426
    case SIM_SH_A1G_REGNUM:
2427
      val = SEXT (A1G);
2428
      break;
2429
    case SIM_SH_A1_REGNUM:
2430
      val = A1;
2431
      break;
2432
    case SIM_SH_M0_REGNUM:
2433
      val = M0;
2434
      break;
2435
    case SIM_SH_M1_REGNUM:
2436
      val = M1;
2437
      break;
2438
    case SIM_SH_X0_REGNUM:
2439
      val = X0;
2440
      break;
2441
    case SIM_SH_X1_REGNUM:
2442
      val = X1;
2443
      break;
2444
    case SIM_SH_Y0_REGNUM:
2445
      val = Y0;
2446
      break;
2447
    case SIM_SH_Y1_REGNUM:
2448
      val = Y1;
2449
      break;
2450
    case SIM_SH_MOD_REGNUM:
2451
      val = MOD;
2452
      break;
2453
    case SIM_SH_RS_REGNUM:
2454
      val = RS;
2455
      break;
2456
    case SIM_SH_RE_REGNUM:
2457
      val = RE;
2458
      break;
2459
    case SIM_SH_SSR_REGNUM:
2460
      val = SSR;
2461
      break;
2462
    case SIM_SH_SPC_REGNUM:
2463
      val = SPC;
2464
      break;
2465
    /* The rn_bank idiosyncracies are not due to hardware differences, but to
2466
       a weird aliasing naming scheme for sh3 / sh3e / sh4.  */
2467
    case SIM_SH_R0_BANK0_REGNUM: case SIM_SH_R1_BANK0_REGNUM:
2468
    case SIM_SH_R2_BANK0_REGNUM: case SIM_SH_R3_BANK0_REGNUM:
2469
    case SIM_SH_R4_BANK0_REGNUM: case SIM_SH_R5_BANK0_REGNUM:
2470
    case SIM_SH_R6_BANK0_REGNUM: case SIM_SH_R7_BANK0_REGNUM:
2471
      if (saved_state.asregs.bfd_mach == bfd_mach_sh2a)
2472
        {
2473
          rn -= SIM_SH_R0_BANK0_REGNUM;
2474
          val = saved_state.asregs.regstack[gdb_bank_number].regs[rn];
2475
        }
2476
      else
2477
      val = (SR_MD && SR_RB
2478
             ? Rn_BANK (rn - SIM_SH_R0_BANK0_REGNUM)
2479
             : saved_state.asregs.regs[rn - SIM_SH_R0_BANK0_REGNUM]);
2480
      break;
2481
    case SIM_SH_R0_BANK1_REGNUM: case SIM_SH_R1_BANK1_REGNUM:
2482
    case SIM_SH_R2_BANK1_REGNUM: case SIM_SH_R3_BANK1_REGNUM:
2483
    case SIM_SH_R4_BANK1_REGNUM: case SIM_SH_R5_BANK1_REGNUM:
2484
    case SIM_SH_R6_BANK1_REGNUM: case SIM_SH_R7_BANK1_REGNUM:
2485
      if (saved_state.asregs.bfd_mach == bfd_mach_sh2a)
2486
        {
2487
          rn -= SIM_SH_R0_BANK1_REGNUM;
2488
          val = saved_state.asregs.regstack[gdb_bank_number].regs[rn + 8];
2489
        }
2490
      else
2491
      val = (! SR_MD || ! SR_RB
2492
             ? Rn_BANK (rn - SIM_SH_R0_BANK1_REGNUM)
2493
             : saved_state.asregs.regs[rn - SIM_SH_R0_BANK1_REGNUM]);
2494
      break;
2495
    case SIM_SH_R0_BANK_REGNUM: case SIM_SH_R1_BANK_REGNUM:
2496
    case SIM_SH_R2_BANK_REGNUM: case SIM_SH_R3_BANK_REGNUM:
2497
    case SIM_SH_R4_BANK_REGNUM: case SIM_SH_R5_BANK_REGNUM:
2498
    case SIM_SH_R6_BANK_REGNUM: case SIM_SH_R7_BANK_REGNUM:
2499
      val = Rn_BANK (rn - SIM_SH_R0_BANK_REGNUM);
2500
      break;
2501
    case SIM_SH_TBR_REGNUM:
2502
      val = TBR;
2503
      break;
2504
    case SIM_SH_IBNR_REGNUM:
2505
      val = IBNR;
2506
      break;
2507
    case SIM_SH_IBCR_REGNUM:
2508
      val = IBCR;
2509
      break;
2510
    case SIM_SH_BANK_REGNUM:
2511
      /* This is a pseudo-register maintained just for gdb.
2512
         It tells us what register bank gdb would like to read/write.  */
2513
      val = gdb_bank_number;
2514
      break;
2515
    case SIM_SH_BANK_MACL_REGNUM:
2516
      val = saved_state.asregs.regstack[gdb_bank_number].regs[REGBANK_MACL];
2517
      break;
2518
    case SIM_SH_BANK_GBR_REGNUM:
2519
      val = saved_state.asregs.regstack[gdb_bank_number].regs[REGBANK_GBR];
2520
      break;
2521
    case SIM_SH_BANK_PR_REGNUM:
2522
      val = saved_state.asregs.regstack[gdb_bank_number].regs[REGBANK_PR];
2523
      break;
2524
    case SIM_SH_BANK_IVN_REGNUM:
2525
      val = saved_state.asregs.regstack[gdb_bank_number].regs[REGBANK_IVN];
2526
      break;
2527
    case SIM_SH_BANK_MACH_REGNUM:
2528
      val = saved_state.asregs.regstack[gdb_bank_number].regs[REGBANK_MACH];
2529
      break;
2530
    default:
2531
      return 0;
2532
    }
2533
  * (int *) memory = swap (val);
2534
  return -1;
2535
}
2536
 
2537
int
2538
sim_trace (sd)
2539
     SIM_DESC sd;
2540
{
2541
  tracing = 1;
2542
  sim_resume (sd, 0, 0);
2543
  tracing = 0;
2544
  return 1;
2545
}
2546
 
2547
void
2548
sim_stop_reason (sd, reason, sigrc)
2549
     SIM_DESC sd;
2550
     enum sim_stop *reason;
2551
     int *sigrc;
2552
{
2553
  /* The SH simulator uses SIGQUIT to indicate that the program has
2554
     exited, so we must check for it here and translate it to exit.  */
2555
  if (saved_state.asregs.exception == SIGQUIT)
2556
    {
2557
      *reason = sim_exited;
2558
      *sigrc = saved_state.asregs.regs[5];
2559
    }
2560
  else
2561
    {
2562
      *reason = sim_stopped;
2563
      *sigrc = saved_state.asregs.exception;
2564
    }
2565
}
2566
 
2567
void
2568
sim_info (sd, verbose)
2569
     SIM_DESC sd;
2570
     int verbose;
2571
{
2572
  double timetaken =
2573
    (double) saved_state.asregs.ticks / (double) now_persec ();
2574
  double virttime = saved_state.asregs.cycles / 36.0e6;
2575
 
2576
  callback->printf_filtered (callback, "\n\n# instructions executed  %10d\n",
2577
                             saved_state.asregs.insts);
2578
  callback->printf_filtered (callback, "# cycles                 %10d\n",
2579
                             saved_state.asregs.cycles);
2580
  callback->printf_filtered (callback, "# pipeline stalls        %10d\n",
2581
                             saved_state.asregs.stalls);
2582
  callback->printf_filtered (callback, "# misaligned load/store  %10d\n",
2583
                             saved_state.asregs.memstalls);
2584
  callback->printf_filtered (callback, "# real time taken        %10.4f\n",
2585
                             timetaken);
2586
  callback->printf_filtered (callback, "# virtual time taken     %10.4f\n",
2587
                             virttime);
2588
  callback->printf_filtered (callback, "# profiling size         %10d\n",
2589
                             sim_profile_size);
2590
  callback->printf_filtered (callback, "# profiling frequency    %10d\n",
2591
                             saved_state.asregs.profile);
2592
  callback->printf_filtered (callback, "# profile maxpc          %10x\n",
2593
                             (1 << sim_profile_size) << PROFILE_SHIFT);
2594
 
2595
  if (timetaken != 0)
2596
    {
2597
      callback->printf_filtered (callback, "# cycles/second          %10d\n",
2598
                                 (int) (saved_state.asregs.cycles / timetaken));
2599
      callback->printf_filtered (callback, "# simulation ratio       %10.4f\n",
2600
                                 virttime / timetaken);
2601
    }
2602
}
2603
 
2604
void
2605
sim_set_profile (n)
2606
     int n;
2607
{
2608
  saved_state.asregs.profile = n;
2609
}
2610
 
2611
void
2612
sim_set_profile_size (n)
2613
     int n;
2614
{
2615
  sim_profile_size = n;
2616
}
2617
 
2618
SIM_DESC
2619
sim_open (kind, cb, abfd, argv)
2620
     SIM_OPEN_KIND kind;
2621
     host_callback *cb;
2622
     struct bfd *abfd;
2623
     char **argv;
2624
{
2625
  char **p;
2626
  int endian_set = 0;
2627
  int i;
2628
  union
2629
    {
2630
      int i;
2631
      short s[2];
2632
      char c[4];
2633
    }
2634
  mem_word;
2635
 
2636
  sim_kind = kind;
2637
  myname = argv[0];
2638
  callback = cb;
2639
 
2640
  for (p = argv + 1; *p != NULL; ++p)
2641
    {
2642
      if (strcmp (*p, "-E") == 0)
2643
        {
2644
          ++p;
2645
          if (*p == NULL)
2646
            {
2647
              /* FIXME: This doesn't use stderr, but then the rest of the
2648
                 file doesn't either.  */
2649
              callback->printf_filtered (callback, "Missing argument to `-E'.\n");
2650
              return 0;
2651
            }
2652
          target_little_endian = strcmp (*p, "big") != 0;
2653
          endian_set = 1;
2654
        }
2655
      else if (isdigit (**p))
2656
        parse_and_set_memory_size (*p);
2657
    }
2658
 
2659
  if (abfd != NULL && ! endian_set)
2660
      target_little_endian = ! bfd_big_endian (abfd);
2661
 
2662
  if (abfd)
2663
    init_dsp (abfd);
2664
 
2665
  for (i = 4; (i -= 2) >= 0; )
2666
    mem_word.s[i >> 1] = i;
2667
  global_endianw = mem_word.i >> (target_little_endian ? 0 : 16) & 0xffff;
2668
 
2669
  for (i = 4; --i >= 0; )
2670
    mem_word.c[i] = i;
2671
  endianb = mem_word.i >> (target_little_endian ? 0 : 24) & 0xff;
2672
 
2673
  /* fudge our descriptor for now */
2674
  return (SIM_DESC) 1;
2675
}
2676
 
2677
static void
2678
parse_and_set_memory_size (str)
2679
     char *str;
2680
{
2681
  int n;
2682
 
2683
  n = strtol (str, NULL, 10);
2684
  if (n > 0 && n <= 24)
2685
    sim_memory_size = n;
2686
  else
2687
    callback->printf_filtered (callback, "Bad memory size %d; must be 1 to 24, inclusive\n", n);
2688
}
2689
 
2690
void
2691
sim_close (sd, quitting)
2692
     SIM_DESC sd;
2693
     int quitting;
2694
{
2695
  /* nothing to do */
2696
}
2697
 
2698
SIM_RC
2699
sim_load (sd, prog, abfd, from_tty)
2700
     SIM_DESC sd;
2701
     char *prog;
2702
     bfd *abfd;
2703
     int from_tty;
2704
{
2705
  extern bfd *sim_load_file (); /* ??? Don't know where this should live.  */
2706
  bfd *prog_bfd;
2707
 
2708
  prog_bfd = sim_load_file (sd, myname, callback, prog, abfd,
2709
                            sim_kind == SIM_OPEN_DEBUG,
2710
                            0, sim_write);
2711
 
2712
  /* Set the bfd machine type.  */
2713
  if (prog_bfd)
2714
    saved_state.asregs.bfd_mach = bfd_get_mach (prog_bfd);
2715
  else if (abfd)
2716
    saved_state.asregs.bfd_mach = bfd_get_mach (abfd);
2717
  else
2718
    saved_state.asregs.bfd_mach = 0;
2719
 
2720
  if (prog_bfd == NULL)
2721
    return SIM_RC_FAIL;
2722
  if (abfd == NULL)
2723
    bfd_close (prog_bfd);
2724
  return SIM_RC_OK;
2725
}
2726
 
2727
SIM_RC
2728
sim_create_inferior (sd, prog_bfd, argv, env)
2729
     SIM_DESC sd;
2730
     struct bfd *prog_bfd;
2731
     char **argv;
2732
     char **env;
2733
{
2734
  /* Clear the registers. */
2735
  memset (&saved_state, 0,
2736
          (char*) &saved_state.asregs.end_of_registers - (char*) &saved_state);
2737
 
2738
  /* Set the PC.  */
2739
  if (prog_bfd != NULL)
2740
    saved_state.asregs.pc = bfd_get_start_address (prog_bfd);
2741
 
2742
  /* Set the bfd machine type.  */
2743
  if (prog_bfd != NULL)
2744
    saved_state.asregs.bfd_mach = bfd_get_mach (prog_bfd);
2745
 
2746
  /* Record the program's arguments. */
2747
  prog_argv = argv;
2748
 
2749
  return SIM_RC_OK;
2750
}
2751
 
2752
void
2753
sim_do_command (sd, cmd)
2754
     SIM_DESC sd;
2755
     char *cmd;
2756
{
2757
  char *sms_cmd = "set-memory-size";
2758
  int cmdsize;
2759
 
2760
  if (cmd == NULL || *cmd == '\0')
2761
    {
2762
      cmd = "help";
2763
    }
2764
 
2765
  cmdsize = strlen (sms_cmd);
2766
  if (strncmp (cmd, sms_cmd, cmdsize) == 0
2767
      && strchr (" \t", cmd[cmdsize]) != NULL)
2768
    {
2769
      parse_and_set_memory_size (cmd + cmdsize + 1);
2770
    }
2771
  else if (strcmp (cmd, "help") == 0)
2772
    {
2773
      (callback->printf_filtered) (callback,
2774
                                   "List of SH simulator commands:\n\n");
2775
      (callback->printf_filtered) (callback, "set-memory-size <n> -- Set the number of address bits to use\n");
2776
      (callback->printf_filtered) (callback, "\n");
2777
    }
2778
  else
2779
    {
2780
      (callback->printf_filtered) (callback, "Error: \"%s\" is not a valid SH simulator command.\n", cmd);
2781
    }
2782
}
2783
 
2784
void
2785
sim_set_callbacks (p)
2786
     host_callback *p;
2787
{
2788
  callback = p;
2789
}

powered by: WebSVN 2.1.0

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