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