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