Remove sanitized-out Magic Cap support, will never be released
[deliverable/binutils-gdb.git] / sim / sh / interp.c
CommitLineData
594266fc
SC
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*/
fe031f82 20
0b0cc453
DE
21#include "config.h"
22
631f6b24 23#include <signal.h>
0b0cc453
DE
24#ifdef HAVE_UNISTD_H
25#include <unistd.h>
26#endif
28920b9d 27
90fe361f 28#include "sysdep.h"
631f6b24 29#include "bfd.h"
0b0cc453 30#include "callback.h"
fe031f82 31#include "remote-sim.h"
e9aea0b3
SC
32
33/* This file is local - if newlib changes, then so should this. */
34#include "syscall.h"
edf6a843 35
95295b41 36#include <math.h>
95295b41 37
27172171
SG
38#ifdef _WIN32
39#include <float.h> /* Needed for _isnan() */
40#define isnan _isnan
41#endif
42
edf6a843
SC
43#ifndef SIGBUS
44#define SIGBUS SIGSEGV
45#endif
e9aea0b3 46
edf6a843
SC
47#ifndef SIGQUIT
48#define SIGQUIT SIGTERM
49#endif
50
27172171
SG
51#ifndef SIGTRAP
52#define SIGTRAP 5
53#endif
54
594266fc
SC
55#define O_RECOMPILE 85
56#define DEFINE_TABLE
594266fc
SC
57#define DISASSEMBLER_TABLE
58
4de6b5d3
AC
59typedef union
60{
61
62 struct
63 {
64
65 int regs[16];
66 int pc;
67 int pr;
68
69 int gbr;
70 int vbr;
71 int mach;
72 int macl;
73
74 int sr;
75
76 int fpul;
77
78 int fpscr;
79
80 /* sh3e */
81 union fregs_u
82 {
83 float f[16];
84 double d[8];
85 int i[16];
86 }
87 /* start-sanitize-sh4 */
88#if 1
89 fregs[2];
90#else
91 /* end-sanitize-sh4 */
92 fregs;
93 /* start-sanitize-sh4 */
94#endif
95 /* end-sanitize-sh4 */
96
97 int ssr;
98 int spc;
99 /* sh3 */
100 int bank[2][8];
101
102 int ticks;
103 int stalls;
104 int memstalls;
105 int cycles;
106 int insts;
107
108 int prevlock;
109 int thislock;
110 int exception;
111
112 int end_of_registers;
113
114 int msize;
115#define PROFILE_FREQ 1
116#define PROFILE_SHIFT 2
117 int profile;
118 unsigned short *profile_hist;
119 unsigned char *memory;
120 }
121 asregs;
122 int asints[28];
123} saved_state_type;
124
125saved_state_type saved_state;
126
127
128/* These variables are at file scope so that functions other than
129 sim_resume can use the fetch/store macros */
130
131static int target_little_endian;
132static int host_little_endian;
133
134#if 1
135static int maskl = ~0;
136static int maskw = ~0;
137#endif
138
139static SIM_OPEN_KIND sim_kind;
140static char *myname;
141
142
143/* Short hand definitions of the registers */
144
594266fc 145#define SBIT(x) ((x)&sbit)
90fe361f
SC
146#define R0 saved_state.asregs.regs[0]
147#define Rn saved_state.asregs.regs[n]
148#define Rm saved_state.asregs.regs[m]
149#define UR0 (unsigned int)(saved_state.asregs.regs[0])
150#define UR (unsigned int)R
151#define UR (unsigned int)R
152#define SR0 saved_state.asregs.regs[0]
153#define GBR saved_state.asregs.gbr
154#define VBR saved_state.asregs.vbr
0b0cc453
DE
155#define SSR saved_state.asregs.ssr
156#define SPC saved_state.asregs.spc
90fe361f
SC
157#define MACH saved_state.asregs.mach
158#define MACL saved_state.asregs.macl
c1bce9f6 159#define FPUL saved_state.asregs.fpul
594266fc 160
594266fc 161#define PC pc
594266fc 162
4de6b5d3
AC
163
164
165/* Alternate bank of registers r0-r6 */
166
167/* Note: code controling SR handles flips between BANK0 and BANK1 */
168#define Rn_BANK(n) (saved_state.asregs.bank[!SR_RB][(n)])
169#define SET_Rn_BANK(n, EXP) do { saved_state.asregs.bank[!SR_RB][(n)] = (EXP); } while (0)
170
171
172/* Manipulate SR */
173
174#define SR_MASK_M (1 << 9)
175#define SR_MASK_Q (1 << 8)
176#define SR_MASK_I (0xf << 4)
177#define SR_MASK_S (1 << 1)
178#define SR_MASK_T (1 << 0)
179
180#define SR_MASK_BL (1 << 28)
181#define SR_MASK_RB (1 << 29)
182#define SR_MASK_MD (1 << 30)
183
184#define M ((saved_state.asregs.sr & SR_MASK_M) != 0)
185#define Q ((saved_state.asregs.sr & SR_MASK_Q) != 0)
186#define S ((saved_state.asregs.sr & SR_MASK_S) != 0)
187#define T ((saved_state.asregs.sr & SR_MASK_T) != 0)
188
189#define SR_BL ((saved_state.asregs.sr & SR_MASK_BL) != 0)
190#define SR_RB ((saved_state.asregs.sr & SR_MASK_RB) != 0)
191#define SR_MD ((saved_state.asregs.sr & SR_MASK_MD) != 0)
192
193/* Note: don't use this for privileged bits */
194#define SET_SR_BIT(EXP, BIT) \
195do { \
196 if ((EXP) & 1) \
197 saved_state.asregs.sr |= (BIT); \
198 else \
199 saved_state.asregs.sr &= ~(BIT); \
200} while (0)
201
202#define SET_SR_M(EXP) SET_SR_BIT ((EXP), SR_MASK_M)
203#define SET_SR_Q(EXP) SET_SR_BIT ((EXP), SR_MASK_Q)
204#define SET_SR_S(EXP) SET_SR_BIT ((EXP), SR_MASK_S)
205#define SET_SR_T(EXP) SET_SR_BIT ((EXP), SR_MASK_T)
206
207#define GET_SR() (saved_state.asregs.sr - 0)
208#define SET_SR(x) set_sr (x)
209static void
210set_sr (new_sr)
211 int new_sr;
212{
213 /* do we need to swap banks */
214 int old_gpr = (SR_MD ? !SR_RB : 0);
215 int new_gpr = ((new_sr & SR_MASK_MD)
216 ? (new_sr & SR_MASK_RB) == 0
217 : 0);
218 if (old_gpr != new_gpr)
219 {
220 int i;
221 for (i = 0; i < 8; i++)
222 {
223 saved_state.asregs.bank[old_gpr][i] = saved_state.asregs.regs[i];
224 saved_state.asregs.regs[i] = saved_state.asregs.bank[new_gpr][i];
225 }
226 }
227}
228
229
230/* Manipulate FPSCR */
231
232/* start-sanitize-sh4 */
233#if 1
234#define FPSCR_MASK_FR (1 << 21)
235#define FPSCR_MASK_SZ (1 << 20)
236#define FPSCR_MASK_PR (1 << 19)
237
238#define FPSCR_FR ((GET_FPSCR() & FPSCR_MASK_FR) != 0)
239#define FPSCR_SZ ((GET_FPSCR() & FPSCR_MASK_SZ) != 0)
240#define FPSCR_PR ((GET_FPSCR() & FPSCR_MASK_PR) != 0)
241
242static void
243set_fpscr1 (x)
244 int x;
245{
246 int old = saved_state.asregs.fpscr;
247 saved_state.asregs.fpscr = (x);
248 /* swap the floating point register banks */
249 if ((saved_state.asregs.fpscr ^ old) & FPSCR_MASK_FR)
250 {
251 union fregs_u tmpf = saved_state.asregs.fregs[0];
252 saved_state.asregs.fregs[0] = saved_state.asregs.fregs[1];
253 saved_state.asregs.fregs[1] = tmpf;
254 }
255}
256
257#define GET_FPSCR() (saved_state.asregs.fpscr)
258#define SET_FPSCR(x) \
259do { \
260 set_fpscr1 (x); \
261} while (0)
262#else
263/* end-sanitize-sh4 */
264#define set_fpscr1(x)
265#define SET_FPSCR(x) (saved_state.asregs.fpscr = (x))
266#define GET_FPSCR() (saved_state.asregs.fpscr)
267/* start-sanitize-sh4 */
268#endif
269/* end-sanitize-sh4 */
270
0b0cc453 271
4d0be1f5
SC
272int
273fail ()
fe031f82 274{
4d0be1f5 275 abort ();
fe031f82
DE
276}
277
bbce7567 278/* start-sanitize-sh4 */
4de6b5d3
AC
279int
280special_address (addr, bits_written, data)
281 void *addr;
282 int bits_written, data;
283{
284 if ((unsigned) addr >> 24 == 0xf0 && bits_written == 32 && (data & 1) == 0)
285 /* This invalidates (if not associative) or might invalidate
552c6220 286 (if associative) an instruction cache line. This is used for
4de6b5d3
AC
287 trampolines. Since we don't simulate the cache, this is a no-op
288 as far as the simulator is concerned. */
289 return 1;
290 /* We can't do anything useful with the other stuff, so fail. */
291 return 0;
292}
293
bbce7567 294/* end-sanitize-sh4 */
0b0cc453
DE
295/* This function exists solely for the purpose of setting a breakpoint to
296 catch simulated bus errors when running the simulator under GDB. */
297
298void
299bp_holder ()
300{
301}
302
4de6b5d3
AC
303/* FIXME: sim_resume should be renamed to sim_engine_run. sim_resume
304 being implemented by ../common/sim_resume.c and the below should
305 make a call to sim_engine_halt */
306
bbce7567
JR
307/* restore-sanitize-sh4#define BUSERROR(addr, mask) \
308 restore-sanitize-sh4 if (addr & ~mask) { saved_state.asregs.exception = SIGBUS; bp_holder (); }
309 start-sanitize-sh4 */
4de6b5d3
AC
310#define BUSERROR(addr, mask, bits_written, data) \
311 if (addr & ~mask) \
312 { \
313 if (special_address (addr, bits_written, data)) \
314 return; \
315 saved_state.asregs.exception = SIGBUS; \
316 bp_holder (); \
317 }
bbce7567 318/* end-sanitize-sh4 */
fe031f82
DE
319
320/* Define this to enable register lifetime checking.
4d0be1f5 321 The compiler generates "add #0,rn" insns to mark registers as invalid,
fe031f82
DE
322 the simulator uses this info to call fail if it finds a ref to an invalid
323 register before a def
4d0be1f5 324
fe031f82
DE
325 #define PARANOID
326*/
327
328#ifdef PARANOID
329int valid[16];
330#define CREF(x) if(!valid[x]) fail();
331#define CDEF(x) valid[x] = 1;
332#define UNDEF(x) valid[x] = 0;
333#else
334#define CREF(x)
335#define CDEF(x)
336#define UNDEF(x)
337#endif
338
c1bce9f6
JL
339static void parse_and_set_memory_size PARAMS ((char *str));
340
0fb39e84 341static int IOMEM PARAMS ((int addr, int write, int value));
90fe361f 342
0b0cc453 343static host_callback *callback;
28920b9d 344
90fe361f 345
90fe361f 346
4de6b5d3 347/* Floating point registers */
90fe361f 348
4de6b5d3
AC
349/* start-sanitize-sh4 */
350#if 1
90fe361f 351
4de6b5d3
AC
352#define DR(n) (get_dr (n))
353static double
354get_dr (n)
355 int n;
356{
357 n = (n & ~1);
358 if (host_little_endian)
359 {
360 union
361 {
362 int i[2];
363 double d;
364 } dr;
365 dr.i[1] = saved_state.asregs.fregs[0].i[n + 0];
366 dr.i[0] = saved_state.asregs.fregs[0].i[n + 1];
367 return dr.d;
368 }
369 else
370 return (saved_state.asregs.fregs[0].d[n >> 1]);
371}
4d0be1f5 372
4de6b5d3
AC
373#define SET_DR(n, EXP) set_dr ((n), (EXP))
374static void
375set_dr (n, exp)
376 int n;
377 double exp;
378{
379 n = (n & ~1);
380 if (host_little_endian)
381 {
382 union
4d0be1f5 383 {
4de6b5d3
AC
384 int i[2];
385 double d;
386 } dr;
387 dr.d = exp;
388 saved_state.asregs.fregs[0].i[n + 0] = dr.i[1];
389 saved_state.asregs.fregs[0].i[n + 1] = dr.i[0];
390 }
391 else
392 saved_state.asregs.fregs[0].d[n >> 1] = exp;
393}
0b0cc453 394
4de6b5d3
AC
395#define SET_FI(n,EXP) (saved_state.asregs.fregs[0].i[(n)] = (EXP))
396#define FI(n) (saved_state.asregs.fregs[0].i[(n)])
397
398#define FR(n) (saved_state.asregs.fregs[0].f[(n)])
399#define SET_FR(n,EXP) (saved_state.asregs.fregs[0].f[(n)] = (EXP))
400
401#define XD_TO_XF(n) ((((n) & 1) << 5) | ((n) & 0x1e))
402#define XF(n) (saved_state.asregs.fregs[(n) >> 5].i[(n) & 0x1f])
403#define SET_XF(n,EXP) (saved_state.asregs.fregs[(n) >> 5].i[(n) & 0x1f] = (EXP))
404
405
406#define FP_OP(n, OP, m) \
407{ \
408 if (FPSCR_PR) \
409 { \
410 if (((n) & 1) || ((m) & 1)) \
411 saved_state.asregs.exception = SIGILL; \
412 else \
413 SET_DR(n, (DR(n) OP DR(m))); \
414 } \
415 else \
416 SET_FR(n, (FR(n) OP FR(m))); \
417} while (0)
418
419#define FP_UNARY(n, OP) \
420{ \
421 if (FPSCR_PR) \
422 { \
423 if ((n) & 1) \
424 saved_state.asregs.exception = SIGILL; \
425 else \
426 SET_DR(n, (OP (DR(n)))); \
427 } \
428 else \
429 SET_FR(n, (OP (FR(n)))); \
430} while (0)
431
432#define FP_CMP(n, OP, m) \
433{ \
434 if (FPSCR_PR) \
435 { \
436 if (((n) & 1) || ((m) & 1)) \
437 saved_state.asregs.exception = SIGILL; \
438 else \
439 SET_SR_T (DR(n) OP DR(m)); \
440 } \
441 else \
442 SET_SR_T (FR(n) OP FR(m)); \
443} while (0)
0b0cc453 444
4de6b5d3
AC
445#else
446/* end-sanitize-sh4 */
447#define FI(n) (saved_state.asregs.fregs.i[(n)])
448#define FR(n) (saved_state.asregs.fregs.f[(n)])
0b0cc453 449
4de6b5d3
AC
450#define SET_FI(n,EXP) (saved_state.asregs.fregs.i[(n)] = (EXP))
451#define SET_FR(n,EXP) (saved_state.asregs.fregs.f[(n)] = (EXP))
452
453#define FP_OP(n, OP, m) (SET_FR(n, (FR(n) OP FR(m))))
454#define FP_UNARY(n, OP) (SET_FR(n, (OP (FR(n)))))
455#define FP_CMP(n, OP, m) SET_SR_T(FR(n) OP FR(m))
456/* start-sanitize-sh4 */
457#endif
458/* end-sanitize-sh4 */
4d0be1f5 459
0b0cc453 460
4d0be1f5
SC
461
462static void INLINE
463wlat_little (memory, x, value, maskl)
464 unsigned char *memory;
465{
466 int v = value;
467 unsigned char *p = memory + ((x) & maskl);
bbce7567
JR
468/* restore-sanitize-sh4 BUSERROR(x, maskl);
469 start-sanitize-sh4 */
4de6b5d3 470 BUSERROR(x, maskl, 32, v);
bbce7567 471/* end-sanitize-sh4 */
4d0be1f5
SC
472 p[3] = v >> 24;
473 p[2] = v >> 16;
474 p[1] = v >> 8;
475 p[0] = v;
476}
477
478static void INLINE
479wwat_little (memory, x, value, maskw)
480 unsigned char *memory;
481{
482 int v = value;
483 unsigned char *p = memory + ((x) & maskw);
bbce7567
JR
484/* restore-sanitize-sh4 BUSERROR(x, maskw);
485 start-sanitize-sh4 */
4de6b5d3 486 BUSERROR(x, maskw, 16, v);
bbce7567 487/* end-sanitize-sh4 */
4d0be1f5
SC
488
489 p[1] = v >> 8;
490 p[0] = v;
491}
492
4d0be1f5
SC
493static void INLINE
494wbat_any (memory, x, value, maskb)
495 unsigned char *memory;
496{
497 unsigned char *p = memory + (x & maskb);
498 if (x > 0x5000000)
499 IOMEM (x, 1, value);
bbce7567
JR
500/* restore-sanitize-sh4 BUSERROR(x, maskb);
501 start-sanitize-sh4 */
4de6b5d3 502 BUSERROR(x, maskb, 8, value);
bbce7567 503/* end-sanitize-sh4 */
4d0be1f5
SC
504
505 p[0] = value;
506}
90fe361f 507
4d0be1f5
SC
508static void INLINE
509wlat_big (memory, x, value, maskl)
510 unsigned char *memory;
511{
512 int v = value;
513 unsigned char *p = memory + ((x) & maskl);
bbce7567
JR
514/* restore-sanitize-sh4 BUSERROR(x, maskl);
515 start-sanitize-sh4 */
4de6b5d3 516 BUSERROR(x, maskl, 32, v);
bbce7567 517/* end-sanitize-sh4 */
4d0be1f5
SC
518
519 p[0] = v >> 24;
520 p[1] = v >> 16;
521 p[2] = v >> 8;
522 p[3] = v;
523}
524
525static void INLINE
526wwat_big (memory, x, value, maskw)
527 unsigned char *memory;
528{
529 int v = value;
530 unsigned char *p = memory + ((x) & maskw);
bbce7567
JR
531/* restore-sanitize-sh4 BUSERROR(x, maskw);
532 start-sanitize-sh4 */
4de6b5d3 533 BUSERROR(x, maskw, 16, v);
bbce7567 534/* end-sanitize-sh4 */
4d0be1f5
SC
535
536 p[0] = v >> 8;
537 p[1] = v;
538}
539
4d0be1f5
SC
540static void INLINE
541wbat_big (memory, x, value, maskb)
542 unsigned char *memory;
543{
544 unsigned char *p = memory + (x & maskb);
bbce7567
JR
545/* restore-sanitize-sh4 BUSERROR(x, maskb);
546 start-sanitize-sh4 */
4de6b5d3 547 BUSERROR(x, maskb, 8, value);
bbce7567 548/* end-sanitize-sh4 */
4d0be1f5
SC
549
550 if (x > 0x5000000)
551 IOMEM (x, 1, value);
552 p[0] = value;
553}
554
4d0be1f5 555/* Read functions */
0b0cc453 556
4d0be1f5
SC
557static int INLINE
558rlat_little (memory, x, maskl)
559 unsigned char *memory;
560{
561 unsigned char *p = memory + ((x) & maskl);
bbce7567
JR
562/* restore-sanitize-sh4 BUSERROR(x, maskl);
563 start-sanitize-sh4 */
4de6b5d3 564 BUSERROR(x, maskl, -32, -1);
bbce7567 565/* end-sanitize-sh4 */
4d0be1f5
SC
566
567 return (p[3] << 24) | (p[2] << 16) | (p[1] << 8) | p[0];
4d0be1f5
SC
568}
569
570static int INLINE
571rwat_little (memory, x, maskw)
572 unsigned char *memory;
573{
574 unsigned char *p = memory + ((x) & maskw);
bbce7567
JR
575/* restore-sanitize-sh4 BUSERROR(x, maskw);
576 start-sanitize-sh4 */
4de6b5d3 577 BUSERROR(x, maskw, -16, -1);
bbce7567 578/* end-sanitize-sh4 */
4d0be1f5
SC
579
580 return (p[1] << 8) | p[0];
581}
582
583static int INLINE
584rbat_any (memory, x, maskb)
585 unsigned char *memory;
586{
587 unsigned char *p = memory + ((x) & maskb);
bbce7567
JR
588/* restore-sanitize-sh4 BUSERROR(x, maskb);
589 start-sanitize-sh4 */
4de6b5d3 590 BUSERROR(x, maskb, -8, -1);
bbce7567 591/* end-sanitize-sh4 */
4d0be1f5
SC
592
593 return p[0];
594}
595
596static int INLINE
597rlat_big (memory, x, maskl)
598 unsigned char *memory;
599{
600 unsigned char *p = memory + ((x) & maskl);
bbce7567
JR
601/* restore-sanitize-sh4 BUSERROR(x, maskl);
602 start-sanitize-sh4 */
603 BUSERROR(x, maskl, -32, -1);
604/* end-sanitize-sh4 */
4d0be1f5
SC
605
606 return (p[0] << 24) | (p[1] << 16) | (p[2] << 8) | p[3];
4d0be1f5
SC
607}
608
609static int INLINE
610rwat_big (memory, x, maskw)
611 unsigned char *memory;
612{
613 unsigned char *p = memory + ((x) & maskw);
bbce7567
JR
614/* restore-sanitize-sh4 BUSERROR(x, maskw);
615 start-sanitize-sh4 */
4de6b5d3 616 BUSERROR(x, maskw, -16, -1);
bbce7567 617/* end-sanitize-sh4 */
4d0be1f5
SC
618
619 return (p[0] << 8) | p[1];
620}
621
4d0be1f5
SC
622#define RWAT(x) (little_endian ? rwat_little(memory, x, maskw): rwat_big(memory, x, maskw))
623#define RLAT(x) (little_endian ? rlat_little(memory, x, maskl): rlat_big(memory, x, maskl))
624#define RBAT(x) (rbat_any (memory, x, maskb))
625#define WWAT(x,v) (little_endian ? wwat_little(memory, x, v, maskw): wwat_big(memory, x, v, maskw))
626#define WLAT(x,v) (little_endian ? wlat_little(memory, x, v, maskl): wlat_big(memory, x, v, maskl))
627#define WBAT(x,v) (wbat_any (memory, x, v, maskb))
628
629#define RUWAT(x) (RWAT(x) & 0xffff)
630#define RSWAT(x) ((short)(RWAT(x)))
631#define RSBAT(x) (SEXT(RBAT(x)))
90fe361f 632
4de6b5d3
AC
633/* start-sanitize-sh4 */
634#define RDAT(x, n) (do_rdat (memory, (x), (n), (little_endian)))
635static int
636do_rdat (memory, x, n, little_endian)
637 char *memory;
638 int x;
639 int n;
640 int little_endian;
641{
642 int f0;
643 int f1;
644 int i = (n & 1);
645 int j = (n & ~1);
646 if (little_endian)
647 {
648 f0 = rlat_little (memory, x + 0, maskl);
649 f1 = rlat_little (memory, x + 4, maskl);
650 }
651 else
652 {
653 f0 = rlat_big (memory, x + 0, maskl);
654 f1 = rlat_big (memory, x + 4, maskl);
655 }
656 saved_state.asregs.fregs[i].i[(j + 0)] = f0;
657 saved_state.asregs.fregs[i].i[(j + 1)] = f1;
658 return 0;
659}
660/* end-sanitize-sh4 */
0b0cc453 661
4de6b5d3
AC
662/* start-sanitize-sh4 */
663#define WDAT(x, n) (do_wdat (memory, (x), (n), (little_endian)))
664static int
665do_wdat (memory, x, n, little_endian)
666 char *memory;
667 int x;
668 int n;
669 int little_endian;
670{
671 int f0;
672 int f1;
673 int i = (n & 1);
674 int j = (n & ~1);
675 f0 = saved_state.asregs.fregs[i].i[(j + 0)];
676 f1 = saved_state.asregs.fregs[i].i[(j + 1)];
677 if (little_endian)
678 {
679 wlat_little (memory, (x + 0), f0, maskl);
680 wlat_little (memory, (x + 4), f1, maskl);
681 }
682 else
683 {
684 wlat_big (memory, (x + 0), f0, maskl);
685 wlat_big (memory, (x + 4), f1, maskl);
686 }
687 return 0;
688}
689/* end-sanitize-sh4 */
690
691
692#define MA(n) do { memstalls += (((pc & 3) != 0) ? (n) : ((n) - 1)); } while (0)
693
694#define SEXT(x) (((x & 0xff) ^ (~0x7f))+0x80)
695#define SEXT12(x) (((x & 0xfff) ^ 0x800) - 0x800)
90fe361f
SC
696#define SEXTW(y) ((int)((short)y))
697
4de6b5d3 698#define Delay_Slot(TEMPPC) iword = RUWAT(TEMPPC); goto top;
90fe361f 699
fe031f82
DE
700int empty[16];
701
90fe361f
SC
702#define L(x) thislock = x;
703#define TL(x) if ((x) == prevlock) stalls++;
704#define TB(x,y) if ((x) == prevlock || (y)==prevlock) stalls++;
fe031f82 705
27172171 706#if defined(__GO32__) || defined(_WIN32)
90fe361f 707int sim_memory_size = 19;
fe031f82
DE
708#else
709int sim_memory_size = 24;
710#endif
711
90fe361f
SC
712static int sim_profile_size = 17;
713static int nsamples;
631f6b24 714
4d0be1f5
SC
715#undef TB
716#define TB(x,y)
594266fc 717
4d0be1f5
SC
718#define SMR1 (0x05FFFEC8) /* Channel 1 serial mode register */
719#define BRR1 (0x05FFFEC9) /* Channel 1 bit rate register */
720#define SCR1 (0x05FFFECA) /* Channel 1 serial control register */
721#define TDR1 (0x05FFFECB) /* Channel 1 transmit data register */
722#define SSR1 (0x05FFFECC) /* Channel 1 serial status register */
723#define RDR1 (0x05FFFECD) /* Channel 1 receive data register */
594266fc 724
4d0be1f5
SC
725#define SCI_RDRF 0x40 /* Recieve data register full */
726#define SCI_TDRE 0x80 /* Transmit data register empty */
594266fc 727
4d0be1f5
SC
728static int
729IOMEM (addr, write, value)
730 int addr;
731 int write;
732 int value;
733{
4d0be1f5
SC
734 if (write)
735 {
736 switch (addr)
594266fc 737 {
4d0be1f5
SC
738 case TDR1:
739 if (value != '\r')
594266fc 740 {
4d0be1f5
SC
741 putchar (value);
742 fflush (stdout);
594266fc 743 }
4d0be1f5
SC
744 break;
745 }
746 }
747 else
748 {
749 switch (addr)
750 {
751 case RDR1:
752 return getchar ();
594266fc 753 }
594266fc 754 }
0b0cc453 755 return 0;
594266fc
SC
756}
757
594266fc
SC
758static int
759get_now ()
760{
4d0be1f5 761 return time ((long *) 0);
594266fc
SC
762}
763
764static int
765now_persec ()
766{
631f6b24 767 return 1;
90fe361f
SC
768}
769
90fe361f
SC
770static FILE *profile_file;
771
4d0be1f5
SC
772static void
773swap (memory, n)
774 unsigned char *memory;
90fe361f 775 int n;
fdc506e6 776{
4de6b5d3 777 int little_endian = target_little_endian;
4d0be1f5 778 WLAT (0, n);
90fe361f 779}
0b0cc453 780
4d0be1f5
SC
781static void
782swap16 (memory, n)
783 unsigned char *memory;
90fe361f 784 int n;
fdc506e6 785{
4de6b5d3 786 int little_endian = target_little_endian;
4d0be1f5 787 WWAT (0, n);
594266fc
SC
788}
789
90fe361f 790static void
fdc506e6 791swapout (n)
90fe361f
SC
792 int n;
793{
fdc506e6 794 if (profile_file)
90fe361f
SC
795 {
796 char b[4];
fdc506e6
SC
797 swap (b, n);
798 fwrite (b, 4, 1, profile_file);
90fe361f 799 }
fdc506e6 800}
90fe361f
SC
801
802static void
fdc506e6 803swapout16 (n)
90fe361f
SC
804 int n;
805{
806 char b[4];
fdc506e6
SC
807 swap16 (b, n);
808 fwrite (b, 2, 1, profile_file);
809}
90fe361f 810
90fe361f
SC
811/* Turn a pointer in a register into a pointer into real memory. */
812
813static char *
814ptr (x)
815 int x;
816{
fdc506e6 817 return (char *) (x + saved_state.asregs.memory);
90fe361f
SC
818}
819
fe031f82 820/* Simulate a monitor trap, put the result into r0 and errno into r1 */
0b0cc453 821
90fe361f 822static void
4d0be1f5 823trap (i, regs, memory, maskl, maskw, little_endian)
90fe361f 824 int i;
594266fc 825 int *regs;
4d0be1f5 826 unsigned char *memory;
594266fc
SC
827{
828 switch (i)
829 {
830 case 1:
831 printf ("%c", regs[0]);
832 break;
833 case 2:
834 saved_state.asregs.exception = SIGQUIT;
835 break;
e9aea0b3 836 case 3: /* FIXME: for backwards compat, should be removed */
c1bce9f6 837 case 34:
90fe361f
SC
838 {
839 extern int errno;
840 int perrno = errno;
841 errno = 0;
842
843 switch (regs[4])
844 {
4d0be1f5 845
27172171 846#if !defined(__GO32__) && !defined(_WIN32)
4d0be1f5
SC
847 case SYS_fork:
848 regs[0] = fork ();
849 break;
fe031f82 850 case SYS_execve:
28920b9d 851 regs[0] = execve (ptr (regs[5]), (char **)ptr (regs[6]), (char **)ptr (regs[7]));
fe031f82
DE
852 break;
853 case SYS_execv:
28920b9d 854 regs[0] = execve (ptr (regs[5]),(char **) ptr (regs[6]), 0);
fe031f82
DE
855 break;
856 case SYS_pipe:
857 {
4d0be1f5 858 char *buf;
fe031f82
DE
859 int host_fd[2];
860
4d0be1f5 861 buf = ptr (regs[5]);
fe031f82 862
4d0be1f5 863 regs[0] = pipe (host_fd);
fe031f82 864
4d0be1f5
SC
865 WLAT (buf, host_fd[0]);
866 buf += 4;
867 WLAT (buf, host_fd[1]);
fe031f82
DE
868 }
869 break;
870
4d0be1f5
SC
871 case SYS_wait:
872 regs[0] = wait (ptr (regs[5]));
fe031f82
DE
873 break;
874#endif
4d0be1f5 875
fe031f82 876 case SYS_read:
28920b9d 877 regs[0] = callback->read (callback, regs[5], ptr (regs[6]), regs[7]);
90fe361f 878 break;
fe031f82 879 case SYS_write:
5897a29e 880 if (regs[5] == 1)
28920b9d 881 regs[0] = (int)callback->write_stdout (callback, ptr(regs[6]), regs[7]);
5897a29e 882 else
28920b9d 883 regs[0] = (int)callback->write (callback, regs[5], ptr (regs[6]), regs[7]);
90fe361f 884 break;
fe031f82 885 case SYS_lseek:
28920b9d 886 regs[0] = callback->lseek (callback,regs[5], regs[6], regs[7]);
90fe361f 887 break;
fe031f82 888 case SYS_close:
28920b9d 889 regs[0] = callback->close (callback,regs[5]);
90fe361f 890 break;
fe031f82 891 case SYS_open:
28920b9d 892 regs[0] = callback->open (callback,ptr (regs[5]), regs[6]);
90fe361f 893 break;
fe031f82 894 case SYS_exit:
0b0cc453 895 /* EXIT - caller can look in r5 to work out the reason */
631f6b24 896 saved_state.asregs.exception = SIGQUIT;
0b0cc453 897 regs[0] = regs[5];
631f6b24 898 break;
4d0be1f5
SC
899
900 case SYS_stat: /* added at hmsi */
fe031f82 901 /* stat system call */
4d0be1f5 902 {
fe031f82
DE
903 struct stat host_stat;
904 char *buf;
905
4d0be1f5
SC
906 regs[0] = stat (ptr (regs[5]), &host_stat);
907
908 buf = ptr (regs[6]);
909
910 WWAT (buf, host_stat.st_dev);
911 buf += 2;
912 WWAT (buf, host_stat.st_ino);
913 buf += 2;
914 WLAT (buf, host_stat.st_mode);
915 buf += 4;
916 WWAT (buf, host_stat.st_nlink);
917 buf += 2;
918 WWAT (buf, host_stat.st_uid);
919 buf += 2;
920 WWAT (buf, host_stat.st_gid);
921 buf += 2;
922 WWAT (buf, host_stat.st_rdev);
923 buf += 2;
924 WLAT (buf, host_stat.st_size);
925 buf += 4;
926 WLAT (buf, host_stat.st_atime);
927 buf += 4;
928 WLAT (buf, 0);
929 buf += 4;
930 WLAT (buf, host_stat.st_mtime);
931 buf += 4;
932 WLAT (buf, 0);
933 buf += 4;
934 WLAT (buf, host_stat.st_ctime);
935 buf += 4;
936 WLAT (buf, 0);
937 buf += 4;
938 WLAT (buf, 0);
939 buf += 4;
940 WLAT (buf, 0);
941 buf += 4;
942 }
943 break;
fe031f82 944
27172171 945#ifndef _WIN32
4d0be1f5
SC
946 case SYS_chown:
947 regs[0] = chown (ptr (regs[5]), regs[6], regs[7]);
fe031f82 948 break;
27172171 949#endif /* _WIN32 */
fe031f82 950 case SYS_chmod:
4d0be1f5
SC
951 regs[0] = chmod (ptr (regs[5]), regs[6]);
952 break;
953 case SYS_utime:
437fb926
JW
954 /* Cast the second argument to void *, to avoid type mismatch
955 if a prototype is present. */
956 regs[0] = utime (ptr (regs[5]), (void *) ptr (regs[6]));
fe031f82 957 break;
90fe361f
SC
958 default:
959 abort ();
960 }
0b0cc453 961 regs[1] = callback->get_errno (callback);
90fe361f
SC
962 errno = perrno;
963 }
90fe361f
SC
964 break;
965
4d0be1f5 966 case 0xc3:
594266fc 967 case 255:
631f6b24 968 saved_state.asregs.exception = SIGTRAP;
594266fc
SC
969 break;
970 }
971
972}
0b0cc453 973
594266fc
SC
974void
975control_c (sig, code, scp, addr)
976 int sig;
977 int code;
978 char *scp;
979 char *addr;
980{
981 saved_state.asregs.exception = SIGINT;
982}
983
fdc506e6 984static int
4de6b5d3 985div1 (R, iRn2, iRn1/*, T*/)
594266fc 986 int *R;
90fe361f
SC
987 int iRn1;
988 int iRn2;
4de6b5d3 989 /* int T;*/
594266fc
SC
990{
991 unsigned long tmp0;
992 unsigned char old_q, tmp1;
90fe361f 993
594266fc 994 old_q = Q;
4de6b5d3 995 SET_SR_Q ((unsigned char) ((0x80000000 & R[iRn1]) != 0));
90fe361f
SC
996 R[iRn1] <<= 1;
997 R[iRn1] |= (unsigned long) T;
998
999 switch (old_q)
594266fc 1000 {
fdc506e6 1001 case 0:
90fe361f 1002 switch (M)
fdc506e6
SC
1003 {
1004 case 0:
1005 tmp0 = R[iRn1];
1006 R[iRn1] -= R[iRn2];
1007 tmp1 = (R[iRn1] > tmp0);
1008 switch (Q)
1009 {
1010 case 0:
4de6b5d3 1011 SET_SR_Q (tmp1);
fdc506e6
SC
1012 break;
1013 case 1:
4de6b5d3 1014 SET_SR_Q ((unsigned char) (tmp1 == 0));
fdc506e6
SC
1015 break;
1016 }
1017 break;
1018 case 1:
1019 tmp0 = R[iRn1];
1020 R[iRn1] += R[iRn2];
1021 tmp1 = (R[iRn1] < tmp0);
1022 switch (Q)
1023 {
1024 case 0:
4de6b5d3 1025 SET_SR_Q ((unsigned char) (tmp1 == 0));
fdc506e6
SC
1026 break;
1027 case 1:
4de6b5d3 1028 SET_SR_Q (tmp1);
fdc506e6
SC
1029 break;
1030 }
1031 break;
1032 }
594266fc
SC
1033 break;
1034 case 1:
1035 switch (M)
1036 {
fdc506e6 1037 case 0:
90fe361f
SC
1038 tmp0 = R[iRn1];
1039 R[iRn1] += R[iRn2];
1040 tmp1 = (R[iRn1] < tmp0);
1041 switch (Q)
1042 {
1043 case 0:
4de6b5d3 1044 SET_SR_Q (tmp1);
90fe361f
SC
1045 break;
1046 case 1:
4de6b5d3 1047 SET_SR_Q ((unsigned char) (tmp1 == 0));
fdc506e6 1048 break;
90fe361f 1049 }
594266fc 1050 break;
fdc506e6 1051 case 1:
90fe361f
SC
1052 tmp0 = R[iRn1];
1053 R[iRn1] -= R[iRn2];
1054 tmp1 = (R[iRn1] > tmp0);
1055 switch (Q)
1056 {
1057 case 0:
4de6b5d3 1058 SET_SR_Q ((unsigned char) (tmp1 == 0));
90fe361f
SC
1059 break;
1060 case 1:
4de6b5d3 1061 SET_SR_Q (tmp1);
90fe361f
SC
1062 break;
1063 }
594266fc
SC
1064 break;
1065 }
1066 break;
90fe361f 1067 }
4de6b5d3
AC
1068 /*T = (Q == M);*/
1069 SET_SR_T (Q == M);
1070 /*return T;*/
90fe361f
SC
1071}
1072
4d0be1f5 1073static void
fdc506e6
SC
1074dmul (sign, rm, rn)
1075 int sign;
1076 unsigned int rm;
1077 unsigned int rn;
1078{
1079 unsigned long RnL, RnH;
1080 unsigned long RmL, RmH;
1081 unsigned long temp0, temp1, temp2, temp3;
1082 unsigned long Res2, Res1, Res0;
90fe361f 1083
0fb39e84
TG
1084 RnL = rn & 0xffff;
1085 RnH = (rn >> 16) & 0xffff;
1086 RmL = rm & 0xffff;
1087 RmH = (rm >> 16) & 0xffff;
1088 temp0 = RmL * RnL;
1089 temp1 = RmH * RnL;
1090 temp2 = RmL * RnH;
1091 temp3 = RmH * RnH;
1092 Res2 = 0;
1093 Res1 = temp1 + temp2;
1094 if (Res1 < temp1)
1095 Res2 += 0x00010000;
1096 temp1 = (Res1 << 16) & 0xffff0000;
1097 Res0 = temp0 + temp1;
1098 if (Res0 < temp0)
1099 Res2 += 1;
1100 Res2 += ((Res1 >> 16) & 0xffff) + temp3;
1101
1102 if (sign)
90fe361f 1103 {
0fb39e84
TG
1104 if (rn & 0x80000000)
1105 Res2 -= rm;
1106 if (rm & 0x80000000)
1107 Res2 -= rn;
1108 }
594266fc 1109
0fb39e84
TG
1110 MACH = Res2;
1111 MACL = Res0;
1112}
594266fc 1113
0fb39e84
TG
1114static void
1115macw (regs, memory, n, m)
1116 int *regs;
1117 unsigned char *memory;
1118 int m, n;
1119{
4de6b5d3 1120 int little_endian = target_little_endian;
0fb39e84
TG
1121 long tempm, tempn;
1122 long prod, macl, sum;
fdc506e6 1123
0fb39e84
TG
1124 tempm=RSWAT(regs[m]); regs[m]+=2;
1125 tempn=RSWAT(regs[n]); regs[n]+=2;
1126
1127 macl = MACL;
1128 prod = (long)(short) tempm * (long)(short) tempn;
1129 sum = prod + macl;
1130 if (S)
1131 {
1132 if ((~(prod ^ macl) & (sum ^ prod)) < 0)
1133 {
1134 /* MACH's lsb is a sticky overflow bit. */
1135 MACH |= 1;
1136 /* Store the smallest negative number in MACL if prod is
1137 negative, and the largest positive number otherwise. */
1138 sum = 0x7fffffff + (prod < 0);
1139 }
1140 }
fdc506e6 1141 else
90fe361f 1142 {
edf6a843 1143 long mach;
0fb39e84 1144 /* Add to MACH the sign extended product, and carry from low sum. */
edf6a843
SC
1145 mach = MACH + (-(prod < 0)) + ((unsigned long) sum < prod);
1146 /* Sign extend at 10:th bit in MACH. */
1147 MACH = (mach & 0x1ff) | -(mach & 0x200);
90fe361f 1148 }
0fb39e84 1149 MACL = sum;
594266fc
SC
1150}
1151
90fe361f
SC
1152/* Set the memory size to the power of two provided. */
1153
1154void
1155sim_size (power)
1156 int power;
1157
1158{
1159 saved_state.asregs.msize = 1 << power;
1160
fdc506e6 1161 sim_memory_size = power;
90fe361f 1162
90fe361f
SC
1163 if (saved_state.asregs.memory)
1164 {
1165 free (saved_state.asregs.memory);
1166 }
1167
1168 saved_state.asregs.memory =
1169 (unsigned char *) calloc (64, saved_state.asregs.msize / 64);
1170
1171 if (!saved_state.asregs.memory)
1172 {
1173 fprintf (stderr,
4d0be1f5 1174 "Not enough VM for simulation of %d bytes of RAM\n",
90fe361f
SC
1175 saved_state.asregs.msize);
1176
1177 saved_state.asregs.msize = 1;
fdc506e6 1178 saved_state.asregs.memory = (unsigned char *) calloc (1, 1);
90fe361f
SC
1179 }
1180}
1181
0b0cc453 1182static void
90fe361f
SC
1183init_pointers ()
1184{
4de6b5d3
AC
1185 host_little_endian = 0;
1186 *(char*)&host_little_endian = 1;
1187 host_little_endian &= 1;
0b0cc453 1188
90fe361f
SC
1189 if (saved_state.asregs.msize != 1 << sim_memory_size)
1190 {
1191 sim_size (sim_memory_size);
1192 }
1193
1194 if (saved_state.asregs.profile && !profile_file)
1195 {
fdc506e6 1196 profile_file = fopen ("gmon.out", "wb");
90fe361f 1197 /* Seek to where to put the call arc data */
fdc506e6 1198 nsamples = (1 << sim_profile_size);
90fe361f 1199
fdc506e6
SC
1200 fseek (profile_file, nsamples * 2 + 12, 0);
1201
1202 if (!profile_file)
90fe361f 1203 {
fdc506e6 1204 fprintf (stderr, "Can't open gmon.out\n");
90fe361f 1205 }
fdc506e6 1206 else
90fe361f
SC
1207 {
1208 saved_state.asregs.profile_hist =
fdc506e6 1209 (unsigned short *) calloc (64, (nsamples * sizeof (short) / 64));
90fe361f
SC
1210 }
1211 }
1212}
1213
1214static void
fdc506e6 1215dump_profile ()
90fe361f 1216{
fdc506e6 1217 unsigned int minpc;
90fe361f
SC
1218 unsigned int maxpc;
1219 unsigned short *p;
90fe361f 1220 int i;
0b0cc453 1221
90fe361f 1222 p = saved_state.asregs.profile_hist;
fdc506e6
SC
1223 minpc = 0;
1224 maxpc = (1 << sim_profile_size);
1225
1226 fseek (profile_file, 0L, 0);
1227 swapout (minpc << PROFILE_SHIFT);
1228 swapout (maxpc << PROFILE_SHIFT);
1229 swapout (nsamples * 2 + 12);
1230 for (i = 0; i < nsamples; i++)
1231 swapout16 (saved_state.asregs.profile_hist[i]);
1232
90fe361f
SC
1233}
1234
0b0cc453 1235static void
fdc506e6 1236gotcall (from, to)
90fe361f
SC
1237 int from;
1238 int to;
1239{
fdc506e6
SC
1240 swapout (from);
1241 swapout (to);
1242 swapout (1);
90fe361f
SC
1243}
1244
1245#define MMASKB ((saved_state.asregs.msize -1) & ~0)
fe031f82 1246
8517f62b
AC
1247int
1248sim_stop (sd)
1249 SIM_DESC sd;
1250{
1251 saved_state.asregs.exception = SIGINT;
1252 return 1;
1253}
1254
90fe361f 1255void
0b0cc453
DE
1256sim_resume (sd, step, siggnal)
1257 SIM_DESC sd;
fe031f82 1258 int step, siggnal;
594266fc 1259{
fdc506e6 1260 register unsigned int pc;
90fe361f
SC
1261 register int cycles = 0;
1262 register int stalls = 0;
0b0cc453 1263 register int memstalls = 0;
90fe361f
SC
1264 register int insts = 0;
1265 register int prevlock;
fdc506e6
SC
1266 register int thislock;
1267 register unsigned int doprofile;
4d0be1f5 1268 register int pollcount = 0;
4de6b5d3 1269 register int little_endian = target_little_endian;
4d0be1f5 1270
594266fc
SC
1271 int tick_start = get_now ();
1272 void (*prev) ();
4de6b5d3 1273 void (*prev_fpe) ();
594266fc
SC
1274 extern unsigned char sh_jump_table0[];
1275
1276 register unsigned char *jump_table = sh_jump_table0;
1277
1278 register int *R = &(saved_state.asregs.regs[0]);
4de6b5d3 1279 /*register int T;*/
594266fc
SC
1280 register int PR;
1281
90fe361f
SC
1282 register int maskb = ((saved_state.asregs.msize - 1) & ~0);
1283 register int maskw = ((saved_state.asregs.msize - 1) & ~1);
1284 register int maskl = ((saved_state.asregs.msize - 1) & ~3);
4d0be1f5 1285 register unsigned char *memory;
c1bce9f6 1286 register unsigned int sbit = ((unsigned int) 1 << 31);
90fe361f 1287
594266fc 1288 prev = signal (SIGINT, control_c);
4de6b5d3 1289 prev_fpe = signal (SIGFPE, SIG_IGN);
594266fc 1290
fdc506e6
SC
1291 init_pointers ();
1292
631f6b24
DE
1293 memory = saved_state.asregs.memory;
1294
594266fc
SC
1295 if (step)
1296 {
1297 saved_state.asregs.exception = SIGTRAP;
1298 }
1299 else
1300 {
1301 saved_state.asregs.exception = 0;
1302 }
1303
1304 pc = saved_state.asregs.pc;
1305 PR = saved_state.asregs.pr;
4de6b5d3 1306 /*T = GET_SR () & SR_MASK_T;*/
90fe361f
SC
1307 prevlock = saved_state.asregs.prevlock;
1308 thislock = saved_state.asregs.thislock;
1309 doprofile = saved_state.asregs.profile;
1310
1311 /* If profiling not enabled, disable it by asking for
1312 profiles infrequently. */
fdc506e6 1313 if (doprofile == 0)
90fe361f 1314 doprofile = ~0;
fdc506e6 1315
594266fc
SC
1316 do
1317 {
fdc506e6
SC
1318 register unsigned int iword = RUWAT (pc);
1319 register unsigned int ult;
4de6b5d3 1320 register unsigned int nia = pc + 2;
4d0be1f5 1321#ifndef ACE_FAST
594266fc 1322 insts++;
4d0be1f5 1323#endif
594266fc
SC
1324 top:
1325
1326#include "code.c"
1327
90fe361f 1328
4de6b5d3 1329 pc = nia;
4d0be1f5 1330
4d0be1f5
SC
1331 pollcount++;
1332 if (pollcount > 1000)
1333 {
1334 pollcount = 0;
8517f62b 1335 if ((*callback->poll_quit) != NULL
d90eb3ff 1336 && (*callback->poll_quit) (callback))
edf6a843 1337 {
8517f62b
AC
1338 sim_stop (sd);
1339 }
edf6a843 1340 }
4d0be1f5
SC
1341
1342#ifndef ACE_FAST
90fe361f
SC
1343 prevlock = thislock;
1344 thislock = 30;
594266fc 1345 cycles++;
90fe361f
SC
1346
1347 if (cycles >= doprofile)
1348 {
4d0be1f5 1349
90fe361f
SC
1350 saved_state.asregs.cycles += doprofile;
1351 cycles -= doprofile;
fdc506e6 1352 if (saved_state.asregs.profile_hist)
90fe361f
SC
1353 {
1354 int n = pc >> PROFILE_SHIFT;
fdc506e6 1355 if (n < nsamples)
90fe361f
SC
1356 {
1357 int i = saved_state.asregs.profile_hist[n];
1358 if (i < 65000)
fdc506e6 1359 saved_state.asregs.profile_hist[n] = i + 1;
90fe361f 1360 }
fdc506e6 1361
90fe361f
SC
1362 }
1363 }
4d0be1f5 1364#endif
594266fc
SC
1365 }
1366 while (!saved_state.asregs.exception);
1367
4d0be1f5 1368 if (saved_state.asregs.exception == SIGILL
edf6a843 1369 || saved_state.asregs.exception == SIGBUS)
594266fc 1370 {
90fe361f 1371 pc -= 2;
594266fc 1372 }
90fe361f 1373
594266fc
SC
1374 saved_state.asregs.ticks += get_now () - tick_start;
1375 saved_state.asregs.cycles += cycles;
90fe361f 1376 saved_state.asregs.stalls += stalls;
0b0cc453 1377 saved_state.asregs.memstalls += memstalls;
594266fc
SC
1378 saved_state.asregs.insts += insts;
1379 saved_state.asregs.pc = pc;
4de6b5d3
AC
1380 /* restore the T and other cached SR bits */
1381 SET_SR (GET_SR());
594266fc
SC
1382 saved_state.asregs.pr = PR;
1383
90fe361f
SC
1384 saved_state.asregs.prevlock = prevlock;
1385 saved_state.asregs.thislock = thislock;
1386
90fe361f
SC
1387 if (profile_file)
1388 {
fdc506e6 1389 dump_profile ();
90fe361f 1390 }
fdc506e6 1391
4de6b5d3 1392 signal (SIGFPE, prev_fpe);
594266fc
SC
1393 signal (SIGINT, prev);
1394}
1395
631f6b24 1396int
0b0cc453
DE
1397sim_write (sd, addr, buffer, size)
1398 SIM_DESC sd;
fe031f82 1399 SIM_ADDR addr;
594266fc
SC
1400 unsigned char *buffer;
1401 int size;
1402{
1403 int i;
0b0cc453 1404
594266fc
SC
1405 init_pointers ();
1406
1407 for (i = 0; i < size; i++)
1408 {
1409 saved_state.asregs.memory[MMASKB & (addr + i)] = buffer[i];
1410 }
fe031f82 1411 return size;
594266fc
SC
1412}
1413
631f6b24 1414int
0b0cc453
DE
1415sim_read (sd, addr, buffer, size)
1416 SIM_DESC sd;
fe031f82
DE
1417 SIM_ADDR addr;
1418 unsigned char *buffer;
594266fc
SC
1419 int size;
1420{
1421 int i;
1422
1423 init_pointers ();
1424
1425 for (i = 0; i < size; i++)
1426 {
1427 buffer[i] = saved_state.asregs.memory[MMASKB & (addr + i)];
1428 }
fe031f82 1429 return size;
594266fc
SC
1430}
1431
90fe361f 1432void
0b0cc453
DE
1433sim_store_register (sd, rn, memory)
1434 SIM_DESC sd;
594266fc 1435 int rn;
4d0be1f5 1436 unsigned char *memory;
594266fc 1437{
4de6b5d3 1438 int little_endian;
0b0cc453 1439 init_pointers ();
4de6b5d3
AC
1440 little_endian = target_little_endian;
1441 if (&saved_state.asints[rn]
1442 == &saved_state.asregs.fpscr)
1443 set_fpscr1 (RLAT(0));
1444 else
1445 saved_state.asints[rn] = RLAT(0);
594266fc
SC
1446}
1447
90fe361f 1448void
0b0cc453
DE
1449sim_fetch_register (sd, rn, memory)
1450 SIM_DESC sd;
594266fc 1451 int rn;
4d0be1f5 1452 unsigned char *memory;
594266fc 1453{
4de6b5d3 1454 int little_endian;
0b0cc453 1455 init_pointers ();
4de6b5d3
AC
1456 little_endian = target_little_endian;
1457 WLAT (0, saved_state.asints[rn]);
594266fc
SC
1458}
1459
1460int
0b0cc453
DE
1461sim_trace (sd)
1462 SIM_DESC sd;
594266fc 1463{
594266fc 1464 return 0;
594266fc
SC
1465}
1466
fe031f82 1467void
0b0cc453
DE
1468sim_stop_reason (sd, reason, sigrc)
1469 SIM_DESC sd;
fe031f82 1470 enum sim_stop *reason;
631f6b24 1471 int *sigrc;
594266fc 1472{
0b0cc453
DE
1473 /* The SH simulator uses SIGQUIT to indicate that the program has
1474 exited, so we must check for it here and translate it to exit. */
1475 if (saved_state.asregs.exception == SIGQUIT)
1476 {
1477 *reason = sim_exited;
1478 *sigrc = saved_state.asregs.regs[5];
1479 }
1480 else
1481 {
1482 *reason = sim_stopped;
1483 *sigrc = saved_state.asregs.exception;
1484 }
594266fc
SC
1485}
1486
90fe361f 1487void
0b0cc453
DE
1488sim_info (sd, verbose)
1489 SIM_DESC sd;
fe031f82 1490 int verbose;
594266fc
SC
1491{
1492 double timetaken = (double) saved_state.asregs.ticks / (double) now_persec ();
90fe361f
SC
1493 double virttime = saved_state.asregs.cycles / 36.0e6;
1494
0b0cc453
DE
1495 callback->printf_filtered (callback, "\n\n# instructions executed %10d\n",
1496 saved_state.asregs.insts);
1497 callback->printf_filtered (callback, "# cycles %10d\n",
1498 saved_state.asregs.cycles);
1499 callback->printf_filtered (callback, "# pipeline stalls %10d\n",
1500 saved_state.asregs.stalls);
1501 callback->printf_filtered (callback, "# misaligned load/store %10d\n",
1502 saved_state.asregs.memstalls);
1503 callback->printf_filtered (callback, "# real time taken %10.4f\n",
1504 timetaken);
1505 callback->printf_filtered (callback, "# virtual time taken %10.4f\n",
1506 virttime);
1507 callback->printf_filtered (callback, "# profiling size %10d\n",
1508 sim_profile_size);
1509 callback->printf_filtered (callback, "# profiling frequency %10d\n",
1510 saved_state.asregs.profile);
1511 callback->printf_filtered (callback, "# profile maxpc %10x\n",
1512 (1 << sim_profile_size) << PROFILE_SHIFT);
fdc506e6
SC
1513
1514 if (timetaken != 0)
90fe361f 1515 {
28920b9d
SC
1516 callback->printf_filtered (callback, "# cycles/second %10d\n",
1517 (int) (saved_state.asregs.cycles / timetaken));
1518 callback->printf_filtered (callback, "# simulation ratio %10.4f\n",
1519 virttime / timetaken);
90fe361f 1520 }
594266fc
SC
1521}
1522
90fe361f 1523void
fdc506e6 1524sim_set_profile (n)
631f6b24 1525 int n;
594266fc 1526{
90fe361f
SC
1527 saved_state.asregs.profile = n;
1528}
1529
1530void
fdc506e6 1531sim_set_profile_size (n)
631f6b24 1532 int n;
90fe361f
SC
1533{
1534 sim_profile_size = n;
594266fc 1535}
631f6b24 1536
0b0cc453 1537SIM_DESC
247fccde 1538sim_open (kind, cb, abfd, argv)
1d77e69d 1539 SIM_OPEN_KIND kind;
247fccde
AC
1540 host_callback *cb;
1541 struct _bfd *abfd;
0b0cc453 1542 char **argv;
631f6b24 1543{
1d77e69d
DE
1544 char **p;
1545
1546 sim_kind = kind;
1547 myname = argv[0];
247fccde 1548 callback = cb;
1d77e69d
DE
1549
1550 for (p = argv + 1; *p != NULL; ++p)
c1bce9f6 1551 {
1d77e69d 1552 if (strcmp (*p, "-E") == 0)
247fccde
AC
1553 {
1554 ++p;
1555 if (*p == NULL)
1556 {
1557 /* FIXME: This doesn't use stderr, but then the rest of the
1558 file doesn't either. */
1559 callback->printf_filtered (callback, "Missing argument to `-E'.\n");
1560 return 0;
1561 }
4de6b5d3 1562 target_little_endian = strcmp (*p, "big") != 0;
247fccde 1563 }
1d77e69d
DE
1564 else if (isdigit (**p))
1565 parse_and_set_memory_size (*p);
c1bce9f6 1566 }
1d77e69d 1567
0b0cc453
DE
1568 /* fudge our descriptor for now */
1569 return (SIM_DESC) 1;
c1bce9f6
JL
1570}
1571
1572static void
1573parse_and_set_memory_size (str)
1574 char *str;
1575{
1576 int n;
1577
1578 n = strtol (str, NULL, 10);
1579 if (n > 0 && n <= 24)
1580 sim_memory_size = n;
1581 else
28920b9d 1582 callback->printf_filtered (callback, "Bad memory size %d; must be 1 to 24, inclusive\n", n);
fe031f82 1583}
631f6b24 1584
fe031f82 1585void
0b0cc453
DE
1586sim_close (sd, quitting)
1587 SIM_DESC sd;
fe031f82
DE
1588 int quitting;
1589{
1590 /* nothing to do */
631f6b24
DE
1591}
1592
1d77e69d
DE
1593SIM_RC
1594sim_load (sd, prog, abfd, from_tty)
0b0cc453 1595 SIM_DESC sd;
fe031f82 1596 char *prog;
1d77e69d 1597 bfd *abfd;
fe031f82 1598 int from_tty;
631f6b24 1599{
1d77e69d
DE
1600 extern bfd *sim_load_file (); /* ??? Don't know where this should live. */
1601 bfd *prog_bfd;
1602
1603 prog_bfd = sim_load_file (sd, myname, callback, prog, abfd,
1604 sim_kind == SIM_OPEN_DEBUG);
1605 if (prog_bfd == NULL)
1606 return SIM_RC_FAIL;
1d77e69d
DE
1607 if (abfd == NULL)
1608 bfd_close (prog_bfd);
1609 return SIM_RC_OK;
631f6b24 1610}
fe031f82 1611
1d77e69d 1612SIM_RC
4de6b5d3 1613sim_create_inferior (sd, prog_bfd, argv, env)
0b0cc453 1614 SIM_DESC sd;
4de6b5d3 1615 struct _bfd *prog_bfd;
fe031f82
DE
1616 char **argv;
1617 char **env;
631f6b24 1618{
bbce7567 1619 /* clear the registers */
4de6b5d3
AC
1620 memset (&saved_state, 0,
1621 (char*)&saved_state.asregs.end_of_registers - (char*)&saved_state);
1622 /* set the PC */
1623 if (prog_bfd != NULL)
1624 saved_state.asregs.pc = bfd_get_start_address (prog_bfd);
1d77e69d 1625 return SIM_RC_OK;
631f6b24
DE
1626}
1627
c1bce9f6 1628void
0b0cc453
DE
1629sim_do_command (sd, cmd)
1630 SIM_DESC sd;
c1bce9f6
JL
1631 char *cmd;
1632{
c1bce9f6 1633 char *sms_cmd = "set-memory-size";
1d77e69d 1634 int cmdsize;
c1bce9f6 1635
1d77e69d
DE
1636 if (cmd == NULL || *cmd == '\0')
1637 {
1638 cmd = "help";
1639 }
c1bce9f6 1640
1d77e69d
DE
1641 cmdsize = strlen (sms_cmd);
1642 if (strncmp (cmd, sms_cmd, cmdsize) == 0 && strchr (" \t", cmd[cmdsize]) != NULL)
1643 {
1644 parse_and_set_memory_size (cmd + cmdsize + 1);
1645 }
c1bce9f6
JL
1646 else if (strcmp (cmd, "help") == 0)
1647 {
1d77e69d
DE
1648 (callback->printf_filtered) (callback, "List of SH simulator commands:\n\n");
1649 (callback->printf_filtered) (callback, "set-memory-size <n> -- Set the number of address bits to use\n");
1650 (callback->printf_filtered) (callback, "\n");
c1bce9f6
JL
1651 }
1652 else
1d77e69d
DE
1653 {
1654 (callback->printf_filtered) (callback, "Error: \"%s\" is not a valid SH simulator command.\n", cmd);
1655 }
c1bce9f6 1656}
28920b9d 1657
28920b9d 1658void
247fccde 1659sim_set_callbacks (p)
28920b9d
SC
1660 host_callback *p;
1661{
1662 callback = p;
1663}
This page took 0.236536 seconds and 4 git commands to generate.