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