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