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