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