OpenCores
URL https://opencores.org/ocsvn/openrisc_2011-10-31/openrisc_2011-10-31/trunk

Subversion Repositories openrisc_2011-10-31

[/] [openrisc/] [trunk/] [gnu-src/] [gdb-6.8/] [sim/] [sh/] [interp.c] - Blame information for rev 320

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

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

powered by: WebSVN 2.1.0

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