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