comment change. This is a mips file, not 88k.
[deliverable/binutils-gdb.git] / sim / sh / interp.c
CommitLineData
594266fc
SC
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*/
90fe361f 20#include "sysdep.h"
594266fc
SC
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)
90fe361f
SC
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
594266fc 43
594266fc
SC
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
90fe361f
SC
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++;
100int sim_memory_size = 19;
101static int sim_profile_size = 17;
102static int nsamples;
594266fc
SC
103typedef 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 {
90fe361f
SC
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;
594266fc
SC
130 }
131 bits;
132 int word;
133 }
134 sr;
135 int ticks;
90fe361f 136 int stalls;
594266fc
SC
137 int cycles;
138 int insts;
594266fc 139
90fe361f
SC
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
594266fc
SC
151 }
152 asregs;
90fe361f 153 int asints[28];
594266fc
SC
154
155}
156
157saved_state_type;
594266fc
SC
158saved_state_type saved_state;
159
594266fc
SC
160static int
161get_now ()
162{
163 struct tms b;
164 times (&b);
165 return b.tms_utime + b.tms_stime;
166}
167
168static int
169now_persec ()
170{
90fe361f
SC
171#ifdef CLK_TCK
172 return CLK_TCK;
173#endif
174#ifdef HZ
594266fc 175 return HZ;
90fe361f
SC
176#endif
177 return 50;
178}
179
180
181
182static FILE *profile_file;
183
184static 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}
193static void swap16(b,n)
194 unsigned char *b;
195 int n;
196{
197 b[0] = n>>8;
198 b[1] = n>>0;
594266fc
SC
199}
200
90fe361f
SC
201static void
202swapout(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
213static void
214swapout16(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
225static char *
226ptr (x)
227 int x;
228{
229 return (char *)(x + saved_state.asregs.memory);
230}
231
232/* Simulate a monitor trap. */
233
234static void
594266fc 235trap (i, regs)
90fe361f 236 int i;
594266fc
SC
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;
90fe361f
SC
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
594266fc
SC
279 case 255:
280 saved_state.asregs.exception = SIGILL;
281 break;
282 }
283
284}
285void
286control_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
90fe361f
SC
296static int
297div1 (R, iRn2, iRn1, T)
594266fc 298 int *R;
90fe361f
SC
299 int iRn1;
300 int iRn2;
594266fc
SC
301 int T;
302{
303 unsigned long tmp0;
304 unsigned char old_q, tmp1;
90fe361f 305
594266fc 306 old_q = Q;
90fe361f
SC
307 Q = (unsigned char) ((0x80000000 & R[iRn1]) != 0);
308 R[iRn1] <<= 1;
309 R[iRn1] |= (unsigned long) T;
310
311 switch (old_q)
594266fc 312 {
90fe361f
SC
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 }
594266fc
SC
345 break;
346 case 1:
347 switch (M)
348 {
90fe361f
SC
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 }
594266fc 362 break;
90fe361f
SC
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 }
594266fc
SC
376 break;
377 }
378 break;
90fe361f
SC
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];
594266fc 393
90fe361f
SC
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;
594266fc 405 }
90fe361f
SC
406 return T;
407}
408#endif
594266fc 409
90fe361f
SC
410static void dmul(sign, rml, rnl)
411 int sign;
412unsigned int rml;
413unsigned int rnl;
414{
415 unsigned int rmh;
416 unsigned int rnh;
594266fc 417
90fe361f
SC
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
594266fc
SC
451}
452
453
90fe361f
SC
454/* Set the memory size to the power of two provided. */
455
456void
457sim_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
487static
488void
489init_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
516static void
517dump_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
541static 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)
551void
594266fc 552sim_resume (step)
90fe361f 553 int step;
594266fc 554{
90fe361f
SC
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
594266fc
SC
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
90fe361f
SC
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);
594266fc 576 register unsigned char *memory = saved_state.asregs.memory;
90fe361f
SC
577 register unsigned int sbit = (1 << 31);
578
594266fc
SC
579 prev = signal (SIGINT, control_c);
580
90fe361f
SC
581 init_pointers();
582
594266fc
SC
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;
90fe361f
SC
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
594266fc
SC
604 do
605 {
90fe361f
SC
606 register unsigned int iword = RUWAT (pc);
607 register unsigned int ult;
594266fc
SC
608
609 insts++;
610 top:
611
612#include "code.c"
613
90fe361f 614
594266fc 615 pc += 2;
90fe361f
SC
616 prevlock = thislock;
617 thislock = 30;
594266fc 618 cycles++;
90fe361f
SC
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 }
594266fc
SC
636 }
637 while (!saved_state.asregs.exception);
638
90fe361f 639 if (saved_state.asregs.exception == SIGILL)
594266fc 640 {
90fe361f 641 pc -= 2;
594266fc 642 }
90fe361f 643
594266fc
SC
644 saved_state.asregs.ticks += get_now () - tick_start;
645 saved_state.asregs.cycles += cycles;
90fe361f 646 saved_state.asregs.stalls += stalls;
594266fc
SC
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
90fe361f
SC
652 saved_state.asregs.prevlock = prevlock;
653 saved_state.asregs.thislock = thislock;
654
655
656 if (profile_file)
657 {
658 dump_profile();
659 }
660
594266fc
SC
661 signal (SIGINT, prev);
662}
663
664
665
90fe361f 666
594266fc
SC
667void
668sim_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
682void
683sim_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
90fe361f 699void
594266fc
SC
700sim_store_register (rn, value)
701 int rn;
702 int value;
703{
704 saved_state.asregs.regs[rn] = value;
705}
706
90fe361f 707void
594266fc
SC
708sim_fetch_register (rn, buf)
709 int rn;
710 char *buf;
711{
594266fc
SC
712 int value = ((int *) (&saved_state))[rn];
713
90fe361f 714 swap(buf, value);
594266fc
SC
715}
716
90fe361f 717
594266fc
SC
718int
719sim_trace ()
720{
594266fc 721 return 0;
594266fc
SC
722}
723
90fe361f 724int
594266fc
SC
725sim_stop_signal ()
726{
727 return saved_state.asregs.exception;
728}
729
90fe361f 730void
594266fc 731sim_set_pc (x)
90fe361f 732 int x;
594266fc
SC
733{
734 saved_state.asregs.pc = x;
735}
736
737
90fe361f 738void
594266fc
SC
739sim_info ()
740{
741 double timetaken = (double) saved_state.asregs.ticks / (double) now_persec ();
90fe361f
SC
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 }
594266fc
SC
758}
759
90fe361f
SC
760
761void
762sim_set_profile(n)
594266fc 763{
90fe361f
SC
764 saved_state.asregs.profile = n;
765}
766
767void
768 sim_set_profile_size(n)
769{
770 sim_profile_size = n;
594266fc 771}
This page took 0.074308 seconds and 4 git commands to generate.