1/* 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
82extern unsigned short sh_jump_table[], sh_dsp_table[0x1000], ppi_table[];
83
84int 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
94typedef struct
95{
96  int regs[20];
97} regstacktype;
98
99typedef 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
196saved_state_type saved_state;
197
198struct 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
203static int target_little_endian;
204static int global_endianw, endianb;
205static int target_dsp;
206static int host_little_endian;
207static char **prog_argv;
208
209static int maskw = 0;
210static int maskl = 0;
211
212static SIM_OPEN_KIND sim_kind;
213static char *myname;
214static 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) \
291do { \
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) \
301do { \
302  IBNR = (IBNR & 0xfe00) | (EXP & 0x1f); \
303} while (0)
304#define SET_ME(EXP) \
305do { \
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.  */
334static int
335count_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
347static void
348set_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) \
367do { \
368  set_fpscr1 (x); \
369} while (0)
370
371#define DSR  (saved_state.asregs.sregs.named.fpscr)
372
373int
374fail ()
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
388void
389raise_exception (x)
390     int x;
391{
392  RAISE_EXCEPTION (x);
393}
394
395void
396raise_buserror ()
397{
398  raise_exception (SIGBUS);
399}
400
401#define PROCESS_SPECIAL_ADDRESS(addr, endian, ptr, bits_written, \
402				forbidden_addr_bits, data, retval) \
403do { \
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
466int 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
476static void parse_and_set_memory_size PARAMS ((char *str));
477static int IOMEM PARAMS ((int addr, int write, int value));
478static struct loop_bounds get_loop_bounds PARAMS ((int, int, unsigned char *,
479						   unsigned char *, int, int));
480static void process_wlat_addr PARAMS ((int, int));
481static void process_wwat_addr PARAMS ((int, int));
482static void process_wbat_addr PARAMS ((int, int));
483static int process_rlat_addr PARAMS ((int));
484static int process_rwat_addr PARAMS ((int));
485static int process_rbat_addr PARAMS ((int));
486static void INLINE wlat_fast PARAMS ((unsigned char *, int, int, int));
487static void INLINE wwat_fast PARAMS ((unsigned char *, int, int, int, int));
488static void INLINE wbat_fast PARAMS ((unsigned char *, int, int, int));
489static int INLINE rlat_fast PARAMS ((unsigned char *, int, int));
490static int INLINE rwat_fast PARAMS ((unsigned char *, int, int, int));
491static int INLINE rbat_fast PARAMS ((unsigned char *, int, int));
492
493static host_callback *callback;
494
495
496
497/* Floating point registers */
498
499#define DR(n) (get_dr (n))
500static double
501get_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))
521static void
522set_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
616static void
617set_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
637static void INLINE
638wlat_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
647static void INLINE
648wwat_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
657static void INLINE
658wbat_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
669static int INLINE
670rlat_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
679static int INLINE
680rwat_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
690static int INLINE
691riat_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
699static int INLINE
700rbat_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)))
723static int
724do_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)))
742static int
743do_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
760static void
761process_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
771static void
772process_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
782static void
783process_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
793static int
794process_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
803static int
804process_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
813static int
814process_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
842static 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) \
846do { \
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__)
874int sim_memory_size = 19;
875#else
876int sim_memory_size = 24;
877#endif
878
879static int sim_profile_size = 17;
880static 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
895static int
896IOMEM (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
925static int
926get_now ()
927{
928  return time ((long *) 0);
929}
930
931static int
932now_persec ()
933{
934  return 1;
935}
936
937static FILE *profile_file;
938
939static unsigned INLINE
940swap (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
949static unsigned short INLINE
950swap16 (n)
951     unsigned short n;
952{
953  if (endianb)
954    n = n << 8 | (n & 0xff00) >> 8;
955  return n;
956}
957
958static void
959swapout (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
970static void
971swapout16 (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
981static char *
982ptr (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.)  */
992static int
993strswaplen (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
1007static void
1008strnswap (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
1031static int
1032trap (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
1264void
1265control_c (sig, code, scp, addr)
1266     int sig;
1267     int code;
1268     char *scp;
1269     char *addr;
1270{
1271  raise_exception (SIGINT);
1272}
1273
1274static int
1275div1 (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
1363static void
1364dmul (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
1404static void
1405macw (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
1442static void
1443macl (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
1487enum {
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.  */
1512void
1513do_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.  */
1579void
1580do_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}
1621float
1622fsca_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
1643float
1644fsrra_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
1679static struct loop_bounds
1680get_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
1696static struct loop_bounds
1697get_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
1735static 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
1743void *
1744mcalloc (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
1762void
1763sim_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
1790static void
1791init_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
1884static void
1885init_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
1916static void
1917dump_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
1937static void
1938gotcall (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
1949int
1950sim_stop (sd)
1951     SIM_DESC sd;
1952{
1953  raise_exception (SIGINT);
1954  return 1;
1955}
1956
1957void
1958sim_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
2140int
2141sim_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
2158int
2159sim_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
2176static int gdb_bank_number;
2177enum {
2178  REGBANK_MACH = 15,
2179  REGBANK_IVN  = 16,
2180  REGBANK_PR   = 17,
2181  REGBANK_GBR  = 18,
2182  REGBANK_MACL = 19
2183};
2184
2185int
2186sim_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
2362int
2363sim_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
2537int
2538sim_trace (sd)
2539     SIM_DESC sd;
2540{
2541  tracing = 1;
2542  sim_resume (sd, 0, 0);
2543  tracing = 0;
2544  return 1;
2545}
2546
2547void
2548sim_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
2567void
2568sim_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
2604void
2605sim_set_profile (n)
2606     int n;
2607{
2608  saved_state.asregs.profile = n;
2609}
2610
2611void
2612sim_set_profile_size (n)
2613     int n;
2614{
2615  sim_profile_size = n;
2616}
2617
2618SIM_DESC
2619sim_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
2677static void
2678parse_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
2690void
2691sim_close (sd, quitting)
2692     SIM_DESC sd;
2693     int quitting;
2694{
2695  /* nothing to do */
2696}
2697
2698SIM_RC
2699sim_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
2727SIM_RC
2728sim_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
2752void
2753sim_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
2784void
2785sim_set_callbacks (p)
2786     host_callback *p;
2787{
2788  callback = p;
2789}
2790