#include <signal.h>
+#include "sim-main.h"
#include "v850_sim.h"
#include "simops.h"
-#include "sys/syscall.h"
+
+#ifdef HAVE_UTIME_H
+#include <utime.h>
+#endif
+
+#ifdef HAVE_TIME_H
+#include <time.h>
+#endif
+
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+
+ /* FIXME - should be including a version of syscall.h that does not
+ pollute the name space */
+#include "../../libgloss/v850/sys/syscall.h"
+
#include "bfd.h"
+#include "libiberty.h"
+
#include <errno.h>
#if !defined(__GO32__) && !defined(_WIN32)
#include <sys/stat.h>
return 1;
}
-/* start-sanitize-v850e */
static unsigned long
Add32 (unsigned long a1, unsigned long a2, int * carry)
{
return;
}
-/* end-sanitize-v850e */
+
+\f
+/* Read a null terminated string from memory, return in a buffer */
+static char *
+fetch_str (sd, addr)
+ SIM_DESC sd;
+ address_word addr;
+{
+ char *buf;
+ int nr = 0;
+ while (sim_core_read_1 (STATE_CPU (sd, 0),
+ PC, sim_core_read_map, addr + nr) != 0)
+ nr++;
+ buf = NZALLOC (char, nr + 1);
+ sim_read (simulator, addr, buf, nr);
+ return buf;
+}
+
+/* Read a null terminated argument vector from memory, return in a
+ buffer */
+static char **
+fetch_argv (sd, addr)
+ SIM_DESC sd;
+ address_word addr;
+{
+ int max_nr = 64;
+ int nr = 0;
+ char **buf = xmalloc (max_nr * sizeof (char*));
+ while (1)
+ {
+ unsigned32 a = sim_core_read_4 (STATE_CPU (sd, 0),
+ PC, sim_core_read_map, addr + nr * 4);
+ if (a == 0) break;
+ buf[nr] = fetch_str (sd, a);
+ nr ++;
+ if (nr == max_nr - 1)
+ {
+ max_nr += 50;
+ buf = xrealloc (buf, max_nr * sizeof (char*));
+ }
+ }
+ buf[nr] = 0;
+ return buf;
+}
\f
/* sld.b */
static int
branch (int code)
{
- unsigned int psw;
- int op0;
-
trace_input ("Bcond", OP_COND_BR, 0);
trace_output (OP_COND_BR);
SP += (OP[3] & 0x3e) << 1;
- /* Load the registers with lower number registers being retrieved from lower addresses. */
- for (i = 0; i < 12; i++)
+ /* Load the registers with lower number registers being retrieved from higher addresses. */
+ for (i = 12; i--;)
if ((OP[3] & (1 << type1_regs[ i ])))
{
State.regs[ 20 + i ] = load_mem (SP, 4);
{
trace_input ("movhi", OP_UIMM_REG_REG, 16);
- State.regs[ OP[1] ] = State.regs[ OP[0] ] + OP[2] << 16;
+ State.regs[ OP[1] ] = State.regs[ OP[0] ] + (OP[2] << 16);
trace_output (OP_UIMM_REG_REG);
}
switch (FUNC)
{
-#if !defined(__GO32__) && !defined(_WIN32)
+
+#ifdef HAVE_FORK
+#ifdef SYS_fork
case SYS_fork:
RETVAL = fork ();
break;
+#endif
+#endif
+
+#ifdef HAVE_EXECVE
+#ifdef SYS_execv
case SYS_execve:
- RETVAL = execve (MEMPTR (PARM1), (char **) MEMPTR (PARM2),
- (char **)MEMPTR (PARM3));
- break;
+ {
+ char *path = fetch_str (simulator, PARM1);
+ char **argv = fetch_argv (simulator, PARM2);
+ char **envp = fetch_argv (simulator, PARM3);
+ RETVAL = execve (path, argv, envp);
+ zfree (path);
+ freeargv (argv);
+ freeargv (envp);
+ break;
+ }
+#endif
+#endif
+
+#if HAVE_EXECV
#ifdef SYS_execv
case SYS_execv:
- RETVAL = execve (MEMPTR (PARM1), (char **) MEMPTR (PARM2), NULL);
- break;
+ {
+ char *path = fetch_str (simulator, PARM1);
+ char **argv = fetch_argv (simulator, PARM2);
+ RETVAL = execv (path, argv);
+ zfree (path);
+ freeargv (argv);
+ break;
+ }
+#endif
#endif
+
#if 0
+#ifdef SYS_pipe
case SYS_pipe:
{
reg_t buf;
SW (buf, host_fd[1]);
}
break;
+#endif
+#endif
+#if 0
+#ifdef SYS_wait
case SYS_wait:
{
int status;
#endif
#endif
+#ifdef SYS_read
case SYS_read:
- RETVAL = v850_callback->read (v850_callback, PARM1, MEMPTR (PARM2),
- PARM3);
- break;
+ {
+ char *buf = zalloc (PARM3);
+ RETVAL = sim_io_read (simulator, PARM1, buf, PARM3);
+ sim_write (simulator, PARM2, buf, PARM3);
+ zfree (buf);
+ break;
+ }
+#endif
+
+#ifdef SYS_write
case SYS_write:
- if (PARM1 == 1)
- RETVAL = (int)v850_callback->write_stdout (v850_callback,
- MEMPTR (PARM2), PARM3);
- else
- RETVAL = (int)v850_callback->write (v850_callback, PARM1,
- MEMPTR (PARM2), PARM3);
- break;
+ {
+ char *buf = zalloc (PARM3);
+ sim_read (simulator, PARM2, buf, PARM3);
+ if (PARM1 == 1)
+ RETVAL = sim_io_write_stdout (simulator, buf, PARM3);
+ else
+ RETVAL = sim_io_write (simulator, PARM1, buf, PARM3);
+ zfree (buf);
+ break;
+ }
+#endif
+
+#ifdef SYS_lseek
case SYS_lseek:
- RETVAL = v850_callback->lseek (v850_callback, PARM1, PARM2, PARM3);
+ RETVAL = sim_io_lseek (simulator, PARM1, PARM2, PARM3);
break;
+#endif
+
+#ifdef SYS_close
case SYS_close:
- RETVAL = v850_callback->close (v850_callback, PARM1);
+ RETVAL = sim_io_close (simulator, PARM1);
break;
+#endif
+
+#ifdef SYS_open
case SYS_open:
- RETVAL = v850_callback->open (v850_callback, MEMPTR (PARM1), PARM2);
- break;
+ {
+ char *buf = fetch_str (simulator, PARM1);
+ RETVAL = sim_io_open (simulator, buf, PARM2);
+ zfree (buf);
+ break;
+ }
+#endif
+
+#ifdef SYS_exit
case SYS_exit:
if ((PARM1 & 0xffff0000) == 0xdead0000 && (PARM1 & 0xffff) != 0)
State.exception = PARM1 & 0xffff; /* get signal encoded by kill */
else
State.exception = SIG_V850_EXIT; /* PARM1 has exit status encoded */
break;
+#endif
#if !defined(__GO32__) && !defined(_WIN32)
+#ifdef SYS_stat
case SYS_stat: /* added at hmsi */
/* stat system call */
{
struct stat host_stat;
reg_t buf;
+ char *path = fetch_str (simulator, PARM1);
- RETVAL = stat (MEMPTR (PARM1), &host_stat);
+ RETVAL = stat (path, &host_stat);
+ zfree (path);
buf = PARM2;
/* Just wild-assed guesses. */
store_mem (buf + 36, 4, host_stat.st_ctime);
}
break;
+#endif
+#endif
+#ifdef HAVE_CHOWN
+#ifdef SYS_chown
case SYS_chown:
- RETVAL = chown (MEMPTR (PARM1), PARM2, PARM3);
+ {
+ char *path = fetch_str (simulator, PARM1);
+ RETVAL = chown (path, PARM2, PARM3);
+ zfree (path);
+ }
break;
+#endif
+#endif
+
+#if HAVE_CHMOD
+#ifdef SYS_chmod
case SYS_chmod:
- RETVAL = chmod (MEMPTR (PARM1), PARM2);
+ {
+ char *path = fetch_str (simulator, PARM1);
+ RETVAL = chmod (path, PARM2);
+ zfree (path);
+ }
break;
+#endif
+#endif
+
#ifdef SYS_time
+#if HAVE_TIME
case SYS_time:
{
time_t now;
}
break;
#endif
+#endif
+
+#if !defined(__GO32__) && !defined(_WIN32)
#ifdef SYS_times
case SYS_times:
{
break;
}
#endif
+#endif
+
+#ifdef SYS_gettimeofday
+#if !defined(__GO32__) && !defined(_WIN32)
case SYS_gettimeofday:
{
struct timeval t;
store_mem (PARM2 + 4, 4, tz.tz_dsttime);
break;
}
+#endif
+#endif
+
#ifdef SYS_utime
+#if HAVE_UTIME
case SYS_utime:
- /* Cast the second argument to void *, to avoid type mismatch
- if a prototype is present. */
- RETVAL = utime (MEMPTR (PARM1), (void *) MEMPTR (PARM2));
+ {
+ /* Cast the second argument to void *, to avoid type mismatch
+ if a prototype is present. */
+ sim_io_error (simulator, "Utime not supported");
+ /* RETVAL = utime (path, (void *) MEMPTR (PARM2)); */
+ }
break;
#endif
#endif
+
default:
abort ();
}
int
OP_4007E0 ()
{
- unsigned int op0;
-
trace_input ("stsr", OP_STSR, 0);
State.regs[ OP[1] ] = State.sregs[ OP[0] ];
return 4;
}
+/* mulu reg1, reg2, reg3 */
+int
+OP_22207E0 (void)
+{
+ trace_input ("mulu", OP_REG_REG_REG, 0);
+
+ Multiply64 (false, State.regs[ OP[0] ]);
+
+ trace_output (OP_REG_REG_REG);
+
+ return 4;
+}
+
/* start-sanitize-v850e */
#define BIT_CHANGE_OP( name, binop ) \
/* end-sanitize-v850e */
/* start-sanitize-v850eq */
+/* This function is courtesy of Sugimoto at NEC, via Seow Tan (Soew_Tan@el.nec.com) */
+static void
+divun
+(
+ unsigned int N,
+ unsigned long int als,
+ unsigned long int sfi,
+ unsigned long int * quotient_ptr,
+ unsigned long int * remainder_ptr,
+ boolean * overflow_ptr
+)
+{
+ unsigned long ald = sfi >> (N - 1);
+ unsigned long alo = als;
+ unsigned int Q = 1;
+ unsigned int C;
+ unsigned int S = 0;
+ unsigned int i;
+ unsigned int R1 = 1;
+ unsigned int DBZ = (als == 0) ? 1 : 0;
+ unsigned long alt = Q ? ~als : als;
+
+ /* 1st Loop */
+ alo = ald + alt + Q;
+ C = (((alt >> 31) & (ald >> 31))
+ | (((alt >> 31) ^ (ald >> 31)) & (~alo >> 31)));
+ C = C ^ Q;
+ Q = ~(C ^ S) & 1;
+ R1 = (alo == 0) ? 0 : (R1 & Q);
+ if ((S ^ (alo>>31)) && !C)
+ {
+ DBZ = 1;
+ }
+ S = alo >> 31;
+ sfi = (sfi << (32-N+1)) | Q;
+ ald = (alo << 1) | (sfi >> 31);
+
+ /* 2nd - N-1th Loop */
+ for (i = 2; i < N; i++)
+ {
+ alt = Q ? ~als : als;
+ alo = ald + alt + Q;
+ C = (((alt >> 31) & (ald >> 31))
+ | (((alt >> 31) ^ (ald >> 31)) & (~alo >> 31)));
+ C = C ^ Q;
+ Q = ~(C ^ S) & 1;
+ R1 = (alo == 0) ? 0 : (R1 & Q);
+ if ((S ^ (alo>>31)) && !C && !DBZ)
+ {
+ DBZ = 1;
+ }
+ S = alo >> 31;
+ sfi = (sfi << 1) | Q;
+ ald = (alo << 1) | (sfi >> 31);
+ }
+
+ /* Nth Loop */
+ alt = Q ? ~als : als;
+ alo = ald + alt + Q;
+ C = (((alt >> 31) & (ald >> 31))
+ | (((alt >> 31) ^ (ald >> 31)) & (~alo >> 31)));
+ C = C ^ Q;
+ Q = ~(C ^ S) & 1;
+ R1 = (alo == 0) ? 0 : (R1 & Q);
+ if ((S ^ (alo>>31)) && !C)
+ {
+ DBZ = 1;
+ }
+
+ * quotient_ptr = (sfi << 1) | Q;
+ * remainder_ptr = Q ? alo : (alo + als);
+ * overflow_ptr = DBZ | R1;
+}
+
+/* This function is courtesy of Sugimoto at NEC, via Seow Tan (Soew_Tan@el.nec.com) */
+static void
+divn
+(
+ unsigned int N,
+ unsigned long int als,
+ unsigned long int sfi,
+ signed long int * quotient_ptr,
+ signed long int * remainder_ptr,
+ boolean * overflow_ptr
+)
+{
+ unsigned long ald = (signed long) sfi >> (N - 1);
+ unsigned long alo = als;
+ unsigned int SS = als >> 31;
+ unsigned int SD = sfi >> 31;
+ unsigned int R1 = 1;
+ unsigned int OV;
+ unsigned int DBZ = als == 0 ? 1 : 0;
+ unsigned int Q = ~(SS ^ SD) & 1;
+ unsigned int C;
+ unsigned int S;
+ unsigned int i;
+ unsigned long alt = Q ? ~als : als;
+
+
+ /* 1st Loop */
+
+ alo = ald + alt + Q;
+ C = (((alt >> 31) & (ald >> 31))
+ | (((alt >> 31) ^ (ald >> 31)) & (~alo >> 31)));
+ Q = C ^ SS;
+ R1 = (alo == 0) ? 0 : (R1 & (Q ^ (SS ^ SD)));
+ S = alo >> 31;
+ sfi = (sfi << (32-N+1)) | Q;
+ ald = (alo << 1) | (sfi >> 31);
+ if ((alo >> 31) ^ (ald >> 31))
+ {
+ DBZ = 1;
+ }
+
+ /* 2nd - N-1th Loop */
+
+ for (i = 2; i < N; i++)
+ {
+ alt = Q ? ~als : als;
+ alo = ald + alt + Q;
+ C = (((alt >> 31) & (ald >> 31))
+ | (((alt >> 31) ^ (ald >> 31)) & (~alo >> 31)));
+ Q = C ^ SS;
+ R1 = (alo == 0) ? 0 : (R1 & (Q ^ (SS ^ SD)));
+ S = alo >> 31;
+ sfi = (sfi << 1) | Q;
+ ald = (alo << 1) | (sfi >> 31);
+ if ((alo >> 31) ^ (ald >> 31))
+ {
+ DBZ = 1;
+ }
+ }
+
+ /* Nth Loop */
+ alt = Q ? ~als : als;
+ alo = ald + alt + Q;
+ C = (((alt >> 31) & (ald >> 31))
+ | (((alt >> 31) ^ (ald >> 31)) & (~alo >> 31)));
+ Q = C ^ SS;
+ R1 = (alo == 0) ? 0 : (R1 & (Q ^ (SS ^ SD)));
+ sfi = (sfi << (32-N+1));
+ ald = alo;
+
+ /* End */
+ if (alo != 0)
+ {
+ alt = Q ? ~als : als;
+ alo = ald + alt + Q;
+ }
+ R1 = R1 & ((~alo >> 31) ^ SD);
+ if ((alo != 0) && ((Q ^ (SS ^ SD)) ^ R1)) alo = ald;
+ if (N != 32)
+ ald = sfi = (long) ((sfi >> 1) | (SS ^ SD) << 31) >> (32-N-1) | Q;
+ else
+ ald = sfi = sfi | Q;
+
+ OV = DBZ | ((alo == 0) ? 0 : R1);
+
+ * remainder_ptr = alo;
+
+ /* Adj */
+ if (((alo != 0) && ((SS ^ SD) ^ R1))
+ || ((alo == 0) && (SS ^ R1)))
+ alo = ald + 1;
+ else
+ alo = ald;
+
+ OV = (DBZ | R1) ? OV : ((alo >> 31) & (~ald >> 31));
+
+ * quotient_ptr = alo;
+ * overflow_ptr = OV;
+}
+
/* sdivun imm5, reg1, reg2, reg3 */
int
OP_1C207E0 (void)
{
- unsigned long long int quotient;
- unsigned long long int remainder;
- unsigned long long int divisor;
- unsigned long long int dividend;
- boolean overflow = false;
- unsigned int imm5;
+ unsigned long int quotient;
+ unsigned long int remainder;
+ unsigned long int divide_by;
+ unsigned long int divide_this;
+ boolean overflow = false;
+ unsigned int imm5;
trace_input ("sdivun", OP_IMM_REG_REG_REG, 0);
imm5 = 32 - ((OP[3] & 0x3c0000) >> 17);
- divisor = State.regs[ OP[0] ] << imm5;
- dividend = State.regs[ OP[1] ];
+ divide_by = State.regs[ OP[0] ];
+ divide_this = State.regs[ OP[1] ] << imm5;
- State.regs[ OP[1] ] = quotient = dividend / divisor;
- State.regs[ OP[2] >> 11 ] = remainder = dividend % divisor;
+ divun (imm5, divide_by, divide_this, & quotient, & remainder, & overflow);
- if (divisor == 0)
- {
- overflow = true;
- quotient = dividend;
- }
+ State.regs[ OP[1] ] = quotient;
+ State.regs[ OP[2] >> 11 ] = remainder;
/* Set condition codes. */
PSW &= ~(PSW_Z | PSW_S | PSW_OV);
if (overflow) PSW |= PSW_OV;
if (quotient == 0) PSW |= PSW_Z;
+ if (quotient & 0x80000000) PSW |= PSW_S;
trace_output (OP_IMM_REG_REG_REG);
int
OP_1C007E0 (void)
{
- signed long long int quotient;
- signed long long int remainder;
- signed long long int divisor;
- signed long long int dividend;
- boolean overflow = false;
- unsigned int imm5;
+ signed long int quotient;
+ signed long int remainder;
+ signed long int divide_by;
+ signed long int divide_this;
+ boolean overflow = false;
+ unsigned int imm5;
trace_input ("sdivn", OP_IMM_REG_REG_REG, 0);
imm5 = 32 - ((OP[3] & 0x3c0000) >> 17);
- divisor = State.regs[ OP[0] ] << imm5;
- dividend = State.regs[ OP[1] ];
+ divide_by = State.regs[ OP[0] ];
+ divide_this = State.regs[ OP[1] ] << imm5;
- State.regs[ OP[1] ] = quotient = dividend / divisor;
- State.regs[ OP[2] >> 11 ] = remainder = dividend % divisor;
+ divn (imm5, divide_by, divide_this, & quotient, & remainder, & overflow);
- if (divisor == 0)
- {
- overflow = true;
- quotient = dividend;
- }
+ State.regs[ OP[1] ] = quotient;
+ State.regs[ OP[2] >> 11 ] = remainder;
/* Set condition codes. */
PSW &= ~(PSW_Z | PSW_S | PSW_OV);
int
OP_18207E0 (void)
{
- unsigned long long int quotient;
- unsigned long long int remainder;
- unsigned long long int divisor;
- unsigned long long int dividend;
- boolean overflow = false;
- unsigned int imm5;
+ unsigned long int quotient;
+ unsigned long int remainder;
+ unsigned long int divide_by;
+ unsigned long int divide_this;
+ boolean overflow = false;
+ unsigned int imm5;
trace_input ("sdivhun", OP_IMM_REG_REG_REG, 0);
imm5 = 32 - ((OP[3] & 0x3c0000) >> 17);
- divisor = State.regs[ OP[0] ] << imm5;
- dividend = State.regs[ OP[1] ] & 0xffff;
+ divide_by = State.regs[ OP[0] ] & 0xffff;
+ divide_this = State.regs[ OP[1] ] << imm5;
- State.regs[ OP[1] ] = quotient = dividend / divisor;
- State.regs[ OP[2] >> 11 ] = remainder = dividend % divisor;
+ divun (imm5, divide_by, divide_this, & quotient, & remainder, & overflow);
- if (divisor == 0)
- {
- overflow = true;
- quotient = dividend;
- }
+ State.regs[ OP[1] ] = quotient;
+ State.regs[ OP[2] >> 11 ] = remainder;
/* Set condition codes. */
PSW &= ~(PSW_Z | PSW_S | PSW_OV);
if (overflow) PSW |= PSW_OV;
if (quotient == 0) PSW |= PSW_Z;
+ if (quotient & 0x80000000) PSW |= PSW_S;
trace_output (OP_IMM_REG_REG_REG);
int
OP_18007E0 (void)
{
- signed long long int quotient;
- signed long long int remainder;
- signed long long int divisor;
- signed long long int dividend;
- boolean overflow = false;
- unsigned int imm5;
+ signed long int quotient;
+ signed long int remainder;
+ signed long int divide_by;
+ signed long int divide_this;
+ boolean overflow = false;
+ unsigned int imm5;
trace_input ("sdivhn", OP_IMM_REG_REG_REG, 0);
imm5 = 32 - ((OP[3] & 0x3c0000) >> 17);
- divisor = State.regs[ OP[0] ] << imm5;
- dividend = SEXT16 (State.regs[ OP[1] ]);
+ divide_by = SEXT16 (State.regs[ OP[0] ]);
+ divide_this = State.regs[ OP[1] ] << imm5;
- State.regs[ OP[1] ] = quotient = dividend / divisor;
- State.regs[ OP[2] >> 11 ] = remainder = dividend % divisor;
+ divn (imm5, divide_by, divide_this, & quotient, & remainder, & overflow);
- if (divisor == 0)
- {
- overflow = true;
- quotient = dividend;
- }
+ State.regs[ OP[1] ] = quotient;
+ State.regs[ OP[2] >> 11 ] = remainder;
/* Set condition codes. */
PSW &= ~(PSW_Z | PSW_S | PSW_OV);
/* start-sanitize-v850e */
/* divu reg1, reg2, reg3 */
-/* divun imm5, reg1, reg2, reg3 */
int
OP_2C207E0 (void)
{
unsigned long int quotient;
unsigned long int remainder;
- unsigned long int divisor;
- unsigned long int dividend;
+ unsigned long int divide_by;
+ unsigned long int divide_this;
boolean overflow = false;
if ((OP[3] & 0x3c0000) == 0)
/* Compute the result. */
- divisor = State.regs[ OP[0] ];
- dividend = State.regs[ OP[1] ];
+ divide_by = State.regs[ OP[0] ];
+ divide_this = State.regs[ OP[1] ];
- if (divisor == 0)
+ if (divide_by == 0)
{
overflow = true;
- divisor = 1;
+ divide_by = 1;
}
- State.regs[ OP[1] ] = quotient = dividend / divisor;
- State.regs[ OP[2] >> 11 ] = remainder = dividend % divisor;
+ State.regs[ OP[1] ] = quotient = divide_this / divide_by;
+ State.regs[ OP[2] >> 11 ] = remainder = divide_this % divide_by;
/* Set condition codes. */
PSW &= ~(PSW_Z | PSW_S | PSW_OV);
if (overflow) PSW |= PSW_OV;
if (quotient == 0) PSW |= PSW_Z;
+ if (quotient & 0x80000000) PSW |= PSW_S;
trace_output (OP_REG_REG_REG);
}
/* start-sanitize-v850eq */
+/* divun imm5, reg1, reg2, reg3 */
else
{
unsigned int imm5;
imm5 = 32 - ((OP[3] & 0x3c0000) >> 17);
- divisor = State.regs[ OP[0] ];
- dividend = State.regs[ OP[1] ];
+ divide_by = State.regs[ OP[0] ];
+ divide_this = State.regs[ OP[1] ];
- State.regs[ OP[1] ] = quotient = dividend / divisor;
- State.regs[ OP[2] >> 11 ] = remainder = dividend % divisor;
+ divun (imm5, divide_by, divide_this, & quotient, & remainder, & overflow);
- if ((divisor == 0)
- || (quotient > (1 << imm5))
- || (quotient < (((imm5 & 1) ? 1 : -1) << imm5)))
- {
- overflow = true;
- quotient = dividend;
- }
+ State.regs[ OP[1] ] = quotient;
+ State.regs[ OP[2] >> 11 ] = remainder;
/* Set condition codes. */
PSW &= ~(PSW_Z | PSW_S | PSW_OV);
if (overflow) PSW |= PSW_OV;
if (quotient == 0) PSW |= PSW_Z;
+ if (quotient & 0x80000000) PSW |= PSW_S;
trace_output (OP_IMM_REG_REG_REG);
}
}
/* div reg1, reg2, reg3 */
-/* divn imm5, reg1, reg2, reg3 */
int
OP_2C007E0 (void)
{
signed long int quotient;
signed long int remainder;
- signed long int divisor;
- signed long int dividend;
+ signed long int divide_by;
+ signed long int divide_this;
boolean overflow = false;
if ((OP[3] & 0x3c0000) == 0)
/* Compute the result. */
- divisor = State.regs[ OP[0] ];
- dividend = State.regs[ OP[1] ];
+ divide_by = State.regs[ OP[0] ];
+ divide_this = State.regs[ OP[1] ];
- if (divisor == 0 || (divisor == -1 && dividend == (1 << 31)))
+ if (divide_by == 0 || (divide_by == -1 && divide_this == (1 << 31)))
{
- overflow = true;
- divisor = 1;
+ overflow = true;
+ divide_by = 1;
}
- State.regs[ OP[1] ] = quotient = dividend / divisor;
- State.regs[ OP[2] >> 11 ] = remainder = dividend % divisor;
+ State.regs[ OP[1] ] = quotient = divide_this / divide_by;
+ State.regs[ OP[2] >> 11 ] = remainder = divide_this % divide_by;
/* Set condition codes. */
PSW &= ~(PSW_Z | PSW_S | PSW_OV);
trace_output (OP_REG_REG_REG);
}
/* start-sanitize-v850eq */
+/* divn imm5, reg1, reg2, reg3 */
else
{
unsigned int imm5;
imm5 = 32 - ((OP[3] & 0x3c0000) >> 17);
- divisor = State.regs[ OP[0] ];
- dividend = State.regs[ OP[1] ];
+ divide_by = State.regs[ OP[0] ];
+ divide_this = State.regs[ OP[1] ];
- State.regs[ OP[1] ] = quotient = dividend / divisor;
- State.regs[ OP[2] >> 11 ] = remainder = dividend % divisor;
+ divn (imm5, divide_by, divide_this, & quotient, & remainder, & overflow);
- if ((divisor == 0)
- || (quotient > (1 << imm5))
- || (divisor == -1 && dividend == (1 << 31))
- || (quotient < (((imm5 & 1) ? 1 : -1) << imm5)))
- {
- overflow = true;
- quotient = dividend;
- }
+ State.regs[ OP[1] ] = quotient;
+ State.regs[ OP[2] >> 11 ] = remainder;
/* Set condition codes. */
PSW &= ~(PSW_Z | PSW_S | PSW_OV);
}
/* divhu reg1, reg2, reg3 */
-/* divhun imm5, reg1, reg2, reg3 */
int
OP_28207E0 (void)
{
unsigned long int quotient;
unsigned long int remainder;
- unsigned long int divisor;
- unsigned long int dividend;
+ unsigned long int divide_by;
+ unsigned long int divide_this;
boolean overflow = false;
if ((OP[3] & 0x3c0000) == 0)
/* Compute the result. */
- divisor = State.regs[ OP[0] ];
- dividend = State.regs[ OP[1] ] & 0xffff;
+ divide_by = State.regs[ OP[0] ] & 0xffff;
+ divide_this = State.regs[ OP[1] ];
- if (divisor == 0)
+ if (divide_by == 0)
{
overflow = true;
- divisor = 1;
+ divide_by = 1;
}
- State.regs[ OP[1] ] = quotient = dividend / divisor;
- State.regs[ OP[2] >> 11 ] = remainder = dividend % divisor;
+ State.regs[ OP[1] ] = quotient = divide_this / divide_by;
+ State.regs[ OP[2] >> 11 ] = remainder = divide_this % divide_by;
/* Set condition codes. */
PSW &= ~(PSW_Z | PSW_S | PSW_OV);
if (overflow) PSW |= PSW_OV;
if (quotient == 0) PSW |= PSW_Z;
+ if (quotient & 0x80000000) PSW |= PSW_S;
trace_output (OP_REG_REG_REG);
}
/* start-sanitize-v850eq */
+/* divhun imm5, reg1, reg2, reg3 */
else
{
unsigned int imm5;
imm5 = 32 - ((OP[3] & 0x3c0000) >> 17);
- divisor = State.regs[ OP[0] ];
- dividend = State.regs[ OP[1] ] & 0xffff;
+ divide_by = State.regs[ OP[0] ] & 0xffff;
+ divide_this = State.regs[ OP[1] ];
- State.regs[ OP[1] ] = quotient = dividend / divisor;
- State.regs[ OP[2] >> 11 ] = remainder = dividend % divisor;
+ divun (imm5, divide_by, divide_this, & quotient, & remainder, & overflow);
- if ((divisor == 0)
- || (quotient > (1 << imm5))
- || (quotient < (((imm5 & 1) ? 1 : -1) << imm5)))
- {
- overflow = true;
- quotient = dividend;
- }
+ State.regs[ OP[1] ] = quotient;
+ State.regs[ OP[2] >> 11 ] = remainder;
/* Set condition codes. */
PSW &= ~(PSW_Z | PSW_S | PSW_OV);
if (overflow) PSW |= PSW_OV;
if (quotient == 0) PSW |= PSW_Z;
+ if (quotient & 0x80000000) PSW |= PSW_S;
trace_output (OP_IMM_REG_REG_REG);
}
}
/* divh reg1, reg2, reg3 */
-/* divhn imm5, reg1, reg2, reg3 */
int
OP_28007E0 (void)
{
signed long int quotient;
signed long int remainder;
- signed long int divisor;
- signed long int dividend;
+ signed long int divide_by;
+ signed long int divide_this;
boolean overflow = false;
if ((OP[3] & 0x3c0000) == 0)
/* Compute the result. */
- divisor = State.regs[ OP[0] ];
- dividend = SEXT16 (State.regs[ OP[1] ]);
+ divide_by = State.regs[ OP[0] ];
+ divide_this = SEXT16 (State.regs[ OP[1] ]);
- if (divisor == 0 || (divisor == -1 && dividend == (1 << 31)))
+ if (divide_by == 0 || (divide_by == -1 && divide_this == (1 << 31)))
{
overflow = true;
- divisor = 1;
+ divide_by = 1;
}
- State.regs[ OP[1] ] = quotient = dividend / divisor;
- State.regs[ OP[2] >> 11 ] = remainder = dividend % divisor;
+ State.regs[ OP[1] ] = quotient = divide_this / divide_by;
+ State.regs[ OP[2] >> 11 ] = remainder = divide_this % divide_by;
/* Set condition codes. */
PSW &= ~(PSW_Z | PSW_S | PSW_OV);
trace_output (OP_REG_REG_REG);
}
/* start-sanitize-v850eq */
+/* divhn imm5, reg1, reg2, reg3 */
else
{
unsigned int imm5;
imm5 = 32 - ((OP[3] & 0x3c0000) >> 17);
- divisor = State.regs[ OP[0] ];
- dividend = SEXT16 (State.regs[ OP[1] ]);
+ divide_by = SEXT16 (State.regs[ OP[0] ]);
+ divide_this = State.regs[ OP[1] ];
- State.regs[ OP[1] ] = quotient = dividend / divisor;
- State.regs[ OP[2] >> 11 ] = remainder = dividend % divisor;
+ divn (imm5, divide_by, divide_this, & quotient, & remainder, & overflow);
- if ((divisor == 0)
- || (quotient > (1 << imm5))
- || (divisor == -1 && dividend == (1 << 31))
- || (quotient < (((imm5 & 1) ? 1 : -1) << imm5)))
- {
- overflow = true;
- quotient = dividend;
- }
+ State.regs[ OP[1] ] = quotient;
+ State.regs[ OP[2] >> 11 ] = remainder;
/* Set condition codes. */
PSW &= ~(PSW_Z | PSW_S | PSW_OV);
return 4;
}
-/* end-sanitize-v850e */
-
-/* mulu reg1, reg2, reg3 */
-int
-OP_22207E0 (void)
-{
- trace_input ("mulu", OP_REG_REG_REG, 0);
-
- Multiply64 (false, State.regs[ OP[0] ]);
-
- trace_output (OP_REG_REG_REG);
-
- return 4;
-}
-
-/* start-sanitize-v850e */
-
/* mul imm9, reg2, reg3 */
int
OP_24007E0 (void)
if (value == 0) PSW |= PSW_Z;
if (value & 0x80000000) PSW |= PSW_S;
- if (((value & 0xffff) == 0) || (value & 0xffff0000) == 0) PSW |= PSW_CY;
+ if (((value & 0xff) == 0) || (value & 0x00ff) == 0) PSW |= PSW_CY;
trace_output (OP_REG_REG3);
trace_input ("pushml", OP_PUSHPOP3, 0);
+ /* Store the registers with lower number registers being placed at higher addresses. */
+ for (i = 0; i < 15; i++)
+ if ((OP[3] & (1 << type3_regs[ i ])))
+ {
+ SP -= 4;
+ store_mem (SP & ~ 3, 4, State.regs[ i + 1 ]);
+ }
+
+ if (OP[3] & (1 << 3))
+ {
+ SP -= 4;
+
+ store_mem (SP & ~ 3, 4, PSW);
+ }
+
if (OP[3] & (1 << 19))
{
SP -= 8;
}
}
- if (OP[3] & (1 << 3))
- {
- SP -= 4;
-
- store_mem (SP & ~ 3, 4, PSW);
- }
-
- /* Store the registers with lower number registers being placed at lower addresses. */
- for (i = 15; i--;)
- if ((OP[3] & (1 << type3_regs[ i ])))
- {
- SP -= 4;
- store_mem (SP & ~ 3, 4, State.regs[ i + 1 ]);
- }
-
trace_output (OP_PUSHPOP2);
}
else
trace_input ("prepare", OP_PUSHPOP1, 0);
- /* Store the registers with lower number registers being placed at lower addresses. */
- for (i = 12; i--;)
+ /* Store the registers with lower number registers being placed at higher addresses. */
+ for (i = 0; i < 12; i++)
if ((OP[3] & (1 << type1_regs[ i ])))
{
SP -= 4;
trace_input ("ld.bu", OP_LOAD32, 1);
- adr = State.regs[ OP[0] ] + SEXT16 (OP[2] & ~1) | ((OP[3] >> 5) & 1);
+ adr = (State.regs[ OP[0] ]
+ + (SEXT16 (OP[2] & ~1) | ((OP[3] >> 5) & 1)));
State.regs[ OP[1] ] = load_mem (adr, 1);
trace_input ("prepare", OP_PUSHPOP1, 0);
- /* Store the registers with lower number registers being placed at lower addresses. */
- for (i = 12; i--;)
+ /* Store the registers with lower number registers being placed at higher addresses. */
+ for (i = 0; i < 12; i++)
if ((OP[3] & (1 << type1_regs[ i ])))
{
SP -= 4;
trace_input ("prepare", OP_PUSHPOP1, 0);
- /* Store the registers with lower number registers being placed at lower addresses. */
- for (i = 12; i--;)
+ /* Store the registers with lower number registers being placed at higher addresses. */
+ for (i = 0; i < 12; i++)
if ((OP[3] & (1 << type1_regs[ i ])))
{
SP -= 4;
trace_input ("prepare", OP_PUSHPOP1, 0);
- /* Store the registers with lower number registers being placed at lower addresses. */
- for (i = 12; i--;)
+ /* Store the registers with lower number registers being placed at higher addresses. */
+ for (i = 0; i < 12; i++)
if ((OP[3] & (1 << type1_regs[ i ])))
{
SP -= 4;
trace_input ("prepare", OP_PUSHPOP1, 0);
- /* Store the registers with lower number registers being placed at lower addresses. */
- for (i = 12; i--;)
+ /* Store the registers with lower number registers being placed at higher addresses. */
+ for (i = 0; i < 12; i++)
if ((OP[3] & (1 << type1_regs[ i ])))
{
SP -= 4;
return 4;
}
+/* sld.hu */
+int
+OP_70 (void)
+{
+ unsigned long result;
+
+ result = load_mem (State.regs[30] + ((OP[3] & 0xf) << 1), 2);
+
+/* start-sanitize-v850eq */
+#ifdef ARCH_v850eq
+ trace_input ("sld.h", OP_LOAD16, 2);
+
+ State.regs[ OP[1] ] = SEXT16 (result);
+#else
+/* end-sanitize-v850eq */
+ trace_input ("sld.hu", OP_LOAD16, 2);
+
+ State.regs[ OP[1] ] = result;
+/* start-sanitize-v850eq */
+#endif
+/* end-sanitize-v850eq */
+
+ trace_output (OP_LOAD16);
+
+ return 2;
+}
+
+/* cmov reg1, reg2, reg3 */
+int
+OP_32007E0 (void)
+{
+ trace_input ("cmov", OP_REG_REG_REG, 0);
+
+ State.regs[ OP[2] >> 11 ] = condition_met (OP[0]) ? State.regs[ OP[0] ] : State.regs[ OP[1] ];
+
+ trace_output (OP_REG_REG_REG);
+
+ return 4;
+}
+
+/* mul reg1, reg2, reg3 */
+int
+OP_22007E0 (void)
+{
+ trace_input ("mul", OP_REG_REG_REG, 0);
+
+ Multiply64 (true, State.regs[ OP[0] ]);
+
+ trace_output (OP_REG_REG_REG);
+
+ return 4;
+}
+
/* end-sanitize-v850e */
/* start-sanitize-v850eq */
trace_input ("popmh", OP_PUSHPOP2, 0);
- /* Load the registers with lower number registers being retrieved from lower addresses. */
- for (i = 0; i++; i < 16)
- if ((OP[3] & (1 << type2_regs[ i ])))
- {
- State.regs[ i + 16 ] = load_mem (SP & ~ 3, 4);
- SP += 4;
- }
-
if (OP[3] & (1 << 19))
{
if ((PSW & PSW_NP) && ((PSW & PSW_EP) == 0))
SP += 8;
}
+ /* Load the registers with lower number registers being retrieved from higher addresses. */
+ for (i = 16; i--;)
+ if ((OP[3] & (1 << type2_regs[ i ])))
+ {
+ State.regs[ i + 16 ] = load_mem (SP & ~ 3, 4);
+ SP += 4;
+ }
+
trace_output (OP_PUSHPOP2);
return 4;
trace_input ("popml", OP_PUSHPOP3, 0);
- /* Load the registers with lower number registers being retrieved from lower addresses. */
- for (i = 0; i++; i < 15)
- if ((OP[3] & (1 << type3_regs[ i ])))
- {
- State.regs[ i + 1 ] = load_mem (SP & ~ 3, 4);
- SP += 4;
- }
-
- if (OP[3] & (1 << 3))
- {
- PSW = load_mem (SP & ~ 3, 4);
- SP += 4;
- }
-
if (OP[3] & (1 << 19))
{
if ((PSW & PSW_NP) && ((PSW & PSW_EP) == 0))
SP += 8;
}
+ if (OP[3] & (1 << 3))
+ {
+ PSW = load_mem (SP & ~ 3, 4);
+ SP += 4;
+ }
+
+ /* Load the registers with lower number registers being retrieved from higher addresses. */
+ for (i = 15; i--;)
+ if ((OP[3] & (1 << type3_regs[ i ])))
+ {
+ State.regs[ i + 1 ] = load_mem (SP & ~ 3, 4);
+ SP += 4;
+ }
+
trace_output (OP_PUSHPOP2);
+
+ return 4;
}
/* pushmh list18 */
trace_input ("pushmh", OP_PUSHPOP2, 0);
+ /* Store the registers with lower number registers being placed at higher addresses. */
+ for (i = 0; i < 16; i++)
+ if ((OP[3] & (1 << type2_regs[ i ])))
+ {
+ SP -= 4;
+ store_mem (SP & ~ 3, 4, State.regs[ i + 16 ]);
+ }
+
if (OP[3] & (1 << 19))
{
SP -= 8;
}
}
- /* Store the registers with lower number registers being placed at lower addresses. */
- for (i = 16; i--;)
- if ((OP[3] & (1 << type2_regs[ i ])))
- {
- SP -= 4;
- store_mem (SP & ~ 3, 4, State.regs[ i + 16 ]);
- }
-
trace_output (OP_PUSHPOP2);
return 4;
}
/* end-sanitize-v850eq */
-/* start-sanitize-v850e */
-
-/* sld.hu */
-int
-OP_70 (void)
-{
- unsigned long result;
-
- result = load_mem (State.regs[30] + ((OP[3] & 0xf) << 1), 2);
-
-/* start-sanitize-v850eq */
-#ifdef ARCH_v850eq
- trace_input ("sld.h", OP_LOAD16, 2);
-
- State.regs[ OP[1] ] = SEXT16 (result);
-#else
-/* end-sanitize-v850eq */
- trace_input ("sld.hu", OP_LOAD16, 2);
-
- State.regs[ OP[1] ] = result;
-/* start-sanitize-v850eq */
-#endif
-/* end-sanitize-v850eq */
-
- trace_output (OP_LOAD16);
-
- return 2;
-}
-
-/* cmov reg1, reg2, reg3 */
-int
-OP_32007E0 (void)
-{
- trace_input ("cmov", OP_REG_REG_REG, 0);
-
- State.regs[ OP[2] >> 11 ] = condition_met (OP[0]) ? State.regs[ OP[0] ] : State.regs[ OP[1] ];
-
- trace_output (OP_REG_REG_REG);
-
- return 4;
-}
-
-/* mul reg1, reg2, reg3 */
-int
-OP_22007E0 (void)
-{
- trace_input ("mul", OP_REG_REG_REG, 0);
-
- Multiply64 (true, State.regs[ OP[0] ]);
-
- trace_output (OP_REG_REG_REG);
-
- return 4;
-}
-
-/* end-sanitize-v850e */