e28fe86fa88765c7d5b307cdf42c373aee284272
[deliverable/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 #include <signal.h>
21 #include "sysdep.h"
22 #include <sys/times.h>
23 #include <sys/param.h>
24 #include "bfd.h"
25 #define O_RECOMPILE 85
26 #define DEFINE_TABLE
27
28 #define DISASSEMBLER_TABLE
29
30 #define SBIT(x) ((x)&sbit)
31 #define R0 saved_state.asregs.regs[0]
32 #define Rn saved_state.asregs.regs[n]
33 #define Rm saved_state.asregs.regs[m]
34 #define UR0 (unsigned int)(saved_state.asregs.regs[0])
35 #define UR (unsigned int)R
36 #define UR (unsigned int)R
37 #define SR0 saved_state.asregs.regs[0]
38 #define GBR saved_state.asregs.gbr
39 #define VBR saved_state.asregs.vbr
40 #define MACH saved_state.asregs.mach
41 #define MACL saved_state.asregs.macl
42 #define M saved_state.asregs.sr.bits.m
43 #define Q saved_state.asregs.sr.bits.q
44
45 #define GET_SR() (saved_state.asregs.sr.bits.t = T, saved_state.asregs.sr.word)
46 #define SET_SR(x) {saved_state.asregs.sr.word = (x); T =saved_state.asregs.sr.bits.t;}
47
48 #define PC pc
49 #define C cycles
50
51 #ifdef TARGET_BIG_ENDIAN
52 #define LMEM(x) *((long *)(memory+((x)&maskl)))
53 #define BMEM(x) *((char *)(memory+((x)&maskb)))
54 #define UWMEM(x) *((unsigned short *)(memory+((x)&maskw)))
55 #define SWMEM(x) *((short *)(memory+((x)&maskw)))
56 #define WLAT(x,value) (LMEM(x) = value)
57 #define RLAT(x) (LMEM(x))
58 #define WWAT(x,value) (UWMEM(x) = value)
59 #define RSWAT(x) (SWMEM(x))
60 #define RUWAT(x) (UWMEM(x))
61 #define WBAT(x,value) (BMEM(x) = value)
62 #define RBAT(x) (BMEM(x))
63 #else
64 /* For little endian or unknown host machines */
65 #define WLAT(x,value)\
66 { int v = value; unsigned char *p = memory + ((x) & maskl);\
67 p[0] =v>>24;p[1] = v>>16;p[2]=v>>8;p[3]=v; }
68
69 #define WWAT(x,value)\
70 { int v = value; unsigned char *p = memory + (x & maskw);p[0] =v>>8;p[1] = v ;}
71
72 #define WBAT(x,value)\
73 { unsigned char *p = memory + (x & maskb);p[0] =value;}
74
75 #define RLAT(x)\
76 ((memory[x&maskl]<<24)|(memory[(x&maskl)+1]<<16)|(memory[(x&maskl)+2]<<8)| (memory[(x&maskl)+3]))
77
78 #define RWAT(x)\
79 ((memory[x&maskw]<<8)|(memory[(x&maskw)+1]))
80
81 #define RBAT(x)\
82 ((memory[x&maskb]))
83
84 #define RUWAT(x) (RWAT(x) & 0xffff)
85 #define RSWAT(x) ((short)(RWAT(x)))
86 #define RSBAT(x) (SEXT(RBAT(x)))
87
88 #endif
89
90
91
92 #define SEXT(x) (((x&0xff) ^ (~0x7f))+0x80)
93 #define SEXTW(y) ((int)((short)y))
94
95 #define SL(TEMPPC) iword= RUWAT(TEMPPC); goto top;
96
97
98 #define L(x) thislock = x;
99 #define TL(x) if ((x) == prevlock) stalls++;
100 #define TB(x,y) if ((x) == prevlock || (y)==prevlock) stalls++;
101 int sim_memory_size = 19;
102 static int sim_profile_size = 17;
103 static int nsamples;
104 static int sim_timeout;
105
106 typedef union
107 {
108
109 struct
110 {
111
112 int regs[16];
113 int pc;
114 int pr;
115
116 int gbr;
117 int vbr;
118 int mach;
119 int macl;
120
121
122 union
123 {
124 struct
125 {
126 unsigned int d0:22;
127 unsigned int m:1;
128 unsigned int q:1;
129 unsigned int i:4;
130 unsigned int d1:2;
131 unsigned int s:1;
132 unsigned int t:1;
133 }
134 bits;
135 int word;
136 }
137 sr;
138 int ticks;
139 int stalls;
140 int cycles;
141 int insts;
142
143
144 int prevlock;
145 int thislock;
146 int exception;
147 int msize;
148 #define PROFILE_FREQ 1
149 #define PROFILE_SHIFT 2
150 int profile;
151 unsigned short *profile_hist;
152 unsigned char *memory;
153
154 }
155 asregs;
156 int asints[28];
157
158 }
159
160 saved_state_type;
161 saved_state_type saved_state;
162
163 static int
164 get_now ()
165 {
166 return time((char*)0);
167 }
168
169 static int
170 now_persec ()
171 {
172 return 1;
173 }
174
175
176
177 static FILE *profile_file;
178
179 static void
180 swap (b, n)
181 unsigned char *b;
182 int n;
183 {
184 b[0] = n >> 24;
185 b[1] = n >> 16;
186 b[2] = n >> 8;
187 b[3] = n >> 0;
188 }
189 static void
190 swap16 (b, n)
191 unsigned char *b;
192 int n;
193 {
194 b[0] = n >> 8;
195 b[1] = n >> 0;
196 }
197
198 static void
199 swapout (n)
200 int n;
201 {
202 if (profile_file)
203 {
204 char b[4];
205 swap (b, n);
206 fwrite (b, 4, 1, profile_file);
207 }
208 }
209
210 static void
211 swapout16 (n)
212 int n;
213 {
214 char b[4];
215 swap16 (b, n);
216 fwrite (b, 2, 1, profile_file);
217 }
218
219
220 /* Turn a pointer in a register into a pointer into real memory. */
221
222 static char *
223 ptr (x)
224 int x;
225 {
226 return (char *) (x + saved_state.asregs.memory);
227 }
228
229 /* Simulate a monitor trap. */
230
231 static void
232 trap (i, regs)
233 int i;
234 int *regs;
235 {
236 switch (i)
237 {
238 case 1:
239 printf ("%c", regs[0]);
240 break;
241 case 2:
242 saved_state.asregs.exception = SIGQUIT;
243 break;
244 case 3:
245 {
246 extern int errno;
247 int perrno = errno;
248 errno = 0;
249
250 switch (regs[4])
251 {
252 case 3:
253 regs[4] = read (regs[5], ptr (regs[6]), regs[7]);
254 break;
255 case 4:
256 regs[4] = write (regs[5], ptr (regs[6]), regs[7]);
257 break;
258 case 19:
259 regs[4] = lseek (regs[5], regs[6], regs[7]);
260 break;
261 case 6:
262 regs[4] = close (regs[5]);
263 break;
264 case 5:
265 regs[4] = open (ptr (regs[5]), regs[6]);
266 break;
267 case 1:
268 /* EXIT */
269 saved_state.asregs.exception = SIGQUIT;
270 errno = regs[5];
271 break;
272
273 default:
274 abort ();
275 }
276 regs[0] = errno;
277 errno = perrno;
278 }
279
280 break;
281
282 case 255:
283 saved_state.asregs.exception = SIGTRAP;
284 break;
285 }
286
287 }
288 void
289 control_c (sig, code, scp, addr)
290 int sig;
291 int code;
292 char *scp;
293 char *addr;
294 {
295 saved_state.asregs.exception = SIGINT;
296 }
297
298
299 static int
300 div1 (R, iRn2, iRn1, T)
301 int *R;
302 int iRn1;
303 int iRn2;
304 int T;
305 {
306 unsigned long tmp0;
307 unsigned char old_q, tmp1;
308
309 old_q = Q;
310 Q = (unsigned char) ((0x80000000 & R[iRn1]) != 0);
311 R[iRn1] <<= 1;
312 R[iRn1] |= (unsigned long) T;
313
314 switch (old_q)
315 {
316 case 0:
317 switch (M)
318 {
319 case 0:
320 tmp0 = R[iRn1];
321 R[iRn1] -= R[iRn2];
322 tmp1 = (R[iRn1] > tmp0);
323 switch (Q)
324 {
325 case 0:
326 Q = tmp1;
327 break;
328 case 1:
329 Q = (unsigned char) (tmp1 == 0);
330 break;
331 }
332 break;
333 case 1:
334 tmp0 = R[iRn1];
335 R[iRn1] += R[iRn2];
336 tmp1 = (R[iRn1] < tmp0);
337 switch (Q)
338 {
339 case 0:
340 Q = (unsigned char) (tmp1 == 0);
341 break;
342 case 1:
343 Q = tmp1;
344 break;
345 }
346 break;
347 }
348 break;
349 case 1:
350 switch (M)
351 {
352 case 0:
353 tmp0 = R[iRn1];
354 R[iRn1] += R[iRn2];
355 tmp1 = (R[iRn1] < tmp0);
356 switch (Q)
357 {
358 case 0:
359 Q = tmp1;
360 break;
361 case 1:
362 Q = (unsigned char) (tmp1 == 0);
363 break;
364 }
365 break;
366 case 1:
367 tmp0 = R[iRn1];
368 R[iRn1] -= R[iRn2];
369 tmp1 = (R[iRn1] > tmp0);
370 switch (Q)
371 {
372 case 0:
373 Q = (unsigned char) (tmp1 == 0);
374 break;
375 case 1:
376 Q = tmp1;
377 break;
378 }
379 break;
380 }
381 break;
382 }
383 T = (Q == M);
384 return T;
385 }
386
387
388 static void
389 dmul (sign, rm, rn)
390 int sign;
391 unsigned int rm;
392 unsigned int rn;
393 {
394 unsigned long RnL, RnH;
395 unsigned long RmL, RmH;
396 unsigned long temp0, temp1, temp2, temp3;
397 unsigned long Res2, Res1, Res0;
398
399
400 if (!sign)
401 {
402
403 RnL = rn & 0xffff;
404 RnH = (rn >> 16) & 0xffff;
405 RmL = rm & 0xffff;
406 RmH = (rm >> 16) & 0xffff;
407 temp0 = RmL * RnL;
408 temp1 = RmH * RnL;
409 temp2 = RmL * RnH;
410 temp3 = RmH * RnH;
411 Res2 = 0;
412 Res1 = temp1 + temp2;
413 if (Res1 < temp1)
414 Res2 += 0x00010000;
415 temp1 = (Res1 << 16) & 0xffff0000;
416 Res0 = temp0 + temp1;
417 if (Res0 < temp0)
418 Res2 += 1;
419 Res2 += ((Res1 >> 16) & 0xffff) + temp3;
420 MACH = Res2;
421 MACL = Res0;
422
423 }
424
425 else
426 {
427 abort ();
428 }
429
430 }
431
432
433 /* Set the memory size to the power of two provided. */
434
435 void
436 sim_size (power)
437 int power;
438
439 {
440 saved_state.asregs.msize = 1 << power;
441
442 sim_memory_size = power;
443
444
445 if (saved_state.asregs.memory)
446 {
447 free (saved_state.asregs.memory);
448 }
449
450 saved_state.asregs.memory =
451 (unsigned char *) calloc (64, saved_state.asregs.msize / 64);
452
453 if (!saved_state.asregs.memory)
454 {
455 fprintf (stderr,
456 "Not enough VM for simuation of %d bytes of RAM\n",
457 saved_state.asregs.msize);
458
459 saved_state.asregs.msize = 1;
460 saved_state.asregs.memory = (unsigned char *) calloc (1, 1);
461 }
462 }
463
464
465
466 static
467 void
468 init_pointers ()
469 {
470 if (saved_state.asregs.msize != 1 << sim_memory_size)
471 {
472 sim_size (sim_memory_size);
473 }
474
475 if (saved_state.asregs.profile && !profile_file)
476 {
477 profile_file = fopen ("gmon.out", "wb");
478 /* Seek to where to put the call arc data */
479 nsamples = (1 << sim_profile_size);
480
481 fseek (profile_file, nsamples * 2 + 12, 0);
482
483 if (!profile_file)
484 {
485 fprintf (stderr, "Can't open gmon.out\n");
486 }
487 else
488 {
489 saved_state.asregs.profile_hist =
490 (unsigned short *) calloc (64, (nsamples * sizeof (short) / 64));
491 }
492 }
493 }
494
495 static void
496 dump_profile ()
497 {
498 unsigned int minpc;
499 unsigned int maxpc;
500 unsigned short *p;
501
502 int thisshift;
503
504 unsigned short *first;
505
506 int i;
507 p = saved_state.asregs.profile_hist;
508 minpc = 0;
509 maxpc = (1 << sim_profile_size);
510
511 fseek (profile_file, 0L, 0);
512 swapout (minpc << PROFILE_SHIFT);
513 swapout (maxpc << PROFILE_SHIFT);
514 swapout (nsamples * 2 + 12);
515 for (i = 0; i < nsamples; i++)
516 swapout16 (saved_state.asregs.profile_hist[i]);
517
518 }
519
520 static int
521 gotcall (from, to)
522 int from;
523 int to;
524 {
525 swapout (from);
526 swapout (to);
527 swapout (1);
528 }
529
530 #define MMASKB ((saved_state.asregs.msize -1) & ~0)
531 void
532 sim_resume (step)
533 int step;
534 {
535 register unsigned int pc;
536 register int cycles = 0;
537 register int stalls = 0;
538 register int insts = 0;
539 register int prevlock;
540 register int thislock;
541 register unsigned int doprofile;
542
543 int tick_start = get_now ();
544 void (*prev) ();
545 extern unsigned char sh_jump_table0[];
546
547 register unsigned char *jump_table = sh_jump_table0;
548
549 register int *R = &(saved_state.asregs.regs[0]);
550 register int T;
551 register int PR;
552
553 register int maskb = ((saved_state.asregs.msize - 1) & ~0);
554 register int maskw = ((saved_state.asregs.msize - 1) & ~1);
555 register int maskl = ((saved_state.asregs.msize - 1) & ~3);
556 register unsigned char *memory ;
557 register unsigned int sbit = (1 << 31);
558
559 prev = signal (SIGINT, control_c);
560
561 init_pointers ();
562
563 memory = saved_state.asregs.memory;
564
565 if (step)
566 {
567 saved_state.asregs.exception = SIGTRAP;
568 }
569 else
570 {
571 saved_state.asregs.exception = 0;
572 }
573
574 pc = saved_state.asregs.pc;
575 PR = saved_state.asregs.pr;
576 T = saved_state.asregs.sr.bits.t;
577 prevlock = saved_state.asregs.prevlock;
578 thislock = saved_state.asregs.thislock;
579 doprofile = saved_state.asregs.profile;
580
581 /* If profiling not enabled, disable it by asking for
582 profiles infrequently. */
583 if (doprofile == 0)
584 doprofile = ~0;
585
586 do
587 {
588 register unsigned int iword = RUWAT (pc);
589 register unsigned int ult;
590
591 insts++;
592 top:
593
594 #include "code.c"
595
596
597 pc += 2;
598 prevlock = thislock;
599 thislock = 30;
600 cycles++;
601
602 if (cycles >= doprofile)
603 {
604 if (cycles > sim_timeout)
605 saved_state.asregs.exception = SIGQUIT;
606
607 saved_state.asregs.cycles += doprofile;
608 cycles -= doprofile;
609 if (saved_state.asregs.profile_hist)
610 {
611 int n = pc >> PROFILE_SHIFT;
612 if (n < nsamples)
613 {
614 int i = saved_state.asregs.profile_hist[n];
615 if (i < 65000)
616 saved_state.asregs.profile_hist[n] = i + 1;
617 }
618
619 }
620 }
621 }
622 while (!saved_state.asregs.exception);
623
624 if (saved_state.asregs.exception == SIGILL)
625 {
626 pc -= 2;
627 }
628
629 saved_state.asregs.ticks += get_now () - tick_start;
630 saved_state.asregs.cycles += cycles;
631 saved_state.asregs.stalls += stalls;
632 saved_state.asregs.insts += insts;
633 saved_state.asregs.pc = pc;
634 saved_state.asregs.sr.bits.t = T;
635 saved_state.asregs.pr = PR;
636
637 saved_state.asregs.prevlock = prevlock;
638 saved_state.asregs.thislock = thislock;
639
640
641 if (profile_file)
642 {
643 dump_profile ();
644 }
645
646 signal (SIGINT, prev);
647 }
648
649
650
651
652 int
653 sim_write (addr, buffer, size)
654 long int addr;
655 unsigned char *buffer;
656 int size;
657 {
658 int i;
659 init_pointers ();
660
661 for (i = 0; i < size; i++)
662 {
663 saved_state.asregs.memory[MMASKB & (addr + i)] = buffer[i];
664 }
665 return size;
666 }
667
668 int
669 sim_read (addr, buffer, size)
670 long int addr;
671 char *buffer;
672 int size;
673 {
674 int i;
675
676 init_pointers ();
677
678 for (i = 0; i < size; i++)
679 {
680 buffer[i] = saved_state.asregs.memory[MMASKB & (addr + i)];
681 }
682 return size;
683 }
684
685
686 void
687 sim_store_register (rn, value)
688 int rn;
689 unsigned char value[4];
690 {
691 saved_state.asregs.regs[rn] = (value[0] << 24) | (value[1] << 16) | (value[2] << 8) | (value[3]);
692 }
693
694 void
695 sim_fetch_register (rn, buf)
696 int rn;
697 char *buf;
698 {
699 int value = ((int *) (&saved_state))[rn];
700
701 swap (buf, value);
702 }
703
704
705 int
706 sim_trace ()
707 {
708 return 0;
709 }
710
711 enum sim_stop
712 sim_stop_signal (sigrc)
713 int *sigrc;
714 {
715 *sigrc = saved_state.asregs.exception;
716 return sim_stopped;
717 }
718
719 void
720 sim_set_pc (x)
721 int x;
722 {
723 saved_state.asregs.pc = x;
724 }
725
726
727 void
728 sim_info ()
729 {
730 double timetaken = (double) saved_state.asregs.ticks / (double) now_persec ();
731 double virttime = saved_state.asregs.cycles / 36.0e6;
732
733 printf ("\n\n# instructions executed %10d\n", saved_state.asregs.insts);
734 printf ("# cycles %10d\n", saved_state.asregs.cycles);
735 printf ("# pipeline stalls %10d\n", saved_state.asregs.stalls);
736 printf ("# real time taken %10.4f\n", timetaken);
737 printf ("# virtual time taken %10.4f\n", virttime);
738 printf ("# profiling size %10d\n", sim_profile_size);
739 printf ("# profiling frequency %10d\n", saved_state.asregs.profile);
740 printf ("# profile maxpc %10x\n", (1 << sim_profile_size) << PROFILE_SHIFT);
741
742 if (timetaken != 0)
743 {
744 printf ("# cycles/second %10d\n", (int) (saved_state.asregs.cycles / timetaken));
745 printf ("# simulation ratio %10.4f\n", virttime / timetaken);
746 }
747 }
748
749
750 void
751 sim_set_profile (n)
752 int n;
753 {
754 saved_state.asregs.profile = n;
755 }
756
757 void
758 sim_set_profile_size (n)
759 int n;
760 {
761 sim_profile_size = n;
762 }
763
764
765 void
766 sim_kill()
767 {
768
769 }
770
771 int
772 sim_open()
773 {
774 return 0;
775 }
776 int sim_set_args()
777 {
778 return 0;
779 }
780
781
This page took 0.060798 seconds and 4 git commands to generate.