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