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