]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blame - sim/sh/interp.c
* symfile.c (symbol_file_add_main_1): Use inferior's
[thirdparty/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
476static void parse_and_set_memory_size PARAMS ((char *str));
c906108c 477static int IOMEM PARAMS ((int addr, int write, int value));
87acb4a7
MS
478static struct loop_bounds get_loop_bounds PARAMS ((int, int, unsigned char *,
479 unsigned char *, int, int));
480static void process_wlat_addr PARAMS ((int, int));
481static void process_wwat_addr PARAMS ((int, int));
482static void process_wbat_addr PARAMS ((int, int));
483static int process_rlat_addr PARAMS ((int));
484static int process_rwat_addr PARAMS ((int));
485static int process_rbat_addr PARAMS ((int));
63978407
JR
486static void INLINE wlat_fast PARAMS ((unsigned char *, int, int, int));
487static void INLINE wwat_fast PARAMS ((unsigned char *, int, int, int, int));
488static void INLINE wbat_fast PARAMS ((unsigned char *, int, int, int));
489static int INLINE rlat_fast PARAMS ((unsigned char *, int, int));
490static int INLINE rwat_fast PARAMS ((unsigned char *, int, int, int));
491static int INLINE rbat_fast PARAMS ((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) \
865 do { memstalls += ((((int) 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
1264void
1265control_c (sig, code, scp, addr)
1266 int sig;
1267 int code;
1268 char *scp;
1269 char *addr;
1270{
63978407 1271 raise_exception (SIGINT);
c906108c
SS
1272}
1273
1274static int
1275div1 (R, iRn2, iRn1/*, T*/)
1276 int *R;
1277 int iRn1;
1278 int iRn2;
1279 /* int T;*/
1280{
1281 unsigned long tmp0;
1282 unsigned char old_q, tmp1;
1283
1284 old_q = Q;
1285 SET_SR_Q ((unsigned char) ((0x80000000 & R[iRn1]) != 0));
1286 R[iRn1] <<= 1;
1287 R[iRn1] |= (unsigned long) T;
1288
1289 switch (old_q)
1290 {
1291 case 0:
1292 switch (M)
1293 {
1294 case 0:
1295 tmp0 = R[iRn1];
1296 R[iRn1] -= R[iRn2];
1297 tmp1 = (R[iRn1] > tmp0);
1298 switch (Q)
1299 {
1300 case 0:
1301 SET_SR_Q (tmp1);
1302 break;
1303 case 1:
1304 SET_SR_Q ((unsigned char) (tmp1 == 0));
1305 break;
1306 }
1307 break;
1308 case 1:
1309 tmp0 = R[iRn1];
1310 R[iRn1] += R[iRn2];
1311 tmp1 = (R[iRn1] < tmp0);
1312 switch (Q)
1313 {
1314 case 0:
1315 SET_SR_Q ((unsigned char) (tmp1 == 0));
1316 break;
1317 case 1:
1318 SET_SR_Q (tmp1);
1319 break;
1320 }
1321 break;
1322 }
1323 break;
1324 case 1:
1325 switch (M)
1326 {
1327 case 0:
1328 tmp0 = R[iRn1];
1329 R[iRn1] += R[iRn2];
1330 tmp1 = (R[iRn1] < tmp0);
1331 switch (Q)
1332 {
1333 case 0:
1334 SET_SR_Q (tmp1);
1335 break;
1336 case 1:
1337 SET_SR_Q ((unsigned char) (tmp1 == 0));
1338 break;
1339 }
1340 break;
1341 case 1:
1342 tmp0 = R[iRn1];
1343 R[iRn1] -= R[iRn2];
1344 tmp1 = (R[iRn1] > tmp0);
1345 switch (Q)
1346 {
1347 case 0:
1348 SET_SR_Q ((unsigned char) (tmp1 == 0));
1349 break;
1350 case 1:
1351 SET_SR_Q (tmp1);
1352 break;
1353 }
1354 break;
1355 }
1356 break;
1357 }
1358 /*T = (Q == M);*/
1359 SET_SR_T (Q == M);
1360 /*return T;*/
1361}
1362
1363static void
1364dmul (sign, rm, rn)
1365 int sign;
1366 unsigned int rm;
1367 unsigned int rn;
1368{
1369 unsigned long RnL, RnH;
1370 unsigned long RmL, RmH;
1371 unsigned long temp0, temp1, temp2, temp3;
1372 unsigned long Res2, Res1, Res0;
1373
1374 RnL = rn & 0xffff;
1375 RnH = (rn >> 16) & 0xffff;
1376 RmL = rm & 0xffff;
1377 RmH = (rm >> 16) & 0xffff;
1378 temp0 = RmL * RnL;
1379 temp1 = RmH * RnL;
1380 temp2 = RmL * RnH;
1381 temp3 = RmH * RnH;
1382 Res2 = 0;
1383 Res1 = temp1 + temp2;
1384 if (Res1 < temp1)
1385 Res2 += 0x00010000;
1386 temp1 = (Res1 << 16) & 0xffff0000;
1387 Res0 = temp0 + temp1;
1388 if (Res0 < temp0)
1389 Res2 += 1;
1390 Res2 += ((Res1 >> 16) & 0xffff) + temp3;
1391
1392 if (sign)
1393 {
1394 if (rn & 0x80000000)
1395 Res2 -= rm;
1396 if (rm & 0x80000000)
1397 Res2 -= rn;
1398 }
1399
1400 MACH = Res2;
1401 MACL = Res0;
1402}
1403
1404static void
63978407 1405macw (regs, memory, n, m, endianw)
c906108c
SS
1406 int *regs;
1407 unsigned char *memory;
1408 int m, n;
63978407 1409 int endianw;
c906108c 1410{
c906108c
SS
1411 long tempm, tempn;
1412 long prod, macl, sum;
1413
87acb4a7
MS
1414 tempm=RSWAT (regs[m]); regs[m]+=2;
1415 tempn=RSWAT (regs[n]); regs[n]+=2;
c906108c
SS
1416
1417 macl = MACL;
87acb4a7 1418 prod = (long) (short) tempm * (long) (short) tempn;
c906108c
SS
1419 sum = prod + macl;
1420 if (S)
1421 {
1422 if ((~(prod ^ macl) & (sum ^ prod)) < 0)
1423 {
1424 /* MACH's lsb is a sticky overflow bit. */
1425 MACH |= 1;
1426 /* Store the smallest negative number in MACL if prod is
1427 negative, and the largest positive number otherwise. */
1428 sum = 0x7fffffff + (prod < 0);
1429 }
1430 }
1431 else
1432 {
1433 long mach;
1434 /* Add to MACH the sign extended product, and carry from low sum. */
1435 mach = MACH + (-(prod < 0)) + ((unsigned long) sum < prod);
1436 /* Sign extend at 10:th bit in MACH. */
1437 MACH = (mach & 0x1ff) | -(mach & 0x200);
1438 }
1439 MACL = sum;
1440}
1441
d1789ace
MS
1442static void
1443macl (regs, memory, n, m)
1444 int *regs;
1445 unsigned char *memory;
1446 int m, n;
1447{
1448 long tempm, tempn;
f3876f69
AS
1449 long macl, mach;
1450 long long ans;
1451 long long mac64;
d1789ace 1452
87acb4a7 1453 tempm = RSLAT (regs[m]);
d1789ace
MS
1454 regs[m] += 4;
1455
87acb4a7 1456 tempn = RSLAT (regs[n]);
d1789ace
MS
1457 regs[n] += 4;
1458
1459 mach = MACH;
1460 macl = MACL;
1461
f3876f69
AS
1462 mac64 = ((long long) macl & 0xffffffff) |
1463 ((long long) mach & 0xffffffff) << 32;
d1789ace 1464
87acb4a7 1465 ans = (long long) tempm * (long long) tempn; /* Multiply 32bit * 32bit */
d1789ace 1466
f3876f69 1467 mac64 += ans; /* Accumulate 64bit + 64 bit */
d1789ace 1468
f3876f69
AS
1469 macl = (long) (mac64 & 0xffffffff);
1470 mach = (long) ((mac64 >> 32) & 0xffffffff);
d1789ace
MS
1471
1472 if (S) /* Store only 48 bits of the result */
1473 {
1474 if (mach < 0) /* Result is negative */
1475 {
1476 mach = mach & 0x0000ffff; /* Mask higher 16 bits */
1477 mach |= 0xffff8000; /* Sign extend higher 16 bits */
1478 }
1479 else
1480 mach = mach & 0x00007fff; /* Postive Result */
1481 }
1482
1483 MACL = macl;
1484 MACH = mach;
1485}
1486
ae0a84af
CV
1487enum {
1488 B_BCLR = 0,
1489 B_BSET = 1,
1490 B_BST = 2,
1491 B_BLD = 3,
1492 B_BAND = 4,
1493 B_BOR = 5,
1494 B_BXOR = 6,
1495 B_BLDNOT = 11,
1496 B_BANDNOT = 12,
1497 B_BORNOT = 13,
1498
1499 MOVB_RM = 0x0000,
1500 MOVW_RM = 0x1000,
1501 MOVL_RM = 0x2000,
1502 FMOV_RM = 0x3000,
1503 MOVB_MR = 0x4000,
1504 MOVW_MR = 0x5000,
1505 MOVL_MR = 0x6000,
1506 FMOV_MR = 0x7000,
1507 MOVU_BMR = 0x8000,
1508 MOVU_WMR = 0x9000,
1509};
1510
1511/* Do extended displacement move instructions. */
1512void
1513do_long_move_insn (int op, int disp12, int m, int n, int *thatlock)
86bc60eb 1514{
ae0a84af
CV
1515 int memstalls = 0;
1516 int thislock = *thatlock;
1517 int endianw = global_endianw;
1518 int *R = &(saved_state.asregs.regs[0]);
1519 unsigned char *memory = saved_state.asregs.memory;
1520 int maskb = ~((saved_state.asregs.msize - 1) & ~0);
1521 unsigned char *insn_ptr = PT2H (saved_state.asregs.pc);
1522
1523 switch (op) {
1524 case MOVB_RM: /* signed */
1525 WBAT (disp12 * 1 + R[n], R[m]);
1526 break;
1527 case MOVW_RM:
1528 WWAT (disp12 * 2 + R[n], R[m]);
1529 break;
1530 case MOVL_RM:
1531 WLAT (disp12 * 4 + R[n], R[m]);
1532 break;
1533 case FMOV_RM: /* floating point */
1534 if (FPSCR_SZ)
1535 {
1536 MA (1);
1537 WDAT (R[n] + 8 * disp12, m);
1538 }
1539 else
1540 WLAT (R[n] + 4 * disp12, FI (m));
1541 break;
1542 case MOVB_MR:
1543 R[n] = RSBAT (disp12 * 1 + R[m]);
1544 L (n);
1545 break;
1546 case MOVW_MR:
1547 R[n] = RSWAT (disp12 * 2 + R[m]);
1548 L (n);
1549 break;
1550 case MOVL_MR:
1551 R[n] = RLAT (disp12 * 4 + R[m]);
1552 L (n);
1553 break;
1554 case FMOV_MR:
1555 if (FPSCR_SZ) {
1556 MA (1);
1557 RDAT (R[m] + 8 * disp12, n);
1558 }
1559 else
1560 SET_FI (n, RLAT (R[m] + 4 * disp12));
1561 break;
1562 case MOVU_BMR: /* unsigned */
1563 R[n] = RBAT (disp12 * 1 + R[m]);
1564 L (n);
1565 break;
1566 case MOVU_WMR:
1567 R[n] = RWAT (disp12 * 2 + R[m]);
1568 L (n);
1569 break;
1570 default:
1571 RAISE_EXCEPTION (SIGINT);
1572 exit (1);
1573 }
1574 saved_state.asregs.memstalls += memstalls;
1575 *thatlock = thislock;
86bc60eb
MS
1576}
1577
ae0a84af
CV
1578/* Do binary logical bit-manipulation insns. */
1579void
1580do_blog_insn (int imm, int addr, int binop,
1581 unsigned char *memory, int maskb)
1582{
1583 int oldval = RBAT (addr);
1584
1585 switch (binop) {
1586 case B_BCLR: /* bclr.b */
1587 WBAT (addr, oldval & ~imm);
1588 break;
1589 case B_BSET: /* bset.b */
1590 WBAT (addr, oldval | imm);
1591 break;
1592 case B_BST: /* bst.b */
1593 if (T)
1594 WBAT (addr, oldval | imm);
1595 else
1596 WBAT (addr, oldval & ~imm);
1597 break;
1598 case B_BLD: /* bld.b */
1599 SET_SR_T ((oldval & imm) != 0);
1600 break;
1601 case B_BAND: /* band.b */
1602 SET_SR_T (T && ((oldval & imm) != 0));
1603 break;
1604 case B_BOR: /* bor.b */
1605 SET_SR_T (T || ((oldval & imm) != 0));
1606 break;
1607 case B_BXOR: /* bxor.b */
1608 SET_SR_T (T ^ ((oldval & imm) != 0));
1609 break;
1610 case B_BLDNOT: /* bldnot.b */
1611 SET_SR_T ((oldval & imm) == 0);
1612 break;
1613 case B_BANDNOT: /* bandnot.b */
1614 SET_SR_T (T && ((oldval & imm) == 0));
1615 break;
1616 case B_BORNOT: /* bornot.b */
1617 SET_SR_T (T || ((oldval & imm) == 0));
1618 break;
1619 }
1620}
794cd17b
JR
1621float
1622fsca_s (int in, double (*f) (double))
1623{
1624 double rad = ldexp ((in & 0xffff), -15) * 3.141592653589793238462643383;
1625 double result = (*f) (rad);
1626 double error, upper, lower, frac;
1627 int exp;
1628
1629 /* Search the value with the maximum error that is still within the
1630 architectural spec. */
1631 error = ldexp (1., -21);
1632 /* compensate for calculation inaccuracy by reducing error. */
1633 error = error - ldexp (1., -50);
1634 upper = result + error;
1635 frac = frexp (upper, &exp);
1636 upper = ldexp (floor (ldexp (frac, 24)), exp - 24);
1637 lower = result - error;
1638 frac = frexp (lower, &exp);
1639 lower = ldexp (ceil (ldexp (frac, 24)), exp - 24);
1640 return abs (upper - result) >= abs (lower - result) ? upper : lower;
1641}
1642
1643float
1644fsrra_s (float in)
1645{
1646 double result = 1. / sqrt (in);
1647 int exp;
1648 double frac, upper, lower, error, eps;
1649
1650 /* refine result */
1651 result = result - (result * result * in - 1) * 0.5 * result;
1652 /* Search the value with the maximum error that is still within the
1653 architectural spec. */
1654 frac = frexp (result, &exp);
1655 frac = ldexp (frac, 24);
87acb4a7 1656 error = 4.0; /* 1 << 24-1-21 */
794cd17b
JR
1657 /* use eps to compensate for possible 1 ulp error in our 'exact' result. */
1658 eps = ldexp (1., -29);
1659 upper = floor (frac + error - eps);
1660 if (upper > 16777216.)
1661 upper = floor ((frac + error - eps) * 0.5) * 2.;
1662 lower = ceil ((frac - error + eps) * 2) * .5;
1663 if (lower > 8388608.)
1664 lower = ceil (frac - error + eps);
1665 upper = ldexp (upper, exp - 24);
1666 lower = ldexp (lower, exp - 24);
1667 return upper - result >= result - lower ? upper : lower;
1668}
1669
ae0a84af
CV
1670
1671/* GET_LOOP_BOUNDS {EXTENDED}
1672 These two functions compute the actual starting and ending point
1673 of the repeat loop, based on the RS and RE registers (repeat start,
1674 repeat stop). The extended version is called for LDRC, and the
1675 regular version is called for SETRC. The difference is that for
1676 LDRC, the loop start and end instructions are literally the ones
1677 pointed to by RS and RE -- for SETRC, they're not (see docs). */
1678
1679static struct loop_bounds
1680get_loop_bounds_ext (rs, re, memory, mem_end, maskw, endianw)
1681 int rs, re;
1682 unsigned char *memory, *mem_end;
1683 int maskw, endianw;
1684{
1685 struct loop_bounds loop;
1686
1687 /* FIXME: should I verify RS < RE? */
1688 loop.start = PT2H (RS); /* FIXME not using the params? */
1689 loop.end = PT2H (RE & ~1); /* Ignore bit 0 of RE. */
1690 SKIP_INSN (loop.end);
1691 if (loop.end >= mem_end)
1692 loop.end = PT2H (0);
1693 return loop;
1694}
1695
63978407
JR
1696static struct loop_bounds
1697get_loop_bounds (rs, re, memory, mem_end, maskw, endianw)
1698 int rs, re;
1699 unsigned char *memory, *mem_end;
1700 int maskw, endianw;
1701{
1702 struct loop_bounds loop;
1703
1704 if (SR_RC)
1705 {
1706 if (RS >= RE)
1707 {
1708 loop.start = PT2H (RE - 4);
1709 SKIP_INSN (loop.start);
1710 loop.end = loop.start;
1711 if (RS - RE == 0)
1712 SKIP_INSN (loop.end);
1713 if (RS - RE <= 2)
1714 SKIP_INSN (loop.end);
1715 SKIP_INSN (loop.end);
1716 }
1717 else
1718 {
1719 loop.start = PT2H (RS);
1720 loop.end = PT2H (RE - 4);
1721 SKIP_INSN (loop.end);
1722 SKIP_INSN (loop.end);
1723 SKIP_INSN (loop.end);
1724 SKIP_INSN (loop.end);
1725 }
1726 if (loop.end >= mem_end)
1727 loop.end = PT2H (0);
1728 }
1729 else
1730 loop.end = PT2H (0);
1731
1732 return loop;
1733}
1734
87acb4a7 1735static void ppi_insn ();
63978407
JR
1736
1737#include "ppi.c"
1738
6a8492b5
JR
1739/* Provide calloc / free versions that use an anonymous mmap. This can
1740 significantly cut the start-up time when a large simulator memory is
1741 required, because pages are only zeroed on demand. */
1742#ifdef MAP_ANONYMOUS
1743void *
1744mcalloc (size_t nmemb, size_t size)
1745{
1746 void *page;
1747
1748 if (nmemb != 1)
1749 size *= nmemb;
1750 return mmap (0, size, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS,
1751 -1, 0);
1752}
1753
1754#define mfree(start,length) munmap ((start), (length))
1755#else
1756#define mcalloc calloc
1757#define mfree(start,length) free(start)
1758#endif
1759
c906108c
SS
1760/* Set the memory size to the power of two provided. */
1761
1762void
1763sim_size (power)
1764 int power;
1765
1766{
c906108c
SS
1767 sim_memory_size = power;
1768
1769 if (saved_state.asregs.memory)
1770 {
6a8492b5 1771 mfree (saved_state.asregs.memory, saved_state.asregs.msize);
c906108c
SS
1772 }
1773
6a8492b5
JR
1774 saved_state.asregs.msize = 1 << power;
1775
c906108c 1776 saved_state.asregs.memory =
6a8492b5 1777 (unsigned char *) mcalloc (1, saved_state.asregs.msize);
c906108c
SS
1778
1779 if (!saved_state.asregs.memory)
1780 {
1781 fprintf (stderr,
1782 "Not enough VM for simulation of %d bytes of RAM\n",
1783 saved_state.asregs.msize);
1784
1785 saved_state.asregs.msize = 1;
6a8492b5 1786 saved_state.asregs.memory = (unsigned char *) mcalloc (1, 1);
c906108c
SS
1787 }
1788}
1789
63978407
JR
1790static void
1791init_dsp (abfd)
6b4a8935 1792 struct bfd *abfd;
63978407
JR
1793{
1794 int was_dsp = target_dsp;
1795 unsigned long mach = bfd_get_mach (abfd);
1796
86bc60eb
MS
1797 if (mach == bfd_mach_sh_dsp ||
1798 mach == bfd_mach_sh4al_dsp ||
1799 mach == bfd_mach_sh3_dsp)
63978407
JR
1800 {
1801 int ram_area_size, xram_start, yram_start;
1802 int new_select;
1803
1804 target_dsp = 1;
1805 if (mach == bfd_mach_sh_dsp)
1806 {
1807 /* SH7410 (orig. sh-sdp):
1808 4KB each for X & Y memory;
1809 On-chip X RAM 0x0800f000-0x0800ffff
1810 On-chip Y RAM 0x0801f000-0x0801ffff */
1811 xram_start = 0x0800f000;
1812 ram_area_size = 0x1000;
1813 }
86bc60eb 1814 if (mach == bfd_mach_sh3_dsp || mach == bfd_mach_sh4al_dsp)
63978407
JR
1815 {
1816 /* SH7612:
1817 8KB each for X & Y memory;
1818 On-chip X RAM 0x1000e000-0x1000ffff
1819 On-chip Y RAM 0x1001e000-0x1001ffff */
1820 xram_start = 0x1000e000;
1821 ram_area_size = 0x2000;
1822 }
1823 yram_start = xram_start + 0x10000;
1824 new_select = ~(ram_area_size - 1);
1825 if (saved_state.asregs.xyram_select != new_select)
1826 {
1827 saved_state.asregs.xyram_select = new_select;
1828 free (saved_state.asregs.xmem);
1829 free (saved_state.asregs.ymem);
ae0a84af
CV
1830 saved_state.asregs.xmem =
1831 (unsigned char *) calloc (1, ram_area_size);
1832 saved_state.asregs.ymem =
1833 (unsigned char *) calloc (1, ram_area_size);
63978407
JR
1834
1835 /* Disable use of X / Y mmeory if not allocated. */
1836 if (! saved_state.asregs.xmem || ! saved_state.asregs.ymem)
1837 {
1838 saved_state.asregs.xyram_select = 0;
1839 if (saved_state.asregs.xmem)
1840 free (saved_state.asregs.xmem);
1841 if (saved_state.asregs.ymem)
1842 free (saved_state.asregs.ymem);
1843 }
1844 }
1845 saved_state.asregs.xram_start = xram_start;
1846 saved_state.asregs.yram_start = yram_start;
1847 saved_state.asregs.xmem_offset = saved_state.asregs.xmem - xram_start;
1848 saved_state.asregs.ymem_offset = saved_state.asregs.ymem - yram_start;
1849 }
1850 else
1851 {
1852 target_dsp = 0;
1853 if (saved_state.asregs.xyram_select)
1854 {
1855 saved_state.asregs.xyram_select = 0;
1856 free (saved_state.asregs.xmem);
1857 free (saved_state.asregs.ymem);
1858 }
1859 }
1860
1861 if (! saved_state.asregs.xyram_select)
1862 {
1863 saved_state.asregs.xram_start = 1;
1864 saved_state.asregs.yram_start = 1;
1865 }
1866
ae0a84af
CV
1867 if (saved_state.asregs.regstack == NULL)
1868 saved_state.asregs.regstack =
1869 calloc (512, sizeof *saved_state.asregs.regstack);
1870
63978407
JR
1871 if (target_dsp != was_dsp)
1872 {
1873 int i, tmp;
1874
3e511797 1875 for (i = (sizeof sh_dsp_table / sizeof sh_dsp_table[0]) - 1; i >= 0; i--)
63978407
JR
1876 {
1877 tmp = sh_jump_table[0xf000 + i];
1878 sh_jump_table[0xf000 + i] = sh_dsp_table[i];
1879 sh_dsp_table[i] = tmp;
1880 }
1881 }
1882}
1883
c906108c
SS
1884static void
1885init_pointers ()
1886{
1887 host_little_endian = 0;
87acb4a7 1888 * (char*) &host_little_endian = 1;
c906108c
SS
1889 host_little_endian &= 1;
1890
1891 if (saved_state.asregs.msize != 1 << sim_memory_size)
1892 {
1893 sim_size (sim_memory_size);
1894 }
1895
1896 if (saved_state.asregs.profile && !profile_file)
1897 {
1898 profile_file = fopen ("gmon.out", "wb");
1899 /* Seek to where to put the call arc data */
1900 nsamples = (1 << sim_profile_size);
1901
1902 fseek (profile_file, nsamples * 2 + 12, 0);
1903
1904 if (!profile_file)
1905 {
1906 fprintf (stderr, "Can't open gmon.out\n");
1907 }
1908 else
1909 {
1910 saved_state.asregs.profile_hist =
1911 (unsigned short *) calloc (64, (nsamples * sizeof (short) / 64));
1912 }
1913 }
1914}
1915
1916static void
1917dump_profile ()
1918{
1919 unsigned int minpc;
1920 unsigned int maxpc;
1921 unsigned short *p;
1922 int i;
1923
1924 p = saved_state.asregs.profile_hist;
1925 minpc = 0;
1926 maxpc = (1 << sim_profile_size);
1927
1928 fseek (profile_file, 0L, 0);
1929 swapout (minpc << PROFILE_SHIFT);
1930 swapout (maxpc << PROFILE_SHIFT);
1931 swapout (nsamples * 2 + 12);
1932 for (i = 0; i < nsamples; i++)
1933 swapout16 (saved_state.asregs.profile_hist[i]);
1934
1935}
1936
1937static void
1938gotcall (from, to)
1939 int from;
1940 int to;
1941{
1942 swapout (from);
1943 swapout (to);
1944 swapout (1);
1945}
1946
1947#define MMASKB ((saved_state.asregs.msize -1) & ~0)
1948
1949int
1950sim_stop (sd)
1951 SIM_DESC sd;
1952{
63978407 1953 raise_exception (SIGINT);
c906108c
SS
1954 return 1;
1955}
1956
1957void
1958sim_resume (sd, step, siggnal)
1959 SIM_DESC sd;
1960 int step, siggnal;
1961{
63978407
JR
1962 register unsigned char *insn_ptr;
1963 unsigned char *mem_end;
1964 struct loop_bounds loop;
c906108c
SS
1965 register int cycles = 0;
1966 register int stalls = 0;
1967 register int memstalls = 0;
1968 register int insts = 0;
1969 register int prevlock;
ae0a84af
CV
1970#if 1
1971 int thislock;
1972#else
c906108c 1973 register int thislock;
ae0a84af 1974#endif
c906108c
SS
1975 register unsigned int doprofile;
1976 register int pollcount = 0;
63978407
JR
1977 /* endianw is used for every insn fetch, hence it makes sense to cache it.
1978 endianb is used less often. */
1979 register int endianw = global_endianw;
c906108c
SS
1980
1981 int tick_start = get_now ();
1982 void (*prev) ();
1983 void (*prev_fpe) ();
c906108c 1984
3e511797 1985 register unsigned short *jump_table = sh_jump_table;
c906108c
SS
1986
1987 register int *R = &(saved_state.asregs.regs[0]);
1988 /*register int T;*/
63978407 1989#ifndef PR
c906108c 1990 register int PR;
63978407 1991#endif
c906108c 1992
63978407
JR
1993 register int maskb = ~((saved_state.asregs.msize - 1) & ~0);
1994 register int maskw = ~((saved_state.asregs.msize - 1) & ~1);
1995 register int maskl = ~((saved_state.asregs.msize - 1) & ~3);
c906108c
SS
1996 register unsigned char *memory;
1997 register unsigned int sbit = ((unsigned int) 1 << 31);
1998
1999 prev = signal (SIGINT, control_c);
2000 prev_fpe = signal (SIGFPE, SIG_IGN);
2001
2002 init_pointers ();
63978407 2003 saved_state.asregs.exception = 0;
c906108c
SS
2004
2005 memory = saved_state.asregs.memory;
63978407 2006 mem_end = memory + saved_state.asregs.msize;
c906108c 2007
86bc60eb
MS
2008 if (RE & 1)
2009 loop = get_loop_bounds_ext (RS, RE, memory, mem_end, maskw, endianw);
2010 else
2011 loop = get_loop_bounds (RS, RE, memory, mem_end, maskw, endianw);
2012
63978407
JR
2013 insn_ptr = PT2H (saved_state.asregs.pc);
2014 CHECK_INSN_PTR (insn_ptr);
c906108c 2015
63978407
JR
2016#ifndef PR
2017 PR = saved_state.asregs.sregs.named.pr;
2018#endif
c906108c
SS
2019 /*T = GET_SR () & SR_MASK_T;*/
2020 prevlock = saved_state.asregs.prevlock;
2021 thislock = saved_state.asregs.thislock;
2022 doprofile = saved_state.asregs.profile;
2023
2024 /* If profiling not enabled, disable it by asking for
2025 profiles infrequently. */
2026 if (doprofile == 0)
2027 doprofile = ~0;
2028
63978407
JR
2029 loop:
2030 if (step && insn_ptr < saved_state.asregs.insn_end)
2031 {
2032 if (saved_state.asregs.exception)
2033 /* This can happen if we've already been single-stepping and
2034 encountered a loop end. */
2035 saved_state.asregs.insn_end = insn_ptr;
2036 else
2037 {
2038 saved_state.asregs.exception = SIGTRAP;
2039 saved_state.asregs.insn_end = insn_ptr + 2;
2040 }
2041 }
2042
2043 while (insn_ptr < saved_state.asregs.insn_end)
c906108c 2044 {
63978407 2045 register unsigned int iword = RIAT (insn_ptr);
c906108c 2046 register unsigned int ult;
63978407
JR
2047 register unsigned char *nip = insn_ptr + 2;
2048
c906108c
SS
2049#ifndef ACE_FAST
2050 insts++;
2051#endif
2052 top:
ae0a84af
CV
2053 if (tracing)
2054 fprintf (stderr, "PC: %08x, insn: %04x\n", PH2T (insn_ptr), iword);
c906108c
SS
2055
2056#include "code.c"
2057
2058
ae0a84af 2059 in_delay_slot = 0;
63978407 2060 insn_ptr = nip;
c906108c
SS
2061
2062 if (--pollcount < 0)
2063 {
7a292a7a 2064 pollcount = POLL_QUIT_INTERVAL;
c906108c
SS
2065 if ((*callback->poll_quit) != NULL
2066 && (*callback->poll_quit) (callback))
2067 {
2068 sim_stop (sd);
2069 }
2070 }
2071
2072#ifndef ACE_FAST
2073 prevlock = thislock;
2074 thislock = 30;
2075 cycles++;
2076
2077 if (cycles >= doprofile)
2078 {
2079
2080 saved_state.asregs.cycles += doprofile;
2081 cycles -= doprofile;
2082 if (saved_state.asregs.profile_hist)
2083 {
63978407 2084 int n = PH2T (insn_ptr) >> PROFILE_SHIFT;
c906108c
SS
2085 if (n < nsamples)
2086 {
2087 int i = saved_state.asregs.profile_hist[n];
2088 if (i < 65000)
2089 saved_state.asregs.profile_hist[n] = i + 1;
2090 }
2091
2092 }
2093 }
2094#endif
2095 }
63978407
JR
2096 if (saved_state.asregs.insn_end == loop.end)
2097 {
2098 saved_state.asregs.cregs.named.sr += SR_RC_INCREMENT;
2099 if (SR_RC)
2100 insn_ptr = loop.start;
2101 else
2102 {
2103 saved_state.asregs.insn_end = mem_end;
2104 loop.end = PT2H (0);
2105 }
2106 goto loop;
2107 }
c906108c
SS
2108
2109 if (saved_state.asregs.exception == SIGILL
2110 || saved_state.asregs.exception == SIGBUS)
2111 {
63978407 2112 insn_ptr -= 2;
c906108c 2113 }
63978407
JR
2114 /* Check for SIGBUS due to insn fetch. */
2115 else if (! saved_state.asregs.exception)
dc9feb5c 2116 saved_state.asregs.exception = SIGBUS;
c906108c
SS
2117
2118 saved_state.asregs.ticks += get_now () - tick_start;
2119 saved_state.asregs.cycles += cycles;
2120 saved_state.asregs.stalls += stalls;
2121 saved_state.asregs.memstalls += memstalls;
2122 saved_state.asregs.insts += insts;
63978407
JR
2123 saved_state.asregs.pc = PH2T (insn_ptr);
2124#ifndef PR
2125 saved_state.asregs.sregs.named.pr = PR;
2126#endif
c906108c
SS
2127
2128 saved_state.asregs.prevlock = prevlock;
2129 saved_state.asregs.thislock = thislock;
2130
2131 if (profile_file)
2132 {
2133 dump_profile ();
2134 }
2135
2136 signal (SIGFPE, prev_fpe);
2137 signal (SIGINT, prev);
2138}
2139
2140int
2141sim_write (sd, addr, buffer, size)
2142 SIM_DESC sd;
2143 SIM_ADDR addr;
5558e7e6 2144 const unsigned char *buffer;
c906108c
SS
2145 int size;
2146{
2147 int i;
2148
2149 init_pointers ();
2150
2151 for (i = 0; i < size; i++)
2152 {
63978407 2153 saved_state.asregs.memory[(MMASKB & (addr + i)) ^ endianb] = buffer[i];
c906108c
SS
2154 }
2155 return size;
2156}
2157
2158int
2159sim_read (sd, addr, buffer, size)
2160 SIM_DESC sd;
2161 SIM_ADDR addr;
2162 unsigned char *buffer;
2163 int size;
2164{
2165 int i;
2166
2167 init_pointers ();
2168
2169 for (i = 0; i < size; i++)
2170 {
63978407 2171 buffer[i] = saved_state.asregs.memory[(MMASKB & (addr + i)) ^ endianb];
c906108c
SS
2172 }
2173 return size;
2174}
2175
ae0a84af
CV
2176static int gdb_bank_number;
2177enum {
2178 REGBANK_MACH = 15,
2179 REGBANK_IVN = 16,
2180 REGBANK_PR = 17,
2181 REGBANK_GBR = 18,
2182 REGBANK_MACL = 19
2183};
2184
c906108c
SS
2185int
2186sim_store_register (sd, rn, memory, length)
2187 SIM_DESC sd;
2188 int rn;
2189 unsigned char *memory;
2190 int length;
2191{
63978407
JR
2192 unsigned val;
2193
c906108c 2194 init_pointers ();
87acb4a7 2195 val = swap (* (int *) memory);
63978407
JR
2196 switch (rn)
2197 {
2f14585c
JR
2198 case SIM_SH_R0_REGNUM: case SIM_SH_R1_REGNUM: case SIM_SH_R2_REGNUM:
2199 case SIM_SH_R3_REGNUM: case SIM_SH_R4_REGNUM: case SIM_SH_R5_REGNUM:
2200 case SIM_SH_R6_REGNUM: case SIM_SH_R7_REGNUM: case SIM_SH_R8_REGNUM:
2201 case SIM_SH_R9_REGNUM: case SIM_SH_R10_REGNUM: case SIM_SH_R11_REGNUM:
2202 case SIM_SH_R12_REGNUM: case SIM_SH_R13_REGNUM: case SIM_SH_R14_REGNUM:
2203 case SIM_SH_R15_REGNUM:
63978407
JR
2204 saved_state.asregs.regs[rn] = val;
2205 break;
2f14585c 2206 case SIM_SH_PC_REGNUM:
63978407
JR
2207 saved_state.asregs.pc = val;
2208 break;
2f14585c 2209 case SIM_SH_PR_REGNUM:
63978407
JR
2210 PR = val;
2211 break;
2f14585c 2212 case SIM_SH_GBR_REGNUM:
63978407
JR
2213 GBR = val;
2214 break;
2f14585c 2215 case SIM_SH_VBR_REGNUM:
63978407
JR
2216 VBR = val;
2217 break;
2f14585c 2218 case SIM_SH_MACH_REGNUM:
63978407
JR
2219 MACH = val;
2220 break;
2f14585c 2221 case SIM_SH_MACL_REGNUM:
63978407
JR
2222 MACL = val;
2223 break;
2f14585c 2224 case SIM_SH_SR_REGNUM:
63978407
JR
2225 SET_SR (val);
2226 break;
2f14585c 2227 case SIM_SH_FPUL_REGNUM:
63978407
JR
2228 FPUL = val;
2229 break;
2f14585c 2230 case SIM_SH_FPSCR_REGNUM:
63978407
JR
2231 SET_FPSCR (val);
2232 break;
2f14585c
JR
2233 case SIM_SH_FR0_REGNUM: case SIM_SH_FR1_REGNUM: case SIM_SH_FR2_REGNUM:
2234 case SIM_SH_FR3_REGNUM: case SIM_SH_FR4_REGNUM: case SIM_SH_FR5_REGNUM:
2235 case SIM_SH_FR6_REGNUM: case SIM_SH_FR7_REGNUM: case SIM_SH_FR8_REGNUM:
2236 case SIM_SH_FR9_REGNUM: case SIM_SH_FR10_REGNUM: case SIM_SH_FR11_REGNUM:
2237 case SIM_SH_FR12_REGNUM: case SIM_SH_FR13_REGNUM: case SIM_SH_FR14_REGNUM:
2238 case SIM_SH_FR15_REGNUM:
2239 SET_FI (rn - SIM_SH_FR0_REGNUM, val);
2240 break;
2241 case SIM_SH_DSR_REGNUM:
2242 DSR = val;
2243 break;
2244 case SIM_SH_A0G_REGNUM:
2245 A0G = val;
2246 break;
2247 case SIM_SH_A0_REGNUM:
2248 A0 = val;
2249 break;
2250 case SIM_SH_A1G_REGNUM:
2251 A1G = val;
2252 break;
2253 case SIM_SH_A1_REGNUM:
2254 A1 = val;
2255 break;
2256 case SIM_SH_M0_REGNUM:
2257 M0 = val;
2258 break;
2259 case SIM_SH_M1_REGNUM:
2260 M1 = val;
2261 break;
2262 case SIM_SH_X0_REGNUM:
2263 X0 = val;
2264 break;
2265 case SIM_SH_X1_REGNUM:
2266 X1 = val;
2267 break;
2268 case SIM_SH_Y0_REGNUM:
2269 Y0 = val;
2270 break;
2271 case SIM_SH_Y1_REGNUM:
2272 Y1 = val;
2273 break;
2274 case SIM_SH_MOD_REGNUM:
2275 SET_MOD (val);
2276 break;
2277 case SIM_SH_RS_REGNUM:
2278 RS = val;
2279 break;
2280 case SIM_SH_RE_REGNUM:
2281 RE = val;
2282 break;
2283 case SIM_SH_SSR_REGNUM:
63978407
JR
2284 SSR = val;
2285 break;
2f14585c 2286 case SIM_SH_SPC_REGNUM:
63978407
JR
2287 SPC = val;
2288 break;
2289 /* The rn_bank idiosyncracies are not due to hardware differences, but to
2290 a weird aliasing naming scheme for sh3 / sh3e / sh4. */
2f14585c
JR
2291 case SIM_SH_R0_BANK0_REGNUM: case SIM_SH_R1_BANK0_REGNUM:
2292 case SIM_SH_R2_BANK0_REGNUM: case SIM_SH_R3_BANK0_REGNUM:
2293 case SIM_SH_R4_BANK0_REGNUM: case SIM_SH_R5_BANK0_REGNUM:
2294 case SIM_SH_R6_BANK0_REGNUM: case SIM_SH_R7_BANK0_REGNUM:
ae0a84af
CV
2295 if (saved_state.asregs.bfd_mach == bfd_mach_sh2a)
2296 {
2297 rn -= SIM_SH_R0_BANK0_REGNUM;
2298 saved_state.asregs.regstack[gdb_bank_number].regs[rn] = val;
2299 }
2300 else
63978407 2301 if (SR_MD && SR_RB)
2f14585c 2302 Rn_BANK (rn - SIM_SH_R0_BANK0_REGNUM) = val;
63978407 2303 else
2f14585c 2304 saved_state.asregs.regs[rn - SIM_SH_R0_BANK0_REGNUM] = val;
63978407 2305 break;
2f14585c
JR
2306 case SIM_SH_R0_BANK1_REGNUM: case SIM_SH_R1_BANK1_REGNUM:
2307 case SIM_SH_R2_BANK1_REGNUM: case SIM_SH_R3_BANK1_REGNUM:
2308 case SIM_SH_R4_BANK1_REGNUM: case SIM_SH_R5_BANK1_REGNUM:
2309 case SIM_SH_R6_BANK1_REGNUM: case SIM_SH_R7_BANK1_REGNUM:
ae0a84af
CV
2310 if (saved_state.asregs.bfd_mach == bfd_mach_sh2a)
2311 {
2312 rn -= SIM_SH_R0_BANK1_REGNUM;
2313 saved_state.asregs.regstack[gdb_bank_number].regs[rn + 8] = val;
2314 }
2315 else
2f14585c
JR
2316 if (SR_MD && SR_RB)
2317 saved_state.asregs.regs[rn - SIM_SH_R0_BANK1_REGNUM] = val;
63978407 2318 else
2f14585c
JR
2319 Rn_BANK (rn - SIM_SH_R0_BANK1_REGNUM) = val;
2320 break;
2321 case SIM_SH_R0_BANK_REGNUM: case SIM_SH_R1_BANK_REGNUM:
2322 case SIM_SH_R2_BANK_REGNUM: case SIM_SH_R3_BANK_REGNUM:
2323 case SIM_SH_R4_BANK_REGNUM: case SIM_SH_R5_BANK_REGNUM:
2324 case SIM_SH_R6_BANK_REGNUM: case SIM_SH_R7_BANK_REGNUM:
2325 SET_Rn_BANK (rn - SIM_SH_R0_BANK_REGNUM, val);
63978407 2326 break;
ae0a84af
CV
2327 case SIM_SH_TBR_REGNUM:
2328 TBR = val;
2329 break;
2330 case SIM_SH_IBNR_REGNUM:
2331 IBNR = val;
2332 break;
2333 case SIM_SH_IBCR_REGNUM:
2334 IBCR = val;
2335 break;
2336 case SIM_SH_BANK_REGNUM:
2337 /* This is a pseudo-register maintained just for gdb.
2338 It tells us what register bank gdb would like to read/write. */
2339 gdb_bank_number = val;
2340 break;
2341 case SIM_SH_BANK_MACL_REGNUM:
2342 saved_state.asregs.regstack[gdb_bank_number].regs[REGBANK_MACL] = val;
2343 break;
2344 case SIM_SH_BANK_GBR_REGNUM:
2345 saved_state.asregs.regstack[gdb_bank_number].regs[REGBANK_GBR] = val;
2346 break;
2347 case SIM_SH_BANK_PR_REGNUM:
2348 saved_state.asregs.regstack[gdb_bank_number].regs[REGBANK_PR] = val;
2349 break;
2350 case SIM_SH_BANK_IVN_REGNUM:
2351 saved_state.asregs.regstack[gdb_bank_number].regs[REGBANK_IVN] = val;
2352 break;
2353 case SIM_SH_BANK_MACH_REGNUM:
2354 saved_state.asregs.regstack[gdb_bank_number].regs[REGBANK_MACH] = val;
2355 break;
63978407
JR
2356 default:
2357 return 0;
2358 }
c906108c
SS
2359 return -1;
2360}
2361
2362int
2363sim_fetch_register (sd, rn, memory, length)
2364 SIM_DESC sd;
2365 int rn;
2366 unsigned char *memory;
2367 int length;
2368{
63978407
JR
2369 int val;
2370
c906108c 2371 init_pointers ();
63978407
JR
2372 switch (rn)
2373 {
2f14585c
JR
2374 case SIM_SH_R0_REGNUM: case SIM_SH_R1_REGNUM: case SIM_SH_R2_REGNUM:
2375 case SIM_SH_R3_REGNUM: case SIM_SH_R4_REGNUM: case SIM_SH_R5_REGNUM:
2376 case SIM_SH_R6_REGNUM: case SIM_SH_R7_REGNUM: case SIM_SH_R8_REGNUM:
2377 case SIM_SH_R9_REGNUM: case SIM_SH_R10_REGNUM: case SIM_SH_R11_REGNUM:
2378 case SIM_SH_R12_REGNUM: case SIM_SH_R13_REGNUM: case SIM_SH_R14_REGNUM:
2379 case SIM_SH_R15_REGNUM:
63978407
JR
2380 val = saved_state.asregs.regs[rn];
2381 break;
2f14585c 2382 case SIM_SH_PC_REGNUM:
63978407
JR
2383 val = saved_state.asregs.pc;
2384 break;
2f14585c 2385 case SIM_SH_PR_REGNUM:
63978407
JR
2386 val = PR;
2387 break;
2f14585c 2388 case SIM_SH_GBR_REGNUM:
63978407
JR
2389 val = GBR;
2390 break;
2f14585c 2391 case SIM_SH_VBR_REGNUM:
63978407
JR
2392 val = VBR;
2393 break;
2f14585c 2394 case SIM_SH_MACH_REGNUM:
63978407
JR
2395 val = MACH;
2396 break;
2f14585c 2397 case SIM_SH_MACL_REGNUM:
63978407
JR
2398 val = MACL;
2399 break;
2f14585c 2400 case SIM_SH_SR_REGNUM:
63978407
JR
2401 val = GET_SR ();
2402 break;
2f14585c 2403 case SIM_SH_FPUL_REGNUM:
63978407
JR
2404 val = FPUL;
2405 break;
2f14585c 2406 case SIM_SH_FPSCR_REGNUM:
63978407
JR
2407 val = GET_FPSCR ();
2408 break;
2f14585c
JR
2409 case SIM_SH_FR0_REGNUM: case SIM_SH_FR1_REGNUM: case SIM_SH_FR2_REGNUM:
2410 case SIM_SH_FR3_REGNUM: case SIM_SH_FR4_REGNUM: case SIM_SH_FR5_REGNUM:
2411 case SIM_SH_FR6_REGNUM: case SIM_SH_FR7_REGNUM: case SIM_SH_FR8_REGNUM:
2412 case SIM_SH_FR9_REGNUM: case SIM_SH_FR10_REGNUM: case SIM_SH_FR11_REGNUM:
2413 case SIM_SH_FR12_REGNUM: case SIM_SH_FR13_REGNUM: case SIM_SH_FR14_REGNUM:
2414 case SIM_SH_FR15_REGNUM:
2415 val = FI (rn - SIM_SH_FR0_REGNUM);
63978407 2416 break;
2f14585c
JR
2417 case SIM_SH_DSR_REGNUM:
2418 val = DSR;
63978407 2419 break;
2f14585c
JR
2420 case SIM_SH_A0G_REGNUM:
2421 val = SEXT (A0G);
63978407 2422 break;
2f14585c
JR
2423 case SIM_SH_A0_REGNUM:
2424 val = A0;
63978407 2425 break;
2f14585c
JR
2426 case SIM_SH_A1G_REGNUM:
2427 val = SEXT (A1G);
63978407 2428 break;
2f14585c
JR
2429 case SIM_SH_A1_REGNUM:
2430 val = A1;
63978407 2431 break;
2f14585c
JR
2432 case SIM_SH_M0_REGNUM:
2433 val = M0;
63978407 2434 break;
2f14585c
JR
2435 case SIM_SH_M1_REGNUM:
2436 val = M1;
63978407 2437 break;
2f14585c
JR
2438 case SIM_SH_X0_REGNUM:
2439 val = X0;
63978407 2440 break;
2f14585c
JR
2441 case SIM_SH_X1_REGNUM:
2442 val = X1;
63978407 2443 break;
2f14585c
JR
2444 case SIM_SH_Y0_REGNUM:
2445 val = Y0;
63978407 2446 break;
2f14585c
JR
2447 case SIM_SH_Y1_REGNUM:
2448 val = Y1;
63978407 2449 break;
2f14585c
JR
2450 case SIM_SH_MOD_REGNUM:
2451 val = MOD;
2452 break;
2453 case SIM_SH_RS_REGNUM:
2454 val = RS;
2455 break;
2456 case SIM_SH_RE_REGNUM:
2457 val = RE;
2458 break;
2459 case SIM_SH_SSR_REGNUM:
63978407
JR
2460 val = SSR;
2461 break;
2f14585c 2462 case SIM_SH_SPC_REGNUM:
63978407
JR
2463 val = SPC;
2464 break;
2465 /* The rn_bank idiosyncracies are not due to hardware differences, but to
2466 a weird aliasing naming scheme for sh3 / sh3e / sh4. */
2f14585c
JR
2467 case SIM_SH_R0_BANK0_REGNUM: case SIM_SH_R1_BANK0_REGNUM:
2468 case SIM_SH_R2_BANK0_REGNUM: case SIM_SH_R3_BANK0_REGNUM:
2469 case SIM_SH_R4_BANK0_REGNUM: case SIM_SH_R5_BANK0_REGNUM:
2470 case SIM_SH_R6_BANK0_REGNUM: case SIM_SH_R7_BANK0_REGNUM:
ae0a84af
CV
2471 if (saved_state.asregs.bfd_mach == bfd_mach_sh2a)
2472 {
2473 rn -= SIM_SH_R0_BANK0_REGNUM;
2474 val = saved_state.asregs.regstack[gdb_bank_number].regs[rn];
2475 }
2476 else
2f14585c
JR
2477 val = (SR_MD && SR_RB
2478 ? Rn_BANK (rn - SIM_SH_R0_BANK0_REGNUM)
2479 : saved_state.asregs.regs[rn - SIM_SH_R0_BANK0_REGNUM]);
2480 break;
2481 case SIM_SH_R0_BANK1_REGNUM: case SIM_SH_R1_BANK1_REGNUM:
2482 case SIM_SH_R2_BANK1_REGNUM: case SIM_SH_R3_BANK1_REGNUM:
2483 case SIM_SH_R4_BANK1_REGNUM: case SIM_SH_R5_BANK1_REGNUM:
2484 case SIM_SH_R6_BANK1_REGNUM: case SIM_SH_R7_BANK1_REGNUM:
ae0a84af
CV
2485 if (saved_state.asregs.bfd_mach == bfd_mach_sh2a)
2486 {
2487 rn -= SIM_SH_R0_BANK1_REGNUM;
2488 val = saved_state.asregs.regstack[gdb_bank_number].regs[rn + 8];
2489 }
2490 else
2f14585c
JR
2491 val = (! SR_MD || ! SR_RB
2492 ? Rn_BANK (rn - SIM_SH_R0_BANK1_REGNUM)
2493 : saved_state.asregs.regs[rn - SIM_SH_R0_BANK1_REGNUM]);
2494 break;
2495 case SIM_SH_R0_BANK_REGNUM: case SIM_SH_R1_BANK_REGNUM:
2496 case SIM_SH_R2_BANK_REGNUM: case SIM_SH_R3_BANK_REGNUM:
2497 case SIM_SH_R4_BANK_REGNUM: case SIM_SH_R5_BANK_REGNUM:
2498 case SIM_SH_R6_BANK_REGNUM: case SIM_SH_R7_BANK_REGNUM:
2499 val = Rn_BANK (rn - SIM_SH_R0_BANK_REGNUM);
63978407 2500 break;
ae0a84af
CV
2501 case SIM_SH_TBR_REGNUM:
2502 val = TBR;
2503 break;
2504 case SIM_SH_IBNR_REGNUM:
2505 val = IBNR;
2506 break;
2507 case SIM_SH_IBCR_REGNUM:
2508 val = IBCR;
2509 break;
2510 case SIM_SH_BANK_REGNUM:
2511 /* This is a pseudo-register maintained just for gdb.
2512 It tells us what register bank gdb would like to read/write. */
2513 val = gdb_bank_number;
2514 break;
2515 case SIM_SH_BANK_MACL_REGNUM:
2516 val = saved_state.asregs.regstack[gdb_bank_number].regs[REGBANK_MACL];
2517 break;
2518 case SIM_SH_BANK_GBR_REGNUM:
2519 val = saved_state.asregs.regstack[gdb_bank_number].regs[REGBANK_GBR];
2520 break;
2521 case SIM_SH_BANK_PR_REGNUM:
2522 val = saved_state.asregs.regstack[gdb_bank_number].regs[REGBANK_PR];
2523 break;
2524 case SIM_SH_BANK_IVN_REGNUM:
2525 val = saved_state.asregs.regstack[gdb_bank_number].regs[REGBANK_IVN];
2526 break;
2527 case SIM_SH_BANK_MACH_REGNUM:
2528 val = saved_state.asregs.regstack[gdb_bank_number].regs[REGBANK_MACH];
2529 break;
63978407
JR
2530 default:
2531 return 0;
2532 }
2533 * (int *) memory = swap (val);
c906108c
SS
2534 return -1;
2535}
2536
2537int
2538sim_trace (sd)
2539 SIM_DESC sd;
2540{
ae0a84af
CV
2541 tracing = 1;
2542 sim_resume (sd, 0, 0);
2543 tracing = 0;
2544 return 1;
c906108c
SS
2545}
2546
2547void
2548sim_stop_reason (sd, reason, sigrc)
2549 SIM_DESC sd;
2550 enum sim_stop *reason;
2551 int *sigrc;
2552{
2553 /* The SH simulator uses SIGQUIT to indicate that the program has
2554 exited, so we must check for it here and translate it to exit. */
2555 if (saved_state.asregs.exception == SIGQUIT)
2556 {
2557 *reason = sim_exited;
2558 *sigrc = saved_state.asregs.regs[5];
2559 }
2560 else
2561 {
2562 *reason = sim_stopped;
2563 *sigrc = saved_state.asregs.exception;
2564 }
2565}
2566
2567void
2568sim_info (sd, verbose)
2569 SIM_DESC sd;
2570 int verbose;
2571{
87acb4a7
MS
2572 double timetaken =
2573 (double) saved_state.asregs.ticks / (double) now_persec ();
c906108c
SS
2574 double virttime = saved_state.asregs.cycles / 36.0e6;
2575
2576 callback->printf_filtered (callback, "\n\n# instructions executed %10d\n",
2577 saved_state.asregs.insts);
2578 callback->printf_filtered (callback, "# cycles %10d\n",
2579 saved_state.asregs.cycles);
2580 callback->printf_filtered (callback, "# pipeline stalls %10d\n",
2581 saved_state.asregs.stalls);
2582 callback->printf_filtered (callback, "# misaligned load/store %10d\n",
2583 saved_state.asregs.memstalls);
2584 callback->printf_filtered (callback, "# real time taken %10.4f\n",
2585 timetaken);
2586 callback->printf_filtered (callback, "# virtual time taken %10.4f\n",
2587 virttime);
2588 callback->printf_filtered (callback, "# profiling size %10d\n",
2589 sim_profile_size);
2590 callback->printf_filtered (callback, "# profiling frequency %10d\n",
2591 saved_state.asregs.profile);
2592 callback->printf_filtered (callback, "# profile maxpc %10x\n",
2593 (1 << sim_profile_size) << PROFILE_SHIFT);
2594
2595 if (timetaken != 0)
2596 {
2597 callback->printf_filtered (callback, "# cycles/second %10d\n",
2598 (int) (saved_state.asregs.cycles / timetaken));
2599 callback->printf_filtered (callback, "# simulation ratio %10.4f\n",
2600 virttime / timetaken);
2601 }
2602}
2603
2604void
2605sim_set_profile (n)
2606 int n;
2607{
2608 saved_state.asregs.profile = n;
2609}
2610
2611void
2612sim_set_profile_size (n)
2613 int n;
2614{
2615 sim_profile_size = n;
2616}
2617
2618SIM_DESC
2619sim_open (kind, cb, abfd, argv)
2620 SIM_OPEN_KIND kind;
2621 host_callback *cb;
6b4a8935 2622 struct bfd *abfd;
c906108c
SS
2623 char **argv;
2624{
2625 char **p;
2626 int endian_set = 0;
63978407
JR
2627 int i;
2628 union
2629 {
2630 int i;
2631 short s[2];
2632 char c[4];
2633 }
2634 mem_word;
c906108c
SS
2635
2636 sim_kind = kind;
2637 myname = argv[0];
2638 callback = cb;
2639
2640 for (p = argv + 1; *p != NULL; ++p)
2641 {
2642 if (strcmp (*p, "-E") == 0)
2643 {
2644 ++p;
2645 if (*p == NULL)
2646 {
2647 /* FIXME: This doesn't use stderr, but then the rest of the
2648 file doesn't either. */
2649 callback->printf_filtered (callback, "Missing argument to `-E'.\n");
2650 return 0;
2651 }
2652 target_little_endian = strcmp (*p, "big") != 0;
2653 endian_set = 1;
2654 }
2655 else if (isdigit (**p))
2656 parse_and_set_memory_size (*p);
2657 }
2658
2659 if (abfd != NULL && ! endian_set)
2660 target_little_endian = ! bfd_big_endian (abfd);
2661
63978407
JR
2662 if (abfd)
2663 init_dsp (abfd);
2664
2665 for (i = 4; (i -= 2) >= 0; )
2666 mem_word.s[i >> 1] = i;
2667 global_endianw = mem_word.i >> (target_little_endian ? 0 : 16) & 0xffff;
2668
2669 for (i = 4; --i >= 0; )
2670 mem_word.c[i] = i;
2671 endianb = mem_word.i >> (target_little_endian ? 0 : 24) & 0xff;
2672
c906108c
SS
2673 /* fudge our descriptor for now */
2674 return (SIM_DESC) 1;
2675}
2676
2677static void
2678parse_and_set_memory_size (str)
2679 char *str;
2680{
2681 int n;
2682
2683 n = strtol (str, NULL, 10);
2684 if (n > 0 && n <= 24)
2685 sim_memory_size = n;
2686 else
2687 callback->printf_filtered (callback, "Bad memory size %d; must be 1 to 24, inclusive\n", n);
2688}
2689
2690void
2691sim_close (sd, quitting)
2692 SIM_DESC sd;
2693 int quitting;
2694{
2695 /* nothing to do */
2696}
2697
2698SIM_RC
2699sim_load (sd, prog, abfd, from_tty)
2700 SIM_DESC sd;
2701 char *prog;
2702 bfd *abfd;
2703 int from_tty;
2704{
2705 extern bfd *sim_load_file (); /* ??? Don't know where this should live. */
2706 bfd *prog_bfd;
2707
2708 prog_bfd = sim_load_file (sd, myname, callback, prog, abfd,
2709 sim_kind == SIM_OPEN_DEBUG,
2710 0, sim_write);
ae0a84af
CV
2711
2712 /* Set the bfd machine type. */
2713 if (prog_bfd)
2714 saved_state.asregs.bfd_mach = bfd_get_mach (prog_bfd);
2715 else if (abfd)
2716 saved_state.asregs.bfd_mach = bfd_get_mach (abfd);
2717 else
2718 saved_state.asregs.bfd_mach = 0;
2719
c906108c
SS
2720 if (prog_bfd == NULL)
2721 return SIM_RC_FAIL;
2722 if (abfd == NULL)
2723 bfd_close (prog_bfd);
2724 return SIM_RC_OK;
2725}
2726
2727SIM_RC
2728sim_create_inferior (sd, prog_bfd, argv, env)
2729 SIM_DESC sd;
6b4a8935 2730 struct bfd *prog_bfd;
c906108c
SS
2731 char **argv;
2732 char **env;
2733{
de0492b6 2734 /* Clear the registers. */
c906108c 2735 memset (&saved_state, 0,
87acb4a7 2736 (char*) &saved_state.asregs.end_of_registers - (char*) &saved_state);
de0492b6
AO
2737
2738 /* Set the PC. */
c906108c
SS
2739 if (prog_bfd != NULL)
2740 saved_state.asregs.pc = bfd_get_start_address (prog_bfd);
de0492b6 2741
ae0a84af
CV
2742 /* Set the bfd machine type. */
2743 if (prog_bfd != NULL)
2744 saved_state.asregs.bfd_mach = bfd_get_mach (prog_bfd);
2745
de0492b6
AO
2746 /* Record the program's arguments. */
2747 prog_argv = argv;
2748
c906108c
SS
2749 return SIM_RC_OK;
2750}
2751
2752void
2753sim_do_command (sd, cmd)
2754 SIM_DESC sd;
2755 char *cmd;
2756{
2757 char *sms_cmd = "set-memory-size";
2758 int cmdsize;
2759
2760 if (cmd == NULL || *cmd == '\0')
2761 {
2762 cmd = "help";
2763 }
2764
2765 cmdsize = strlen (sms_cmd);
87acb4a7
MS
2766 if (strncmp (cmd, sms_cmd, cmdsize) == 0
2767 && strchr (" \t", cmd[cmdsize]) != NULL)
c906108c
SS
2768 {
2769 parse_and_set_memory_size (cmd + cmdsize + 1);
2770 }
2771 else if (strcmp (cmd, "help") == 0)
2772 {
87acb4a7
MS
2773 (callback->printf_filtered) (callback,
2774 "List of SH simulator commands:\n\n");
c906108c
SS
2775 (callback->printf_filtered) (callback, "set-memory-size <n> -- Set the number of address bits to use\n");
2776 (callback->printf_filtered) (callback, "\n");
2777 }
2778 else
2779 {
2780 (callback->printf_filtered) (callback, "Error: \"%s\" is not a valid SH simulator command.\n", cmd);
2781 }
2782}
2783
2784void
2785sim_set_callbacks (p)
2786 host_callback *p;
2787{
2788 callback = p;
2789}
af9f7da7
MF
2790
2791char **
2792sim_complete_command (SIM_DESC sd, char *text, char *word)
2793{
2794 return NULL;
2795}