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