(sim_stop_signal): Result is now enum sim_stop.
[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;
fdc506e6 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
fdc506e6
SC
184static void
185swap (b, n)
90fe361f
SC
186 unsigned char *b;
187 int n;
fdc506e6
SC
188{
189 b[0] = n >> 24;
190 b[1] = n >> 16;
191 b[2] = n >> 8;
192 b[3] = n >> 0;
90fe361f 193}
fdc506e6
SC
194static void
195swap16 (b, n)
90fe361f
SC
196 unsigned char *b;
197 int n;
fdc506e6
SC
198{
199 b[0] = n >> 8;
200 b[1] = n >> 0;
594266fc
SC
201}
202
90fe361f 203static void
fdc506e6 204swapout (n)
90fe361f
SC
205 int n;
206{
fdc506e6 207 if (profile_file)
90fe361f
SC
208 {
209 char b[4];
fdc506e6
SC
210 swap (b, n);
211 fwrite (b, 4, 1, profile_file);
90fe361f 212 }
fdc506e6 213}
90fe361f
SC
214
215static void
fdc506e6 216swapout16 (n)
90fe361f
SC
217 int n;
218{
219 char b[4];
fdc506e6
SC
220 swap16 (b, n);
221 fwrite (b, 2, 1, profile_file);
222}
90fe361f
SC
223
224
225/* Turn a pointer in a register into a pointer into real memory. */
226
227static char *
228ptr (x)
229 int x;
230{
fdc506e6 231 return (char *) (x + saved_state.asregs.memory);
90fe361f
SC
232}
233
234/* Simulate a monitor trap. */
235
236static void
594266fc 237trap (i, regs)
90fe361f 238 int i;
594266fc
SC
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;
90fe361f
SC
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
594266fc
SC
281 case 255:
282 saved_state.asregs.exception = SIGILL;
283 break;
284 }
285
286}
287void
288control_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
fdc506e6 298static int
90fe361f 299div1 (R, iRn2, iRn1, T)
594266fc 300 int *R;
90fe361f
SC
301 int iRn1;
302 int iRn2;
594266fc
SC
303 int T;
304{
305 unsigned long tmp0;
306 unsigned char old_q, tmp1;
90fe361f 307
594266fc 308 old_q = Q;
90fe361f
SC
309 Q = (unsigned char) ((0x80000000 & R[iRn1]) != 0);
310 R[iRn1] <<= 1;
311 R[iRn1] |= (unsigned long) T;
312
313 switch (old_q)
594266fc 314 {
fdc506e6 315 case 0:
90fe361f 316 switch (M)
fdc506e6
SC
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 }
594266fc
SC
347 break;
348 case 1:
349 switch (M)
350 {
fdc506e6 351 case 0:
90fe361f
SC
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);
fdc506e6 362 break;
90fe361f 363 }
594266fc 364 break;
fdc506e6 365 case 1:
90fe361f
SC
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 }
594266fc
SC
378 break;
379 }
380 break;
90fe361f
SC
381 }
382 T = (Q == M);
383 return T;
384}
385
90fe361f 386
fdc506e6
SC
387static void
388dmul (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;
90fe361f 397
594266fc 398
fdc506e6 399 if (!sign)
90fe361f 400 {
594266fc 401
fdc506e6
SC
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;
594266fc 421
90fe361f 422 }
fdc506e6
SC
423
424 else
90fe361f 425 {
fdc506e6 426 abort ();
90fe361f 427 }
fdc506e6 428
594266fc
SC
429}
430
fdc506e6 431
90fe361f
SC
432/* Set the memory size to the power of two provided. */
433
434void
435sim_size (power)
436 int power;
437
438{
439 saved_state.asregs.msize = 1 << power;
440
fdc506e6 441 sim_memory_size = power;
90fe361f
SC
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;
fdc506e6 459 saved_state.asregs.memory = (unsigned char *) calloc (1, 1);
90fe361f
SC
460 }
461}
462
463
464
fdc506e6 465static
90fe361f
SC
466void
467init_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 {
fdc506e6 476 profile_file = fopen ("gmon.out", "wb");
90fe361f 477 /* Seek to where to put the call arc data */
fdc506e6 478 nsamples = (1 << sim_profile_size);
90fe361f 479
fdc506e6
SC
480 fseek (profile_file, nsamples * 2 + 12, 0);
481
482 if (!profile_file)
90fe361f 483 {
fdc506e6 484 fprintf (stderr, "Can't open gmon.out\n");
90fe361f 485 }
fdc506e6 486 else
90fe361f
SC
487 {
488 saved_state.asregs.profile_hist =
fdc506e6 489 (unsigned short *) calloc (64, (nsamples * sizeof (short) / 64));
90fe361f
SC
490 }
491 }
492}
493
494static void
fdc506e6 495dump_profile ()
90fe361f 496{
fdc506e6 497 unsigned int minpc;
90fe361f
SC
498 unsigned int maxpc;
499 unsigned short *p;
500
501 int thisshift;
fdc506e6 502
90fe361f
SC
503 unsigned short *first;
504
505 int i;
506 p = saved_state.asregs.profile_hist;
fdc506e6
SC
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
90fe361f
SC
517}
518
fdc506e6
SC
519static int
520gotcall (from, to)
90fe361f
SC
521 int from;
522 int to;
523{
fdc506e6
SC
524 swapout (from);
525 swapout (to);
526 swapout (1);
90fe361f
SC
527}
528
529#define MMASKB ((saved_state.asregs.msize -1) & ~0)
530void
594266fc 531sim_resume (step)
90fe361f 532 int step;
594266fc 533{
fdc506e6 534 register unsigned int pc;
90fe361f
SC
535 register int cycles = 0;
536 register int stalls = 0;
537 register int insts = 0;
538 register int prevlock;
fdc506e6
SC
539 register int thislock;
540 register unsigned int doprofile;
90fe361f 541
594266fc
SC
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
90fe361f
SC
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);
594266fc 555 register unsigned char *memory = saved_state.asregs.memory;
90fe361f
SC
556 register unsigned int sbit = (1 << 31);
557
594266fc
SC
558 prev = signal (SIGINT, control_c);
559
fdc506e6
SC
560 init_pointers ();
561
594266fc
SC
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;
90fe361f
SC
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. */
fdc506e6 580 if (doprofile == 0)
90fe361f 581 doprofile = ~0;
fdc506e6 582
594266fc
SC
583 do
584 {
fdc506e6
SC
585 register unsigned int iword = RUWAT (pc);
586 register unsigned int ult;
594266fc
SC
587
588 insts++;
589 top:
590
591#include "code.c"
592
90fe361f 593
594266fc 594 pc += 2;
90fe361f
SC
595 prevlock = thislock;
596 thislock = 30;
594266fc 597 cycles++;
90fe361f
SC
598
599 if (cycles >= doprofile)
600 {
601 saved_state.asregs.cycles += doprofile;
602 cycles -= doprofile;
fdc506e6 603 if (saved_state.asregs.profile_hist)
90fe361f
SC
604 {
605 int n = pc >> PROFILE_SHIFT;
fdc506e6 606 if (n < nsamples)
90fe361f
SC
607 {
608 int i = saved_state.asregs.profile_hist[n];
609 if (i < 65000)
fdc506e6 610 saved_state.asregs.profile_hist[n] = i + 1;
90fe361f 611 }
fdc506e6 612
90fe361f
SC
613 }
614 }
594266fc
SC
615 }
616 while (!saved_state.asregs.exception);
617
90fe361f 618 if (saved_state.asregs.exception == SIGILL)
594266fc 619 {
90fe361f 620 pc -= 2;
594266fc 621 }
90fe361f 622
594266fc
SC
623 saved_state.asregs.ticks += get_now () - tick_start;
624 saved_state.asregs.cycles += cycles;
90fe361f 625 saved_state.asregs.stalls += stalls;
594266fc
SC
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
90fe361f
SC
631 saved_state.asregs.prevlock = prevlock;
632 saved_state.asregs.thislock = thislock;
633
634
635 if (profile_file)
636 {
fdc506e6 637 dump_profile ();
90fe361f 638 }
fdc506e6 639
594266fc
SC
640 signal (SIGINT, prev);
641}
642
643
644
90fe361f 645
594266fc
SC
646void
647sim_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
661void
662sim_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
90fe361f 678void
594266fc
SC
679sim_store_register (rn, value)
680 int rn;
681 int value;
682{
683 saved_state.asregs.regs[rn] = value;
684}
685
90fe361f 686void
594266fc
SC
687sim_fetch_register (rn, buf)
688 int rn;
689 char *buf;
690{
594266fc
SC
691 int value = ((int *) (&saved_state))[rn];
692
fdc506e6 693 swap (buf, value);
594266fc
SC
694}
695
90fe361f 696
594266fc
SC
697int
698sim_trace ()
699{
594266fc 700 return 0;
594266fc
SC
701}
702
90fe361f 703int
594266fc
SC
704sim_stop_signal ()
705{
706 return saved_state.asregs.exception;
707}
708
90fe361f 709void
594266fc 710sim_set_pc (x)
90fe361f 711 int x;
594266fc
SC
712{
713 saved_state.asregs.pc = x;
714}
715
716
90fe361f 717void
594266fc
SC
718sim_info ()
719{
720 double timetaken = (double) saved_state.asregs.ticks / (double) now_persec ();
90fe361f
SC
721 double virttime = saved_state.asregs.cycles / 36.0e6;
722
723 printf ("\n\n# instructions executed %10d\n", saved_state.asregs.insts);
fdc506e6 724 printf ("# cycles %10d\n", saved_state.asregs.cycles);
90fe361f
SC
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);
fdc506e6
SC
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)
90fe361f
SC
733 {
734 printf ("# cycles/second %10d\n", (int) (saved_state.asregs.cycles / timetaken));
735 printf ("# simulation ratio %10.4f\n", virttime / timetaken);
736 }
594266fc
SC
737}
738
90fe361f
SC
739
740void
fdc506e6 741sim_set_profile (n)
594266fc 742{
90fe361f
SC
743 saved_state.asregs.profile = n;
744}
745
746void
fdc506e6 747sim_set_profile_size (n)
90fe361f
SC
748{
749 sim_profile_size = n;
594266fc 750}
This page took 0.073884 seconds and 4 git commands to generate.