]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blob - sim/sh/interp.c
This commit was generated by cvs2svn to track changes on a CVS vendor
[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 "callback.h"
31 #include "remote-sim.h"
32
33 /* This file is local - if newlib changes, then so should this. */
34 #include "syscall.h"
35
36 #include <math.h>
37
38 #ifdef _WIN32
39 #include <float.h> /* Needed for _isnan() */
40 #define isnan _isnan
41 #endif
42
43 #ifndef SIGBUS
44 #define SIGBUS SIGSEGV
45 #endif
46
47 #ifndef SIGQUIT
48 #define SIGQUIT SIGTERM
49 #endif
50
51 #ifndef SIGTRAP
52 #define SIGTRAP 5
53 #endif
54
55 #define O_RECOMPILE 85
56 #define DEFINE_TABLE
57 #define DISASSEMBLER_TABLE
58
59 /* Define the rate at which the simulator should poll the host
60 for a quit. */
61 #define POLL_QUIT_INTERVAL 0x60000
62
63 typedef union
64 {
65
66 struct
67 {
68 /* On targets like sparc-sun-solaris, fregs will be aligned on a 64 bit
69 boundary (because of the d member). To avoid padding between
70 registers - which whould make the job of sim_fetch_register harder,
71 we add padding at the start. */
72 int pad_dummy;
73 int regs[16];
74 int pc;
75 int pr;
76
77 int gbr;
78 int vbr;
79 int mach;
80 int macl;
81
82 int sr;
83
84 int fpul;
85
86 int fpscr;
87
88 /* sh3e */
89 union fregs_u
90 {
91 float f[16];
92 double d[8];
93 int i[16];
94 }
95 fregs[2];
96
97 int ssr;
98 int spc;
99 /* sh3 */
100 int bank[2][8];
101
102 int ticks;
103 int stalls;
104 int memstalls;
105 int cycles;
106 int insts;
107
108 int prevlock;
109 int thislock;
110 int exception;
111
112 int end_of_registers;
113
114 int msize;
115 #define PROFILE_FREQ 1
116 #define PROFILE_SHIFT 2
117 int profile;
118 unsigned short *profile_hist;
119 unsigned char *memory;
120 }
121 asregs;
122 int asints[40];
123 } saved_state_type;
124
125 saved_state_type saved_state;
126
127
128 /* These variables are at file scope so that functions other than
129 sim_resume can use the fetch/store macros */
130
131 static int target_little_endian;
132 static int host_little_endian;
133
134 #if 1
135 static int maskl = ~0;
136 static int maskw = ~0;
137 #endif
138
139 static SIM_OPEN_KIND sim_kind;
140 static char *myname;
141
142
143 /* Short hand definitions of the registers */
144
145 #define SBIT(x) ((x)&sbit)
146 #define R0 saved_state.asregs.regs[0]
147 #define Rn saved_state.asregs.regs[n]
148 #define Rm saved_state.asregs.regs[m]
149 #define UR0 (unsigned int)(saved_state.asregs.regs[0])
150 #define UR (unsigned int)R
151 #define UR (unsigned int)R
152 #define SR0 saved_state.asregs.regs[0]
153 #define GBR saved_state.asregs.gbr
154 #define VBR saved_state.asregs.vbr
155 #define SSR saved_state.asregs.ssr
156 #define SPC saved_state.asregs.spc
157 #define MACH saved_state.asregs.mach
158 #define MACL saved_state.asregs.macl
159 #define FPUL saved_state.asregs.fpul
160
161 #define PC pc
162
163
164
165 /* Alternate bank of registers r0-r6 */
166
167 /* Note: code controling SR handles flips between BANK0 and BANK1 */
168 #define Rn_BANK(n) (saved_state.asregs.bank[!SR_RB][(n)])
169 #define SET_Rn_BANK(n, EXP) do { saved_state.asregs.bank[!SR_RB][(n)] = (EXP); } while (0)
170
171
172 /* Manipulate SR */
173
174 #define SR_MASK_M (1 << 9)
175 #define SR_MASK_Q (1 << 8)
176 #define SR_MASK_I (0xf << 4)
177 #define SR_MASK_S (1 << 1)
178 #define SR_MASK_T (1 << 0)
179
180 #define SR_MASK_BL (1 << 28)
181 #define SR_MASK_RB (1 << 29)
182 #define SR_MASK_MD (1 << 30)
183
184 #define M ((saved_state.asregs.sr & SR_MASK_M) != 0)
185 #define Q ((saved_state.asregs.sr & SR_MASK_Q) != 0)
186 #define S ((saved_state.asregs.sr & SR_MASK_S) != 0)
187 #define T ((saved_state.asregs.sr & SR_MASK_T) != 0)
188
189 #define SR_BL ((saved_state.asregs.sr & SR_MASK_BL) != 0)
190 #define SR_RB ((saved_state.asregs.sr & SR_MASK_RB) != 0)
191 #define SR_MD ((saved_state.asregs.sr & SR_MASK_MD) != 0)
192
193 /* Note: don't use this for privileged bits */
194 #define SET_SR_BIT(EXP, BIT) \
195 do { \
196 if ((EXP) & 1) \
197 saved_state.asregs.sr |= (BIT); \
198 else \
199 saved_state.asregs.sr &= ~(BIT); \
200 } while (0)
201
202 #define SET_SR_M(EXP) SET_SR_BIT ((EXP), SR_MASK_M)
203 #define SET_SR_Q(EXP) SET_SR_BIT ((EXP), SR_MASK_Q)
204 #define SET_SR_S(EXP) SET_SR_BIT ((EXP), SR_MASK_S)
205 #define SET_SR_T(EXP) SET_SR_BIT ((EXP), SR_MASK_T)
206
207 #define GET_SR() (saved_state.asregs.sr - 0)
208 #define SET_SR(x) set_sr (x)
209 static void
210 set_sr (new_sr)
211 int new_sr;
212 {
213 /* do we need to swap banks */
214 int old_gpr = (SR_MD ? !SR_RB : 0);
215 int new_gpr = ((new_sr & SR_MASK_MD)
216 ? (new_sr & SR_MASK_RB) == 0
217 : 0);
218 if (old_gpr != new_gpr)
219 {
220 int i;
221 for (i = 0; i < 8; i++)
222 {
223 saved_state.asregs.bank[old_gpr][i] = saved_state.asregs.regs[i];
224 saved_state.asregs.regs[i] = saved_state.asregs.bank[new_gpr][i];
225 }
226 }
227 }
228
229
230 /* Manipulate FPSCR */
231
232 #define FPSCR_MASK_FR (1 << 21)
233 #define FPSCR_MASK_SZ (1 << 20)
234 #define FPSCR_MASK_PR (1 << 19)
235
236 #define FPSCR_FR ((GET_FPSCR() & FPSCR_MASK_FR) != 0)
237 #define FPSCR_SZ ((GET_FPSCR() & FPSCR_MASK_SZ) != 0)
238 #define FPSCR_PR ((GET_FPSCR() & FPSCR_MASK_PR) != 0)
239
240 static void
241 set_fpscr1 (x)
242 int x;
243 {
244 int old = saved_state.asregs.fpscr;
245 saved_state.asregs.fpscr = (x);
246 /* swap the floating point register banks */
247 if ((saved_state.asregs.fpscr ^ old) & FPSCR_MASK_FR)
248 {
249 union fregs_u tmpf = saved_state.asregs.fregs[0];
250 saved_state.asregs.fregs[0] = saved_state.asregs.fregs[1];
251 saved_state.asregs.fregs[1] = tmpf;
252 }
253 }
254
255 #define GET_FPSCR() (saved_state.asregs.fpscr)
256 #define SET_FPSCR(x) \
257 do { \
258 set_fpscr1 (x); \
259 } while (0)
260
261
262 int
263 fail ()
264 {
265 abort ();
266 }
267
268 int
269 special_address (addr, bits_written, data)
270 void *addr;
271 int bits_written, data;
272 {
273 if ((unsigned) addr >> 24 == 0xf0 && bits_written == 32 && (data & 1) == 0)
274 /* This invalidates (if not associative) or might invalidate
275 (if associative) an instruction cache line. This is used for
276 trampolines. Since we don't simulate the cache, this is a no-op
277 as far as the simulator is concerned. */
278 return 1;
279 /* We can't do anything useful with the other stuff, so fail. */
280 return 0;
281 }
282
283 /* This function exists solely for the purpose of setting a breakpoint to
284 catch simulated bus errors when running the simulator under GDB. */
285
286 void
287 bp_holder ()
288 {
289 }
290
291 /* FIXME: sim_resume should be renamed to sim_engine_run. sim_resume
292 being implemented by ../common/sim_resume.c and the below should
293 make a call to sim_engine_halt */
294
295 #define BUSERROR(addr, mask, bits_written, data) \
296 if (addr & ~mask) \
297 { \
298 if (special_address (addr, bits_written, data)) \
299 return; \
300 saved_state.asregs.exception = SIGBUS; \
301 bp_holder (); \
302 }
303
304 /* Define this to enable register lifetime checking.
305 The compiler generates "add #0,rn" insns to mark registers as invalid,
306 the simulator uses this info to call fail if it finds a ref to an invalid
307 register before a def
308
309 #define PARANOID
310 */
311
312 #ifdef PARANOID
313 int valid[16];
314 #define CREF(x) if(!valid[x]) fail();
315 #define CDEF(x) valid[x] = 1;
316 #define UNDEF(x) valid[x] = 0;
317 #else
318 #define CREF(x)
319 #define CDEF(x)
320 #define UNDEF(x)
321 #endif
322
323 static void parse_and_set_memory_size PARAMS ((char *str));
324
325 static int IOMEM PARAMS ((int addr, int write, int value));
326
327 static host_callback *callback;
328
329
330
331 /* Floating point registers */
332
333 #define DR(n) (get_dr (n))
334 static double
335 get_dr (n)
336 int n;
337 {
338 n = (n & ~1);
339 if (host_little_endian)
340 {
341 union
342 {
343 int i[2];
344 double d;
345 } dr;
346 dr.i[1] = saved_state.asregs.fregs[0].i[n + 0];
347 dr.i[0] = saved_state.asregs.fregs[0].i[n + 1];
348 return dr.d;
349 }
350 else
351 return (saved_state.asregs.fregs[0].d[n >> 1]);
352 }
353
354 #define SET_DR(n, EXP) set_dr ((n), (EXP))
355 static void
356 set_dr (n, exp)
357 int n;
358 double exp;
359 {
360 n = (n & ~1);
361 if (host_little_endian)
362 {
363 union
364 {
365 int i[2];
366 double d;
367 } dr;
368 dr.d = exp;
369 saved_state.asregs.fregs[0].i[n + 0] = dr.i[1];
370 saved_state.asregs.fregs[0].i[n + 1] = dr.i[0];
371 }
372 else
373 saved_state.asregs.fregs[0].d[n >> 1] = exp;
374 }
375
376 #define SET_FI(n,EXP) (saved_state.asregs.fregs[0].i[(n)] = (EXP))
377 #define FI(n) (saved_state.asregs.fregs[0].i[(n)])
378
379 #define FR(n) (saved_state.asregs.fregs[0].f[(n)])
380 #define SET_FR(n,EXP) (saved_state.asregs.fregs[0].f[(n)] = (EXP))
381
382 #define XD_TO_XF(n) ((((n) & 1) << 5) | ((n) & 0x1e))
383 #define XF(n) (saved_state.asregs.fregs[(n) >> 5].i[(n) & 0x1f])
384 #define SET_XF(n,EXP) (saved_state.asregs.fregs[(n) >> 5].i[(n) & 0x1f] = (EXP))
385
386
387 #define FP_OP(n, OP, m) \
388 { \
389 if (FPSCR_PR) \
390 { \
391 if (((n) & 1) || ((m) & 1)) \
392 saved_state.asregs.exception = SIGILL; \
393 else \
394 SET_DR(n, (DR(n) OP DR(m))); \
395 } \
396 else \
397 SET_FR(n, (FR(n) OP FR(m))); \
398 } while (0)
399
400 #define FP_UNARY(n, OP) \
401 { \
402 if (FPSCR_PR) \
403 { \
404 if ((n) & 1) \
405 saved_state.asregs.exception = SIGILL; \
406 else \
407 SET_DR(n, (OP (DR(n)))); \
408 } \
409 else \
410 SET_FR(n, (OP (FR(n)))); \
411 } while (0)
412
413 #define FP_CMP(n, OP, m) \
414 { \
415 if (FPSCR_PR) \
416 { \
417 if (((n) & 1) || ((m) & 1)) \
418 saved_state.asregs.exception = SIGILL; \
419 else \
420 SET_SR_T (DR(n) OP DR(m)); \
421 } \
422 else \
423 SET_SR_T (FR(n) OP FR(m)); \
424 } while (0)
425
426
427
428 static void INLINE
429 wlat_little (memory, x, value, maskl)
430 unsigned char *memory;
431 {
432 int v = value;
433 unsigned char *p = memory + ((x) & maskl);
434 BUSERROR(x, maskl, 32, v);
435 p[3] = v >> 24;
436 p[2] = v >> 16;
437 p[1] = v >> 8;
438 p[0] = v;
439 }
440
441 static void INLINE
442 wwat_little (memory, x, value, maskw)
443 unsigned char *memory;
444 {
445 int v = value;
446 unsigned char *p = memory + ((x) & maskw);
447 BUSERROR(x, maskw, 16, v);
448
449 p[1] = v >> 8;
450 p[0] = v;
451 }
452
453 static void INLINE
454 wbat_any (memory, x, value, maskb)
455 unsigned char *memory;
456 {
457 unsigned char *p = memory + (x & maskb);
458 if (x > 0x5000000)
459 IOMEM (x, 1, value);
460 BUSERROR(x, maskb, 8, value);
461
462 p[0] = value;
463 }
464
465 static void INLINE
466 wlat_big (memory, x, value, maskl)
467 unsigned char *memory;
468 {
469 int v = value;
470 unsigned char *p = memory + ((x) & maskl);
471 BUSERROR(x, maskl, 32, v);
472
473 p[0] = v >> 24;
474 p[1] = v >> 16;
475 p[2] = v >> 8;
476 p[3] = v;
477 }
478
479 static void INLINE
480 wwat_big (memory, x, value, maskw)
481 unsigned char *memory;
482 {
483 int v = value;
484 unsigned char *p = memory + ((x) & maskw);
485 BUSERROR(x, maskw, 16, v);
486
487 p[0] = v >> 8;
488 p[1] = v;
489 }
490
491 static void INLINE
492 wbat_big (memory, x, value, maskb)
493 unsigned char *memory;
494 {
495 unsigned char *p = memory + (x & maskb);
496 BUSERROR(x, maskb, 8, value);
497
498 if (x > 0x5000000)
499 IOMEM (x, 1, value);
500 p[0] = value;
501 }
502
503 /* Read functions */
504
505 static int INLINE
506 rlat_little (memory, x, maskl)
507 unsigned char *memory;
508 {
509 unsigned char *p = memory + ((x) & maskl);
510 BUSERROR(x, maskl, -32, -1);
511
512 return (p[3] << 24) | (p[2] << 16) | (p[1] << 8) | p[0];
513 }
514
515 static int INLINE
516 rwat_little (memory, x, maskw)
517 unsigned char *memory;
518 {
519 unsigned char *p = memory + ((x) & maskw);
520 BUSERROR(x, maskw, -16, -1);
521
522 return (p[1] << 8) | p[0];
523 }
524
525 static int INLINE
526 rbat_any (memory, x, maskb)
527 unsigned char *memory;
528 {
529 unsigned char *p = memory + ((x) & maskb);
530 BUSERROR(x, maskb, -8, -1);
531
532 return p[0];
533 }
534
535 static int INLINE
536 rlat_big (memory, x, maskl)
537 unsigned char *memory;
538 {
539 unsigned char *p = memory + ((x) & maskl);
540 BUSERROR(x, maskl, -32, -1);
541
542 return (p[0] << 24) | (p[1] << 16) | (p[2] << 8) | p[3];
543 }
544
545 static int INLINE
546 rwat_big (memory, x, maskw)
547 unsigned char *memory;
548 {
549 unsigned char *p = memory + ((x) & maskw);
550 BUSERROR(x, maskw, -16, -1);
551
552 return (p[0] << 8) | p[1];
553 }
554
555 #define RWAT(x) (little_endian ? rwat_little(memory, x, maskw): rwat_big(memory, x, maskw))
556 #define RLAT(x) (little_endian ? rlat_little(memory, x, maskl): rlat_big(memory, x, maskl))
557 #define RBAT(x) (rbat_any (memory, x, maskb))
558 #define WWAT(x,v) (little_endian ? wwat_little(memory, x, v, maskw): wwat_big(memory, x, v, maskw))
559 #define WLAT(x,v) (little_endian ? wlat_little(memory, x, v, maskl): wlat_big(memory, x, v, maskl))
560 #define WBAT(x,v) (wbat_any (memory, x, v, maskb))
561
562 #define RUWAT(x) (RWAT(x) & 0xffff)
563 #define RSWAT(x) ((short)(RWAT(x)))
564 #define RSBAT(x) (SEXT(RBAT(x)))
565
566 #define RDAT(x, n) (do_rdat (memory, (x), (n), (little_endian)))
567 static int
568 do_rdat (memory, x, n, little_endian)
569 char *memory;
570 int x;
571 int n;
572 int little_endian;
573 {
574 int f0;
575 int f1;
576 int i = (n & 1);
577 int j = (n & ~1);
578 if (little_endian)
579 {
580 f0 = rlat_little (memory, x + 0, maskl);
581 f1 = rlat_little (memory, x + 4, maskl);
582 }
583 else
584 {
585 f0 = rlat_big (memory, x + 0, maskl);
586 f1 = rlat_big (memory, x + 4, maskl);
587 }
588 saved_state.asregs.fregs[i].i[(j + 0)] = f0;
589 saved_state.asregs.fregs[i].i[(j + 1)] = f1;
590 return 0;
591 }
592
593 #define WDAT(x, n) (do_wdat (memory, (x), (n), (little_endian)))
594 static int
595 do_wdat (memory, x, n, little_endian)
596 char *memory;
597 int x;
598 int n;
599 int little_endian;
600 {
601 int f0;
602 int f1;
603 int i = (n & 1);
604 int j = (n & ~1);
605 f0 = saved_state.asregs.fregs[i].i[(j + 0)];
606 f1 = saved_state.asregs.fregs[i].i[(j + 1)];
607 if (little_endian)
608 {
609 wlat_little (memory, (x + 0), f0, maskl);
610 wlat_little (memory, (x + 4), f1, maskl);
611 }
612 else
613 {
614 wlat_big (memory, (x + 0), f0, maskl);
615 wlat_big (memory, (x + 4), f1, maskl);
616 }
617 return 0;
618 }
619
620
621 #define MA(n) do { memstalls += (((pc & 3) != 0) ? (n) : ((n) - 1)); } while (0)
622
623 #define SEXT(x) (((x & 0xff) ^ (~0x7f))+0x80)
624 #define SEXT12(x) (((x & 0xfff) ^ 0x800) - 0x800)
625 #define SEXTW(y) ((int)((short)y))
626
627 #define Delay_Slot(TEMPPC) iword = RUWAT(TEMPPC); goto top;
628
629 int empty[16];
630
631 #define L(x) thislock = x;
632 #define TL(x) if ((x) == prevlock) stalls++;
633 #define TB(x,y) if ((x) == prevlock || (y)==prevlock) stalls++;
634
635 #if defined(__GO32__) || defined(_WIN32)
636 int sim_memory_size = 19;
637 #else
638 int sim_memory_size = 24;
639 #endif
640
641 static int sim_profile_size = 17;
642 static int nsamples;
643
644 #undef TB
645 #define TB(x,y)
646
647 #define SMR1 (0x05FFFEC8) /* Channel 1 serial mode register */
648 #define BRR1 (0x05FFFEC9) /* Channel 1 bit rate register */
649 #define SCR1 (0x05FFFECA) /* Channel 1 serial control register */
650 #define TDR1 (0x05FFFECB) /* Channel 1 transmit data register */
651 #define SSR1 (0x05FFFECC) /* Channel 1 serial status register */
652 #define RDR1 (0x05FFFECD) /* Channel 1 receive data register */
653
654 #define SCI_RDRF 0x40 /* Recieve data register full */
655 #define SCI_TDRE 0x80 /* Transmit data register empty */
656
657 static int
658 IOMEM (addr, write, value)
659 int addr;
660 int write;
661 int value;
662 {
663 if (write)
664 {
665 switch (addr)
666 {
667 case TDR1:
668 if (value != '\r')
669 {
670 putchar (value);
671 fflush (stdout);
672 }
673 break;
674 }
675 }
676 else
677 {
678 switch (addr)
679 {
680 case RDR1:
681 return getchar ();
682 }
683 }
684 return 0;
685 }
686
687 static int
688 get_now ()
689 {
690 return time ((long *) 0);
691 }
692
693 static int
694 now_persec ()
695 {
696 return 1;
697 }
698
699 static FILE *profile_file;
700
701 static void
702 swap (memory, n)
703 unsigned char *memory;
704 int n;
705 {
706 int little_endian = target_little_endian;
707 WLAT (0, n);
708 }
709
710 static void
711 swap16 (memory, n)
712 unsigned char *memory;
713 int n;
714 {
715 int little_endian = target_little_endian;
716 WWAT (0, n);
717 }
718
719 static void
720 swapout (n)
721 int n;
722 {
723 if (profile_file)
724 {
725 char b[4];
726 swap (b, n);
727 fwrite (b, 4, 1, profile_file);
728 }
729 }
730
731 static void
732 swapout16 (n)
733 int n;
734 {
735 char b[4];
736 swap16 (b, n);
737 fwrite (b, 2, 1, profile_file);
738 }
739
740 /* Turn a pointer in a register into a pointer into real memory. */
741
742 static char *
743 ptr (x)
744 int x;
745 {
746 return (char *) (x + saved_state.asregs.memory);
747 }
748
749 /* Simulate a monitor trap, put the result into r0 and errno into r1 */
750
751 static void
752 trap (i, regs, memory, maskl, maskw, little_endian)
753 int i;
754 int *regs;
755 unsigned char *memory;
756 {
757 switch (i)
758 {
759 case 1:
760 printf ("%c", regs[0]);
761 break;
762 case 2:
763 saved_state.asregs.exception = SIGQUIT;
764 break;
765 case 3: /* FIXME: for backwards compat, should be removed */
766 case 34:
767 {
768 extern int errno;
769 int perrno = errno;
770 errno = 0;
771
772 switch (regs[4])
773 {
774
775 #if !defined(__GO32__) && !defined(_WIN32)
776 case SYS_fork:
777 regs[0] = fork ();
778 break;
779 case SYS_execve:
780 regs[0] = execve (ptr (regs[5]), (char **)ptr (regs[6]), (char **)ptr (regs[7]));
781 break;
782 case SYS_execv:
783 regs[0] = execve (ptr (regs[5]),(char **) ptr (regs[6]), 0);
784 break;
785 case SYS_pipe:
786 {
787 char *buf;
788 int host_fd[2];
789
790 buf = ptr (regs[5]);
791
792 regs[0] = pipe (host_fd);
793
794 WLAT (buf, host_fd[0]);
795 buf += 4;
796 WLAT (buf, host_fd[1]);
797 }
798 break;
799
800 case SYS_wait:
801 regs[0] = wait (ptr (regs[5]));
802 break;
803 #endif
804
805 case SYS_read:
806 regs[0] = callback->read (callback, regs[5], ptr (regs[6]), regs[7]);
807 break;
808 case SYS_write:
809 if (regs[5] == 1)
810 regs[0] = (int)callback->write_stdout (callback, ptr(regs[6]), regs[7]);
811 else
812 regs[0] = (int)callback->write (callback, regs[5], ptr (regs[6]), regs[7]);
813 break;
814 case SYS_lseek:
815 regs[0] = callback->lseek (callback,regs[5], regs[6], regs[7]);
816 break;
817 case SYS_close:
818 regs[0] = callback->close (callback,regs[5]);
819 break;
820 case SYS_open:
821 regs[0] = callback->open (callback,ptr (regs[5]), regs[6]);
822 break;
823 case SYS_exit:
824 /* EXIT - caller can look in r5 to work out the reason */
825 saved_state.asregs.exception = SIGQUIT;
826 regs[0] = regs[5];
827 break;
828
829 case SYS_stat: /* added at hmsi */
830 /* stat system call */
831 {
832 struct stat host_stat;
833 char *buf;
834
835 regs[0] = stat (ptr (regs[5]), &host_stat);
836
837 buf = ptr (regs[6]);
838
839 WWAT (buf, host_stat.st_dev);
840 buf += 2;
841 WWAT (buf, host_stat.st_ino);
842 buf += 2;
843 WLAT (buf, host_stat.st_mode);
844 buf += 4;
845 WWAT (buf, host_stat.st_nlink);
846 buf += 2;
847 WWAT (buf, host_stat.st_uid);
848 buf += 2;
849 WWAT (buf, host_stat.st_gid);
850 buf += 2;
851 WWAT (buf, host_stat.st_rdev);
852 buf += 2;
853 WLAT (buf, host_stat.st_size);
854 buf += 4;
855 WLAT (buf, host_stat.st_atime);
856 buf += 4;
857 WLAT (buf, 0);
858 buf += 4;
859 WLAT (buf, host_stat.st_mtime);
860 buf += 4;
861 WLAT (buf, 0);
862 buf += 4;
863 WLAT (buf, host_stat.st_ctime);
864 buf += 4;
865 WLAT (buf, 0);
866 buf += 4;
867 WLAT (buf, 0);
868 buf += 4;
869 WLAT (buf, 0);
870 buf += 4;
871 }
872 break;
873
874 #ifndef _WIN32
875 case SYS_chown:
876 regs[0] = chown (ptr (regs[5]), regs[6], regs[7]);
877 break;
878 #endif /* _WIN32 */
879 case SYS_chmod:
880 regs[0] = chmod (ptr (regs[5]), regs[6]);
881 break;
882 case SYS_utime:
883 /* Cast the second argument to void *, to avoid type mismatch
884 if a prototype is present. */
885 regs[0] = utime (ptr (regs[5]), (void *) ptr (regs[6]));
886 break;
887 default:
888 abort ();
889 }
890 regs[1] = callback->get_errno (callback);
891 errno = perrno;
892 }
893 break;
894
895 case 0xc3:
896 case 255:
897 saved_state.asregs.exception = SIGTRAP;
898 break;
899 }
900
901 }
902
903 void
904 control_c (sig, code, scp, addr)
905 int sig;
906 int code;
907 char *scp;
908 char *addr;
909 {
910 saved_state.asregs.exception = SIGINT;
911 }
912
913 static int
914 div1 (R, iRn2, iRn1/*, T*/)
915 int *R;
916 int iRn1;
917 int iRn2;
918 /* int T;*/
919 {
920 unsigned long tmp0;
921 unsigned char old_q, tmp1;
922
923 old_q = Q;
924 SET_SR_Q ((unsigned char) ((0x80000000 & R[iRn1]) != 0));
925 R[iRn1] <<= 1;
926 R[iRn1] |= (unsigned long) T;
927
928 switch (old_q)
929 {
930 case 0:
931 switch (M)
932 {
933 case 0:
934 tmp0 = R[iRn1];
935 R[iRn1] -= R[iRn2];
936 tmp1 = (R[iRn1] > tmp0);
937 switch (Q)
938 {
939 case 0:
940 SET_SR_Q (tmp1);
941 break;
942 case 1:
943 SET_SR_Q ((unsigned char) (tmp1 == 0));
944 break;
945 }
946 break;
947 case 1:
948 tmp0 = R[iRn1];
949 R[iRn1] += R[iRn2];
950 tmp1 = (R[iRn1] < tmp0);
951 switch (Q)
952 {
953 case 0:
954 SET_SR_Q ((unsigned char) (tmp1 == 0));
955 break;
956 case 1:
957 SET_SR_Q (tmp1);
958 break;
959 }
960 break;
961 }
962 break;
963 case 1:
964 switch (M)
965 {
966 case 0:
967 tmp0 = R[iRn1];
968 R[iRn1] += R[iRn2];
969 tmp1 = (R[iRn1] < tmp0);
970 switch (Q)
971 {
972 case 0:
973 SET_SR_Q (tmp1);
974 break;
975 case 1:
976 SET_SR_Q ((unsigned char) (tmp1 == 0));
977 break;
978 }
979 break;
980 case 1:
981 tmp0 = R[iRn1];
982 R[iRn1] -= R[iRn2];
983 tmp1 = (R[iRn1] > tmp0);
984 switch (Q)
985 {
986 case 0:
987 SET_SR_Q ((unsigned char) (tmp1 == 0));
988 break;
989 case 1:
990 SET_SR_Q (tmp1);
991 break;
992 }
993 break;
994 }
995 break;
996 }
997 /*T = (Q == M);*/
998 SET_SR_T (Q == M);
999 /*return T;*/
1000 }
1001
1002 static void
1003 dmul (sign, rm, rn)
1004 int sign;
1005 unsigned int rm;
1006 unsigned int rn;
1007 {
1008 unsigned long RnL, RnH;
1009 unsigned long RmL, RmH;
1010 unsigned long temp0, temp1, temp2, temp3;
1011 unsigned long Res2, Res1, Res0;
1012
1013 RnL = rn & 0xffff;
1014 RnH = (rn >> 16) & 0xffff;
1015 RmL = rm & 0xffff;
1016 RmH = (rm >> 16) & 0xffff;
1017 temp0 = RmL * RnL;
1018 temp1 = RmH * RnL;
1019 temp2 = RmL * RnH;
1020 temp3 = RmH * RnH;
1021 Res2 = 0;
1022 Res1 = temp1 + temp2;
1023 if (Res1 < temp1)
1024 Res2 += 0x00010000;
1025 temp1 = (Res1 << 16) & 0xffff0000;
1026 Res0 = temp0 + temp1;
1027 if (Res0 < temp0)
1028 Res2 += 1;
1029 Res2 += ((Res1 >> 16) & 0xffff) + temp3;
1030
1031 if (sign)
1032 {
1033 if (rn & 0x80000000)
1034 Res2 -= rm;
1035 if (rm & 0x80000000)
1036 Res2 -= rn;
1037 }
1038
1039 MACH = Res2;
1040 MACL = Res0;
1041 }
1042
1043 static void
1044 macw (regs, memory, n, m)
1045 int *regs;
1046 unsigned char *memory;
1047 int m, n;
1048 {
1049 int little_endian = target_little_endian;
1050 long tempm, tempn;
1051 long prod, macl, sum;
1052
1053 tempm=RSWAT(regs[m]); regs[m]+=2;
1054 tempn=RSWAT(regs[n]); regs[n]+=2;
1055
1056 macl = MACL;
1057 prod = (long)(short) tempm * (long)(short) tempn;
1058 sum = prod + macl;
1059 if (S)
1060 {
1061 if ((~(prod ^ macl) & (sum ^ prod)) < 0)
1062 {
1063 /* MACH's lsb is a sticky overflow bit. */
1064 MACH |= 1;
1065 /* Store the smallest negative number in MACL if prod is
1066 negative, and the largest positive number otherwise. */
1067 sum = 0x7fffffff + (prod < 0);
1068 }
1069 }
1070 else
1071 {
1072 long mach;
1073 /* Add to MACH the sign extended product, and carry from low sum. */
1074 mach = MACH + (-(prod < 0)) + ((unsigned long) sum < prod);
1075 /* Sign extend at 10:th bit in MACH. */
1076 MACH = (mach & 0x1ff) | -(mach & 0x200);
1077 }
1078 MACL = sum;
1079 }
1080
1081 /* Set the memory size to the power of two provided. */
1082
1083 void
1084 sim_size (power)
1085 int power;
1086
1087 {
1088 saved_state.asregs.msize = 1 << power;
1089
1090 sim_memory_size = power;
1091
1092 if (saved_state.asregs.memory)
1093 {
1094 free (saved_state.asregs.memory);
1095 }
1096
1097 saved_state.asregs.memory =
1098 (unsigned char *) calloc (64, saved_state.asregs.msize / 64);
1099
1100 if (!saved_state.asregs.memory)
1101 {
1102 fprintf (stderr,
1103 "Not enough VM for simulation of %d bytes of RAM\n",
1104 saved_state.asregs.msize);
1105
1106 saved_state.asregs.msize = 1;
1107 saved_state.asregs.memory = (unsigned char *) calloc (1, 1);
1108 }
1109 }
1110
1111 static void
1112 init_pointers ()
1113 {
1114 host_little_endian = 0;
1115 *(char*)&host_little_endian = 1;
1116 host_little_endian &= 1;
1117
1118 if (saved_state.asregs.msize != 1 << sim_memory_size)
1119 {
1120 sim_size (sim_memory_size);
1121 }
1122
1123 if (saved_state.asregs.profile && !profile_file)
1124 {
1125 profile_file = fopen ("gmon.out", "wb");
1126 /* Seek to where to put the call arc data */
1127 nsamples = (1 << sim_profile_size);
1128
1129 fseek (profile_file, nsamples * 2 + 12, 0);
1130
1131 if (!profile_file)
1132 {
1133 fprintf (stderr, "Can't open gmon.out\n");
1134 }
1135 else
1136 {
1137 saved_state.asregs.profile_hist =
1138 (unsigned short *) calloc (64, (nsamples * sizeof (short) / 64));
1139 }
1140 }
1141 }
1142
1143 static void
1144 dump_profile ()
1145 {
1146 unsigned int minpc;
1147 unsigned int maxpc;
1148 unsigned short *p;
1149 int i;
1150
1151 p = saved_state.asregs.profile_hist;
1152 minpc = 0;
1153 maxpc = (1 << sim_profile_size);
1154
1155 fseek (profile_file, 0L, 0);
1156 swapout (minpc << PROFILE_SHIFT);
1157 swapout (maxpc << PROFILE_SHIFT);
1158 swapout (nsamples * 2 + 12);
1159 for (i = 0; i < nsamples; i++)
1160 swapout16 (saved_state.asregs.profile_hist[i]);
1161
1162 }
1163
1164 static void
1165 gotcall (from, to)
1166 int from;
1167 int to;
1168 {
1169 swapout (from);
1170 swapout (to);
1171 swapout (1);
1172 }
1173
1174 #define MMASKB ((saved_state.asregs.msize -1) & ~0)
1175
1176 int
1177 sim_stop (sd)
1178 SIM_DESC sd;
1179 {
1180 saved_state.asregs.exception = SIGINT;
1181 return 1;
1182 }
1183
1184 void
1185 sim_resume (sd, step, siggnal)
1186 SIM_DESC sd;
1187 int step, siggnal;
1188 {
1189 register unsigned int pc;
1190 register int cycles = 0;
1191 register int stalls = 0;
1192 register int memstalls = 0;
1193 register int insts = 0;
1194 register int prevlock;
1195 register int thislock;
1196 register unsigned int doprofile;
1197 register int pollcount = 0;
1198 register int little_endian = target_little_endian;
1199
1200 int tick_start = get_now ();
1201 void (*prev) ();
1202 void (*prev_fpe) ();
1203 extern unsigned char sh_jump_table0[];
1204
1205 register unsigned char *jump_table = sh_jump_table0;
1206
1207 register int *R = &(saved_state.asregs.regs[0]);
1208 /*register int T;*/
1209 register int PR;
1210
1211 register int maskb = ((saved_state.asregs.msize - 1) & ~0);
1212 register int maskw = ((saved_state.asregs.msize - 1) & ~1);
1213 register int maskl = ((saved_state.asregs.msize - 1) & ~3);
1214 register unsigned char *memory;
1215 register unsigned int sbit = ((unsigned int) 1 << 31);
1216
1217 prev = signal (SIGINT, control_c);
1218 prev_fpe = signal (SIGFPE, SIG_IGN);
1219
1220 init_pointers ();
1221
1222 memory = saved_state.asregs.memory;
1223
1224 if (step)
1225 {
1226 saved_state.asregs.exception = SIGTRAP;
1227 }
1228 else
1229 {
1230 saved_state.asregs.exception = 0;
1231 }
1232
1233 pc = saved_state.asregs.pc;
1234 PR = saved_state.asregs.pr;
1235 /*T = GET_SR () & SR_MASK_T;*/
1236 prevlock = saved_state.asregs.prevlock;
1237 thislock = saved_state.asregs.thislock;
1238 doprofile = saved_state.asregs.profile;
1239
1240 /* If profiling not enabled, disable it by asking for
1241 profiles infrequently. */
1242 if (doprofile == 0)
1243 doprofile = ~0;
1244
1245 do
1246 {
1247 register unsigned int iword = RUWAT (pc);
1248 register unsigned int ult;
1249 register unsigned int nia = pc + 2;
1250 #ifndef ACE_FAST
1251 insts++;
1252 #endif
1253 top:
1254
1255 #include "code.c"
1256
1257
1258 pc = nia;
1259
1260 if (--pollcount < 0)
1261 {
1262 pollcount = POLL_QUIT_INTERVAL;
1263 if ((*callback->poll_quit) != NULL
1264 && (*callback->poll_quit) (callback))
1265 {
1266 sim_stop (sd);
1267 }
1268 }
1269
1270 #ifndef ACE_FAST
1271 prevlock = thislock;
1272 thislock = 30;
1273 cycles++;
1274
1275 if (cycles >= doprofile)
1276 {
1277
1278 saved_state.asregs.cycles += doprofile;
1279 cycles -= doprofile;
1280 if (saved_state.asregs.profile_hist)
1281 {
1282 int n = pc >> PROFILE_SHIFT;
1283 if (n < nsamples)
1284 {
1285 int i = saved_state.asregs.profile_hist[n];
1286 if (i < 65000)
1287 saved_state.asregs.profile_hist[n] = i + 1;
1288 }
1289
1290 }
1291 }
1292 #endif
1293 }
1294 while (!saved_state.asregs.exception);
1295
1296 if (saved_state.asregs.exception == SIGILL
1297 || saved_state.asregs.exception == SIGBUS)
1298 {
1299 pc -= 2;
1300 }
1301
1302 saved_state.asregs.ticks += get_now () - tick_start;
1303 saved_state.asregs.cycles += cycles;
1304 saved_state.asregs.stalls += stalls;
1305 saved_state.asregs.memstalls += memstalls;
1306 saved_state.asregs.insts += insts;
1307 saved_state.asregs.pc = pc;
1308 /* restore the T and other cached SR bits */
1309 SET_SR (GET_SR());
1310 saved_state.asregs.pr = PR;
1311
1312 saved_state.asregs.prevlock = prevlock;
1313 saved_state.asregs.thislock = thislock;
1314
1315 if (profile_file)
1316 {
1317 dump_profile ();
1318 }
1319
1320 signal (SIGFPE, prev_fpe);
1321 signal (SIGINT, prev);
1322 }
1323
1324 int
1325 sim_write (sd, addr, buffer, size)
1326 SIM_DESC sd;
1327 SIM_ADDR addr;
1328 unsigned char *buffer;
1329 int size;
1330 {
1331 int i;
1332
1333 init_pointers ();
1334
1335 for (i = 0; i < size; i++)
1336 {
1337 saved_state.asregs.memory[MMASKB & (addr + i)] = buffer[i];
1338 }
1339 return size;
1340 }
1341
1342 int
1343 sim_read (sd, addr, buffer, size)
1344 SIM_DESC sd;
1345 SIM_ADDR addr;
1346 unsigned char *buffer;
1347 int size;
1348 {
1349 int i;
1350
1351 init_pointers ();
1352
1353 for (i = 0; i < size; i++)
1354 {
1355 buffer[i] = saved_state.asregs.memory[MMASKB & (addr + i)];
1356 }
1357 return size;
1358 }
1359
1360 /* We have to add one to RN as an index into asints because of the padding
1361 added at the start of asregs. */
1362 int
1363 sim_store_register (sd, rn, memory, length)
1364 SIM_DESC sd;
1365 int rn;
1366 unsigned char *memory;
1367 int length;
1368 {
1369 int little_endian;
1370 init_pointers ();
1371 little_endian = target_little_endian;
1372 if (&saved_state.asints[rn+1]
1373 == &saved_state.asregs.fpscr)
1374 set_fpscr1 (RLAT(0));
1375 else
1376 saved_state.asints[rn+1] = RLAT(0);
1377 return -1;
1378 }
1379
1380 int
1381 sim_fetch_register (sd, rn, memory, length)
1382 SIM_DESC sd;
1383 int rn;
1384 unsigned char *memory;
1385 int length;
1386 {
1387 int little_endian;
1388 init_pointers ();
1389 little_endian = target_little_endian;
1390 WLAT (0, saved_state.asints[rn+1]);
1391 return -1;
1392 }
1393
1394 int
1395 sim_trace (sd)
1396 SIM_DESC sd;
1397 {
1398 return 0;
1399 }
1400
1401 void
1402 sim_stop_reason (sd, reason, sigrc)
1403 SIM_DESC sd;
1404 enum sim_stop *reason;
1405 int *sigrc;
1406 {
1407 /* The SH simulator uses SIGQUIT to indicate that the program has
1408 exited, so we must check for it here and translate it to exit. */
1409 if (saved_state.asregs.exception == SIGQUIT)
1410 {
1411 *reason = sim_exited;
1412 *sigrc = saved_state.asregs.regs[5];
1413 }
1414 else
1415 {
1416 *reason = sim_stopped;
1417 *sigrc = saved_state.asregs.exception;
1418 }
1419 }
1420
1421 void
1422 sim_info (sd, verbose)
1423 SIM_DESC sd;
1424 int verbose;
1425 {
1426 double timetaken = (double) saved_state.asregs.ticks / (double) now_persec ();
1427 double virttime = saved_state.asregs.cycles / 36.0e6;
1428
1429 callback->printf_filtered (callback, "\n\n# instructions executed %10d\n",
1430 saved_state.asregs.insts);
1431 callback->printf_filtered (callback, "# cycles %10d\n",
1432 saved_state.asregs.cycles);
1433 callback->printf_filtered (callback, "# pipeline stalls %10d\n",
1434 saved_state.asregs.stalls);
1435 callback->printf_filtered (callback, "# misaligned load/store %10d\n",
1436 saved_state.asregs.memstalls);
1437 callback->printf_filtered (callback, "# real time taken %10.4f\n",
1438 timetaken);
1439 callback->printf_filtered (callback, "# virtual time taken %10.4f\n",
1440 virttime);
1441 callback->printf_filtered (callback, "# profiling size %10d\n",
1442 sim_profile_size);
1443 callback->printf_filtered (callback, "# profiling frequency %10d\n",
1444 saved_state.asregs.profile);
1445 callback->printf_filtered (callback, "# profile maxpc %10x\n",
1446 (1 << sim_profile_size) << PROFILE_SHIFT);
1447
1448 if (timetaken != 0)
1449 {
1450 callback->printf_filtered (callback, "# cycles/second %10d\n",
1451 (int) (saved_state.asregs.cycles / timetaken));
1452 callback->printf_filtered (callback, "# simulation ratio %10.4f\n",
1453 virttime / timetaken);
1454 }
1455 }
1456
1457 void
1458 sim_set_profile (n)
1459 int n;
1460 {
1461 saved_state.asregs.profile = n;
1462 }
1463
1464 void
1465 sim_set_profile_size (n)
1466 int n;
1467 {
1468 sim_profile_size = n;
1469 }
1470
1471 SIM_DESC
1472 sim_open (kind, cb, abfd, argv)
1473 SIM_OPEN_KIND kind;
1474 host_callback *cb;
1475 struct _bfd *abfd;
1476 char **argv;
1477 {
1478 char **p;
1479 int endian_set = 0;
1480
1481 sim_kind = kind;
1482 myname = argv[0];
1483 callback = cb;
1484
1485 for (p = argv + 1; *p != NULL; ++p)
1486 {
1487 if (strcmp (*p, "-E") == 0)
1488 {
1489 ++p;
1490 if (*p == NULL)
1491 {
1492 /* FIXME: This doesn't use stderr, but then the rest of the
1493 file doesn't either. */
1494 callback->printf_filtered (callback, "Missing argument to `-E'.\n");
1495 return 0;
1496 }
1497 target_little_endian = strcmp (*p, "big") != 0;
1498 endian_set = 1;
1499 }
1500 else if (isdigit (**p))
1501 parse_and_set_memory_size (*p);
1502 }
1503
1504 if (abfd != NULL && ! endian_set)
1505 target_little_endian = ! bfd_big_endian (abfd);
1506
1507 /* fudge our descriptor for now */
1508 return (SIM_DESC) 1;
1509 }
1510
1511 static void
1512 parse_and_set_memory_size (str)
1513 char *str;
1514 {
1515 int n;
1516
1517 n = strtol (str, NULL, 10);
1518 if (n > 0 && n <= 24)
1519 sim_memory_size = n;
1520 else
1521 callback->printf_filtered (callback, "Bad memory size %d; must be 1 to 24, inclusive\n", n);
1522 }
1523
1524 void
1525 sim_close (sd, quitting)
1526 SIM_DESC sd;
1527 int quitting;
1528 {
1529 /* nothing to do */
1530 }
1531
1532 SIM_RC
1533 sim_load (sd, prog, abfd, from_tty)
1534 SIM_DESC sd;
1535 char *prog;
1536 bfd *abfd;
1537 int from_tty;
1538 {
1539 extern bfd *sim_load_file (); /* ??? Don't know where this should live. */
1540 bfd *prog_bfd;
1541
1542 prog_bfd = sim_load_file (sd, myname, callback, prog, abfd,
1543 sim_kind == SIM_OPEN_DEBUG,
1544 0, sim_write);
1545 if (prog_bfd == NULL)
1546 return SIM_RC_FAIL;
1547 if (abfd == NULL)
1548 bfd_close (prog_bfd);
1549 return SIM_RC_OK;
1550 }
1551
1552 SIM_RC
1553 sim_create_inferior (sd, prog_bfd, argv, env)
1554 SIM_DESC sd;
1555 struct _bfd *prog_bfd;
1556 char **argv;
1557 char **env;
1558 {
1559 /* clear the registers */
1560 memset (&saved_state, 0,
1561 (char*)&saved_state.asregs.end_of_registers - (char*)&saved_state);
1562 /* set the PC */
1563 if (prog_bfd != NULL)
1564 saved_state.asregs.pc = bfd_get_start_address (prog_bfd);
1565 return SIM_RC_OK;
1566 }
1567
1568 void
1569 sim_do_command (sd, cmd)
1570 SIM_DESC sd;
1571 char *cmd;
1572 {
1573 char *sms_cmd = "set-memory-size";
1574 int cmdsize;
1575
1576 if (cmd == NULL || *cmd == '\0')
1577 {
1578 cmd = "help";
1579 }
1580
1581 cmdsize = strlen (sms_cmd);
1582 if (strncmp (cmd, sms_cmd, cmdsize) == 0 && strchr (" \t", cmd[cmdsize]) != NULL)
1583 {
1584 parse_and_set_memory_size (cmd + cmdsize + 1);
1585 }
1586 else if (strcmp (cmd, "help") == 0)
1587 {
1588 (callback->printf_filtered) (callback, "List of SH simulator commands:\n\n");
1589 (callback->printf_filtered) (callback, "set-memory-size <n> -- Set the number of address bits to use\n");
1590 (callback->printf_filtered) (callback, "\n");
1591 }
1592 else
1593 {
1594 (callback->printf_filtered) (callback, "Error: \"%s\" is not a valid SH simulator command.\n", cmd);
1595 }
1596 }
1597
1598 void
1599 sim_set_callbacks (p)
1600 host_callback *p;
1601 {
1602 callback = p;
1603 }