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