]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blob - sim/sh/interp.c
Initial creation of sourceware repository
[thirdparty/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
21 #include "config.h"
22
23 #include <signal.h>
24 #ifdef HAVE_UNISTD_H
25 #include <unistd.h>
26 #endif
27
28 #include "sysdep.h"
29 #include "bfd.h"
30 #include "callback.h"
31 #include "remote-sim.h"
32
33 /* This file is local - if newlib changes, then so should this. */
34 #include "syscall.h"
35
36 #include <math.h>
37
38 #ifdef _WIN32
39 #include <float.h> /* Needed for _isnan() */
40 #define isnan _isnan
41 #endif
42
43 #ifndef SIGBUS
44 #define SIGBUS SIGSEGV
45 #endif
46
47 #ifndef SIGQUIT
48 #define SIGQUIT SIGTERM
49 #endif
50
51 #ifndef SIGTRAP
52 #define SIGTRAP 5
53 #endif
54
55 #define O_RECOMPILE 85
56 #define DEFINE_TABLE
57 #define DISASSEMBLER_TABLE
58
59 typedef union
60 {
61
62 struct
63 {
64 int pad_dummy;
65 int regs[16];
66 int pc;
67 int pr;
68
69 int gbr;
70 int vbr;
71 int mach;
72 int macl;
73
74 int sr;
75
76 int fpul;
77
78 int fpscr;
79
80 /* sh3e */
81 union fregs_u
82 {
83 float f[16];
84 double d[8];
85 int i[16];
86 }
87 fregs;
88
89 int ssr;
90 int spc;
91 /* sh3 */
92 int bank[2][8];
93
94 int ticks;
95 int stalls;
96 int memstalls;
97 int cycles;
98 int insts;
99
100 int prevlock;
101 int thislock;
102 int exception;
103
104 int end_of_registers;
105
106 int msize;
107 #define PROFILE_FREQ 1
108 #define PROFILE_SHIFT 2
109 int profile;
110 unsigned short *profile_hist;
111 unsigned char *memory;
112 }
113 asregs;
114 int asints[40];
115 } saved_state_type;
116
117 saved_state_type saved_state;
118
119
120 /* These variables are at file scope so that functions other than
121 sim_resume can use the fetch/store macros */
122
123 static int target_little_endian;
124 static int host_little_endian;
125
126 #if 1
127 static int maskl = ~0;
128 static int maskw = ~0;
129 #endif
130
131 static SIM_OPEN_KIND sim_kind;
132 static char *myname;
133
134
135 /* Short hand definitions of the registers */
136
137 #define SBIT(x) ((x)&sbit)
138 #define R0 saved_state.asregs.regs[0]
139 #define Rn saved_state.asregs.regs[n]
140 #define Rm saved_state.asregs.regs[m]
141 #define UR0 (unsigned int)(saved_state.asregs.regs[0])
142 #define UR (unsigned int)R
143 #define UR (unsigned int)R
144 #define SR0 saved_state.asregs.regs[0]
145 #define GBR saved_state.asregs.gbr
146 #define VBR saved_state.asregs.vbr
147 #define SSR saved_state.asregs.ssr
148 #define SPC saved_state.asregs.spc
149 #define MACH saved_state.asregs.mach
150 #define MACL saved_state.asregs.macl
151 #define FPUL saved_state.asregs.fpul
152
153 #define PC pc
154
155
156
157 /* Alternate bank of registers r0-r6 */
158
159 /* Note: code controling SR handles flips between BANK0 and BANK1 */
160 #define Rn_BANK(n) (saved_state.asregs.bank[!SR_RB][(n)])
161 #define SET_Rn_BANK(n, EXP) do { saved_state.asregs.bank[!SR_RB][(n)] = (EXP); } while (0)
162
163
164 /* Manipulate SR */
165
166 #define SR_MASK_M (1 << 9)
167 #define SR_MASK_Q (1 << 8)
168 #define SR_MASK_I (0xf << 4)
169 #define SR_MASK_S (1 << 1)
170 #define SR_MASK_T (1 << 0)
171
172 #define SR_MASK_BL (1 << 28)
173 #define SR_MASK_RB (1 << 29)
174 #define SR_MASK_MD (1 << 30)
175
176 #define M ((saved_state.asregs.sr & SR_MASK_M) != 0)
177 #define Q ((saved_state.asregs.sr & SR_MASK_Q) != 0)
178 #define S ((saved_state.asregs.sr & SR_MASK_S) != 0)
179 #define T ((saved_state.asregs.sr & SR_MASK_T) != 0)
180
181 #define SR_BL ((saved_state.asregs.sr & SR_MASK_BL) != 0)
182 #define SR_RB ((saved_state.asregs.sr & SR_MASK_RB) != 0)
183 #define SR_MD ((saved_state.asregs.sr & SR_MASK_MD) != 0)
184
185 /* Note: don't use this for privileged bits */
186 #define SET_SR_BIT(EXP, BIT) \
187 do { \
188 if ((EXP) & 1) \
189 saved_state.asregs.sr |= (BIT); \
190 else \
191 saved_state.asregs.sr &= ~(BIT); \
192 } while (0)
193
194 #define SET_SR_M(EXP) SET_SR_BIT ((EXP), SR_MASK_M)
195 #define SET_SR_Q(EXP) SET_SR_BIT ((EXP), SR_MASK_Q)
196 #define SET_SR_S(EXP) SET_SR_BIT ((EXP), SR_MASK_S)
197 #define SET_SR_T(EXP) SET_SR_BIT ((EXP), SR_MASK_T)
198
199 #define GET_SR() (saved_state.asregs.sr - 0)
200 #define SET_SR(x) set_sr (x)
201 static void
202 set_sr (new_sr)
203 int new_sr;
204 {
205 /* do we need to swap banks */
206 int old_gpr = (SR_MD ? !SR_RB : 0);
207 int new_gpr = ((new_sr & SR_MASK_MD)
208 ? (new_sr & SR_MASK_RB) == 0
209 : 0);
210 if (old_gpr != new_gpr)
211 {
212 int i;
213 for (i = 0; i < 8; i++)
214 {
215 saved_state.asregs.bank[old_gpr][i] = saved_state.asregs.regs[i];
216 saved_state.asregs.regs[i] = saved_state.asregs.bank[new_gpr][i];
217 }
218 }
219 }
220
221
222 /* Manipulate FPSCR */
223
224 #define set_fpscr1(x)
225 #define SET_FPSCR(x) (saved_state.asregs.fpscr = (x))
226 #define GET_FPSCR() (saved_state.asregs.fpscr)
227
228
229 int
230 fail ()
231 {
232 abort ();
233 }
234
235 /* This function exists solely for the purpose of setting a breakpoint to
236 catch simulated bus errors when running the simulator under GDB. */
237
238 void
239 bp_holder ()
240 {
241 }
242
243 /* FIXME: sim_resume should be renamed to sim_engine_run. sim_resume
244 being implemented by ../common/sim_resume.c and the below should
245 make a call to sim_engine_halt */
246
247 #define BUSERROR(addr, mask) \
248 if (addr & ~mask) { saved_state.asregs.exception = SIGBUS; bp_holder (); }
249
250 /* Define this to enable register lifetime checking.
251 The compiler generates "add #0,rn" insns to mark registers as invalid,
252 the simulator uses this info to call fail if it finds a ref to an invalid
253 register before a def
254
255 #define PARANOID
256 */
257
258 #ifdef PARANOID
259 int valid[16];
260 #define CREF(x) if(!valid[x]) fail();
261 #define CDEF(x) valid[x] = 1;
262 #define UNDEF(x) valid[x] = 0;
263 #else
264 #define CREF(x)
265 #define CDEF(x)
266 #define UNDEF(x)
267 #endif
268
269 static void parse_and_set_memory_size PARAMS ((char *str));
270
271 static int IOMEM PARAMS ((int addr, int write, int value));
272
273 static host_callback *callback;
274
275
276
277 /* Floating point registers */
278
279 #define FI(n) (saved_state.asregs.fregs.i[(n)])
280 #define FR(n) (saved_state.asregs.fregs.f[(n)])
281
282 #define SET_FI(n,EXP) (saved_state.asregs.fregs.i[(n)] = (EXP))
283 #define SET_FR(n,EXP) (saved_state.asregs.fregs.f[(n)] = (EXP))
284
285 #define FP_OP(n, OP, m) (SET_FR(n, (FR(n) OP FR(m))))
286 #define FP_UNARY(n, OP) (SET_FR(n, (OP (FR(n)))))
287 #define FP_CMP(n, OP, m) SET_SR_T(FR(n) OP FR(m))
288
289
290
291 static void INLINE
292 wlat_little (memory, x, value, maskl)
293 unsigned char *memory;
294 {
295 int v = value;
296 unsigned char *p = memory + ((x) & maskl);
297 BUSERROR(x, maskl);
298 p[3] = v >> 24;
299 p[2] = v >> 16;
300 p[1] = v >> 8;
301 p[0] = v;
302 }
303
304 static void INLINE
305 wwat_little (memory, x, value, maskw)
306 unsigned char *memory;
307 {
308 int v = value;
309 unsigned char *p = memory + ((x) & maskw);
310 BUSERROR(x, maskw);
311
312 p[1] = v >> 8;
313 p[0] = v;
314 }
315
316 static void INLINE
317 wbat_any (memory, x, value, maskb)
318 unsigned char *memory;
319 {
320 unsigned char *p = memory + (x & maskb);
321 if (x > 0x5000000)
322 IOMEM (x, 1, value);
323 BUSERROR(x, maskb);
324
325 p[0] = value;
326 }
327
328 static void INLINE
329 wlat_big (memory, x, value, maskl)
330 unsigned char *memory;
331 {
332 int v = value;
333 unsigned char *p = memory + ((x) & maskl);
334 BUSERROR(x, maskl);
335
336 p[0] = v >> 24;
337 p[1] = v >> 16;
338 p[2] = v >> 8;
339 p[3] = v;
340 }
341
342 static void INLINE
343 wwat_big (memory, x, value, maskw)
344 unsigned char *memory;
345 {
346 int v = value;
347 unsigned char *p = memory + ((x) & maskw);
348 BUSERROR(x, maskw);
349
350 p[0] = v >> 8;
351 p[1] = v;
352 }
353
354 static void INLINE
355 wbat_big (memory, x, value, maskb)
356 unsigned char *memory;
357 {
358 unsigned char *p = memory + (x & maskb);
359 BUSERROR(x, maskb);
360
361 if (x > 0x5000000)
362 IOMEM (x, 1, value);
363 p[0] = value;
364 }
365
366 /* Read functions */
367
368 static int INLINE
369 rlat_little (memory, x, maskl)
370 unsigned char *memory;
371 {
372 unsigned char *p = memory + ((x) & maskl);
373 BUSERROR(x, maskl);
374
375 return (p[3] << 24) | (p[2] << 16) | (p[1] << 8) | p[0];
376 }
377
378 static int INLINE
379 rwat_little (memory, x, maskw)
380 unsigned char *memory;
381 {
382 unsigned char *p = memory + ((x) & maskw);
383 BUSERROR(x, maskw);
384
385 return (p[1] << 8) | p[0];
386 }
387
388 static int INLINE
389 rbat_any (memory, x, maskb)
390 unsigned char *memory;
391 {
392 unsigned char *p = memory + ((x) & maskb);
393 BUSERROR(x, maskb);
394
395 return p[0];
396 }
397
398 static int INLINE
399 rlat_big (memory, x, maskl)
400 unsigned char *memory;
401 {
402 unsigned char *p = memory + ((x) & maskl);
403 BUSERROR(x, maskl);
404
405 return (p[0] << 24) | (p[1] << 16) | (p[2] << 8) | p[3];
406 }
407
408 static int INLINE
409 rwat_big (memory, x, maskw)
410 unsigned char *memory;
411 {
412 unsigned char *p = memory + ((x) & maskw);
413 BUSERROR(x, maskw);
414
415 return (p[0] << 8) | p[1];
416 }
417
418 #define RWAT(x) (little_endian ? rwat_little(memory, x, maskw): rwat_big(memory, x, maskw))
419 #define RLAT(x) (little_endian ? rlat_little(memory, x, maskl): rlat_big(memory, x, maskl))
420 #define RBAT(x) (rbat_any (memory, x, maskb))
421 #define WWAT(x,v) (little_endian ? wwat_little(memory, x, v, maskw): wwat_big(memory, x, v, maskw))
422 #define WLAT(x,v) (little_endian ? wlat_little(memory, x, v, maskl): wlat_big(memory, x, v, maskl))
423 #define WBAT(x,v) (wbat_any (memory, x, v, maskb))
424
425 #define RUWAT(x) (RWAT(x) & 0xffff)
426 #define RSWAT(x) ((short)(RWAT(x)))
427 #define RSBAT(x) (SEXT(RBAT(x)))
428
429
430
431
432 #define MA(n) do { memstalls += (((pc & 3) != 0) ? (n) : ((n) - 1)); } while (0)
433
434 #define SEXT(x) (((x & 0xff) ^ (~0x7f))+0x80)
435 #define SEXT12(x) (((x & 0xfff) ^ 0x800) - 0x800)
436 #define SEXTW(y) ((int)((short)y))
437
438 #define Delay_Slot(TEMPPC) iword = RUWAT(TEMPPC); goto top;
439
440 int empty[16];
441
442 #define L(x) thislock = x;
443 #define TL(x) if ((x) == prevlock) stalls++;
444 #define TB(x,y) if ((x) == prevlock || (y)==prevlock) stalls++;
445
446 #if defined(__GO32__) || defined(_WIN32)
447 int sim_memory_size = 19;
448 #else
449 int sim_memory_size = 24;
450 #endif
451
452 static int sim_profile_size = 17;
453 static int nsamples;
454
455 #undef TB
456 #define TB(x,y)
457
458 #define SMR1 (0x05FFFEC8) /* Channel 1 serial mode register */
459 #define BRR1 (0x05FFFEC9) /* Channel 1 bit rate register */
460 #define SCR1 (0x05FFFECA) /* Channel 1 serial control register */
461 #define TDR1 (0x05FFFECB) /* Channel 1 transmit data register */
462 #define SSR1 (0x05FFFECC) /* Channel 1 serial status register */
463 #define RDR1 (0x05FFFECD) /* Channel 1 receive data register */
464
465 #define SCI_RDRF 0x40 /* Recieve data register full */
466 #define SCI_TDRE 0x80 /* Transmit data register empty */
467
468 static int
469 IOMEM (addr, write, value)
470 int addr;
471 int write;
472 int value;
473 {
474 if (write)
475 {
476 switch (addr)
477 {
478 case TDR1:
479 if (value != '\r')
480 {
481 putchar (value);
482 fflush (stdout);
483 }
484 break;
485 }
486 }
487 else
488 {
489 switch (addr)
490 {
491 case RDR1:
492 return getchar ();
493 }
494 }
495 return 0;
496 }
497
498 static int
499 get_now ()
500 {
501 return time ((long *) 0);
502 }
503
504 static int
505 now_persec ()
506 {
507 return 1;
508 }
509
510 static FILE *profile_file;
511
512 static void
513 swap (memory, n)
514 unsigned char *memory;
515 int n;
516 {
517 int little_endian = target_little_endian;
518 WLAT (0, n);
519 }
520
521 static void
522 swap16 (memory, n)
523 unsigned char *memory;
524 int n;
525 {
526 int little_endian = target_little_endian;
527 WWAT (0, n);
528 }
529
530 static void
531 swapout (n)
532 int n;
533 {
534 if (profile_file)
535 {
536 char b[4];
537 swap (b, n);
538 fwrite (b, 4, 1, profile_file);
539 }
540 }
541
542 static void
543 swapout16 (n)
544 int n;
545 {
546 char b[4];
547 swap16 (b, n);
548 fwrite (b, 2, 1, profile_file);
549 }
550
551 /* Turn a pointer in a register into a pointer into real memory. */
552
553 static char *
554 ptr (x)
555 int x;
556 {
557 return (char *) (x + saved_state.asregs.memory);
558 }
559
560 /* Simulate a monitor trap, put the result into r0 and errno into r1 */
561
562 static void
563 trap (i, regs, memory, maskl, maskw, little_endian)
564 int i;
565 int *regs;
566 unsigned char *memory;
567 {
568 switch (i)
569 {
570 case 1:
571 printf ("%c", regs[0]);
572 break;
573 case 2:
574 saved_state.asregs.exception = SIGQUIT;
575 break;
576 case 3: /* FIXME: for backwards compat, should be removed */
577 case 34:
578 {
579 extern int errno;
580 int perrno = errno;
581 errno = 0;
582
583 switch (regs[4])
584 {
585
586 #if !defined(__GO32__) && !defined(_WIN32)
587 case SYS_fork:
588 regs[0] = fork ();
589 break;
590 case SYS_execve:
591 regs[0] = execve (ptr (regs[5]), (char **)ptr (regs[6]), (char **)ptr (regs[7]));
592 break;
593 case SYS_execv:
594 regs[0] = execve (ptr (regs[5]),(char **) ptr (regs[6]), 0);
595 break;
596 case SYS_pipe:
597 {
598 char *buf;
599 int host_fd[2];
600
601 buf = ptr (regs[5]);
602
603 regs[0] = pipe (host_fd);
604
605 WLAT (buf, host_fd[0]);
606 buf += 4;
607 WLAT (buf, host_fd[1]);
608 }
609 break;
610
611 case SYS_wait:
612 regs[0] = wait (ptr (regs[5]));
613 break;
614 #endif
615
616 case SYS_read:
617 regs[0] = callback->read (callback, regs[5], ptr (regs[6]), regs[7]);
618 break;
619 case SYS_write:
620 if (regs[5] == 1)
621 regs[0] = (int)callback->write_stdout (callback, ptr(regs[6]), regs[7]);
622 else
623 regs[0] = (int)callback->write (callback, regs[5], ptr (regs[6]), regs[7]);
624 break;
625 case SYS_lseek:
626 regs[0] = callback->lseek (callback,regs[5], regs[6], regs[7]);
627 break;
628 case SYS_close:
629 regs[0] = callback->close (callback,regs[5]);
630 break;
631 case SYS_open:
632 regs[0] = callback->open (callback,ptr (regs[5]), regs[6]);
633 break;
634 case SYS_exit:
635 /* EXIT - caller can look in r5 to work out the reason */
636 saved_state.asregs.exception = SIGQUIT;
637 regs[0] = regs[5];
638 break;
639
640 case SYS_stat: /* added at hmsi */
641 /* stat system call */
642 {
643 struct stat host_stat;
644 char *buf;
645
646 regs[0] = stat (ptr (regs[5]), &host_stat);
647
648 buf = ptr (regs[6]);
649
650 WWAT (buf, host_stat.st_dev);
651 buf += 2;
652 WWAT (buf, host_stat.st_ino);
653 buf += 2;
654 WLAT (buf, host_stat.st_mode);
655 buf += 4;
656 WWAT (buf, host_stat.st_nlink);
657 buf += 2;
658 WWAT (buf, host_stat.st_uid);
659 buf += 2;
660 WWAT (buf, host_stat.st_gid);
661 buf += 2;
662 WWAT (buf, host_stat.st_rdev);
663 buf += 2;
664 WLAT (buf, host_stat.st_size);
665 buf += 4;
666 WLAT (buf, host_stat.st_atime);
667 buf += 4;
668 WLAT (buf, 0);
669 buf += 4;
670 WLAT (buf, host_stat.st_mtime);
671 buf += 4;
672 WLAT (buf, 0);
673 buf += 4;
674 WLAT (buf, host_stat.st_ctime);
675 buf += 4;
676 WLAT (buf, 0);
677 buf += 4;
678 WLAT (buf, 0);
679 buf += 4;
680 WLAT (buf, 0);
681 buf += 4;
682 }
683 break;
684
685 #ifndef _WIN32
686 case SYS_chown:
687 regs[0] = chown (ptr (regs[5]), regs[6], regs[7]);
688 break;
689 #endif /* _WIN32 */
690 case SYS_chmod:
691 regs[0] = chmod (ptr (regs[5]), regs[6]);
692 break;
693 case SYS_utime:
694 /* Cast the second argument to void *, to avoid type mismatch
695 if a prototype is present. */
696 regs[0] = utime (ptr (regs[5]), (void *) ptr (regs[6]));
697 break;
698 default:
699 abort ();
700 }
701 regs[1] = callback->get_errno (callback);
702 errno = perrno;
703 }
704 break;
705
706 case 0xc3:
707 case 255:
708 saved_state.asregs.exception = SIGTRAP;
709 break;
710 }
711
712 }
713
714 void
715 control_c (sig, code, scp, addr)
716 int sig;
717 int code;
718 char *scp;
719 char *addr;
720 {
721 saved_state.asregs.exception = SIGINT;
722 }
723
724 static int
725 div1 (R, iRn2, iRn1/*, T*/)
726 int *R;
727 int iRn1;
728 int iRn2;
729 /* int T;*/
730 {
731 unsigned long tmp0;
732 unsigned char old_q, tmp1;
733
734 old_q = Q;
735 SET_SR_Q ((unsigned char) ((0x80000000 & R[iRn1]) != 0));
736 R[iRn1] <<= 1;
737 R[iRn1] |= (unsigned long) T;
738
739 switch (old_q)
740 {
741 case 0:
742 switch (M)
743 {
744 case 0:
745 tmp0 = R[iRn1];
746 R[iRn1] -= R[iRn2];
747 tmp1 = (R[iRn1] > tmp0);
748 switch (Q)
749 {
750 case 0:
751 SET_SR_Q (tmp1);
752 break;
753 case 1:
754 SET_SR_Q ((unsigned char) (tmp1 == 0));
755 break;
756 }
757 break;
758 case 1:
759 tmp0 = R[iRn1];
760 R[iRn1] += R[iRn2];
761 tmp1 = (R[iRn1] < tmp0);
762 switch (Q)
763 {
764 case 0:
765 SET_SR_Q ((unsigned char) (tmp1 == 0));
766 break;
767 case 1:
768 SET_SR_Q (tmp1);
769 break;
770 }
771 break;
772 }
773 break;
774 case 1:
775 switch (M)
776 {
777 case 0:
778 tmp0 = R[iRn1];
779 R[iRn1] += R[iRn2];
780 tmp1 = (R[iRn1] < tmp0);
781 switch (Q)
782 {
783 case 0:
784 SET_SR_Q (tmp1);
785 break;
786 case 1:
787 SET_SR_Q ((unsigned char) (tmp1 == 0));
788 break;
789 }
790 break;
791 case 1:
792 tmp0 = R[iRn1];
793 R[iRn1] -= R[iRn2];
794 tmp1 = (R[iRn1] > tmp0);
795 switch (Q)
796 {
797 case 0:
798 SET_SR_Q ((unsigned char) (tmp1 == 0));
799 break;
800 case 1:
801 SET_SR_Q (tmp1);
802 break;
803 }
804 break;
805 }
806 break;
807 }
808 /*T = (Q == M);*/
809 SET_SR_T (Q == M);
810 /*return T;*/
811 }
812
813 static void
814 dmul (sign, rm, rn)
815 int sign;
816 unsigned int rm;
817 unsigned int rn;
818 {
819 unsigned long RnL, RnH;
820 unsigned long RmL, RmH;
821 unsigned long temp0, temp1, temp2, temp3;
822 unsigned long Res2, Res1, Res0;
823
824 RnL = rn & 0xffff;
825 RnH = (rn >> 16) & 0xffff;
826 RmL = rm & 0xffff;
827 RmH = (rm >> 16) & 0xffff;
828 temp0 = RmL * RnL;
829 temp1 = RmH * RnL;
830 temp2 = RmL * RnH;
831 temp3 = RmH * RnH;
832 Res2 = 0;
833 Res1 = temp1 + temp2;
834 if (Res1 < temp1)
835 Res2 += 0x00010000;
836 temp1 = (Res1 << 16) & 0xffff0000;
837 Res0 = temp0 + temp1;
838 if (Res0 < temp0)
839 Res2 += 1;
840 Res2 += ((Res1 >> 16) & 0xffff) + temp3;
841
842 if (sign)
843 {
844 if (rn & 0x80000000)
845 Res2 -= rm;
846 if (rm & 0x80000000)
847 Res2 -= rn;
848 }
849
850 MACH = Res2;
851 MACL = Res0;
852 }
853
854 static void
855 macw (regs, memory, n, m)
856 int *regs;
857 unsigned char *memory;
858 int m, n;
859 {
860 int little_endian = target_little_endian;
861 long tempm, tempn;
862 long prod, macl, sum;
863
864 tempm=RSWAT(regs[m]); regs[m]+=2;
865 tempn=RSWAT(regs[n]); regs[n]+=2;
866
867 macl = MACL;
868 prod = (long)(short) tempm * (long)(short) tempn;
869 sum = prod + macl;
870 if (S)
871 {
872 if ((~(prod ^ macl) & (sum ^ prod)) < 0)
873 {
874 /* MACH's lsb is a sticky overflow bit. */
875 MACH |= 1;
876 /* Store the smallest negative number in MACL if prod is
877 negative, and the largest positive number otherwise. */
878 sum = 0x7fffffff + (prod < 0);
879 }
880 }
881 else
882 {
883 long mach;
884 /* Add to MACH the sign extended product, and carry from low sum. */
885 mach = MACH + (-(prod < 0)) + ((unsigned long) sum < prod);
886 /* Sign extend at 10:th bit in MACH. */
887 MACH = (mach & 0x1ff) | -(mach & 0x200);
888 }
889 MACL = sum;
890 }
891
892 /* Set the memory size to the power of two provided. */
893
894 void
895 sim_size (power)
896 int power;
897
898 {
899 saved_state.asregs.msize = 1 << power;
900
901 sim_memory_size = power;
902
903 if (saved_state.asregs.memory)
904 {
905 free (saved_state.asregs.memory);
906 }
907
908 saved_state.asregs.memory =
909 (unsigned char *) calloc (64, saved_state.asregs.msize / 64);
910
911 if (!saved_state.asregs.memory)
912 {
913 fprintf (stderr,
914 "Not enough VM for simulation of %d bytes of RAM\n",
915 saved_state.asregs.msize);
916
917 saved_state.asregs.msize = 1;
918 saved_state.asregs.memory = (unsigned char *) calloc (1, 1);
919 }
920 }
921
922 static void
923 init_pointers ()
924 {
925 host_little_endian = 0;
926 *(char*)&host_little_endian = 1;
927 host_little_endian &= 1;
928
929 if (saved_state.asregs.msize != 1 << sim_memory_size)
930 {
931 sim_size (sim_memory_size);
932 }
933
934 if (saved_state.asregs.profile && !profile_file)
935 {
936 profile_file = fopen ("gmon.out", "wb");
937 /* Seek to where to put the call arc data */
938 nsamples = (1 << sim_profile_size);
939
940 fseek (profile_file, nsamples * 2 + 12, 0);
941
942 if (!profile_file)
943 {
944 fprintf (stderr, "Can't open gmon.out\n");
945 }
946 else
947 {
948 saved_state.asregs.profile_hist =
949 (unsigned short *) calloc (64, (nsamples * sizeof (short) / 64));
950 }
951 }
952 }
953
954 static void
955 dump_profile ()
956 {
957 unsigned int minpc;
958 unsigned int maxpc;
959 unsigned short *p;
960 int i;
961
962 p = saved_state.asregs.profile_hist;
963 minpc = 0;
964 maxpc = (1 << sim_profile_size);
965
966 fseek (profile_file, 0L, 0);
967 swapout (minpc << PROFILE_SHIFT);
968 swapout (maxpc << PROFILE_SHIFT);
969 swapout (nsamples * 2 + 12);
970 for (i = 0; i < nsamples; i++)
971 swapout16 (saved_state.asregs.profile_hist[i]);
972
973 }
974
975 static void
976 gotcall (from, to)
977 int from;
978 int to;
979 {
980 swapout (from);
981 swapout (to);
982 swapout (1);
983 }
984
985 #define MMASKB ((saved_state.asregs.msize -1) & ~0)
986
987 int
988 sim_stop (sd)
989 SIM_DESC sd;
990 {
991 saved_state.asregs.exception = SIGINT;
992 return 1;
993 }
994
995 void
996 sim_resume (sd, step, siggnal)
997 SIM_DESC sd;
998 int step, siggnal;
999 {
1000 register unsigned int pc;
1001 register int cycles = 0;
1002 register int stalls = 0;
1003 register int memstalls = 0;
1004 register int insts = 0;
1005 register int prevlock;
1006 register int thislock;
1007 register unsigned int doprofile;
1008 register int pollcount = 0;
1009 register int little_endian = target_little_endian;
1010
1011 int tick_start = get_now ();
1012 void (*prev) ();
1013 void (*prev_fpe) ();
1014 extern unsigned char sh_jump_table0[];
1015
1016 register unsigned char *jump_table = sh_jump_table0;
1017
1018 register int *R = &(saved_state.asregs.regs[0]);
1019 /*register int T;*/
1020 register int PR;
1021
1022 register int maskb = ((saved_state.asregs.msize - 1) & ~0);
1023 register int maskw = ((saved_state.asregs.msize - 1) & ~1);
1024 register int maskl = ((saved_state.asregs.msize - 1) & ~3);
1025 register unsigned char *memory;
1026 register unsigned int sbit = ((unsigned int) 1 << 31);
1027
1028 prev = signal (SIGINT, control_c);
1029 prev_fpe = signal (SIGFPE, SIG_IGN);
1030
1031 init_pointers ();
1032
1033 memory = saved_state.asregs.memory;
1034
1035 if (step)
1036 {
1037 saved_state.asregs.exception = SIGTRAP;
1038 }
1039 else
1040 {
1041 saved_state.asregs.exception = 0;
1042 }
1043
1044 pc = saved_state.asregs.pc;
1045 PR = saved_state.asregs.pr;
1046 /*T = GET_SR () & SR_MASK_T;*/
1047 prevlock = saved_state.asregs.prevlock;
1048 thislock = saved_state.asregs.thislock;
1049 doprofile = saved_state.asregs.profile;
1050
1051 /* If profiling not enabled, disable it by asking for
1052 profiles infrequently. */
1053 if (doprofile == 0)
1054 doprofile = ~0;
1055
1056 do
1057 {
1058 register unsigned int iword = RUWAT (pc);
1059 register unsigned int ult;
1060 register unsigned int nia = pc + 2;
1061 #ifndef ACE_FAST
1062 insts++;
1063 #endif
1064 top:
1065
1066 #include "code.c"
1067
1068
1069 pc = nia;
1070
1071 if (--pollcount < 0)
1072 {
1073 pollcount = 1000;
1074 if ((*callback->poll_quit) != NULL
1075 && (*callback->poll_quit) (callback))
1076 {
1077 sim_stop (sd);
1078 }
1079 }
1080
1081 #ifndef ACE_FAST
1082 prevlock = thislock;
1083 thislock = 30;
1084 cycles++;
1085
1086 if (cycles >= doprofile)
1087 {
1088
1089 saved_state.asregs.cycles += doprofile;
1090 cycles -= doprofile;
1091 if (saved_state.asregs.profile_hist)
1092 {
1093 int n = pc >> PROFILE_SHIFT;
1094 if (n < nsamples)
1095 {
1096 int i = saved_state.asregs.profile_hist[n];
1097 if (i < 65000)
1098 saved_state.asregs.profile_hist[n] = i + 1;
1099 }
1100
1101 }
1102 }
1103 #endif
1104 }
1105 while (!saved_state.asregs.exception);
1106
1107 if (saved_state.asregs.exception == SIGILL
1108 || saved_state.asregs.exception == SIGBUS)
1109 {
1110 pc -= 2;
1111 }
1112
1113 saved_state.asregs.ticks += get_now () - tick_start;
1114 saved_state.asregs.cycles += cycles;
1115 saved_state.asregs.stalls += stalls;
1116 saved_state.asregs.memstalls += memstalls;
1117 saved_state.asregs.insts += insts;
1118 saved_state.asregs.pc = pc;
1119 /* restore the T and other cached SR bits */
1120 SET_SR (GET_SR());
1121 saved_state.asregs.pr = PR;
1122
1123 saved_state.asregs.prevlock = prevlock;
1124 saved_state.asregs.thislock = thislock;
1125
1126 if (profile_file)
1127 {
1128 dump_profile ();
1129 }
1130
1131 signal (SIGFPE, prev_fpe);
1132 signal (SIGINT, prev);
1133 }
1134
1135 int
1136 sim_write (sd, addr, buffer, size)
1137 SIM_DESC sd;
1138 SIM_ADDR addr;
1139 unsigned char *buffer;
1140 int size;
1141 {
1142 int i;
1143
1144 init_pointers ();
1145
1146 for (i = 0; i < size; i++)
1147 {
1148 saved_state.asregs.memory[MMASKB & (addr + i)] = buffer[i];
1149 }
1150 return size;
1151 }
1152
1153 int
1154 sim_read (sd, addr, buffer, size)
1155 SIM_DESC sd;
1156 SIM_ADDR addr;
1157 unsigned char *buffer;
1158 int size;
1159 {
1160 int i;
1161
1162 init_pointers ();
1163
1164 for (i = 0; i < size; i++)
1165 {
1166 buffer[i] = saved_state.asregs.memory[MMASKB & (addr + i)];
1167 }
1168 return size;
1169 }
1170
1171 /* We have to add one to RN as an index into asints because of the padding
1172 added at the start of asregs. */
1173 int
1174 sim_store_register (sd, rn, memory, length)
1175 SIM_DESC sd;
1176 int rn;
1177 unsigned char *memory;
1178 int length;
1179 {
1180 int little_endian;
1181 init_pointers ();
1182 little_endian = target_little_endian;
1183 if (&saved_state.asints[rn+1]
1184 == &saved_state.asregs.fpscr)
1185 set_fpscr1 (RLAT(0));
1186 else
1187 saved_state.asints[rn+1] = RLAT(0);
1188 return -1;
1189 }
1190
1191 int
1192 sim_fetch_register (sd, rn, memory, length)
1193 SIM_DESC sd;
1194 int rn;
1195 unsigned char *memory;
1196 int length;
1197 {
1198 int little_endian;
1199 init_pointers ();
1200 little_endian = target_little_endian;
1201 WLAT (0, saved_state.asints[rn+1]);
1202 return -1;
1203 }
1204
1205 int
1206 sim_trace (sd)
1207 SIM_DESC sd;
1208 {
1209 return 0;
1210 }
1211
1212 void
1213 sim_stop_reason (sd, reason, sigrc)
1214 SIM_DESC sd;
1215 enum sim_stop *reason;
1216 int *sigrc;
1217 {
1218 /* The SH simulator uses SIGQUIT to indicate that the program has
1219 exited, so we must check for it here and translate it to exit. */
1220 if (saved_state.asregs.exception == SIGQUIT)
1221 {
1222 *reason = sim_exited;
1223 *sigrc = saved_state.asregs.regs[5];
1224 }
1225 else
1226 {
1227 *reason = sim_stopped;
1228 *sigrc = saved_state.asregs.exception;
1229 }
1230 }
1231
1232 void
1233 sim_info (sd, verbose)
1234 SIM_DESC sd;
1235 int verbose;
1236 {
1237 double timetaken = (double) saved_state.asregs.ticks / (double) now_persec ();
1238 double virttime = saved_state.asregs.cycles / 36.0e6;
1239
1240 callback->printf_filtered (callback, "\n\n# instructions executed %10d\n",
1241 saved_state.asregs.insts);
1242 callback->printf_filtered (callback, "# cycles %10d\n",
1243 saved_state.asregs.cycles);
1244 callback->printf_filtered (callback, "# pipeline stalls %10d\n",
1245 saved_state.asregs.stalls);
1246 callback->printf_filtered (callback, "# misaligned load/store %10d\n",
1247 saved_state.asregs.memstalls);
1248 callback->printf_filtered (callback, "# real time taken %10.4f\n",
1249 timetaken);
1250 callback->printf_filtered (callback, "# virtual time taken %10.4f\n",
1251 virttime);
1252 callback->printf_filtered (callback, "# profiling size %10d\n",
1253 sim_profile_size);
1254 callback->printf_filtered (callback, "# profiling frequency %10d\n",
1255 saved_state.asregs.profile);
1256 callback->printf_filtered (callback, "# profile maxpc %10x\n",
1257 (1 << sim_profile_size) << PROFILE_SHIFT);
1258
1259 if (timetaken != 0)
1260 {
1261 callback->printf_filtered (callback, "# cycles/second %10d\n",
1262 (int) (saved_state.asregs.cycles / timetaken));
1263 callback->printf_filtered (callback, "# simulation ratio %10.4f\n",
1264 virttime / timetaken);
1265 }
1266 }
1267
1268 void
1269 sim_set_profile (n)
1270 int n;
1271 {
1272 saved_state.asregs.profile = n;
1273 }
1274
1275 void
1276 sim_set_profile_size (n)
1277 int n;
1278 {
1279 sim_profile_size = n;
1280 }
1281
1282 SIM_DESC
1283 sim_open (kind, cb, abfd, argv)
1284 SIM_OPEN_KIND kind;
1285 host_callback *cb;
1286 struct _bfd *abfd;
1287 char **argv;
1288 {
1289 char **p;
1290 int endian_set = 0;
1291
1292 sim_kind = kind;
1293 myname = argv[0];
1294 callback = cb;
1295
1296 for (p = argv + 1; *p != NULL; ++p)
1297 {
1298 if (strcmp (*p, "-E") == 0)
1299 {
1300 ++p;
1301 if (*p == NULL)
1302 {
1303 /* FIXME: This doesn't use stderr, but then the rest of the
1304 file doesn't either. */
1305 callback->printf_filtered (callback, "Missing argument to `-E'.\n");
1306 return 0;
1307 }
1308 target_little_endian = strcmp (*p, "big") != 0;
1309 endian_set = 1;
1310 }
1311 else if (isdigit (**p))
1312 parse_and_set_memory_size (*p);
1313 }
1314
1315 if (abfd != NULL && ! endian_set)
1316 target_little_endian = ! bfd_big_endian (abfd);
1317
1318 /* fudge our descriptor for now */
1319 return (SIM_DESC) 1;
1320 }
1321
1322 static void
1323 parse_and_set_memory_size (str)
1324 char *str;
1325 {
1326 int n;
1327
1328 n = strtol (str, NULL, 10);
1329 if (n > 0 && n <= 24)
1330 sim_memory_size = n;
1331 else
1332 callback->printf_filtered (callback, "Bad memory size %d; must be 1 to 24, inclusive\n", n);
1333 }
1334
1335 void
1336 sim_close (sd, quitting)
1337 SIM_DESC sd;
1338 int quitting;
1339 {
1340 /* nothing to do */
1341 }
1342
1343 SIM_RC
1344 sim_load (sd, prog, abfd, from_tty)
1345 SIM_DESC sd;
1346 char *prog;
1347 bfd *abfd;
1348 int from_tty;
1349 {
1350 extern bfd *sim_load_file (); /* ??? Don't know where this should live. */
1351 bfd *prog_bfd;
1352
1353 prog_bfd = sim_load_file (sd, myname, callback, prog, abfd,
1354 sim_kind == SIM_OPEN_DEBUG,
1355 0, sim_write);
1356 if (prog_bfd == NULL)
1357 return SIM_RC_FAIL;
1358 if (abfd == NULL)
1359 bfd_close (prog_bfd);
1360 return SIM_RC_OK;
1361 }
1362
1363 SIM_RC
1364 sim_create_inferior (sd, prog_bfd, argv, env)
1365 SIM_DESC sd;
1366 struct _bfd *prog_bfd;
1367 char **argv;
1368 char **env;
1369 {
1370 /* clear the registers */
1371 memset (&saved_state, 0,
1372 (char*)&saved_state.asregs.end_of_registers - (char*)&saved_state);
1373 /* set the PC */
1374 if (prog_bfd != NULL)
1375 saved_state.asregs.pc = bfd_get_start_address (prog_bfd);
1376 return SIM_RC_OK;
1377 }
1378
1379 void
1380 sim_do_command (sd, cmd)
1381 SIM_DESC sd;
1382 char *cmd;
1383 {
1384 char *sms_cmd = "set-memory-size";
1385 int cmdsize;
1386
1387 if (cmd == NULL || *cmd == '\0')
1388 {
1389 cmd = "help";
1390 }
1391
1392 cmdsize = strlen (sms_cmd);
1393 if (strncmp (cmd, sms_cmd, cmdsize) == 0 && strchr (" \t", cmd[cmdsize]) != NULL)
1394 {
1395 parse_and_set_memory_size (cmd + cmdsize + 1);
1396 }
1397 else if (strcmp (cmd, "help") == 0)
1398 {
1399 (callback->printf_filtered) (callback, "List of SH simulator commands:\n\n");
1400 (callback->printf_filtered) (callback, "set-memory-size <n> -- Set the number of address bits to use\n");
1401 (callback->printf_filtered) (callback, "\n");
1402 }
1403 else
1404 {
1405 (callback->printf_filtered) (callback, "Error: \"%s\" is not a valid SH simulator command.\n", cmd);
1406 }
1407 }
1408
1409 void
1410 sim_set_callbacks (p)
1411 host_callback *p;
1412 {
1413 callback = p;
1414 }