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