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