sim: constify arg to sim_do_command
[deliverable/binutils-gdb.git] / sim / sh / interp.c
CommitLineData
86bc60eb 1/* Simulator for the Renesas (formerly Hitachi) / SuperH Inc. SH architecture.
c906108c
SS
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
22e041e2
MM
23#include <stdio.h>
24#include <errno.h>
c906108c
SS
25#include <signal.h>
26#ifdef HAVE_UNISTD_H
27#include <unistd.h>
28#endif
6a8492b5
JR
29#ifdef HAVE_MMAP
30#include <sys/mman.h>
31# ifndef MAP_FAILED
32# define MAP_FAILED -1
33# endif
34# if !defined (MAP_ANONYMOUS) && defined (MAP_ANON)
35# define MAP_ANONYMOUS MAP_ANON
36# endif
37#endif
c906108c 38
22e041e2
MM
39#ifdef HAVE_STRING_H
40#include <string.h>
41#else
42#ifdef HAVE_STRINGS_H
43#include <strings.h>
44#endif
45#endif
46
47#ifdef HAVE_STDLIB_H
48#include <stdlib.h>
49#endif
50
51#ifdef HAVE_SYS_STAT_H
52#include <sys/stat.h>
53#endif
54
c906108c 55#include "bfd.h"
3c25f8c7
AC
56#include "gdb/callback.h"
57#include "gdb/remote-sim.h"
2f14585c 58#include "gdb/sim-sh.h"
c906108c
SS
59
60/* This file is local - if newlib changes, then so should this. */
61#include "syscall.h"
62
63#include <math.h>
64
65#ifdef _WIN32
66#include <float.h> /* Needed for _isnan() */
67#define isnan _isnan
68#endif
69
70#ifndef SIGBUS
71#define SIGBUS SIGSEGV
72#endif
73
74#ifndef SIGQUIT
75#define SIGQUIT SIGTERM
76#endif
77
78#ifndef SIGTRAP
79#define SIGTRAP 5
80#endif
81
3e511797 82extern unsigned short sh_jump_table[], sh_dsp_table[0x1000], ppi_table[];
63978407 83
5558e7e6 84int sim_write (SIM_DESC sd, SIM_ADDR addr, const unsigned char *buffer, int size);
de0492b6 85
c906108c
SS
86#define O_RECOMPILE 85
87#define DEFINE_TABLE
88#define DISASSEMBLER_TABLE
89
7a292a7a
SS
90/* Define the rate at which the simulator should poll the host
91 for a quit. */
92#define POLL_QUIT_INTERVAL 0x60000
93
ae0a84af
CV
94typedef struct
95{
96 int regs[20];
97} regstacktype;
98
c906108c
SS
99typedef union
100{
101
102 struct
103 {
c906108c
SS
104 int regs[16];
105 int pc;
c906108c 106
63978407
JR
107 /* System registers. For sh-dsp this also includes A0 / X0 / X1 / Y0 / Y1
108 which are located in fregs, i.e. strictly speaking, these are
109 out-of-bounds accesses of sregs.i . This wart of the code could be
110 fixed by making fregs part of sregs, and including pc too - to avoid
111 alignment repercussions - but this would cause very onerous union /
112 structure nesting, which would only be managable with anonymous
113 unions and structs. */
114 union
115 {
116 struct
117 {
118 int mach;
119 int macl;
120 int pr;
121 int dummy3, dummy4;
122 int fpul; /* A1 for sh-dsp - but only for movs etc. */
123 int fpscr; /* dsr for sh-dsp */
124 } named;
125 int i[7];
126 } sregs;
127
128 /* sh3e / sh-dsp */
c906108c
SS
129 union fregs_u
130 {
131 float f[16];
132 double d[8];
133 int i[16];
134 }
7a292a7a 135 fregs[2];
c906108c 136
63978407
JR
137 /* Control registers; on the SH4, ldc / stc is privileged, except when
138 accessing gbr. */
139 union
140 {
141 struct
142 {
143 int sr;
144 int gbr;
145 int vbr;
146 int ssr;
147 int spc;
148 int mod;
149 /* sh-dsp */
150 int rs;
151 int re;
152 /* sh3 */
153 int bank[8];
86bc60eb
MS
154 int dbr; /* debug base register */
155 int sgr; /* saved gr15 */
156 int ldst; /* load/store flag (boolean) */
ae0a84af
CV
157 int tbr;
158 int ibcr; /* sh2a bank control register */
159 int ibnr; /* sh2a bank number register */
63978407
JR
160 } named;
161 int i[16];
162 } cregs;
163
164 unsigned char *insn_end;
c906108c
SS
165
166 int ticks;
167 int stalls;
168 int memstalls;
169 int cycles;
170 int insts;
171
172 int prevlock;
173 int thislock;
174 int exception;
175
176 int end_of_registers;
177
178 int msize;
179#define PROFILE_FREQ 1
180#define PROFILE_SHIFT 2
181 int profile;
182 unsigned short *profile_hist;
183 unsigned char *memory;
63978407
JR
184 int xyram_select, xram_start, yram_start;
185 unsigned char *xmem;
186 unsigned char *ymem;
187 unsigned char *xmem_offset;
188 unsigned char *ymem_offset;
ae0a84af
CV
189 unsigned long bfd_mach;
190 regstacktype *regstack;
c906108c
SS
191 }
192 asregs;
193 int asints[40];
194} saved_state_type;
195
196saved_state_type saved_state;
197
63978407 198struct loop_bounds { unsigned char *start, *end; };
c906108c
SS
199
200/* These variables are at file scope so that functions other than
201 sim_resume can use the fetch/store macros */
202
203static int target_little_endian;
63978407
JR
204static int global_endianw, endianb;
205static int target_dsp;
c906108c 206static int host_little_endian;
de0492b6 207static char **prog_argv;
c906108c 208
63978407 209static int maskw = 0;
d1789ace 210static int maskl = 0;
c906108c
SS
211
212static SIM_OPEN_KIND sim_kind;
213static char *myname;
ae0a84af 214static int tracing = 0;
c906108c
SS
215
216
217/* Short hand definitions of the registers */
218
219#define SBIT(x) ((x)&sbit)
220#define R0 saved_state.asregs.regs[0]
221#define Rn saved_state.asregs.regs[n]
222#define Rm saved_state.asregs.regs[m]
87acb4a7
MS
223#define UR0 (unsigned int) (saved_state.asregs.regs[0])
224#define UR (unsigned int) R
225#define UR (unsigned int) R
c906108c 226#define SR0 saved_state.asregs.regs[0]
63978407
JR
227#define CREG(n) (saved_state.asregs.cregs.i[(n)])
228#define GBR saved_state.asregs.cregs.named.gbr
229#define VBR saved_state.asregs.cregs.named.vbr
86bc60eb 230#define DBR saved_state.asregs.cregs.named.dbr
ae0a84af
CV
231#define TBR saved_state.asregs.cregs.named.tbr
232#define IBCR saved_state.asregs.cregs.named.ibcr
233#define IBNR saved_state.asregs.cregs.named.ibnr
234#define BANKN (saved_state.asregs.cregs.named.ibnr & 0x1ff)
235#define ME ((saved_state.asregs.cregs.named.ibnr >> 14) & 0x3)
63978407
JR
236#define SSR saved_state.asregs.cregs.named.ssr
237#define SPC saved_state.asregs.cregs.named.spc
86bc60eb 238#define SGR saved_state.asregs.cregs.named.sgr
63978407
JR
239#define SREG(n) (saved_state.asregs.sregs.i[(n)])
240#define MACH saved_state.asregs.sregs.named.mach
241#define MACL saved_state.asregs.sregs.named.macl
242#define PR saved_state.asregs.sregs.named.pr
243#define FPUL saved_state.asregs.sregs.named.fpul
c906108c 244
63978407 245#define PC insn_ptr
c906108c
SS
246
247
248
63978407 249/* Alternate bank of registers r0-r7 */
c906108c
SS
250
251/* Note: code controling SR handles flips between BANK0 and BANK1 */
63978407
JR
252#define Rn_BANK(n) (saved_state.asregs.cregs.named.bank[(n)])
253#define SET_Rn_BANK(n, EXP) do { saved_state.asregs.cregs.named.bank[(n)] = (EXP); } while (0)
c906108c
SS
254
255
256/* Manipulate SR */
257
ae0a84af
CV
258#define SR_MASK_BO (1 << 14)
259#define SR_MASK_CS (1 << 13)
63978407
JR
260#define SR_MASK_DMY (1 << 11)
261#define SR_MASK_DMX (1 << 10)
c906108c
SS
262#define SR_MASK_M (1 << 9)
263#define SR_MASK_Q (1 << 8)
264#define SR_MASK_I (0xf << 4)
265#define SR_MASK_S (1 << 1)
266#define SR_MASK_T (1 << 0)
267
268#define SR_MASK_BL (1 << 28)
269#define SR_MASK_RB (1 << 29)
270#define SR_MASK_MD (1 << 30)
63978407
JR
271#define SR_MASK_RC 0x0fff0000
272#define SR_RC_INCREMENT -0x00010000
c906108c 273
ae0a84af
CV
274#define BO ((saved_state.asregs.cregs.named.sr & SR_MASK_BO) != 0)
275#define CS ((saved_state.asregs.cregs.named.sr & SR_MASK_CS) != 0)
63978407
JR
276#define M ((saved_state.asregs.cregs.named.sr & SR_MASK_M) != 0)
277#define Q ((saved_state.asregs.cregs.named.sr & SR_MASK_Q) != 0)
278#define S ((saved_state.asregs.cregs.named.sr & SR_MASK_S) != 0)
279#define T ((saved_state.asregs.cregs.named.sr & SR_MASK_T) != 0)
86bc60eb 280#define LDST ((saved_state.asregs.cregs.named.ldst) != 0)
c906108c 281
63978407
JR
282#define SR_BL ((saved_state.asregs.cregs.named.sr & SR_MASK_BL) != 0)
283#define SR_RB ((saved_state.asregs.cregs.named.sr & SR_MASK_RB) != 0)
284#define SR_MD ((saved_state.asregs.cregs.named.sr & SR_MASK_MD) != 0)
285#define SR_DMY ((saved_state.asregs.cregs.named.sr & SR_MASK_DMY) != 0)
286#define SR_DMX ((saved_state.asregs.cregs.named.sr & SR_MASK_DMX) != 0)
287#define SR_RC ((saved_state.asregs.cregs.named.sr & SR_MASK_RC))
c906108c
SS
288
289/* Note: don't use this for privileged bits */
290#define SET_SR_BIT(EXP, BIT) \
291do { \
292 if ((EXP) & 1) \
63978407 293 saved_state.asregs.cregs.named.sr |= (BIT); \
c906108c 294 else \
63978407 295 saved_state.asregs.cregs.named.sr &= ~(BIT); \
c906108c
SS
296} while (0)
297
ae0a84af
CV
298#define SET_SR_BO(EXP) SET_SR_BIT ((EXP), SR_MASK_BO)
299#define SET_SR_CS(EXP) SET_SR_BIT ((EXP), SR_MASK_CS)
300#define SET_BANKN(EXP) \
301do { \
302 IBNR = (IBNR & 0xfe00) | (EXP & 0x1f); \
303} while (0)
304#define SET_ME(EXP) \
305do { \
306 IBNR = (IBNR & 0x3fff) | ((EXP & 0x3) << 14); \
307} while (0)
c906108c
SS
308#define SET_SR_M(EXP) SET_SR_BIT ((EXP), SR_MASK_M)
309#define SET_SR_Q(EXP) SET_SR_BIT ((EXP), SR_MASK_Q)
310#define SET_SR_S(EXP) SET_SR_BIT ((EXP), SR_MASK_S)
311#define SET_SR_T(EXP) SET_SR_BIT ((EXP), SR_MASK_T)
86bc60eb 312#define SET_LDST(EXP) (saved_state.asregs.cregs.named.ldst = ((EXP) != 0))
c906108c 313
63978407
JR
314/* stc currently relies on being able to read SR without modifications. */
315#define GET_SR() (saved_state.asregs.cregs.named.sr - 0)
316
c906108c 317#define SET_SR(x) set_sr (x)
c906108c 318
63978407
JR
319#define SET_RC(x) \
320 (saved_state.asregs.cregs.named.sr \
321 = saved_state.asregs.cregs.named.sr & 0xf000ffff | ((x) & 0xfff) << 16)
c906108c
SS
322
323/* Manipulate FPSCR */
324
7a292a7a
SS
325#define FPSCR_MASK_FR (1 << 21)
326#define FPSCR_MASK_SZ (1 << 20)
327#define FPSCR_MASK_PR (1 << 19)
328
87acb4a7
MS
329#define FPSCR_FR ((GET_FPSCR () & FPSCR_MASK_FR) != 0)
330#define FPSCR_SZ ((GET_FPSCR () & FPSCR_MASK_SZ) != 0)
331#define FPSCR_PR ((GET_FPSCR () & FPSCR_MASK_PR) != 0)
7a292a7a 332
de0492b6
AO
333/* Count the number of arguments in an argv. */
334static int
335count_argc (char **argv)
336{
337 int i;
338
339 if (! argv)
340 return -1;
341
342 for (i = 0; argv[i] != NULL; ++i)
343 continue;
344 return i;
345}
346
7a292a7a
SS
347static void
348set_fpscr1 (x)
349 int x;
350{
63978407
JR
351 int old = saved_state.asregs.sregs.named.fpscr;
352 saved_state.asregs.sregs.named.fpscr = (x);
7a292a7a 353 /* swap the floating point register banks */
63978407
JR
354 if ((saved_state.asregs.sregs.named.fpscr ^ old) & FPSCR_MASK_FR
355 /* Ignore bit change if simulating sh-dsp. */
356 && ! target_dsp)
7a292a7a
SS
357 {
358 union fregs_u tmpf = saved_state.asregs.fregs[0];
359 saved_state.asregs.fregs[0] = saved_state.asregs.fregs[1];
360 saved_state.asregs.fregs[1] = tmpf;
361 }
362}
363
63978407
JR
364/* sts relies on being able to read fpscr directly. */
365#define GET_FPSCR() (saved_state.asregs.sregs.named.fpscr)
7a292a7a
SS
366#define SET_FPSCR(x) \
367do { \
368 set_fpscr1 (x); \
369} while (0)
c906108c 370
63978407 371#define DSR (saved_state.asregs.sregs.named.fpscr)
c906108c
SS
372
373int
374fail ()
375{
376 abort ();
377}
378
63978407
JR
379#define RAISE_EXCEPTION(x) \
380 (saved_state.asregs.exception = x, saved_state.asregs.insn_end = 0)
7a292a7a 381
ae0a84af
CV
382#define RAISE_EXCEPTION_IF_IN_DELAY_SLOT() \
383 if (in_delay_slot) RAISE_EXCEPTION (SIGILL)
384
63978407 385/* This function exists mainly for the purpose of setting a breakpoint to
c906108c
SS
386 catch simulated bus errors when running the simulator under GDB. */
387
388void
63978407
JR
389raise_exception (x)
390 int x;
391{
87acb4a7 392 RAISE_EXCEPTION (x);
63978407
JR
393}
394
395void
396raise_buserror ()
c906108c 397{
63978407 398 raise_exception (SIGBUS);
c906108c
SS
399}
400
63978407
JR
401#define PROCESS_SPECIAL_ADDRESS(addr, endian, ptr, bits_written, \
402 forbidden_addr_bits, data, retval) \
403do { \
404 if (addr & forbidden_addr_bits) \
405 { \
406 raise_buserror (); \
407 return retval; \
408 } \
409 else if ((addr & saved_state.asregs.xyram_select) \
410 == saved_state.asregs.xram_start) \
411 ptr = (void *) &saved_state.asregs.xmem_offset[addr ^ endian]; \
412 else if ((addr & saved_state.asregs.xyram_select) \
413 == saved_state.asregs.yram_start) \
414 ptr = (void *) &saved_state.asregs.ymem_offset[addr ^ endian]; \
415 else if ((unsigned) addr >> 24 == 0xf0 \
416 && bits_written == 32 && (data & 1) == 0) \
417 /* This invalidates (if not associative) or might invalidate \
418 (if associative) an instruction cache line. This is used for \
419 trampolines. Since we don't simulate the cache, this is a no-op \
420 as far as the simulator is concerned. */ \
421 return retval; \
422 else \
423 { \
424 if (bits_written == 8 && addr > 0x5000000) \
425 IOMEM (addr, 1, data); \
426 /* We can't do anything useful with the other stuff, so fail. */ \
427 raise_buserror (); \
428 return retval; \
429 } \
430} while (0)
431
c906108c
SS
432/* FIXME: sim_resume should be renamed to sim_engine_run. sim_resume
433 being implemented by ../common/sim_resume.c and the below should
434 make a call to sim_engine_halt */
435
63978407
JR
436#define BUSERROR(addr, mask) ((addr) & (mask))
437
438#define WRITE_BUSERROR(addr, mask, data, addr_func) \
439 do \
7a292a7a 440 { \
63978407
JR
441 if (addr & mask) \
442 { \
443 addr_func (addr, data); \
444 return; \
445 } \
446 } \
447 while (0)
448
449#define READ_BUSERROR(addr, mask, addr_func) \
450 do \
451 { \
452 if (addr & mask) \
453 return addr_func (addr); \
454 } \
455 while (0)
c906108c
SS
456
457/* Define this to enable register lifetime checking.
458 The compiler generates "add #0,rn" insns to mark registers as invalid,
459 the simulator uses this info to call fail if it finds a ref to an invalid
460 register before a def
461
462 #define PARANOID
463*/
464
465#ifdef PARANOID
466int valid[16];
87acb4a7 467#define CREF(x) if (!valid[x]) fail ();
c906108c
SS
468#define CDEF(x) valid[x] = 1;
469#define UNDEF(x) valid[x] = 0;
470#else
471#define CREF(x)
472#define CDEF(x)
473#define UNDEF(x)
474#endif
475
60d847df 476static void parse_and_set_memory_size (const char *str);
bdca5ee4
TT
477static int IOMEM (int addr, int write, int value);
478static struct loop_bounds get_loop_bounds (int, int, unsigned char *,
479 unsigned char *, int, int);
480static void process_wlat_addr (int, int);
481static void process_wwat_addr (int, int);
482static void process_wbat_addr (int, int);
483static int process_rlat_addr (int);
484static int process_rwat_addr (int);
485static int process_rbat_addr (int);
486static void INLINE wlat_fast (unsigned char *, int, int, int);
487static void INLINE wwat_fast (unsigned char *, int, int, int, int);
488static void INLINE wbat_fast (unsigned char *, int, int, int);
489static int INLINE rlat_fast (unsigned char *, int, int);
490static int INLINE rwat_fast (unsigned char *, int, int, int);
491static int INLINE rbat_fast (unsigned char *, int, int);
c906108c
SS
492
493static host_callback *callback;
494
495
496
497/* Floating point registers */
498
7a292a7a
SS
499#define DR(n) (get_dr (n))
500static double
501get_dr (n)
502 int n;
503{
504 n = (n & ~1);
505 if (host_little_endian)
506 {
507 union
508 {
509 int i[2];
510 double d;
511 } dr;
512 dr.i[1] = saved_state.asregs.fregs[0].i[n + 0];
513 dr.i[0] = saved_state.asregs.fregs[0].i[n + 1];
514 return dr.d;
515 }
516 else
517 return (saved_state.asregs.fregs[0].d[n >> 1]);
518}
519
520#define SET_DR(n, EXP) set_dr ((n), (EXP))
521static void
522set_dr (n, exp)
523 int n;
524 double exp;
525{
526 n = (n & ~1);
527 if (host_little_endian)
528 {
529 union
530 {
531 int i[2];
532 double d;
533 } dr;
534 dr.d = exp;
535 saved_state.asregs.fregs[0].i[n + 0] = dr.i[1];
536 saved_state.asregs.fregs[0].i[n + 1] = dr.i[0];
537 }
538 else
539 saved_state.asregs.fregs[0].d[n >> 1] = exp;
540}
541
542#define SET_FI(n,EXP) (saved_state.asregs.fregs[0].i[(n)] = (EXP))
543#define FI(n) (saved_state.asregs.fregs[0].i[(n)])
c906108c 544
7a292a7a
SS
545#define FR(n) (saved_state.asregs.fregs[0].f[(n)])
546#define SET_FR(n,EXP) (saved_state.asregs.fregs[0].f[(n)] = (EXP))
c906108c 547
7a292a7a
SS
548#define XD_TO_XF(n) ((((n) & 1) << 5) | ((n) & 0x1e))
549#define XF(n) (saved_state.asregs.fregs[(n) >> 5].i[(n) & 0x1f])
550#define SET_XF(n,EXP) (saved_state.asregs.fregs[(n) >> 5].i[(n) & 0x1f] = (EXP))
551
63978407
JR
552#define RS saved_state.asregs.cregs.named.rs
553#define RE saved_state.asregs.cregs.named.re
554#define MOD (saved_state.asregs.cregs.named.mod)
555#define SET_MOD(i) \
556(MOD = (i), \
557 MOD_ME = (unsigned) MOD >> 16 | (SR_DMY ? ~0xffff : (SR_DMX ? 0 : 0x10000)), \
558 MOD_DELTA = (MOD & 0xffff) - ((unsigned) MOD >> 16))
559
560#define DSP_R(n) saved_state.asregs.sregs.i[(n)]
561#define DSP_GRD(n) DSP_R ((n) + 8)
562#define GET_DSP_GRD(n) ((n | 2) == 7 ? SEXT (DSP_GRD (n)) : SIGN32 (DSP_R (n)))
563#define A1 DSP_R (5)
564#define A0 DSP_R (7)
565#define X0 DSP_R (8)
566#define X1 DSP_R (9)
567#define Y0 DSP_R (10)
568#define Y1 DSP_R (11)
569#define M0 DSP_R (12)
570#define A1G DSP_R (13)
571#define M1 DSP_R (14)
572#define A0G DSP_R (15)
573/* DSP_R (16) / DSP_GRD (16) are used as a fake destination for pcmp. */
574#define MOD_ME DSP_GRD (17)
575#define MOD_DELTA DSP_GRD (18)
7a292a7a
SS
576
577#define FP_OP(n, OP, m) \
578{ \
579 if (FPSCR_PR) \
580 { \
581 if (((n) & 1) || ((m) & 1)) \
63978407 582 RAISE_EXCEPTION (SIGILL); \
7a292a7a 583 else \
87acb4a7 584 SET_DR (n, (DR (n) OP DR (m))); \
7a292a7a
SS
585 } \
586 else \
87acb4a7 587 SET_FR (n, (FR (n) OP FR (m))); \
7a292a7a
SS
588} while (0)
589
590#define FP_UNARY(n, OP) \
591{ \
592 if (FPSCR_PR) \
593 { \
594 if ((n) & 1) \
63978407 595 RAISE_EXCEPTION (SIGILL); \
7a292a7a 596 else \
87acb4a7 597 SET_DR (n, (OP (DR (n)))); \
7a292a7a
SS
598 } \
599 else \
87acb4a7 600 SET_FR (n, (OP (FR (n)))); \
7a292a7a
SS
601} while (0)
602
603#define FP_CMP(n, OP, m) \
604{ \
605 if (FPSCR_PR) \
606 { \
607 if (((n) & 1) || ((m) & 1)) \
63978407 608 RAISE_EXCEPTION (SIGILL); \
7a292a7a 609 else \
87acb4a7 610 SET_SR_T (DR (n) OP DR (m)); \
7a292a7a
SS
611 } \
612 else \
87acb4a7 613 SET_SR_T (FR (n) OP FR (m)); \
7a292a7a 614} while (0)
c906108c 615
63978407
JR
616static void
617set_sr (new_sr)
618 int new_sr;
c906108c 619{
63978407
JR
620 /* do we need to swap banks */
621 int old_gpr = SR_MD && SR_RB;
622 int new_gpr = (new_sr & SR_MASK_MD) && (new_sr & SR_MASK_RB);
623 if (old_gpr != new_gpr)
624 {
625 int i, tmp;
626 for (i = 0; i < 8; i++)
627 {
628 tmp = saved_state.asregs.cregs.named.bank[i];
629 saved_state.asregs.cregs.named.bank[i] = saved_state.asregs.regs[i];
630 saved_state.asregs.regs[i] = tmp;
631 }
632 }
633 saved_state.asregs.cregs.named.sr = new_sr;
634 SET_MOD (MOD);
c906108c
SS
635}
636
637static void INLINE
63978407 638wlat_fast (memory, x, value, maskl)
c906108c
SS
639 unsigned char *memory;
640{
641 int v = value;
87acb4a7 642 unsigned int *p = (unsigned int *) (memory + x);
63978407
JR
643 WRITE_BUSERROR (x, maskl, v, process_wlat_addr);
644 *p = v;
c906108c
SS
645}
646
647static void INLINE
63978407 648wwat_fast (memory, x, value, maskw, endianw)
c906108c
SS
649 unsigned char *memory;
650{
651 int v = value;
87acb4a7 652 unsigned short *p = (unsigned short *) (memory + (x ^ endianw));
63978407
JR
653 WRITE_BUSERROR (x, maskw, v, process_wwat_addr);
654 *p = v;
c906108c
SS
655}
656
657static void INLINE
63978407 658wbat_fast (memory, x, value, maskb)
c906108c
SS
659 unsigned char *memory;
660{
63978407
JR
661 unsigned char *p = memory + (x ^ endianb);
662 WRITE_BUSERROR (x, maskb, value, process_wbat_addr);
c906108c 663
c906108c
SS
664 p[0] = value;
665}
666
667/* Read functions */
668
669static int INLINE
63978407 670rlat_fast (memory, x, maskl)
c906108c
SS
671 unsigned char *memory;
672{
87acb4a7 673 unsigned int *p = (unsigned int *) (memory + x);
63978407 674 READ_BUSERROR (x, maskl, process_rlat_addr);
c906108c 675
63978407 676 return *p;
c906108c
SS
677}
678
679static int INLINE
63978407 680rwat_fast (memory, x, maskw, endianw)
c906108c 681 unsigned char *memory;
63978407 682 int x, maskw, endianw;
c906108c 683{
87acb4a7 684 unsigned short *p = (unsigned short *) (memory + (x ^ endianw));
63978407 685 READ_BUSERROR (x, maskw, process_rwat_addr);
c906108c 686
63978407 687 return *p;
c906108c
SS
688}
689
690static int INLINE
63978407
JR
691riat_fast (insn_ptr, endianw)
692 unsigned char *insn_ptr;
c906108c 693{
87acb4a7 694 unsigned short *p = (unsigned short *) ((size_t) insn_ptr ^ endianw);
c906108c 695
63978407 696 return *p;
c906108c
SS
697}
698
699static int INLINE
63978407 700rbat_fast (memory, x, maskb)
c906108c
SS
701 unsigned char *memory;
702{
63978407
JR
703 unsigned char *p = memory + (x ^ endianb);
704 READ_BUSERROR (x, maskb, process_rbat_addr);
c906108c 705
63978407 706 return *p;
c906108c
SS
707}
708
63978407
JR
709#define RWAT(x) (rwat_fast (memory, x, maskw, endianw))
710#define RLAT(x) (rlat_fast (memory, x, maskl))
711#define RBAT(x) (rbat_fast (memory, x, maskb))
712#define RIAT(p) (riat_fast ((p), endianw))
713#define WWAT(x,v) (wwat_fast (memory, x, v, maskw, endianw))
714#define WLAT(x,v) (wlat_fast (memory, x, v, maskl))
715#define WBAT(x,v) (wbat_fast (memory, x, v, maskb))
c906108c 716
87acb4a7
MS
717#define RUWAT(x) (RWAT (x) & 0xffff)
718#define RSWAT(x) ((short) (RWAT (x)))
719#define RSLAT(x) ((long) (RLAT (x)))
720#define RSBAT(x) (SEXT (RBAT (x)))
c906108c 721
63978407 722#define RDAT(x, n) (do_rdat (memory, (x), (n), (maskl)))
7a292a7a 723static int
63978407 724do_rdat (memory, x, n, maskl)
7a292a7a
SS
725 char *memory;
726 int x;
727 int n;
63978407 728 int maskl;
7a292a7a
SS
729{
730 int f0;
731 int f1;
732 int i = (n & 1);
733 int j = (n & ~1);
63978407
JR
734 f0 = rlat_fast (memory, x + 0, maskl);
735 f1 = rlat_fast (memory, x + 4, maskl);
7a292a7a
SS
736 saved_state.asregs.fregs[i].i[(j + 0)] = f0;
737 saved_state.asregs.fregs[i].i[(j + 1)] = f1;
738 return 0;
739}
c906108c 740
63978407 741#define WDAT(x, n) (do_wdat (memory, (x), (n), (maskl)))
7a292a7a 742static int
63978407 743do_wdat (memory, x, n, maskl)
7a292a7a
SS
744 char *memory;
745 int x;
746 int n;
63978407 747 int maskl;
7a292a7a
SS
748{
749 int f0;
750 int f1;
751 int i = (n & 1);
752 int j = (n & ~1);
753 f0 = saved_state.asregs.fregs[i].i[(j + 0)];
754 f1 = saved_state.asregs.fregs[i].i[(j + 1)];
63978407
JR
755 wlat_fast (memory, (x + 0), f0, maskl);
756 wlat_fast (memory, (x + 4), f1, maskl);
7a292a7a
SS
757 return 0;
758}
c906108c 759
63978407
JR
760static void
761process_wlat_addr (addr, value)
762 int addr;
763 int value;
764{
765 unsigned int *ptr;
766
767 PROCESS_SPECIAL_ADDRESS (addr, endianb, ptr, 32, 3, value, );
768 *ptr = value;
769}
770
771static void
772process_wwat_addr (addr, value)
773 int addr;
774 int value;
775{
776 unsigned short *ptr;
777
778 PROCESS_SPECIAL_ADDRESS (addr, endianb, ptr, 16, 1, value, );
779 *ptr = value;
780}
781
782static void
783process_wbat_addr (addr, value)
784 int addr;
785 int value;
786{
787 unsigned char *ptr;
788
789 PROCESS_SPECIAL_ADDRESS (addr, endianb, ptr, 8, 0, value, );
790 *ptr = value;
791}
c906108c 792
63978407
JR
793static int
794process_rlat_addr (addr)
795 int addr;
796{
797 unsigned char *ptr;
798
799 PROCESS_SPECIAL_ADDRESS (addr, endianb, ptr, -32, 3, -1, 0);
800 return *ptr;
801}
802
803static int
804process_rwat_addr (addr)
805 int addr;
806{
807 unsigned char *ptr;
808
809 PROCESS_SPECIAL_ADDRESS (addr, endianb, ptr, -16, 1, -1, 0);
810 return *ptr;
811}
812
813static int
814process_rbat_addr (addr)
815 int addr;
816{
817 unsigned char *ptr;
818
819 PROCESS_SPECIAL_ADDRESS (addr, endianb, ptr, -8, 0, -1, 0);
820 return *ptr;
821}
c906108c
SS
822
823#define SEXT(x) (((x & 0xff) ^ (~0x7f))+0x80)
824#define SEXT12(x) (((x & 0xfff) ^ 0x800) - 0x800)
87acb4a7 825#define SEXTW(y) ((int) ((short) y))
63978407 826#if 0
87acb4a7 827#define SEXT32(x) ((int) ((x & 0xffffffff) ^ 0x80000000U) - 0x7fffffff - 1)
63978407 828#else
87acb4a7 829#define SEXT32(x) ((int) (x))
63978407
JR
830#endif
831#define SIGN32(x) (SEXT32 (x) >> 31)
832
833/* convert pointer from target to host value. */
834#define PT2H(x) ((x) + memory)
835/* convert pointer from host to target value. */
836#define PH2T(x) ((x) - memory)
837
838#define SKIP_INSN(p) ((p) += ((RIAT (p) & 0xfc00) == 0xf800 ? 4 : 2))
c906108c 839
63978407 840#define SET_NIP(x) nip = (x); CHECK_INSN_PTR (nip);
c906108c 841
ae0a84af
CV
842static int in_delay_slot = 0;
843#define Delay_Slot(TEMPPC) iword = RIAT (TEMPPC); in_delay_slot = 1; goto top;
63978407
JR
844
845#define CHECK_INSN_PTR(p) \
846do { \
847 if (saved_state.asregs.exception || PH2T (p) & maskw) \
848 saved_state.asregs.insn_end = 0; \
849 else if (p < loop.end) \
850 saved_state.asregs.insn_end = loop.end; \
851 else \
852 saved_state.asregs.insn_end = mem_end; \
853} while (0)
854
855#ifdef ACE_FAST
856
857#define MA(n)
858#define L(x)
859#define TL(x)
860#define TB(x)
861
862#else
863
864#define MA(n) \
f95586a4 865 do { memstalls += ((((long) PC & 3) != 0) ? (n) : ((n) - 1)); } while (0)
c906108c
SS
866
867#define L(x) thislock = x;
868#define TL(x) if ((x) == prevlock) stalls++;
87acb4a7 869#define TB(x,y) if ((x) == prevlock || (y) == prevlock) stalls++;
c906108c 870
63978407
JR
871#endif
872
72a37d8d 873#if defined(__GO32__)
c906108c
SS
874int sim_memory_size = 19;
875#else
876int sim_memory_size = 24;
877#endif
878
879static int sim_profile_size = 17;
880static int nsamples;
881
882#undef TB
883#define TB(x,y)
884
885#define SMR1 (0x05FFFEC8) /* Channel 1 serial mode register */
886#define BRR1 (0x05FFFEC9) /* Channel 1 bit rate register */
887#define SCR1 (0x05FFFECA) /* Channel 1 serial control register */
888#define TDR1 (0x05FFFECB) /* Channel 1 transmit data register */
889#define SSR1 (0x05FFFECC) /* Channel 1 serial status register */
890#define RDR1 (0x05FFFECD) /* Channel 1 receive data register */
891
892#define SCI_RDRF 0x40 /* Recieve data register full */
893#define SCI_TDRE 0x80 /* Transmit data register empty */
894
895static int
896IOMEM (addr, write, value)
897 int addr;
898 int write;
899 int value;
900{
901 if (write)
902 {
903 switch (addr)
904 {
905 case TDR1:
906 if (value != '\r')
907 {
908 putchar (value);
909 fflush (stdout);
910 }
911 break;
912 }
913 }
914 else
915 {
916 switch (addr)
917 {
918 case RDR1:
919 return getchar ();
920 }
921 }
922 return 0;
923}
924
925static int
926get_now ()
927{
928 return time ((long *) 0);
929}
930
931static int
932now_persec ()
933{
934 return 1;
935}
936
937static FILE *profile_file;
938
63978407
JR
939static unsigned INLINE
940swap (n)
941 unsigned n;
c906108c 942{
63978407
JR
943 if (endianb)
944 n = (n << 24 | (n & 0xff00) << 8
945 | (n & 0xff0000) >> 8 | (n & 0xff000000) >> 24);
946 return n;
c906108c
SS
947}
948
63978407
JR
949static unsigned short INLINE
950swap16 (n)
951 unsigned short n;
c906108c 952{
63978407
JR
953 if (endianb)
954 n = n << 8 | (n & 0xff00) >> 8;
955 return n;
c906108c
SS
956}
957
958static void
959swapout (n)
960 int n;
961{
962 if (profile_file)
963 {
63978407
JR
964 union { char b[4]; int n; } u;
965 u.n = swap (n);
966 fwrite (u.b, 4, 1, profile_file);
c906108c
SS
967 }
968}
969
970static void
971swapout16 (n)
972 int n;
973{
63978407
JR
974 union { char b[4]; int n; } u;
975 u.n = swap16 (n);
976 fwrite (u.b, 2, 1, profile_file);
c906108c
SS
977}
978
979/* Turn a pointer in a register into a pointer into real memory. */
980
981static char *
982ptr (x)
983 int x;
984{
985 return (char *) (x + saved_state.asregs.memory);
986}
987
63bee803
JR
988/* STR points to a zero-terminated string in target byte order. Return
989 the number of bytes that need to be converted to host byte order in order
990 to use this string as a zero-terminated string on the host.
991 (Not counting the rounding up needed to operate on entire words.) */
63978407
JR
992static int
993strswaplen (str)
994 int str;
995{
996 unsigned char *memory = saved_state.asregs.memory;
997 int start, end;
998 int endian = endianb;
999
1000 if (! endian)
1001 return 0;
1002 end = str;
1003 for (end = str; memory[end ^ endian]; end++) ;
63bee803 1004 return end - str + 1;
63978407
JR
1005}
1006
1007static void
1008strnswap (str, len)
1009 int str;
1010 int len;
1011{
1012 int *start, *end;
1013
1014 if (! endianb || ! len)
1015 return;
1016 start = (int *) ptr (str & ~3);
1017 end = (int *) ptr (str + len);
1018 do
1019 {
1020 int old = *start;
1021 *start = (old << 24 | (old & 0xff00) << 8
1022 | (old & 0xff0000) >> 8 | (old & 0xff000000) >> 24);
1023 start++;
1024 }
1025 while (start < end);
1026}
1027
fd8f4948
JR
1028/* Simulate a monitor trap, put the result into r0 and errno into r1
1029 return offset by which to adjust pc. */
c906108c 1030
fd8f4948
JR
1031static int
1032trap (i, regs, insn_ptr, memory, maskl, maskw, endianw)
c906108c
SS
1033 int i;
1034 int *regs;
fd8f4948 1035 unsigned char *insn_ptr;
c906108c
SS
1036 unsigned char *memory;
1037{
1038 switch (i)
1039 {
1040 case 1:
1041 printf ("%c", regs[0]);
1042 break;
1043 case 2:
63978407 1044 raise_exception (SIGQUIT);
c906108c
SS
1045 break;
1046 case 3: /* FIXME: for backwards compat, should be removed */
fd8f4948
JR
1047 case 33:
1048 {
1049 unsigned int countp = * (unsigned int *) (insn_ptr + 4);
1050
1051 WLAT (countp, RLAT (countp) + 1);
1052 return 6;
1053 }
c906108c
SS
1054 case 34:
1055 {
1056 extern int errno;
1057 int perrno = errno;
1058 errno = 0;
1059
1060 switch (regs[4])
1061 {
1062
1063#if !defined(__GO32__) && !defined(_WIN32)
1064 case SYS_fork:
1065 regs[0] = fork ();
1066 break;
63978407
JR
1067/* This would work only if endianness matched between host and target.
1068 Besides, it's quite dangerous. */
1069#if 0
c906108c 1070 case SYS_execve:
87acb4a7
MS
1071 regs[0] = execve (ptr (regs[5]), (char **) ptr (regs[6]),
1072 (char **) ptr (regs[7]));
c906108c
SS
1073 break;
1074 case SYS_execv:
87acb4a7 1075 regs[0] = execve (ptr (regs[5]), (char **) ptr (regs[6]), 0);
c906108c 1076 break;
63978407 1077#endif
c906108c
SS
1078 case SYS_pipe:
1079 {
63978407
JR
1080 regs[0] = (BUSERROR (regs[5], maskl)
1081 ? -EINVAL
1082 : pipe ((int *) ptr (regs[5])));
c906108c
SS
1083 }
1084 break;
1085
1086 case SYS_wait:
1087 regs[0] = wait (ptr (regs[5]));
1088 break;
63978407 1089#endif /* !defined(__GO32__) && !defined(_WIN32) */
c906108c
SS
1090
1091 case SYS_read:
63978407
JR
1092 strnswap (regs[6], regs[7]);
1093 regs[0]
1094 = callback->read (callback, regs[5], ptr (regs[6]), regs[7]);
1095 strnswap (regs[6], regs[7]);
c906108c
SS
1096 break;
1097 case SYS_write:
63978407 1098 strnswap (regs[6], regs[7]);
c906108c 1099 if (regs[5] == 1)
87acb4a7
MS
1100 regs[0] = (int) callback->write_stdout (callback,
1101 ptr (regs[6]), regs[7]);
c906108c 1102 else
87acb4a7
MS
1103 regs[0] = (int) callback->write (callback, regs[5],
1104 ptr (regs[6]), regs[7]);
63978407 1105 strnswap (regs[6], regs[7]);
c906108c
SS
1106 break;
1107 case SYS_lseek:
1108 regs[0] = callback->lseek (callback,regs[5], regs[6], regs[7]);
1109 break;
1110 case SYS_close:
1111 regs[0] = callback->close (callback,regs[5]);
1112 break;
1113 case SYS_open:
63978407
JR
1114 {
1115 int len = strswaplen (regs[5]);
1116 strnswap (regs[5], len);
87acb4a7 1117 regs[0] = callback->open (callback, ptr (regs[5]), regs[6]);
63978407
JR
1118 strnswap (regs[5], len);
1119 break;
1120 }
c906108c
SS
1121 case SYS_exit:
1122 /* EXIT - caller can look in r5 to work out the reason */
63978407 1123 raise_exception (SIGQUIT);
c906108c
SS
1124 regs[0] = regs[5];
1125 break;
1126
1127 case SYS_stat: /* added at hmsi */
1128 /* stat system call */
1129 {
1130 struct stat host_stat;
63978407
JR
1131 int buf;
1132 int len = strswaplen (regs[5]);
c906108c 1133
63978407 1134 strnswap (regs[5], len);
c906108c 1135 regs[0] = stat (ptr (regs[5]), &host_stat);
63978407 1136 strnswap (regs[5], len);
c906108c 1137
63978407 1138 buf = regs[6];
c906108c
SS
1139
1140 WWAT (buf, host_stat.st_dev);
1141 buf += 2;
1142 WWAT (buf, host_stat.st_ino);
1143 buf += 2;
1144 WLAT (buf, host_stat.st_mode);
1145 buf += 4;
1146 WWAT (buf, host_stat.st_nlink);
1147 buf += 2;
1148 WWAT (buf, host_stat.st_uid);
1149 buf += 2;
1150 WWAT (buf, host_stat.st_gid);
1151 buf += 2;
1152 WWAT (buf, host_stat.st_rdev);
1153 buf += 2;
1154 WLAT (buf, host_stat.st_size);
1155 buf += 4;
1156 WLAT (buf, host_stat.st_atime);
1157 buf += 4;
1158 WLAT (buf, 0);
1159 buf += 4;
1160 WLAT (buf, host_stat.st_mtime);
1161 buf += 4;
1162 WLAT (buf, 0);
1163 buf += 4;
1164 WLAT (buf, host_stat.st_ctime);
1165 buf += 4;
1166 WLAT (buf, 0);
1167 buf += 4;
1168 WLAT (buf, 0);
1169 buf += 4;
1170 WLAT (buf, 0);
1171 buf += 4;
1172 }
1173 break;
1174
1175#ifndef _WIN32
1176 case SYS_chown:
63978407
JR
1177 {
1178 int len = strswaplen (regs[5]);
1179
1180 strnswap (regs[5], len);
1181 regs[0] = chown (ptr (regs[5]), regs[6], regs[7]);
1182 strnswap (regs[5], len);
1183 break;
1184 }
c906108c
SS
1185#endif /* _WIN32 */
1186 case SYS_chmod:
63978407
JR
1187 {
1188 int len = strswaplen (regs[5]);
1189
1190 strnswap (regs[5], len);
1191 regs[0] = chmod (ptr (regs[5]), regs[6]);
1192 strnswap (regs[5], len);
1193 break;
1194 }
c906108c 1195 case SYS_utime:
63978407
JR
1196 {
1197 /* Cast the second argument to void *, to avoid type mismatch
1198 if a prototype is present. */
1199 int len = strswaplen (regs[5]);
1200
1201 strnswap (regs[5], len);
1202 regs[0] = utime (ptr (regs[5]), (void *) ptr (regs[6]));
1203 strnswap (regs[5], len);
1204 break;
1205 }
de0492b6
AO
1206 case SYS_argc:
1207 regs[0] = count_argc (prog_argv);
1208 break;
1209 case SYS_argnlen:
1210 if (regs[5] < count_argc (prog_argv))
1211 regs[0] = strlen (prog_argv[regs[5]]);
1212 else
1213 regs[0] = -1;
1214 break;
1215 case SYS_argn:
1216 if (regs[5] < count_argc (prog_argv))
1217 {
1218 /* Include the termination byte. */
1219 int i = strlen (prog_argv[regs[5]]) + 1;
1220 regs[0] = sim_write (0, regs[6], prog_argv[regs[5]], i);
1221 }
1222 else
1223 regs[0] = -1;
1224 break;
55406459
AO
1225 case SYS_time:
1226 regs[0] = get_now ();
1227 break;
8822d001
JR
1228 case SYS_ftruncate:
1229 regs[0] = callback->ftruncate (callback, regs[5], regs[6]);
1230 break;
1231 case SYS_truncate:
1232 {
1233 int len = strswaplen (regs[5]);
1234 strnswap (regs[5], len);
1235 regs[0] = callback->truncate (callback, ptr (regs[5]), regs[6]);
1236 strnswap (regs[5], len);
1237 break;
1238 }
c906108c 1239 default:
de0492b6
AO
1240 regs[0] = -1;
1241 break;
c906108c
SS
1242 }
1243 regs[1] = callback->get_errno (callback);
1244 errno = perrno;
1245 }
1246 break;
1247
ae0a84af
CV
1248 case 13: /* Set IBNR */
1249 IBNR = regs[0] & 0xffff;
1250 break;
1251 case 14: /* Set IBCR */
1252 IBCR = regs[0] & 0xffff;
1253 break;
c906108c
SS
1254 case 0xc3:
1255 case 255:
63978407 1256 raise_exception (SIGTRAP);
fd8f4948
JR
1257 if (i == 0xc3)
1258 return -2;
c906108c
SS
1259 break;
1260 }
fd8f4948 1261 return 0;
c906108c
SS
1262}
1263
c906108c
SS
1264static int
1265div1 (R, iRn2, iRn1/*, T*/)
1266 int *R;
1267 int iRn1;
1268 int iRn2;
1269 /* int T;*/
1270{
1271 unsigned long tmp0;
1272 unsigned char old_q, tmp1;
1273
1274 old_q = Q;
1275 SET_SR_Q ((unsigned char) ((0x80000000 & R[iRn1]) != 0));
1276 R[iRn1] <<= 1;
1277 R[iRn1] |= (unsigned long) T;
1278
1279 switch (old_q)
1280 {
1281 case 0:
1282 switch (M)
1283 {
1284 case 0:
1285 tmp0 = R[iRn1];
1286 R[iRn1] -= R[iRn2];
1287 tmp1 = (R[iRn1] > tmp0);
1288 switch (Q)
1289 {
1290 case 0:
1291 SET_SR_Q (tmp1);
1292 break;
1293 case 1:
1294 SET_SR_Q ((unsigned char) (tmp1 == 0));
1295 break;
1296 }
1297 break;
1298 case 1:
1299 tmp0 = R[iRn1];
1300 R[iRn1] += R[iRn2];
1301 tmp1 = (R[iRn1] < tmp0);
1302 switch (Q)
1303 {
1304 case 0:
1305 SET_SR_Q ((unsigned char) (tmp1 == 0));
1306 break;
1307 case 1:
1308 SET_SR_Q (tmp1);
1309 break;
1310 }
1311 break;
1312 }
1313 break;
1314 case 1:
1315 switch (M)
1316 {
1317 case 0:
1318 tmp0 = R[iRn1];
1319 R[iRn1] += R[iRn2];
1320 tmp1 = (R[iRn1] < tmp0);
1321 switch (Q)
1322 {
1323 case 0:
1324 SET_SR_Q (tmp1);
1325 break;
1326 case 1:
1327 SET_SR_Q ((unsigned char) (tmp1 == 0));
1328 break;
1329 }
1330 break;
1331 case 1:
1332 tmp0 = R[iRn1];
1333 R[iRn1] -= R[iRn2];
1334 tmp1 = (R[iRn1] > tmp0);
1335 switch (Q)
1336 {
1337 case 0:
1338 SET_SR_Q ((unsigned char) (tmp1 == 0));
1339 break;
1340 case 1:
1341 SET_SR_Q (tmp1);
1342 break;
1343 }
1344 break;
1345 }
1346 break;
1347 }
1348 /*T = (Q == M);*/
1349 SET_SR_T (Q == M);
1350 /*return T;*/
1351}
1352
1353static void
1354dmul (sign, rm, rn)
1355 int sign;
1356 unsigned int rm;
1357 unsigned int rn;
1358{
1359 unsigned long RnL, RnH;
1360 unsigned long RmL, RmH;
1361 unsigned long temp0, temp1, temp2, temp3;
1362 unsigned long Res2, Res1, Res0;
1363
1364 RnL = rn & 0xffff;
1365 RnH = (rn >> 16) & 0xffff;
1366 RmL = rm & 0xffff;
1367 RmH = (rm >> 16) & 0xffff;
1368 temp0 = RmL * RnL;
1369 temp1 = RmH * RnL;
1370 temp2 = RmL * RnH;
1371 temp3 = RmH * RnH;
1372 Res2 = 0;
1373 Res1 = temp1 + temp2;
1374 if (Res1 < temp1)
1375 Res2 += 0x00010000;
1376 temp1 = (Res1 << 16) & 0xffff0000;
1377 Res0 = temp0 + temp1;
1378 if (Res0 < temp0)
1379 Res2 += 1;
1380 Res2 += ((Res1 >> 16) & 0xffff) + temp3;
1381
1382 if (sign)
1383 {
1384 if (rn & 0x80000000)
1385 Res2 -= rm;
1386 if (rm & 0x80000000)
1387 Res2 -= rn;
1388 }
1389
1390 MACH = Res2;
1391 MACL = Res0;
1392}
1393
1394static void
63978407 1395macw (regs, memory, n, m, endianw)
c906108c
SS
1396 int *regs;
1397 unsigned char *memory;
1398 int m, n;
63978407 1399 int endianw;
c906108c 1400{
c906108c
SS
1401 long tempm, tempn;
1402 long prod, macl, sum;
1403
87acb4a7
MS
1404 tempm=RSWAT (regs[m]); regs[m]+=2;
1405 tempn=RSWAT (regs[n]); regs[n]+=2;
c906108c
SS
1406
1407 macl = MACL;
87acb4a7 1408 prod = (long) (short) tempm * (long) (short) tempn;
c906108c
SS
1409 sum = prod + macl;
1410 if (S)
1411 {
1412 if ((~(prod ^ macl) & (sum ^ prod)) < 0)
1413 {
1414 /* MACH's lsb is a sticky overflow bit. */
1415 MACH |= 1;
1416 /* Store the smallest negative number in MACL if prod is
1417 negative, and the largest positive number otherwise. */
1418 sum = 0x7fffffff + (prod < 0);
1419 }
1420 }
1421 else
1422 {
1423 long mach;
1424 /* Add to MACH the sign extended product, and carry from low sum. */
1425 mach = MACH + (-(prod < 0)) + ((unsigned long) sum < prod);
1426 /* Sign extend at 10:th bit in MACH. */
1427 MACH = (mach & 0x1ff) | -(mach & 0x200);
1428 }
1429 MACL = sum;
1430}
1431
d1789ace
MS
1432static void
1433macl (regs, memory, n, m)
1434 int *regs;
1435 unsigned char *memory;
1436 int m, n;
1437{
1438 long tempm, tempn;
f3876f69
AS
1439 long macl, mach;
1440 long long ans;
1441 long long mac64;
d1789ace 1442
87acb4a7 1443 tempm = RSLAT (regs[m]);
d1789ace
MS
1444 regs[m] += 4;
1445
87acb4a7 1446 tempn = RSLAT (regs[n]);
d1789ace
MS
1447 regs[n] += 4;
1448
1449 mach = MACH;
1450 macl = MACL;
1451
f3876f69
AS
1452 mac64 = ((long long) macl & 0xffffffff) |
1453 ((long long) mach & 0xffffffff) << 32;
d1789ace 1454
87acb4a7 1455 ans = (long long) tempm * (long long) tempn; /* Multiply 32bit * 32bit */
d1789ace 1456
f3876f69 1457 mac64 += ans; /* Accumulate 64bit + 64 bit */
d1789ace 1458
f3876f69
AS
1459 macl = (long) (mac64 & 0xffffffff);
1460 mach = (long) ((mac64 >> 32) & 0xffffffff);
d1789ace
MS
1461
1462 if (S) /* Store only 48 bits of the result */
1463 {
1464 if (mach < 0) /* Result is negative */
1465 {
1466 mach = mach & 0x0000ffff; /* Mask higher 16 bits */
1467 mach |= 0xffff8000; /* Sign extend higher 16 bits */
1468 }
1469 else
1470 mach = mach & 0x00007fff; /* Postive Result */
1471 }
1472
1473 MACL = macl;
1474 MACH = mach;
1475}
1476
ae0a84af
CV
1477enum {
1478 B_BCLR = 0,
1479 B_BSET = 1,
1480 B_BST = 2,
1481 B_BLD = 3,
1482 B_BAND = 4,
1483 B_BOR = 5,
1484 B_BXOR = 6,
1485 B_BLDNOT = 11,
1486 B_BANDNOT = 12,
1487 B_BORNOT = 13,
1488
1489 MOVB_RM = 0x0000,
1490 MOVW_RM = 0x1000,
1491 MOVL_RM = 0x2000,
1492 FMOV_RM = 0x3000,
1493 MOVB_MR = 0x4000,
1494 MOVW_MR = 0x5000,
1495 MOVL_MR = 0x6000,
1496 FMOV_MR = 0x7000,
1497 MOVU_BMR = 0x8000,
1498 MOVU_WMR = 0x9000,
1499};
1500
1501/* Do extended displacement move instructions. */
1502void
1503do_long_move_insn (int op, int disp12, int m, int n, int *thatlock)
86bc60eb 1504{
ae0a84af
CV
1505 int memstalls = 0;
1506 int thislock = *thatlock;
1507 int endianw = global_endianw;
1508 int *R = &(saved_state.asregs.regs[0]);
1509 unsigned char *memory = saved_state.asregs.memory;
1510 int maskb = ~((saved_state.asregs.msize - 1) & ~0);
1511 unsigned char *insn_ptr = PT2H (saved_state.asregs.pc);
1512
1513 switch (op) {
1514 case MOVB_RM: /* signed */
1515 WBAT (disp12 * 1 + R[n], R[m]);
1516 break;
1517 case MOVW_RM:
1518 WWAT (disp12 * 2 + R[n], R[m]);
1519 break;
1520 case MOVL_RM:
1521 WLAT (disp12 * 4 + R[n], R[m]);
1522 break;
1523 case FMOV_RM: /* floating point */
1524 if (FPSCR_SZ)
1525 {
1526 MA (1);
1527 WDAT (R[n] + 8 * disp12, m);
1528 }
1529 else
1530 WLAT (R[n] + 4 * disp12, FI (m));
1531 break;
1532 case MOVB_MR:
1533 R[n] = RSBAT (disp12 * 1 + R[m]);
1534 L (n);
1535 break;
1536 case MOVW_MR:
1537 R[n] = RSWAT (disp12 * 2 + R[m]);
1538 L (n);
1539 break;
1540 case MOVL_MR:
1541 R[n] = RLAT (disp12 * 4 + R[m]);
1542 L (n);
1543 break;
1544 case FMOV_MR:
1545 if (FPSCR_SZ) {
1546 MA (1);
1547 RDAT (R[m] + 8 * disp12, n);
1548 }
1549 else
1550 SET_FI (n, RLAT (R[m] + 4 * disp12));
1551 break;
1552 case MOVU_BMR: /* unsigned */
1553 R[n] = RBAT (disp12 * 1 + R[m]);
1554 L (n);
1555 break;
1556 case MOVU_WMR:
1557 R[n] = RWAT (disp12 * 2 + R[m]);
1558 L (n);
1559 break;
1560 default:
1561 RAISE_EXCEPTION (SIGINT);
1562 exit (1);
1563 }
1564 saved_state.asregs.memstalls += memstalls;
1565 *thatlock = thislock;
86bc60eb
MS
1566}
1567
ae0a84af
CV
1568/* Do binary logical bit-manipulation insns. */
1569void
1570do_blog_insn (int imm, int addr, int binop,
1571 unsigned char *memory, int maskb)
1572{
1573 int oldval = RBAT (addr);
1574
1575 switch (binop) {
1576 case B_BCLR: /* bclr.b */
1577 WBAT (addr, oldval & ~imm);
1578 break;
1579 case B_BSET: /* bset.b */
1580 WBAT (addr, oldval | imm);
1581 break;
1582 case B_BST: /* bst.b */
1583 if (T)
1584 WBAT (addr, oldval | imm);
1585 else
1586 WBAT (addr, oldval & ~imm);
1587 break;
1588 case B_BLD: /* bld.b */
1589 SET_SR_T ((oldval & imm) != 0);
1590 break;
1591 case B_BAND: /* band.b */
1592 SET_SR_T (T && ((oldval & imm) != 0));
1593 break;
1594 case B_BOR: /* bor.b */
1595 SET_SR_T (T || ((oldval & imm) != 0));
1596 break;
1597 case B_BXOR: /* bxor.b */
1598 SET_SR_T (T ^ ((oldval & imm) != 0));
1599 break;
1600 case B_BLDNOT: /* bldnot.b */
1601 SET_SR_T ((oldval & imm) == 0);
1602 break;
1603 case B_BANDNOT: /* bandnot.b */
1604 SET_SR_T (T && ((oldval & imm) == 0));
1605 break;
1606 case B_BORNOT: /* bornot.b */
1607 SET_SR_T (T || ((oldval & imm) == 0));
1608 break;
1609 }
1610}
794cd17b
JR
1611float
1612fsca_s (int in, double (*f) (double))
1613{
1614 double rad = ldexp ((in & 0xffff), -15) * 3.141592653589793238462643383;
1615 double result = (*f) (rad);
1616 double error, upper, lower, frac;
1617 int exp;
1618
1619 /* Search the value with the maximum error that is still within the
1620 architectural spec. */
1621 error = ldexp (1., -21);
1622 /* compensate for calculation inaccuracy by reducing error. */
1623 error = error - ldexp (1., -50);
1624 upper = result + error;
1625 frac = frexp (upper, &exp);
1626 upper = ldexp (floor (ldexp (frac, 24)), exp - 24);
1627 lower = result - error;
1628 frac = frexp (lower, &exp);
1629 lower = ldexp (ceil (ldexp (frac, 24)), exp - 24);
1630 return abs (upper - result) >= abs (lower - result) ? upper : lower;
1631}
1632
1633float
1634fsrra_s (float in)
1635{
1636 double result = 1. / sqrt (in);
1637 int exp;
1638 double frac, upper, lower, error, eps;
1639
1640 /* refine result */
1641 result = result - (result * result * in - 1) * 0.5 * result;
1642 /* Search the value with the maximum error that is still within the
1643 architectural spec. */
1644 frac = frexp (result, &exp);
1645 frac = ldexp (frac, 24);
87acb4a7 1646 error = 4.0; /* 1 << 24-1-21 */
794cd17b
JR
1647 /* use eps to compensate for possible 1 ulp error in our 'exact' result. */
1648 eps = ldexp (1., -29);
1649 upper = floor (frac + error - eps);
1650 if (upper > 16777216.)
1651 upper = floor ((frac + error - eps) * 0.5) * 2.;
1652 lower = ceil ((frac - error + eps) * 2) * .5;
1653 if (lower > 8388608.)
1654 lower = ceil (frac - error + eps);
1655 upper = ldexp (upper, exp - 24);
1656 lower = ldexp (lower, exp - 24);
1657 return upper - result >= result - lower ? upper : lower;
1658}
1659
ae0a84af
CV
1660
1661/* GET_LOOP_BOUNDS {EXTENDED}
1662 These two functions compute the actual starting and ending point
1663 of the repeat loop, based on the RS and RE registers (repeat start,
1664 repeat stop). The extended version is called for LDRC, and the
1665 regular version is called for SETRC. The difference is that for
1666 LDRC, the loop start and end instructions are literally the ones
1667 pointed to by RS and RE -- for SETRC, they're not (see docs). */
1668
1669static struct loop_bounds
1670get_loop_bounds_ext (rs, re, memory, mem_end, maskw, endianw)
1671 int rs, re;
1672 unsigned char *memory, *mem_end;
1673 int maskw, endianw;
1674{
1675 struct loop_bounds loop;
1676
1677 /* FIXME: should I verify RS < RE? */
1678 loop.start = PT2H (RS); /* FIXME not using the params? */
1679 loop.end = PT2H (RE & ~1); /* Ignore bit 0 of RE. */
1680 SKIP_INSN (loop.end);
1681 if (loop.end >= mem_end)
1682 loop.end = PT2H (0);
1683 return loop;
1684}
1685
63978407
JR
1686static struct loop_bounds
1687get_loop_bounds (rs, re, memory, mem_end, maskw, endianw)
1688 int rs, re;
1689 unsigned char *memory, *mem_end;
1690 int maskw, endianw;
1691{
1692 struct loop_bounds loop;
1693
1694 if (SR_RC)
1695 {
1696 if (RS >= RE)
1697 {
1698 loop.start = PT2H (RE - 4);
1699 SKIP_INSN (loop.start);
1700 loop.end = loop.start;
1701 if (RS - RE == 0)
1702 SKIP_INSN (loop.end);
1703 if (RS - RE <= 2)
1704 SKIP_INSN (loop.end);
1705 SKIP_INSN (loop.end);
1706 }
1707 else
1708 {
1709 loop.start = PT2H (RS);
1710 loop.end = PT2H (RE - 4);
1711 SKIP_INSN (loop.end);
1712 SKIP_INSN (loop.end);
1713 SKIP_INSN (loop.end);
1714 SKIP_INSN (loop.end);
1715 }
1716 if (loop.end >= mem_end)
1717 loop.end = PT2H (0);
1718 }
1719 else
1720 loop.end = PT2H (0);
1721
1722 return loop;
1723}
1724
87acb4a7 1725static void ppi_insn ();
63978407
JR
1726
1727#include "ppi.c"
1728
6a8492b5
JR
1729/* Provide calloc / free versions that use an anonymous mmap. This can
1730 significantly cut the start-up time when a large simulator memory is
1731 required, because pages are only zeroed on demand. */
1732#ifdef MAP_ANONYMOUS
1733void *
1734mcalloc (size_t nmemb, size_t size)
1735{
1736 void *page;
1737
1738 if (nmemb != 1)
1739 size *= nmemb;
1740 return mmap (0, size, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS,
1741 -1, 0);
1742}
1743
1744#define mfree(start,length) munmap ((start), (length))
1745#else
1746#define mcalloc calloc
1747#define mfree(start,length) free(start)
1748#endif
1749
c906108c
SS
1750/* Set the memory size to the power of two provided. */
1751
1752void
1753sim_size (power)
1754 int power;
1755
1756{
c906108c
SS
1757 sim_memory_size = power;
1758
1759 if (saved_state.asregs.memory)
1760 {
6a8492b5 1761 mfree (saved_state.asregs.memory, saved_state.asregs.msize);
c906108c
SS
1762 }
1763
6a8492b5
JR
1764 saved_state.asregs.msize = 1 << power;
1765
c906108c 1766 saved_state.asregs.memory =
6a8492b5 1767 (unsigned char *) mcalloc (1, saved_state.asregs.msize);
c906108c
SS
1768
1769 if (!saved_state.asregs.memory)
1770 {
1771 fprintf (stderr,
1772 "Not enough VM for simulation of %d bytes of RAM\n",
1773 saved_state.asregs.msize);
1774
1775 saved_state.asregs.msize = 1;
6a8492b5 1776 saved_state.asregs.memory = (unsigned char *) mcalloc (1, 1);
c906108c
SS
1777 }
1778}
1779
63978407
JR
1780static void
1781init_dsp (abfd)
6b4a8935 1782 struct bfd *abfd;
63978407
JR
1783{
1784 int was_dsp = target_dsp;
1785 unsigned long mach = bfd_get_mach (abfd);
1786
86bc60eb
MS
1787 if (mach == bfd_mach_sh_dsp ||
1788 mach == bfd_mach_sh4al_dsp ||
1789 mach == bfd_mach_sh3_dsp)
63978407
JR
1790 {
1791 int ram_area_size, xram_start, yram_start;
1792 int new_select;
1793
1794 target_dsp = 1;
1795 if (mach == bfd_mach_sh_dsp)
1796 {
1797 /* SH7410 (orig. sh-sdp):
1798 4KB each for X & Y memory;
1799 On-chip X RAM 0x0800f000-0x0800ffff
1800 On-chip Y RAM 0x0801f000-0x0801ffff */
1801 xram_start = 0x0800f000;
1802 ram_area_size = 0x1000;
1803 }
86bc60eb 1804 if (mach == bfd_mach_sh3_dsp || mach == bfd_mach_sh4al_dsp)
63978407
JR
1805 {
1806 /* SH7612:
1807 8KB each for X & Y memory;
1808 On-chip X RAM 0x1000e000-0x1000ffff
1809 On-chip Y RAM 0x1001e000-0x1001ffff */
1810 xram_start = 0x1000e000;
1811 ram_area_size = 0x2000;
1812 }
1813 yram_start = xram_start + 0x10000;
1814 new_select = ~(ram_area_size - 1);
1815 if (saved_state.asregs.xyram_select != new_select)
1816 {
1817 saved_state.asregs.xyram_select = new_select;
1818 free (saved_state.asregs.xmem);
1819 free (saved_state.asregs.ymem);
ae0a84af
CV
1820 saved_state.asregs.xmem =
1821 (unsigned char *) calloc (1, ram_area_size);
1822 saved_state.asregs.ymem =
1823 (unsigned char *) calloc (1, ram_area_size);
63978407
JR
1824
1825 /* Disable use of X / Y mmeory if not allocated. */
1826 if (! saved_state.asregs.xmem || ! saved_state.asregs.ymem)
1827 {
1828 saved_state.asregs.xyram_select = 0;
1829 if (saved_state.asregs.xmem)
1830 free (saved_state.asregs.xmem);
1831 if (saved_state.asregs.ymem)
1832 free (saved_state.asregs.ymem);
1833 }
1834 }
1835 saved_state.asregs.xram_start = xram_start;
1836 saved_state.asregs.yram_start = yram_start;
1837 saved_state.asregs.xmem_offset = saved_state.asregs.xmem - xram_start;
1838 saved_state.asregs.ymem_offset = saved_state.asregs.ymem - yram_start;
1839 }
1840 else
1841 {
1842 target_dsp = 0;
1843 if (saved_state.asregs.xyram_select)
1844 {
1845 saved_state.asregs.xyram_select = 0;
1846 free (saved_state.asregs.xmem);
1847 free (saved_state.asregs.ymem);
1848 }
1849 }
1850
1851 if (! saved_state.asregs.xyram_select)
1852 {
1853 saved_state.asregs.xram_start = 1;
1854 saved_state.asregs.yram_start = 1;
1855 }
1856
ae0a84af
CV
1857 if (saved_state.asregs.regstack == NULL)
1858 saved_state.asregs.regstack =
1859 calloc (512, sizeof *saved_state.asregs.regstack);
1860
63978407
JR
1861 if (target_dsp != was_dsp)
1862 {
1863 int i, tmp;
1864
3e511797 1865 for (i = (sizeof sh_dsp_table / sizeof sh_dsp_table[0]) - 1; i >= 0; i--)
63978407
JR
1866 {
1867 tmp = sh_jump_table[0xf000 + i];
1868 sh_jump_table[0xf000 + i] = sh_dsp_table[i];
1869 sh_dsp_table[i] = tmp;
1870 }
1871 }
1872}
1873
c906108c
SS
1874static void
1875init_pointers ()
1876{
1877 host_little_endian = 0;
87acb4a7 1878 * (char*) &host_little_endian = 1;
c906108c
SS
1879 host_little_endian &= 1;
1880
1881 if (saved_state.asregs.msize != 1 << sim_memory_size)
1882 {
1883 sim_size (sim_memory_size);
1884 }
1885
1886 if (saved_state.asregs.profile && !profile_file)
1887 {
1888 profile_file = fopen ("gmon.out", "wb");
1889 /* Seek to where to put the call arc data */
1890 nsamples = (1 << sim_profile_size);
1891
1892 fseek (profile_file, nsamples * 2 + 12, 0);
1893
1894 if (!profile_file)
1895 {
1896 fprintf (stderr, "Can't open gmon.out\n");
1897 }
1898 else
1899 {
1900 saved_state.asregs.profile_hist =
1901 (unsigned short *) calloc (64, (nsamples * sizeof (short) / 64));
1902 }
1903 }
1904}
1905
1906static void
1907dump_profile ()
1908{
1909 unsigned int minpc;
1910 unsigned int maxpc;
1911 unsigned short *p;
1912 int i;
1913
1914 p = saved_state.asregs.profile_hist;
1915 minpc = 0;
1916 maxpc = (1 << sim_profile_size);
1917
1918 fseek (profile_file, 0L, 0);
1919 swapout (minpc << PROFILE_SHIFT);
1920 swapout (maxpc << PROFILE_SHIFT);
1921 swapout (nsamples * 2 + 12);
1922 for (i = 0; i < nsamples; i++)
1923 swapout16 (saved_state.asregs.profile_hist[i]);
1924
1925}
1926
1927static void
1928gotcall (from, to)
1929 int from;
1930 int to;
1931{
1932 swapout (from);
1933 swapout (to);
1934 swapout (1);
1935}
1936
1937#define MMASKB ((saved_state.asregs.msize -1) & ~0)
1938
1939int
1940sim_stop (sd)
1941 SIM_DESC sd;
1942{
63978407 1943 raise_exception (SIGINT);
c906108c
SS
1944 return 1;
1945}
1946
1947void
1948sim_resume (sd, step, siggnal)
1949 SIM_DESC sd;
1950 int step, siggnal;
1951{
63978407
JR
1952 register unsigned char *insn_ptr;
1953 unsigned char *mem_end;
1954 struct loop_bounds loop;
c906108c
SS
1955 register int cycles = 0;
1956 register int stalls = 0;
1957 register int memstalls = 0;
1958 register int insts = 0;
1959 register int prevlock;
ae0a84af
CV
1960#if 1
1961 int thislock;
1962#else
c906108c 1963 register int thislock;
ae0a84af 1964#endif
c906108c
SS
1965 register unsigned int doprofile;
1966 register int pollcount = 0;
63978407
JR
1967 /* endianw is used for every insn fetch, hence it makes sense to cache it.
1968 endianb is used less often. */
1969 register int endianw = global_endianw;
c906108c
SS
1970
1971 int tick_start = get_now ();
c906108c 1972 void (*prev_fpe) ();
c906108c 1973
3e511797 1974 register unsigned short *jump_table = sh_jump_table;
c906108c
SS
1975
1976 register int *R = &(saved_state.asregs.regs[0]);
1977 /*register int T;*/
63978407 1978#ifndef PR
c906108c 1979 register int PR;
63978407 1980#endif
c906108c 1981
63978407
JR
1982 register int maskb = ~((saved_state.asregs.msize - 1) & ~0);
1983 register int maskw = ~((saved_state.asregs.msize - 1) & ~1);
1984 register int maskl = ~((saved_state.asregs.msize - 1) & ~3);
c906108c
SS
1985 register unsigned char *memory;
1986 register unsigned int sbit = ((unsigned int) 1 << 31);
1987
c906108c
SS
1988 prev_fpe = signal (SIGFPE, SIG_IGN);
1989
1990 init_pointers ();
63978407 1991 saved_state.asregs.exception = 0;
c906108c
SS
1992
1993 memory = saved_state.asregs.memory;
63978407 1994 mem_end = memory + saved_state.asregs.msize;
c906108c 1995
86bc60eb
MS
1996 if (RE & 1)
1997 loop = get_loop_bounds_ext (RS, RE, memory, mem_end, maskw, endianw);
1998 else
1999 loop = get_loop_bounds (RS, RE, memory, mem_end, maskw, endianw);
2000
63978407
JR
2001 insn_ptr = PT2H (saved_state.asregs.pc);
2002 CHECK_INSN_PTR (insn_ptr);
c906108c 2003
63978407
JR
2004#ifndef PR
2005 PR = saved_state.asregs.sregs.named.pr;
2006#endif
c906108c
SS
2007 /*T = GET_SR () & SR_MASK_T;*/
2008 prevlock = saved_state.asregs.prevlock;
2009 thislock = saved_state.asregs.thislock;
2010 doprofile = saved_state.asregs.profile;
2011
2012 /* If profiling not enabled, disable it by asking for
2013 profiles infrequently. */
2014 if (doprofile == 0)
2015 doprofile = ~0;
2016
63978407
JR
2017 loop:
2018 if (step && insn_ptr < saved_state.asregs.insn_end)
2019 {
2020 if (saved_state.asregs.exception)
2021 /* This can happen if we've already been single-stepping and
2022 encountered a loop end. */
2023 saved_state.asregs.insn_end = insn_ptr;
2024 else
2025 {
2026 saved_state.asregs.exception = SIGTRAP;
2027 saved_state.asregs.insn_end = insn_ptr + 2;
2028 }
2029 }
2030
2031 while (insn_ptr < saved_state.asregs.insn_end)
c906108c 2032 {
63978407 2033 register unsigned int iword = RIAT (insn_ptr);
c906108c 2034 register unsigned int ult;
63978407
JR
2035 register unsigned char *nip = insn_ptr + 2;
2036
c906108c
SS
2037#ifndef ACE_FAST
2038 insts++;
2039#endif
2040 top:
ae0a84af
CV
2041 if (tracing)
2042 fprintf (stderr, "PC: %08x, insn: %04x\n", PH2T (insn_ptr), iword);
c906108c
SS
2043
2044#include "code.c"
2045
2046
ae0a84af 2047 in_delay_slot = 0;
63978407 2048 insn_ptr = nip;
c906108c
SS
2049
2050 if (--pollcount < 0)
2051 {
7a292a7a 2052 pollcount = POLL_QUIT_INTERVAL;
c906108c
SS
2053 if ((*callback->poll_quit) != NULL
2054 && (*callback->poll_quit) (callback))
2055 {
2056 sim_stop (sd);
2057 }
2058 }
2059
2060#ifndef ACE_FAST
2061 prevlock = thislock;
2062 thislock = 30;
2063 cycles++;
2064
2065 if (cycles >= doprofile)
2066 {
2067
2068 saved_state.asregs.cycles += doprofile;
2069 cycles -= doprofile;
2070 if (saved_state.asregs.profile_hist)
2071 {
63978407 2072 int n = PH2T (insn_ptr) >> PROFILE_SHIFT;
c906108c
SS
2073 if (n < nsamples)
2074 {
2075 int i = saved_state.asregs.profile_hist[n];
2076 if (i < 65000)
2077 saved_state.asregs.profile_hist[n] = i + 1;
2078 }
2079
2080 }
2081 }
2082#endif
2083 }
63978407
JR
2084 if (saved_state.asregs.insn_end == loop.end)
2085 {
2086 saved_state.asregs.cregs.named.sr += SR_RC_INCREMENT;
2087 if (SR_RC)
2088 insn_ptr = loop.start;
2089 else
2090 {
2091 saved_state.asregs.insn_end = mem_end;
2092 loop.end = PT2H (0);
2093 }
2094 goto loop;
2095 }
c906108c
SS
2096
2097 if (saved_state.asregs.exception == SIGILL
2098 || saved_state.asregs.exception == SIGBUS)
2099 {
63978407 2100 insn_ptr -= 2;
c906108c 2101 }
63978407
JR
2102 /* Check for SIGBUS due to insn fetch. */
2103 else if (! saved_state.asregs.exception)
dc9feb5c 2104 saved_state.asregs.exception = SIGBUS;
c906108c
SS
2105
2106 saved_state.asregs.ticks += get_now () - tick_start;
2107 saved_state.asregs.cycles += cycles;
2108 saved_state.asregs.stalls += stalls;
2109 saved_state.asregs.memstalls += memstalls;
2110 saved_state.asregs.insts += insts;
63978407
JR
2111 saved_state.asregs.pc = PH2T (insn_ptr);
2112#ifndef PR
2113 saved_state.asregs.sregs.named.pr = PR;
2114#endif
c906108c
SS
2115
2116 saved_state.asregs.prevlock = prevlock;
2117 saved_state.asregs.thislock = thislock;
2118
2119 if (profile_file)
2120 {
2121 dump_profile ();
2122 }
2123
2124 signal (SIGFPE, prev_fpe);
c906108c
SS
2125}
2126
2127int
2128sim_write (sd, addr, buffer, size)
2129 SIM_DESC sd;
2130 SIM_ADDR addr;
5558e7e6 2131 const unsigned char *buffer;
c906108c
SS
2132 int size;
2133{
2134 int i;
2135
2136 init_pointers ();
2137
2138 for (i = 0; i < size; i++)
2139 {
63978407 2140 saved_state.asregs.memory[(MMASKB & (addr + i)) ^ endianb] = buffer[i];
c906108c
SS
2141 }
2142 return size;
2143}
2144
2145int
2146sim_read (sd, addr, buffer, size)
2147 SIM_DESC sd;
2148 SIM_ADDR addr;
2149 unsigned char *buffer;
2150 int size;
2151{
2152 int i;
2153
2154 init_pointers ();
2155
2156 for (i = 0; i < size; i++)
2157 {
63978407 2158 buffer[i] = saved_state.asregs.memory[(MMASKB & (addr + i)) ^ endianb];
c906108c
SS
2159 }
2160 return size;
2161}
2162
ae0a84af
CV
2163static int gdb_bank_number;
2164enum {
2165 REGBANK_MACH = 15,
2166 REGBANK_IVN = 16,
2167 REGBANK_PR = 17,
2168 REGBANK_GBR = 18,
2169 REGBANK_MACL = 19
2170};
2171
c906108c
SS
2172int
2173sim_store_register (sd, rn, memory, length)
2174 SIM_DESC sd;
2175 int rn;
2176 unsigned char *memory;
2177 int length;
2178{
63978407
JR
2179 unsigned val;
2180
c906108c 2181 init_pointers ();
87acb4a7 2182 val = swap (* (int *) memory);
63978407
JR
2183 switch (rn)
2184 {
2f14585c
JR
2185 case SIM_SH_R0_REGNUM: case SIM_SH_R1_REGNUM: case SIM_SH_R2_REGNUM:
2186 case SIM_SH_R3_REGNUM: case SIM_SH_R4_REGNUM: case SIM_SH_R5_REGNUM:
2187 case SIM_SH_R6_REGNUM: case SIM_SH_R7_REGNUM: case SIM_SH_R8_REGNUM:
2188 case SIM_SH_R9_REGNUM: case SIM_SH_R10_REGNUM: case SIM_SH_R11_REGNUM:
2189 case SIM_SH_R12_REGNUM: case SIM_SH_R13_REGNUM: case SIM_SH_R14_REGNUM:
2190 case SIM_SH_R15_REGNUM:
63978407
JR
2191 saved_state.asregs.regs[rn] = val;
2192 break;
2f14585c 2193 case SIM_SH_PC_REGNUM:
63978407
JR
2194 saved_state.asregs.pc = val;
2195 break;
2f14585c 2196 case SIM_SH_PR_REGNUM:
63978407
JR
2197 PR = val;
2198 break;
2f14585c 2199 case SIM_SH_GBR_REGNUM:
63978407
JR
2200 GBR = val;
2201 break;
2f14585c 2202 case SIM_SH_VBR_REGNUM:
63978407
JR
2203 VBR = val;
2204 break;
2f14585c 2205 case SIM_SH_MACH_REGNUM:
63978407
JR
2206 MACH = val;
2207 break;
2f14585c 2208 case SIM_SH_MACL_REGNUM:
63978407
JR
2209 MACL = val;
2210 break;
2f14585c 2211 case SIM_SH_SR_REGNUM:
63978407
JR
2212 SET_SR (val);
2213 break;
2f14585c 2214 case SIM_SH_FPUL_REGNUM:
63978407
JR
2215 FPUL = val;
2216 break;
2f14585c 2217 case SIM_SH_FPSCR_REGNUM:
63978407
JR
2218 SET_FPSCR (val);
2219 break;
2f14585c
JR
2220 case SIM_SH_FR0_REGNUM: case SIM_SH_FR1_REGNUM: case SIM_SH_FR2_REGNUM:
2221 case SIM_SH_FR3_REGNUM: case SIM_SH_FR4_REGNUM: case SIM_SH_FR5_REGNUM:
2222 case SIM_SH_FR6_REGNUM: case SIM_SH_FR7_REGNUM: case SIM_SH_FR8_REGNUM:
2223 case SIM_SH_FR9_REGNUM: case SIM_SH_FR10_REGNUM: case SIM_SH_FR11_REGNUM:
2224 case SIM_SH_FR12_REGNUM: case SIM_SH_FR13_REGNUM: case SIM_SH_FR14_REGNUM:
2225 case SIM_SH_FR15_REGNUM:
2226 SET_FI (rn - SIM_SH_FR0_REGNUM, val);
2227 break;
2228 case SIM_SH_DSR_REGNUM:
2229 DSR = val;
2230 break;
2231 case SIM_SH_A0G_REGNUM:
2232 A0G = val;
2233 break;
2234 case SIM_SH_A0_REGNUM:
2235 A0 = val;
2236 break;
2237 case SIM_SH_A1G_REGNUM:
2238 A1G = val;
2239 break;
2240 case SIM_SH_A1_REGNUM:
2241 A1 = val;
2242 break;
2243 case SIM_SH_M0_REGNUM:
2244 M0 = val;
2245 break;
2246 case SIM_SH_M1_REGNUM:
2247 M1 = val;
2248 break;
2249 case SIM_SH_X0_REGNUM:
2250 X0 = val;
2251 break;
2252 case SIM_SH_X1_REGNUM:
2253 X1 = val;
2254 break;
2255 case SIM_SH_Y0_REGNUM:
2256 Y0 = val;
2257 break;
2258 case SIM_SH_Y1_REGNUM:
2259 Y1 = val;
2260 break;
2261 case SIM_SH_MOD_REGNUM:
2262 SET_MOD (val);
2263 break;
2264 case SIM_SH_RS_REGNUM:
2265 RS = val;
2266 break;
2267 case SIM_SH_RE_REGNUM:
2268 RE = val;
2269 break;
2270 case SIM_SH_SSR_REGNUM:
63978407
JR
2271 SSR = val;
2272 break;
2f14585c 2273 case SIM_SH_SPC_REGNUM:
63978407
JR
2274 SPC = val;
2275 break;
2276 /* The rn_bank idiosyncracies are not due to hardware differences, but to
2277 a weird aliasing naming scheme for sh3 / sh3e / sh4. */
2f14585c
JR
2278 case SIM_SH_R0_BANK0_REGNUM: case SIM_SH_R1_BANK0_REGNUM:
2279 case SIM_SH_R2_BANK0_REGNUM: case SIM_SH_R3_BANK0_REGNUM:
2280 case SIM_SH_R4_BANK0_REGNUM: case SIM_SH_R5_BANK0_REGNUM:
2281 case SIM_SH_R6_BANK0_REGNUM: case SIM_SH_R7_BANK0_REGNUM:
ae0a84af
CV
2282 if (saved_state.asregs.bfd_mach == bfd_mach_sh2a)
2283 {
2284 rn -= SIM_SH_R0_BANK0_REGNUM;
2285 saved_state.asregs.regstack[gdb_bank_number].regs[rn] = val;
2286 }
2287 else
63978407 2288 if (SR_MD && SR_RB)
2f14585c 2289 Rn_BANK (rn - SIM_SH_R0_BANK0_REGNUM) = val;
63978407 2290 else
2f14585c 2291 saved_state.asregs.regs[rn - SIM_SH_R0_BANK0_REGNUM] = val;
63978407 2292 break;
2f14585c
JR
2293 case SIM_SH_R0_BANK1_REGNUM: case SIM_SH_R1_BANK1_REGNUM:
2294 case SIM_SH_R2_BANK1_REGNUM: case SIM_SH_R3_BANK1_REGNUM:
2295 case SIM_SH_R4_BANK1_REGNUM: case SIM_SH_R5_BANK1_REGNUM:
2296 case SIM_SH_R6_BANK1_REGNUM: case SIM_SH_R7_BANK1_REGNUM:
ae0a84af
CV
2297 if (saved_state.asregs.bfd_mach == bfd_mach_sh2a)
2298 {
2299 rn -= SIM_SH_R0_BANK1_REGNUM;
2300 saved_state.asregs.regstack[gdb_bank_number].regs[rn + 8] = val;
2301 }
2302 else
2f14585c
JR
2303 if (SR_MD && SR_RB)
2304 saved_state.asregs.regs[rn - SIM_SH_R0_BANK1_REGNUM] = val;
63978407 2305 else
2f14585c
JR
2306 Rn_BANK (rn - SIM_SH_R0_BANK1_REGNUM) = val;
2307 break;
2308 case SIM_SH_R0_BANK_REGNUM: case SIM_SH_R1_BANK_REGNUM:
2309 case SIM_SH_R2_BANK_REGNUM: case SIM_SH_R3_BANK_REGNUM:
2310 case SIM_SH_R4_BANK_REGNUM: case SIM_SH_R5_BANK_REGNUM:
2311 case SIM_SH_R6_BANK_REGNUM: case SIM_SH_R7_BANK_REGNUM:
2312 SET_Rn_BANK (rn - SIM_SH_R0_BANK_REGNUM, val);
63978407 2313 break;
ae0a84af
CV
2314 case SIM_SH_TBR_REGNUM:
2315 TBR = val;
2316 break;
2317 case SIM_SH_IBNR_REGNUM:
2318 IBNR = val;
2319 break;
2320 case SIM_SH_IBCR_REGNUM:
2321 IBCR = val;
2322 break;
2323 case SIM_SH_BANK_REGNUM:
2324 /* This is a pseudo-register maintained just for gdb.
2325 It tells us what register bank gdb would like to read/write. */
2326 gdb_bank_number = val;
2327 break;
2328 case SIM_SH_BANK_MACL_REGNUM:
2329 saved_state.asregs.regstack[gdb_bank_number].regs[REGBANK_MACL] = val;
2330 break;
2331 case SIM_SH_BANK_GBR_REGNUM:
2332 saved_state.asregs.regstack[gdb_bank_number].regs[REGBANK_GBR] = val;
2333 break;
2334 case SIM_SH_BANK_PR_REGNUM:
2335 saved_state.asregs.regstack[gdb_bank_number].regs[REGBANK_PR] = val;
2336 break;
2337 case SIM_SH_BANK_IVN_REGNUM:
2338 saved_state.asregs.regstack[gdb_bank_number].regs[REGBANK_IVN] = val;
2339 break;
2340 case SIM_SH_BANK_MACH_REGNUM:
2341 saved_state.asregs.regstack[gdb_bank_number].regs[REGBANK_MACH] = val;
2342 break;
63978407
JR
2343 default:
2344 return 0;
2345 }
f95586a4 2346 return length;
c906108c
SS
2347}
2348
2349int
2350sim_fetch_register (sd, rn, memory, length)
2351 SIM_DESC sd;
2352 int rn;
2353 unsigned char *memory;
2354 int length;
2355{
63978407
JR
2356 int val;
2357
c906108c 2358 init_pointers ();
63978407
JR
2359 switch (rn)
2360 {
2f14585c
JR
2361 case SIM_SH_R0_REGNUM: case SIM_SH_R1_REGNUM: case SIM_SH_R2_REGNUM:
2362 case SIM_SH_R3_REGNUM: case SIM_SH_R4_REGNUM: case SIM_SH_R5_REGNUM:
2363 case SIM_SH_R6_REGNUM: case SIM_SH_R7_REGNUM: case SIM_SH_R8_REGNUM:
2364 case SIM_SH_R9_REGNUM: case SIM_SH_R10_REGNUM: case SIM_SH_R11_REGNUM:
2365 case SIM_SH_R12_REGNUM: case SIM_SH_R13_REGNUM: case SIM_SH_R14_REGNUM:
2366 case SIM_SH_R15_REGNUM:
63978407
JR
2367 val = saved_state.asregs.regs[rn];
2368 break;
2f14585c 2369 case SIM_SH_PC_REGNUM:
63978407
JR
2370 val = saved_state.asregs.pc;
2371 break;
2f14585c 2372 case SIM_SH_PR_REGNUM:
63978407
JR
2373 val = PR;
2374 break;
2f14585c 2375 case SIM_SH_GBR_REGNUM:
63978407
JR
2376 val = GBR;
2377 break;
2f14585c 2378 case SIM_SH_VBR_REGNUM:
63978407
JR
2379 val = VBR;
2380 break;
2f14585c 2381 case SIM_SH_MACH_REGNUM:
63978407
JR
2382 val = MACH;
2383 break;
2f14585c 2384 case SIM_SH_MACL_REGNUM:
63978407
JR
2385 val = MACL;
2386 break;
2f14585c 2387 case SIM_SH_SR_REGNUM:
63978407
JR
2388 val = GET_SR ();
2389 break;
2f14585c 2390 case SIM_SH_FPUL_REGNUM:
63978407
JR
2391 val = FPUL;
2392 break;
2f14585c 2393 case SIM_SH_FPSCR_REGNUM:
63978407
JR
2394 val = GET_FPSCR ();
2395 break;
2f14585c
JR
2396 case SIM_SH_FR0_REGNUM: case SIM_SH_FR1_REGNUM: case SIM_SH_FR2_REGNUM:
2397 case SIM_SH_FR3_REGNUM: case SIM_SH_FR4_REGNUM: case SIM_SH_FR5_REGNUM:
2398 case SIM_SH_FR6_REGNUM: case SIM_SH_FR7_REGNUM: case SIM_SH_FR8_REGNUM:
2399 case SIM_SH_FR9_REGNUM: case SIM_SH_FR10_REGNUM: case SIM_SH_FR11_REGNUM:
2400 case SIM_SH_FR12_REGNUM: case SIM_SH_FR13_REGNUM: case SIM_SH_FR14_REGNUM:
2401 case SIM_SH_FR15_REGNUM:
2402 val = FI (rn - SIM_SH_FR0_REGNUM);
63978407 2403 break;
2f14585c
JR
2404 case SIM_SH_DSR_REGNUM:
2405 val = DSR;
63978407 2406 break;
2f14585c
JR
2407 case SIM_SH_A0G_REGNUM:
2408 val = SEXT (A0G);
63978407 2409 break;
2f14585c
JR
2410 case SIM_SH_A0_REGNUM:
2411 val = A0;
63978407 2412 break;
2f14585c
JR
2413 case SIM_SH_A1G_REGNUM:
2414 val = SEXT (A1G);
63978407 2415 break;
2f14585c
JR
2416 case SIM_SH_A1_REGNUM:
2417 val = A1;
63978407 2418 break;
2f14585c
JR
2419 case SIM_SH_M0_REGNUM:
2420 val = M0;
63978407 2421 break;
2f14585c
JR
2422 case SIM_SH_M1_REGNUM:
2423 val = M1;
63978407 2424 break;
2f14585c
JR
2425 case SIM_SH_X0_REGNUM:
2426 val = X0;
63978407 2427 break;
2f14585c
JR
2428 case SIM_SH_X1_REGNUM:
2429 val = X1;
63978407 2430 break;
2f14585c
JR
2431 case SIM_SH_Y0_REGNUM:
2432 val = Y0;
63978407 2433 break;
2f14585c
JR
2434 case SIM_SH_Y1_REGNUM:
2435 val = Y1;
63978407 2436 break;
2f14585c
JR
2437 case SIM_SH_MOD_REGNUM:
2438 val = MOD;
2439 break;
2440 case SIM_SH_RS_REGNUM:
2441 val = RS;
2442 break;
2443 case SIM_SH_RE_REGNUM:
2444 val = RE;
2445 break;
2446 case SIM_SH_SSR_REGNUM:
63978407
JR
2447 val = SSR;
2448 break;
2f14585c 2449 case SIM_SH_SPC_REGNUM:
63978407
JR
2450 val = SPC;
2451 break;
2452 /* The rn_bank idiosyncracies are not due to hardware differences, but to
2453 a weird aliasing naming scheme for sh3 / sh3e / sh4. */
2f14585c
JR
2454 case SIM_SH_R0_BANK0_REGNUM: case SIM_SH_R1_BANK0_REGNUM:
2455 case SIM_SH_R2_BANK0_REGNUM: case SIM_SH_R3_BANK0_REGNUM:
2456 case SIM_SH_R4_BANK0_REGNUM: case SIM_SH_R5_BANK0_REGNUM:
2457 case SIM_SH_R6_BANK0_REGNUM: case SIM_SH_R7_BANK0_REGNUM:
ae0a84af
CV
2458 if (saved_state.asregs.bfd_mach == bfd_mach_sh2a)
2459 {
2460 rn -= SIM_SH_R0_BANK0_REGNUM;
2461 val = saved_state.asregs.regstack[gdb_bank_number].regs[rn];
2462 }
2463 else
2f14585c
JR
2464 val = (SR_MD && SR_RB
2465 ? Rn_BANK (rn - SIM_SH_R0_BANK0_REGNUM)
2466 : saved_state.asregs.regs[rn - SIM_SH_R0_BANK0_REGNUM]);
2467 break;
2468 case SIM_SH_R0_BANK1_REGNUM: case SIM_SH_R1_BANK1_REGNUM:
2469 case SIM_SH_R2_BANK1_REGNUM: case SIM_SH_R3_BANK1_REGNUM:
2470 case SIM_SH_R4_BANK1_REGNUM: case SIM_SH_R5_BANK1_REGNUM:
2471 case SIM_SH_R6_BANK1_REGNUM: case SIM_SH_R7_BANK1_REGNUM:
ae0a84af
CV
2472 if (saved_state.asregs.bfd_mach == bfd_mach_sh2a)
2473 {
2474 rn -= SIM_SH_R0_BANK1_REGNUM;
2475 val = saved_state.asregs.regstack[gdb_bank_number].regs[rn + 8];
2476 }
2477 else
2f14585c
JR
2478 val = (! SR_MD || ! SR_RB
2479 ? Rn_BANK (rn - SIM_SH_R0_BANK1_REGNUM)
2480 : saved_state.asregs.regs[rn - SIM_SH_R0_BANK1_REGNUM]);
2481 break;
2482 case SIM_SH_R0_BANK_REGNUM: case SIM_SH_R1_BANK_REGNUM:
2483 case SIM_SH_R2_BANK_REGNUM: case SIM_SH_R3_BANK_REGNUM:
2484 case SIM_SH_R4_BANK_REGNUM: case SIM_SH_R5_BANK_REGNUM:
2485 case SIM_SH_R6_BANK_REGNUM: case SIM_SH_R7_BANK_REGNUM:
2486 val = Rn_BANK (rn - SIM_SH_R0_BANK_REGNUM);
63978407 2487 break;
ae0a84af
CV
2488 case SIM_SH_TBR_REGNUM:
2489 val = TBR;
2490 break;
2491 case SIM_SH_IBNR_REGNUM:
2492 val = IBNR;
2493 break;
2494 case SIM_SH_IBCR_REGNUM:
2495 val = IBCR;
2496 break;
2497 case SIM_SH_BANK_REGNUM:
2498 /* This is a pseudo-register maintained just for gdb.
2499 It tells us what register bank gdb would like to read/write. */
2500 val = gdb_bank_number;
2501 break;
2502 case SIM_SH_BANK_MACL_REGNUM:
2503 val = saved_state.asregs.regstack[gdb_bank_number].regs[REGBANK_MACL];
2504 break;
2505 case SIM_SH_BANK_GBR_REGNUM:
2506 val = saved_state.asregs.regstack[gdb_bank_number].regs[REGBANK_GBR];
2507 break;
2508 case SIM_SH_BANK_PR_REGNUM:
2509 val = saved_state.asregs.regstack[gdb_bank_number].regs[REGBANK_PR];
2510 break;
2511 case SIM_SH_BANK_IVN_REGNUM:
2512 val = saved_state.asregs.regstack[gdb_bank_number].regs[REGBANK_IVN];
2513 break;
2514 case SIM_SH_BANK_MACH_REGNUM:
2515 val = saved_state.asregs.regstack[gdb_bank_number].regs[REGBANK_MACH];
2516 break;
63978407
JR
2517 default:
2518 return 0;
2519 }
2520 * (int *) memory = swap (val);
f95586a4 2521 return length;
c906108c
SS
2522}
2523
2524int
2525sim_trace (sd)
2526 SIM_DESC sd;
2527{
ae0a84af
CV
2528 tracing = 1;
2529 sim_resume (sd, 0, 0);
2530 tracing = 0;
2531 return 1;
c906108c
SS
2532}
2533
2534void
2535sim_stop_reason (sd, reason, sigrc)
2536 SIM_DESC sd;
2537 enum sim_stop *reason;
2538 int *sigrc;
2539{
2540 /* The SH simulator uses SIGQUIT to indicate that the program has
2541 exited, so we must check for it here and translate it to exit. */
2542 if (saved_state.asregs.exception == SIGQUIT)
2543 {
2544 *reason = sim_exited;
2545 *sigrc = saved_state.asregs.regs[5];
2546 }
2547 else
2548 {
2549 *reason = sim_stopped;
2550 *sigrc = saved_state.asregs.exception;
2551 }
2552}
2553
2554void
2555sim_info (sd, verbose)
2556 SIM_DESC sd;
2557 int verbose;
2558{
87acb4a7
MS
2559 double timetaken =
2560 (double) saved_state.asregs.ticks / (double) now_persec ();
c906108c
SS
2561 double virttime = saved_state.asregs.cycles / 36.0e6;
2562
2563 callback->printf_filtered (callback, "\n\n# instructions executed %10d\n",
2564 saved_state.asregs.insts);
2565 callback->printf_filtered (callback, "# cycles %10d\n",
2566 saved_state.asregs.cycles);
2567 callback->printf_filtered (callback, "# pipeline stalls %10d\n",
2568 saved_state.asregs.stalls);
2569 callback->printf_filtered (callback, "# misaligned load/store %10d\n",
2570 saved_state.asregs.memstalls);
2571 callback->printf_filtered (callback, "# real time taken %10.4f\n",
2572 timetaken);
2573 callback->printf_filtered (callback, "# virtual time taken %10.4f\n",
2574 virttime);
2575 callback->printf_filtered (callback, "# profiling size %10d\n",
2576 sim_profile_size);
2577 callback->printf_filtered (callback, "# profiling frequency %10d\n",
2578 saved_state.asregs.profile);
2579 callback->printf_filtered (callback, "# profile maxpc %10x\n",
2580 (1 << sim_profile_size) << PROFILE_SHIFT);
2581
2582 if (timetaken != 0)
2583 {
2584 callback->printf_filtered (callback, "# cycles/second %10d\n",
2585 (int) (saved_state.asregs.cycles / timetaken));
2586 callback->printf_filtered (callback, "# simulation ratio %10.4f\n",
2587 virttime / timetaken);
2588 }
2589}
2590
2591void
2592sim_set_profile (n)
2593 int n;
2594{
2595 saved_state.asregs.profile = n;
2596}
2597
2598void
2599sim_set_profile_size (n)
2600 int n;
2601{
2602 sim_profile_size = n;
2603}
2604
2605SIM_DESC
2606sim_open (kind, cb, abfd, argv)
2607 SIM_OPEN_KIND kind;
2608 host_callback *cb;
6b4a8935 2609 struct bfd *abfd;
c906108c
SS
2610 char **argv;
2611{
2612 char **p;
2613 int endian_set = 0;
63978407
JR
2614 int i;
2615 union
2616 {
2617 int i;
2618 short s[2];
2619 char c[4];
2620 }
2621 mem_word;
c906108c
SS
2622
2623 sim_kind = kind;
2624 myname = argv[0];
2625 callback = cb;
2626
2627 for (p = argv + 1; *p != NULL; ++p)
2628 {
2629 if (strcmp (*p, "-E") == 0)
2630 {
2631 ++p;
2632 if (*p == NULL)
2633 {
2634 /* FIXME: This doesn't use stderr, but then the rest of the
2635 file doesn't either. */
2636 callback->printf_filtered (callback, "Missing argument to `-E'.\n");
2637 return 0;
2638 }
2639 target_little_endian = strcmp (*p, "big") != 0;
2640 endian_set = 1;
2641 }
2642 else if (isdigit (**p))
2643 parse_and_set_memory_size (*p);
2644 }
2645
2646 if (abfd != NULL && ! endian_set)
2647 target_little_endian = ! bfd_big_endian (abfd);
2648
63978407
JR
2649 if (abfd)
2650 init_dsp (abfd);
2651
2652 for (i = 4; (i -= 2) >= 0; )
2653 mem_word.s[i >> 1] = i;
2654 global_endianw = mem_word.i >> (target_little_endian ? 0 : 16) & 0xffff;
2655
2656 for (i = 4; --i >= 0; )
2657 mem_word.c[i] = i;
2658 endianb = mem_word.i >> (target_little_endian ? 0 : 24) & 0xff;
2659
c906108c
SS
2660 /* fudge our descriptor for now */
2661 return (SIM_DESC) 1;
2662}
2663
2664static void
2665parse_and_set_memory_size (str)
60d847df 2666 const char *str;
c906108c
SS
2667{
2668 int n;
2669
2670 n = strtol (str, NULL, 10);
2671 if (n > 0 && n <= 24)
2672 sim_memory_size = n;
2673 else
2674 callback->printf_filtered (callback, "Bad memory size %d; must be 1 to 24, inclusive\n", n);
2675}
2676
2677void
2678sim_close (sd, quitting)
2679 SIM_DESC sd;
2680 int quitting;
2681{
2682 /* nothing to do */
2683}
2684
2685SIM_RC
2686sim_load (sd, prog, abfd, from_tty)
2687 SIM_DESC sd;
b2b255bd 2688 const char *prog;
c906108c
SS
2689 bfd *abfd;
2690 int from_tty;
2691{
2692 extern bfd *sim_load_file (); /* ??? Don't know where this should live. */
2693 bfd *prog_bfd;
2694
2695 prog_bfd = sim_load_file (sd, myname, callback, prog, abfd,
2696 sim_kind == SIM_OPEN_DEBUG,
2697 0, sim_write);
ae0a84af
CV
2698
2699 /* Set the bfd machine type. */
2700 if (prog_bfd)
2701 saved_state.asregs.bfd_mach = bfd_get_mach (prog_bfd);
2702 else if (abfd)
2703 saved_state.asregs.bfd_mach = bfd_get_mach (abfd);
2704 else
2705 saved_state.asregs.bfd_mach = 0;
2706
c906108c
SS
2707 if (prog_bfd == NULL)
2708 return SIM_RC_FAIL;
2709 if (abfd == NULL)
2710 bfd_close (prog_bfd);
2711 return SIM_RC_OK;
2712}
2713
2714SIM_RC
2715sim_create_inferior (sd, prog_bfd, argv, env)
2716 SIM_DESC sd;
6b4a8935 2717 struct bfd *prog_bfd;
c906108c
SS
2718 char **argv;
2719 char **env;
2720{
de0492b6 2721 /* Clear the registers. */
c906108c 2722 memset (&saved_state, 0,
87acb4a7 2723 (char*) &saved_state.asregs.end_of_registers - (char*) &saved_state);
de0492b6
AO
2724
2725 /* Set the PC. */
c906108c
SS
2726 if (prog_bfd != NULL)
2727 saved_state.asregs.pc = bfd_get_start_address (prog_bfd);
de0492b6 2728
ae0a84af
CV
2729 /* Set the bfd machine type. */
2730 if (prog_bfd != NULL)
2731 saved_state.asregs.bfd_mach = bfd_get_mach (prog_bfd);
2732
de0492b6
AO
2733 /* Record the program's arguments. */
2734 prog_argv = argv;
2735
c906108c
SS
2736 return SIM_RC_OK;
2737}
2738
2739void
2740sim_do_command (sd, cmd)
2741 SIM_DESC sd;
60d847df 2742 const char *cmd;
c906108c 2743{
60d847df 2744 const char *sms_cmd = "set-memory-size";
c906108c
SS
2745 int cmdsize;
2746
2747 if (cmd == NULL || *cmd == '\0')
2748 {
2749 cmd = "help";
2750 }
2751
2752 cmdsize = strlen (sms_cmd);
87acb4a7
MS
2753 if (strncmp (cmd, sms_cmd, cmdsize) == 0
2754 && strchr (" \t", cmd[cmdsize]) != NULL)
c906108c
SS
2755 {
2756 parse_and_set_memory_size (cmd + cmdsize + 1);
2757 }
2758 else if (strcmp (cmd, "help") == 0)
2759 {
87acb4a7
MS
2760 (callback->printf_filtered) (callback,
2761 "List of SH simulator commands:\n\n");
c906108c
SS
2762 (callback->printf_filtered) (callback, "set-memory-size <n> -- Set the number of address bits to use\n");
2763 (callback->printf_filtered) (callback, "\n");
2764 }
2765 else
2766 {
2767 (callback->printf_filtered) (callback, "Error: \"%s\" is not a valid SH simulator command.\n", cmd);
2768 }
2769}
2770
2771void
2772sim_set_callbacks (p)
2773 host_callback *p;
2774{
2775 callback = p;
2776}
af9f7da7
MF
2777
2778char **
3cb2ab1a 2779sim_complete_command (SIM_DESC sd, const char *text, const char *word)
af9f7da7
MF
2780{
2781 return NULL;
2782}
This page took 0.726109 seconds and 4 git commands to generate.