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