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