Commit | Line | Data |
---|---|---|
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++; | |
100 | int sim_memory_size = 19; | |
101 | static int sim_profile_size = 17; | |
102 | static int nsamples; | |
594266fc SC |
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 | { | |
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 | ||
157 | saved_state_type; | |
594266fc SC |
158 | saved_state_type saved_state; |
159 | ||
594266fc SC |
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 | { | |
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 | ||
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; | |
594266fc SC |
199 | } |
200 | ||
90fe361f SC |
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 | |
594266fc | 235 | trap (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 | } | |
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 | ||
90fe361f SC |
296 | static int |
297 | div1 (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 |
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; | |
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 | ||
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 | |
594266fc | 552 | sim_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 |
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 | ||
90fe361f | 699 | void |
594266fc SC |
700 | sim_store_register (rn, value) |
701 | int rn; | |
702 | int value; | |
703 | { | |
704 | saved_state.asregs.regs[rn] = value; | |
705 | } | |
706 | ||
90fe361f | 707 | void |
594266fc SC |
708 | sim_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 |
718 | int |
719 | sim_trace () | |
720 | { | |
594266fc | 721 | return 0; |
594266fc SC |
722 | } |
723 | ||
90fe361f | 724 | int |
594266fc SC |
725 | sim_stop_signal () |
726 | { | |
727 | return saved_state.asregs.exception; | |
728 | } | |
729 | ||
90fe361f | 730 | void |
594266fc | 731 | sim_set_pc (x) |
90fe361f | 732 | int x; |
594266fc SC |
733 | { |
734 | saved_state.asregs.pc = x; | |
735 | } | |
736 | ||
737 | ||
90fe361f | 738 | void |
594266fc SC |
739 | sim_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 | |
761 | void | |
762 | sim_set_profile(n) | |
594266fc | 763 | { |
90fe361f SC |
764 | saved_state.asregs.profile = n; |
765 | } | |
766 | ||
767 | void | |
768 | sim_set_profile_size(n) | |
769 | { | |
770 | sim_profile_size = n; | |
594266fc | 771 | } |