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