*/
-#include "config.h"
+/* This must come before any other includes. */
+#include "defs.h"
#include <ctype.h>
#include <stdio.h>
#include <errno.h>
#include <signal.h>
-#ifdef HAVE_UNISTD_H
#include <unistd.h>
-#endif
#ifdef HAVE_MMAP
#include <sys/mman.h>
# ifndef MAP_FAILED
#endif
#include <time.h>
#include <sys/time.h>
-#ifndef _WIN32
+#ifdef HAVE_UTIME_H
#include <utime.h>
+#endif
+#ifndef _WIN32
#include <sys/wait.h>
#endif
#include "bfd.h"
#include "sim/callback.h"
#include "sim/sim.h"
-#include "gdb/sim-sh.h"
+#include "sim/sim-sh.h"
#include "sim-main.h"
#include "sim-base.h"
#include "sim-options.h"
-#include "targ-vals.h"
+#include "target-newlib-syscall.h"
+
+#include "sh-sim.h"
#include <math.h>
#ifdef _WIN32
#include <float.h> /* Needed for _isnan() */
+#ifndef isnan
#define isnan _isnan
#endif
+#endif
#ifndef SIGBUS
#define SIGBUS SIGSEGV
#define UR (unsigned int) R
#define UR (unsigned int) R
#define SR0 saved_state.asregs.regs[0]
-#define CREG(n) (saved_state.asregs.cregs.i[(n)])
-#define GBR saved_state.asregs.cregs.named.gbr
-#define VBR saved_state.asregs.cregs.named.vbr
-#define DBR saved_state.asregs.cregs.named.dbr
-#define TBR saved_state.asregs.cregs.named.tbr
-#define IBCR saved_state.asregs.cregs.named.ibcr
-#define IBNR saved_state.asregs.cregs.named.ibnr
-#define BANKN (saved_state.asregs.cregs.named.ibnr & 0x1ff)
-#define ME ((saved_state.asregs.cregs.named.ibnr >> 14) & 0x3)
-#define SSR saved_state.asregs.cregs.named.ssr
-#define SPC saved_state.asregs.cregs.named.spc
-#define SGR saved_state.asregs.cregs.named.sgr
-#define SREG(n) (saved_state.asregs.sregs.i[(n)])
-#define MACH saved_state.asregs.sregs.named.mach
-#define MACL saved_state.asregs.sregs.named.macl
-#define PR saved_state.asregs.sregs.named.pr
-#define FPUL saved_state.asregs.sregs.named.fpul
+#define CREG(n) (saved_state.asregs.cregs[(n)])
+#define GBR saved_state.asregs.gbr
+#define VBR saved_state.asregs.vbr
+#define DBR saved_state.asregs.dbr
+#define TBR saved_state.asregs.tbr
+#define IBCR saved_state.asregs.ibcr
+#define IBNR saved_state.asregs.ibnr
+#define BANKN (saved_state.asregs.ibnr & 0x1ff)
+#define ME ((saved_state.asregs.ibnr >> 14) & 0x3)
+#define SSR saved_state.asregs.ssr
+#define SPC saved_state.asregs.spc
+#define SGR saved_state.asregs.sgr
+#define SREG(n) (saved_state.asregs.sregs[(n)])
+#define MACH saved_state.asregs.mach
+#define MACL saved_state.asregs.macl
+#define PR saved_state.asregs.pr
+#define FPUL saved_state.asregs.fpul
#define PC insn_ptr
/* Alternate bank of registers r0-r7 */
/* Note: code controling SR handles flips between BANK0 and BANK1 */
-#define Rn_BANK(n) (saved_state.asregs.cregs.named.bank[(n)])
-#define SET_Rn_BANK(n, EXP) do { saved_state.asregs.cregs.named.bank[(n)] = (EXP); } while (0)
+#define Rn_BANK(n) (saved_state.asregs.bank[(n)])
+#define SET_Rn_BANK(n, EXP) do { saved_state.asregs.bank[(n)] = (EXP); } while (0)
/* Manipulate SR */
#define SR_MASK_RC 0x0fff0000
#define SR_RC_INCREMENT -0x00010000
-#define BO ((saved_state.asregs.cregs.named.sr & SR_MASK_BO) != 0)
-#define CS ((saved_state.asregs.cregs.named.sr & SR_MASK_CS) != 0)
-#define M ((saved_state.asregs.cregs.named.sr & SR_MASK_M) != 0)
-#define Q ((saved_state.asregs.cregs.named.sr & SR_MASK_Q) != 0)
-#define S ((saved_state.asregs.cregs.named.sr & SR_MASK_S) != 0)
-#define T ((saved_state.asregs.cregs.named.sr & SR_MASK_T) != 0)
-#define LDST ((saved_state.asregs.cregs.named.ldst) != 0)
-
-#define SR_BL ((saved_state.asregs.cregs.named.sr & SR_MASK_BL) != 0)
-#define SR_RB ((saved_state.asregs.cregs.named.sr & SR_MASK_RB) != 0)
-#define SR_MD ((saved_state.asregs.cregs.named.sr & SR_MASK_MD) != 0)
-#define SR_DMY ((saved_state.asregs.cregs.named.sr & SR_MASK_DMY) != 0)
-#define SR_DMX ((saved_state.asregs.cregs.named.sr & SR_MASK_DMX) != 0)
-#define SR_RC ((saved_state.asregs.cregs.named.sr & SR_MASK_RC))
+#define BO ((saved_state.asregs.sr & SR_MASK_BO) != 0)
+#define CS ((saved_state.asregs.sr & SR_MASK_CS) != 0)
+#define M ((saved_state.asregs.sr & SR_MASK_M) != 0)
+#define Q ((saved_state.asregs.sr & SR_MASK_Q) != 0)
+#define S ((saved_state.asregs.sr & SR_MASK_S) != 0)
+#define T ((saved_state.asregs.sr & SR_MASK_T) != 0)
+#define LDST ((saved_state.asregs.ldst) != 0)
+
+#define SR_BL ((saved_state.asregs.sr & SR_MASK_BL) != 0)
+#define SR_RB ((saved_state.asregs.sr & SR_MASK_RB) != 0)
+#define SR_MD ((saved_state.asregs.sr & SR_MASK_MD) != 0)
+#define SR_DMY ((saved_state.asregs.sr & SR_MASK_DMY) != 0)
+#define SR_DMX ((saved_state.asregs.sr & SR_MASK_DMX) != 0)
+#define SR_RC ((saved_state.asregs.sr & SR_MASK_RC))
/* Note: don't use this for privileged bits */
#define SET_SR_BIT(EXP, BIT) \
do { \
if ((EXP) & 1) \
- saved_state.asregs.cregs.named.sr |= (BIT); \
+ saved_state.asregs.sr |= (BIT); \
else \
- saved_state.asregs.cregs.named.sr &= ~(BIT); \
+ saved_state.asregs.sr &= ~(BIT); \
} while (0)
#define SET_SR_BO(EXP) SET_SR_BIT ((EXP), SR_MASK_BO)
#define SET_SR_CS(EXP) SET_SR_BIT ((EXP), SR_MASK_CS)
#define SET_BANKN(EXP) \
do { \
- IBNR = (IBNR & 0xfe00) | (EXP & 0x1f); \
+ IBNR = (IBNR & 0xfe00) | ((EXP) & 0x1f); \
} while (0)
#define SET_ME(EXP) \
do { \
- IBNR = (IBNR & 0x3fff) | ((EXP & 0x3) << 14); \
+ IBNR = (IBNR & 0x3fff) | (((EXP) & 0x3) << 14); \
} while (0)
#define SET_SR_M(EXP) SET_SR_BIT ((EXP), SR_MASK_M)
#define SET_SR_Q(EXP) SET_SR_BIT ((EXP), SR_MASK_Q)
#define SET_SR_S(EXP) SET_SR_BIT ((EXP), SR_MASK_S)
#define SET_SR_T(EXP) SET_SR_BIT ((EXP), SR_MASK_T)
-#define SET_LDST(EXP) (saved_state.asregs.cregs.named.ldst = ((EXP) != 0))
+#define SET_LDST(EXP) (saved_state.asregs.ldst = ((EXP) != 0))
/* stc currently relies on being able to read SR without modifications. */
-#define GET_SR() (saved_state.asregs.cregs.named.sr - 0)
+#define GET_SR() (saved_state.asregs.sr - 0)
#define SET_SR(x) set_sr (x)
#define SET_RC(x) \
- (saved_state.asregs.cregs.named.sr \
- = saved_state.asregs.cregs.named.sr & 0xf000ffff | ((x) & 0xfff) << 16)
+ (saved_state.asregs.sr \
+ = (saved_state.asregs.sr & 0xf000ffff) | ((x) & 0xfff) << 16)
/* Manipulate FPSCR */
static void
set_fpscr1 (int x)
{
- int old = saved_state.asregs.sregs.named.fpscr;
- saved_state.asregs.sregs.named.fpscr = (x);
+ int old = saved_state.asregs.fpscr;
+ saved_state.asregs.fpscr = (x);
/* swap the floating point register banks */
- if ((saved_state.asregs.sregs.named.fpscr ^ old) & FPSCR_MASK_FR
+ if ((saved_state.asregs.fpscr ^ old) & FPSCR_MASK_FR
/* Ignore bit change if simulating sh-dsp. */
&& ! target_dsp)
{
}
/* sts relies on being able to read fpscr directly. */
-#define GET_FPSCR() (saved_state.asregs.sregs.named.fpscr)
+#define GET_FPSCR() (saved_state.asregs.fpscr)
#define SET_FPSCR(x) \
do { \
set_fpscr1 (x); \
} while (0)
-#define DSR (saved_state.asregs.sregs.named.fpscr)
+#define DSR (saved_state.asregs.fpscr)
#define RAISE_EXCEPTION(x) \
(saved_state.asregs.exception = x, saved_state.asregs.insn_end = 0)
#define XF(n) (saved_state.asregs.fregs[(n) >> 5].i[(n) & 0x1f])
#define SET_XF(n,EXP) (saved_state.asregs.fregs[(n) >> 5].i[(n) & 0x1f] = (EXP))
-#define RS saved_state.asregs.cregs.named.rs
-#define RE saved_state.asregs.cregs.named.re
-#define MOD (saved_state.asregs.cregs.named.mod)
+#define RS saved_state.asregs.rs
+#define RE saved_state.asregs.re
+#define MOD (saved_state.asregs.mod)
#define SET_MOD(i) \
(MOD = (i), \
MOD_ME = (unsigned) MOD >> 16 | (SR_DMY ? ~0xffff : (SR_DMX ? 0 : 0x10000)), \
MOD_DELTA = (MOD & 0xffff) - ((unsigned) MOD >> 16))
-#define DSP_R(n) saved_state.asregs.sregs.i[(n)]
+#define DSP_R(n) saved_state.asregs.sregs[(n)]
#define DSP_GRD(n) DSP_R ((n) + 8)
#define GET_DSP_GRD(n) ((n | 2) == 7 ? SEXT (DSP_GRD (n)) : SIGN32 (DSP_R (n)))
#define A1 DSP_R (5)
int i, tmp;
for (i = 0; i < 8; i++)
{
- tmp = saved_state.asregs.cregs.named.bank[i];
- saved_state.asregs.cregs.named.bank[i] = saved_state.asregs.regs[i];
+ tmp = saved_state.asregs.bank[i];
+ saved_state.asregs.bank[i] = saved_state.asregs.regs[i];
saved_state.asregs.regs[i] = tmp;
}
}
- saved_state.asregs.cregs.named.sr = new_sr;
+ saved_state.asregs.sr = new_sr;
SET_MOD (MOD);
}
#else
#define MA(n) \
- do { memstalls += ((((long) PC & 3) != 0) ? (n) : ((n) - 1)); } while (0)
+ do { memstalls += ((((uintptr_t) PC & 3) != 0) ? (n) : ((n) - 1)); } while (0)
#define L(x) thislock = x;
#define TL(x) if ((x) == prevlock) stalls++;
static int
get_now (void)
{
- return time ((long *) 0);
+ return time (NULL);
}
static int
}
case 34:
{
- extern int errno;
int perrno = errno;
errno = 0;
{
#if !defined(__GO32__) && !defined(_WIN32)
- case TARGET_SYS_fork:
+ case TARGET_NEWLIB_SH_SYS_fork:
regs[0] = fork ();
break;
/* This would work only if endianness matched between host and target.
Besides, it's quite dangerous. */
#if 0
- case TARGET_SYS_execve:
+ case TARGET_NEWLIB_SH_SYS_execve:
regs[0] = execve (ptr (regs[5]), (char **) ptr (regs[6]),
(char **) ptr (regs[7]));
break;
- case TARGET_SYS_execv:
+ case TARGET_NEWLIB_SH_SYS_execv:
regs[0] = execve (ptr (regs[5]), (char **) ptr (regs[6]), 0);
break;
#endif
- case TARGET_SYS_pipe:
+ case TARGET_NEWLIB_SH_SYS_pipe:
{
regs[0] = (BUSERROR (regs[5], maskl)
? -EINVAL
}
break;
- case TARGET_SYS_wait:
+ case TARGET_NEWLIB_SH_SYS_wait:
regs[0] = wait ((int *) ptr (regs[5]));
break;
#endif /* !defined(__GO32__) && !defined(_WIN32) */
- case TARGET_SYS_read:
+ case TARGET_NEWLIB_SH_SYS_read:
strnswap (regs[6], regs[7]);
regs[0]
= callback->read (callback, regs[5], ptr (regs[6]), regs[7]);
strnswap (regs[6], regs[7]);
break;
- case TARGET_SYS_write:
+ case TARGET_NEWLIB_SH_SYS_write:
strnswap (regs[6], regs[7]);
if (regs[5] == 1)
regs[0] = (int) callback->write_stdout (callback,
ptr (regs[6]), regs[7]);
strnswap (regs[6], regs[7]);
break;
- case TARGET_SYS_lseek:
+ case TARGET_NEWLIB_SH_SYS_lseek:
regs[0] = callback->lseek (callback,regs[5], regs[6], regs[7]);
break;
- case TARGET_SYS_close:
+ case TARGET_NEWLIB_SH_SYS_close:
regs[0] = callback->close (callback,regs[5]);
break;
- case TARGET_SYS_open:
+ case TARGET_NEWLIB_SH_SYS_open:
{
int len = strswaplen (regs[5]);
strnswap (regs[5], len);
strnswap (regs[5], len);
break;
}
- case TARGET_SYS_exit:
+ case TARGET_NEWLIB_SH_SYS_exit:
/* EXIT - caller can look in r5 to work out the reason */
raise_exception (SIGQUIT);
regs[0] = regs[5];
break;
- case TARGET_SYS_stat: /* added at hmsi */
+ case TARGET_NEWLIB_SH_SYS_stat: /* added at hmsi */
/* stat system call */
{
struct stat host_stat;
break;
#ifndef _WIN32
- case TARGET_SYS_chown:
+ case TARGET_NEWLIB_SH_SYS_chown:
{
int len = strswaplen (regs[5]);
break;
}
#endif /* _WIN32 */
- case TARGET_SYS_chmod:
+ case TARGET_NEWLIB_SH_SYS_chmod:
{
int len = strswaplen (regs[5]);
strnswap (regs[5], len);
break;
}
- case TARGET_SYS_utime:
+ case TARGET_NEWLIB_SH_SYS_utime:
{
/* Cast the second argument to void *, to avoid type mismatch
if a prototype is present. */
int len = strswaplen (regs[5]);
strnswap (regs[5], len);
+#ifdef HAVE_UTIME_H
regs[0] = utime (ptr (regs[5]), (void *) ptr (regs[6]));
+#else
+ errno = ENOSYS;
+ regs[0] = -1;
+#endif
strnswap (regs[5], len);
break;
}
- case TARGET_SYS_argc:
+ case TARGET_NEWLIB_SH_SYS_argc:
regs[0] = countargv (prog_argv);
break;
- case TARGET_SYS_argnlen:
+ case TARGET_NEWLIB_SH_SYS_argnlen:
if (regs[5] < countargv (prog_argv))
regs[0] = strlen (prog_argv[regs[5]]);
else
regs[0] = -1;
break;
- case TARGET_SYS_argn:
+ case TARGET_NEWLIB_SH_SYS_argn:
if (regs[5] < countargv (prog_argv))
{
/* Include the termination byte. */
int i = strlen (prog_argv[regs[5]]) + 1;
- regs[0] = sim_write (0, regs[6], (void *) prog_argv[regs[5]], i);
+ regs[0] = sim_write (0, regs[6], prog_argv[regs[5]], i);
}
else
regs[0] = -1;
break;
- case TARGET_SYS_time:
+ case TARGET_NEWLIB_SH_SYS_time:
regs[0] = get_now ();
break;
- case TARGET_SYS_ftruncate:
+ case TARGET_NEWLIB_SH_SYS_ftruncate:
regs[0] = callback->ftruncate (callback, regs[5], regs[6]);
break;
- case TARGET_SYS_truncate:
+ case TARGET_NEWLIB_SH_SYS_truncate:
{
int len = strswaplen (regs[5]);
strnswap (regs[5], len);
R[iRn1] <<= 1;
R[iRn1] |= (unsigned long) T;
- switch (old_q)
+ if (!old_q)
{
- case 0:
- switch (M)
+ if (!M)
{
- case 0:
tmp0 = R[iRn1];
R[iRn1] -= R[iRn2];
tmp1 = (R[iRn1] > tmp0);
- switch (Q)
- {
- case 0:
- SET_SR_Q (tmp1);
- break;
- case 1:
- SET_SR_Q ((unsigned char) (tmp1 == 0));
- break;
- }
- break;
- case 1:
+ if (!Q)
+ SET_SR_Q (tmp1);
+ else
+ SET_SR_Q ((unsigned char) (tmp1 == 0));
+ }
+ else
+ {
tmp0 = R[iRn1];
R[iRn1] += R[iRn2];
tmp1 = (R[iRn1] < tmp0);
- switch (Q)
- {
- case 0:
- SET_SR_Q ((unsigned char) (tmp1 == 0));
- break;
- case 1:
- SET_SR_Q (tmp1);
- break;
- }
- break;
+ if (!Q)
+ SET_SR_Q ((unsigned char) (tmp1 == 0));
+ else
+ SET_SR_Q (tmp1);
}
- break;
- case 1:
- switch (M)
+ }
+ else
+ {
+ if (!M)
{
- case 0:
tmp0 = R[iRn1];
R[iRn1] += R[iRn2];
tmp1 = (R[iRn1] < tmp0);
- switch (Q)
- {
- case 0:
- SET_SR_Q (tmp1);
- break;
- case 1:
- SET_SR_Q ((unsigned char) (tmp1 == 0));
- break;
- }
- break;
- case 1:
+ if (!Q)
+ SET_SR_Q (tmp1);
+ else
+ SET_SR_Q ((unsigned char) (tmp1 == 0));
+ }
+ else
+ {
tmp0 = R[iRn1];
R[iRn1] -= R[iRn2];
tmp1 = (R[iRn1] > tmp0);
- switch (Q)
- {
- case 0:
- SET_SR_Q ((unsigned char) (tmp1 == 0));
- break;
- case 1:
- SET_SR_Q (tmp1);
- break;
- }
- break;
+ if (!Q)
+ SET_SR_Q ((unsigned char) (tmp1 == 0));
+ else
+ SET_SR_Q (tmp1);
}
- break;
}
/*T = (Q == M);*/
SET_SR_T (Q == M);
lower = result - error;
frac = frexp (lower, &exp);
lower = ldexp (ceil (ldexp (frac, 24)), exp - 24);
- return abs (upper - result) >= abs (lower - result) ? upper : lower;
+ return fabs (upper - result) >= fabs (lower - result) ? upper : lower;
}
static float
return loop;
}
-static void ppi_insn ();
-
#include "ppi.c"
/* Provide calloc / free versions that use an anonymous mmap. This can
CHECK_INSN_PTR (insn_ptr);
#ifndef PR
- PR = saved_state.asregs.sregs.named.pr;
+ PR = saved_state.asregs.pr;
#endif
/*T = GET_SR () & SR_MASK_T;*/
prevlock = saved_state.asregs.prevlock;
}
if (saved_state.asregs.insn_end == loop.end)
{
- saved_state.asregs.cregs.named.sr += SR_RC_INCREMENT;
+ saved_state.asregs.sr += SR_RC_INCREMENT;
if (SR_RC)
insn_ptr = loop.start;
else
saved_state.asregs.insts += insts;
saved_state.asregs.pc = PH2T (insn_ptr);
#ifndef PR
- saved_state.asregs.sregs.named.pr = PR;
+ saved_state.asregs.pr = PR;
#endif
saved_state.asregs.prevlock = prevlock;
signal (SIGFPE, prev_fpe);
}
-int
-sim_write (SIM_DESC sd, SIM_ADDR addr, const unsigned char *buffer, int size)
+uint64_t
+sim_write (SIM_DESC sd, uint64_t addr, const void *buffer, uint64_t size)
{
int i;
+ const unsigned char *data = buffer;
init_pointers ();
for (i = 0; i < size; i++)
{
- saved_state.asregs.memory[(MMASKB & (addr + i)) ^ endianb] = buffer[i];
+ saved_state.asregs.memory[(MMASKB & (addr + i)) ^ endianb] = data[i];
}
return size;
}
-int
-sim_read (SIM_DESC sd, SIM_ADDR addr, unsigned char *buffer, int size)
+uint64_t
+sim_read (SIM_DESC sd, uint64_t addr, void *buffer, uint64_t size)
{
int i;
+ unsigned char *data = buffer;
init_pointers ();
for (i = 0; i < size; i++)
{
- buffer[i] = saved_state.asregs.memory[(MMASKB & (addr + i)) ^ endianb];
+ data[i] = saved_state.asregs.memory[(MMASKB & (addr + i)) ^ endianb];
}
return size;
}
};
static int
-sh_reg_store (SIM_CPU *cpu, int rn, unsigned char *memory, int length)
+sh_reg_store (SIM_CPU *cpu, int rn, const void *memory, int length)
{
unsigned val;
}
static int
-sh_reg_fetch (SIM_CPU *cpu, int rn, unsigned char *memory, int length)
+sh_reg_fetch (SIM_CPU *cpu, int rn, void *memory, int length)
{
int val;
sim_open (SIM_OPEN_KIND kind, host_callback *cb,
struct bfd *abfd, char * const *argv)
{
- char **p;
+ char * const *p;
int i;
union
{
SIM_DESC sd = sim_state_alloc (kind, cb);
SIM_ASSERT (STATE_MAGIC (sd) == SIM_MAGIC_NUMBER);
+ /* Set default options before parsing user options. */
+ current_alignment = STRICT_ALIGNMENT;
+ cb->syscall_map = cb_sh_syscall_map;
+
/* The cpu data is kept in a separately allocated chunk of memory. */
- if (sim_cpu_alloc_all (sd, 1) != SIM_RC_OK)
+ if (sim_cpu_alloc_all (sd, 0) != SIM_RC_OK)
{
free_state (sd);
return 0;
}
/* Check for/establish the a reference program image. */
- if (sim_analyze_program (sd,
- (STATE_PROG_ARGV (sd) != NULL
- ? *STATE_PROG_ARGV (sd)
- : NULL), abfd) != SIM_RC_OK)
+ if (sim_analyze_program (sd, STATE_PROG_FILE (sd), abfd) != SIM_RC_OK)
{
free_state (sd);
return 0;