* gencode.c: Fix some opcodes.
[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 swap(b,n)
185 unsigned char *b;
186 int n;
187 {
188 b[0] = n>>24;
189 b[1] = n>>16;
190 b[2] = n>>8;
191 b[3] = n>>0;
192 }
193 static void swap16(b,n)
194 unsigned char *b;
195 int n;
196 {
197 b[0] = n>>8;
198 b[1] = n>>0;
199 }
200
201 static void
202 swapout(n)
203 int n;
204 {
205 if (profile_file)
206 {
207 char b[4];
208 swap(b,n);
209 fwrite(b, 4, 1, profile_file);
210 }
211 }
212
213 static void
214 swapout16(n)
215 int n;
216 {
217 char b[4];
218 swap16(b,n);
219 fwrite(b, 2, 1, profile_file);
220 }
221
222
223 /* Turn a pointer in a register into a pointer into real memory. */
224
225 static char *
226 ptr (x)
227 int x;
228 {
229 return (char *)(x + saved_state.asregs.memory);
230 }
231
232 /* Simulate a monitor trap. */
233
234 static void
235 trap (i, regs)
236 int i;
237 int *regs;
238 {
239 switch (i)
240 {
241 case 1:
242 printf ("%c", regs[0]);
243 break;
244 case 2:
245 saved_state.asregs.exception = SIGQUIT;
246 break;
247 case 3:
248 {
249 extern int errno;
250 int perrno = errno;
251 errno = 0;
252
253 switch (regs[4])
254 {
255 case 3:
256 regs[4] = read (regs[5], ptr (regs[6]), regs[7]);
257 break;
258 case 4:
259 regs[4] = write (regs[5], ptr (regs[6]), regs[7]);
260 break;
261 case 19:
262 regs[4] = lseek (regs[5], regs[6], regs[7]);
263 break;
264 case 6:
265 regs[4] = close (regs[5]);
266 break;
267 case 5:
268 regs[4] = open (ptr (regs[5]), regs[6]);
269 break;
270 default:
271 abort ();
272 }
273 regs[0] = errno;
274 errno = perrno;
275 }
276
277 break;
278
279 case 255:
280 saved_state.asregs.exception = SIGILL;
281 break;
282 }
283
284 }
285 void
286 control_c (sig, code, scp, addr)
287 int sig;
288 int code;
289 char *scp;
290 char *addr;
291 {
292 saved_state.asregs.exception = SIGINT;
293 }
294
295
296 static int
297 div1 (R, iRn2, iRn1, T)
298 int *R;
299 int iRn1;
300 int iRn2;
301 int T;
302 {
303 unsigned long tmp0;
304 unsigned char old_q, tmp1;
305
306 old_q = Q;
307 Q = (unsigned char) ((0x80000000 & R[iRn1]) != 0);
308 R[iRn1] <<= 1;
309 R[iRn1] |= (unsigned long) T;
310
311 switch (old_q)
312 {
313 case 0:
314 switch (M)
315 {
316 case 0:
317 tmp0 = R[iRn1];
318 R[iRn1] -= R[iRn2];
319 tmp1 = (R[iRn1] > tmp0);
320 switch (Q)
321 {
322 case 0:
323 Q = tmp1;
324 break;
325 case 1:
326 Q = (unsigned char) (tmp1 == 0);
327 break;
328 }
329 break;
330 case 1:
331 tmp0 = R[iRn1];
332 R[iRn1] += R[iRn2];
333 tmp1 = (R[iRn1] < tmp0);
334 switch (Q)
335 {
336 case 0:
337 Q = (unsigned char) (tmp1 == 0);
338 break;
339 case 1:
340 Q = tmp1;
341 break;
342 }
343 break;
344 }
345 break;
346 case 1:
347 switch (M)
348 {
349 case 0:
350 tmp0 = R[iRn1];
351 R[iRn1] += R[iRn2];
352 tmp1 = (R[iRn1] < tmp0);
353 switch (Q)
354 {
355 case 0:
356 Q = tmp1;
357 break;
358 case 1:
359 Q = (unsigned char) (tmp1 == 0);
360 break;
361 }
362 break;
363 case 1:
364 tmp0 = R[iRn1];
365 R[iRn1] -= R[iRn2];
366 tmp1 = (R[iRn1] > tmp0);
367 switch (Q)
368 {
369 case 0:
370 Q = (unsigned char) (tmp1 == 0);
371 break;
372 case 1:
373 Q = tmp1;
374 break;
375 }
376 break;
377 }
378 break;
379 }
380 T = (Q == M);
381 return T;
382 }
383
384 #if 0
385
386 old_q = Q;
387 Q = (R[n]&0x80000000) != 0;
388
389 R[n] <<= 1;
390 R[n] |= T;
391
392 tmp0 = R[n];
393
394 if (M==old_q)
395 {
396 R[n] -= R[m];
397 tmp1 = (R[n] > tmp0) != Q;
398 T = 1;
399 }
400 else
401 {
402 R[n] += R[m];
403 tmp1 = (R[n] < tmp0) == Q;
404 T = 0;
405 }
406 return T;
407 }
408 #endif
409
410 static void dmul(sign, rml, rnl)
411 int sign;
412 unsigned int rml;
413 unsigned int rnl;
414 {
415 unsigned int rmh;
416 unsigned int rnh;
417
418 unsigned int t0,t1,t2,t3;
419 unsigned int res0,res1,res2;
420 /* Sign extend input if signed multiply */
421 if (sign)
422 {
423 rmh = (rml & 0x80000000) ? ~0 : 0;
424 rnh = (rnl & 0x80000000) ? ~0 : 0;
425 }
426 else
427 {
428 rmh = 0;
429 rnh = 0;
430 }
431 t0 = rml *rnl;
432 t1 = rmh *rnl;
433 t2 = rml*rnh;
434 t3 = rmh*rnh;
435 res2 = 0;
436 res1 = t1+t2;
437
438 if (res1 < t1)
439 res2 += 0x00010000;
440
441 t1 = ((res1 << 16) & 0xffff0000);
442 res0 = t0 + t1;
443
444 if (res0 < t0) res2++;
445
446 res2 = res2 + ((res1 >> 16) & 0xffff) + t3;
447
448 MACH = res2;
449 MACL = res0;
450
451 }
452
453
454 /* Set the memory size to the power of two provided. */
455
456 void
457 sim_size (power)
458 int power;
459
460 {
461 saved_state.asregs.msize = 1 << power;
462
463 sim_memory_size = power;
464
465
466 if (saved_state.asregs.memory)
467 {
468 free (saved_state.asregs.memory);
469 }
470
471 saved_state.asregs.memory =
472 (unsigned char *) calloc (64, saved_state.asregs.msize / 64);
473
474 if (!saved_state.asregs.memory)
475 {
476 fprintf (stderr,
477 "Not enough VM for simuation of %d bytes of RAM\n",
478 saved_state.asregs.msize);
479
480 saved_state.asregs.msize = 1;
481 saved_state.asregs.memory = (unsigned char *)calloc(1,1);
482 }
483 }
484
485
486
487 static
488 void
489 init_pointers ()
490 {
491 if (saved_state.asregs.msize != 1 << sim_memory_size)
492 {
493 sim_size (sim_memory_size);
494 }
495
496 if (saved_state.asregs.profile && !profile_file)
497 {
498 profile_file = fopen("gmon.out","wb");
499 /* Seek to where to put the call arc data */
500 nsamples = (1<<sim_profile_size);
501
502 fseek (profile_file, nsamples * 2 +12, 0);
503
504 if (!profile_file)
505 {
506 fprintf(stderr,"Can't open gmon.out\n");
507 }
508 else
509 {
510 saved_state.asregs.profile_hist =
511 (unsigned short *) calloc(64, (nsamples * sizeof(short) / 64));
512 }
513 }
514 }
515
516 static void
517 dump_profile()
518 {
519 unsigned int minpc ;
520 unsigned int maxpc;
521 unsigned short *p;
522
523 int thisshift;
524
525 unsigned short *first;
526
527 int i;
528 p = saved_state.asregs.profile_hist;
529 minpc =0;
530 maxpc = (1<<sim_profile_size) ;
531
532 fseek(profile_file, 0L, 0);
533 swapout(minpc<<PROFILE_SHIFT);
534 swapout(maxpc<<PROFILE_SHIFT);
535 swapout(nsamples * 2 + 12);
536 for (i = 0; i < nsamples ; i++)
537 swapout16(saved_state.asregs.profile_hist[i]);
538
539 }
540
541 static int gotcall(from, to)
542 int from;
543 int to;
544 {
545 swapout(from);
546 swapout(to);
547 swapout(1);
548 }
549
550 #define MMASKB ((saved_state.asregs.msize -1) & ~0)
551 void
552 sim_resume (step)
553 int step;
554 {
555 register unsigned int pc;
556 register int cycles = 0;
557 register int stalls = 0;
558 register int insts = 0;
559 register int prevlock;
560 register int thislock ;
561 register unsigned int doprofile ;
562
563 int tick_start = get_now ();
564 void (*prev) ();
565 extern unsigned char sh_jump_table0[];
566
567 register unsigned char *jump_table = sh_jump_table0;
568
569 register int *R = &(saved_state.asregs.regs[0]);
570 register int T;
571 register int PR;
572
573 register int maskb = ((saved_state.asregs.msize - 1) & ~0);
574 register int maskw = ((saved_state.asregs.msize - 1) & ~1);
575 register int maskl = ((saved_state.asregs.msize - 1) & ~3);
576 register unsigned char *memory = saved_state.asregs.memory;
577 register unsigned int sbit = (1 << 31);
578
579 prev = signal (SIGINT, control_c);
580
581 init_pointers();
582
583 if (step)
584 {
585 saved_state.asregs.exception = SIGTRAP;
586 }
587 else
588 {
589 saved_state.asregs.exception = 0;
590 }
591
592 pc = saved_state.asregs.pc;
593 PR = saved_state.asregs.pr;
594 T = saved_state.asregs.sr.bits.t;
595 prevlock = saved_state.asregs.prevlock;
596 thislock = saved_state.asregs.thislock;
597 doprofile = saved_state.asregs.profile;
598
599 /* If profiling not enabled, disable it by asking for
600 profiles infrequently. */
601 if (doprofile==0)
602 doprofile = ~0;
603
604 do
605 {
606 register unsigned int iword = RUWAT (pc);
607 register unsigned int ult;
608
609 insts++;
610 top:
611
612 #include "code.c"
613
614
615 pc += 2;
616 prevlock = thislock;
617 thislock = 30;
618 cycles++;
619
620 if (cycles >= doprofile)
621 {
622 saved_state.asregs.cycles += doprofile;
623 cycles -= doprofile;
624 if (saved_state.asregs.profile_hist)
625 {
626 int n = pc >> PROFILE_SHIFT;
627 if (n < nsamples)
628 {
629 int i = saved_state.asregs.profile_hist[n];
630 if (i < 65000)
631 saved_state.asregs.profile_hist[n] = i+1;
632 }
633
634 }
635 }
636 }
637 while (!saved_state.asregs.exception);
638
639 if (saved_state.asregs.exception == SIGILL)
640 {
641 pc -= 2;
642 }
643
644 saved_state.asregs.ticks += get_now () - tick_start;
645 saved_state.asregs.cycles += cycles;
646 saved_state.asregs.stalls += stalls;
647 saved_state.asregs.insts += insts;
648 saved_state.asregs.pc = pc;
649 saved_state.asregs.sr.bits.t = T;
650 saved_state.asregs.pr = PR;
651
652 saved_state.asregs.prevlock = prevlock;
653 saved_state.asregs.thislock = thislock;
654
655
656 if (profile_file)
657 {
658 dump_profile();
659 }
660
661 signal (SIGINT, prev);
662 }
663
664
665
666
667 void
668 sim_write (addr, buffer, size)
669 long int addr;
670 unsigned char *buffer;
671 int size;
672 {
673 int i;
674 init_pointers ();
675
676 for (i = 0; i < size; i++)
677 {
678 saved_state.asregs.memory[MMASKB & (addr + i)] = buffer[i];
679 }
680 }
681
682 void
683 sim_read (addr, buffer, size)
684 long int addr;
685 char *buffer;
686 int size;
687 {
688 int i;
689
690 init_pointers ();
691
692 for (i = 0; i < size; i++)
693 {
694 buffer[i] = saved_state.asregs.memory[MMASKB & (addr + i)];
695 }
696 }
697
698
699 void
700 sim_store_register (rn, value)
701 int rn;
702 int value;
703 {
704 saved_state.asregs.regs[rn] = value;
705 }
706
707 void
708 sim_fetch_register (rn, buf)
709 int rn;
710 char *buf;
711 {
712 int value = ((int *) (&saved_state))[rn];
713
714 swap(buf, value);
715 }
716
717
718 int
719 sim_trace ()
720 {
721 return 0;
722 }
723
724 int
725 sim_stop_signal ()
726 {
727 return saved_state.asregs.exception;
728 }
729
730 void
731 sim_set_pc (x)
732 int x;
733 {
734 saved_state.asregs.pc = x;
735 }
736
737
738 void
739 sim_info ()
740 {
741 double timetaken = (double) saved_state.asregs.ticks / (double) now_persec ();
742 double virttime = saved_state.asregs.cycles / 36.0e6;
743
744 printf ("\n\n# instructions executed %10d\n", saved_state.asregs.insts);
745 printf ("# cycles %10d\n", saved_state.asregs.cycles);
746 printf ("# pipeline stalls %10d\n", saved_state.asregs.stalls);
747 printf ("# real time taken %10.4f\n", timetaken);
748 printf ("# virtual time taked %10.4f\n", virttime);
749 printf ("# profiling size %10d\n", sim_profile_size);
750 printf( "# profiling frequency %10d\n", saved_state.asregs.profile);
751 printf( "# profile maxpc %10x\n", (1<<sim_profile_size) << PROFILE_SHIFT);
752
753 if (timetaken != 0)
754 {
755 printf ("# cycles/second %10d\n", (int) (saved_state.asregs.cycles / timetaken));
756 printf ("# simulation ratio %10.4f\n", virttime / timetaken);
757 }
758 }
759
760
761 void
762 sim_set_profile(n)
763 {
764 saved_state.asregs.profile = n;
765 }
766
767 void
768 sim_set_profile_size(n)
769 {
770 sim_profile_size = n;
771 }
This page took 0.121717 seconds and 5 git commands to generate.