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