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