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