aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sim/v850/ChangeLog24
-rw-r--r--sim/v850/interp.c26
-rw-r--r--sim/v850/simops.c237
-rw-r--r--sim/v850/v850_sim.h39
4 files changed, 248 insertions, 78 deletions
diff --git a/sim/v850/ChangeLog b/sim/v850/ChangeLog
index cfbb027..75293ff 100644
--- a/sim/v850/ChangeLog
+++ b/sim/v850/ChangeLog
@@ -1,3 +1,27 @@
+Tue Sep 3 10:20:30 1996 Jeffrey A Law (law@cygnus.com)
+
+ * interp.c: OP should be an array of 32bit operands!
+ (v850_callback): Declare.
+ (do_format_5): Fix extraction of OP[0].
+ (sim_size): Remove debugging printf.
+ (sim_set_callbacks): Do something useful.
+ (sim_stop_reason): Gross hacks to get c-torture running.
+ * simops.c: Simplify code for computing targets of bCC
+ insns. Invert 's' bit if 'ov' bit is set for some
+ instructions. Fix 'cy' bit handling for numerous
+ instructions. Make the simulator stop when a halt
+ instruction is encountered. Very crude support for
+ emulated syscalls (trap 0).
+ * v850_sim.h: Include "callback.h" and declare
+ v850_callback. Items in the operand array are 32bits.
+
+Sun Sep 1 22:35:35 1996 Jeffrey A Law (law@cygnus.com)
+
+ * interp.c (sim_resume): Fix code to check for a format 3
+ opcode.
+ * simops.c: bCC insns only argument is a constant, not a
+ register value (duh...)
+
Fri Aug 30 10:33:49 1996 Jeffrey A Law (law@cygnus.com)
* simops.c: Fix "not1" and "set1".
diff --git a/sim/v850/interp.c b/sim/v850/interp.c
index 71c391e..b99dea6 100644
--- a/sim/v850/interp.c
+++ b/sim/v850/interp.c
@@ -8,7 +8,10 @@
#define MEM_SIZE 18 /* V850 memory size is 18 bits XXX */
-uint16 OP[4];
+host_callback *v850_callback;
+
+
+uint32 OP[4];
static struct hash_entry *lookup_hash PARAMS ((uint32 ins));
@@ -161,7 +164,7 @@ do_format_5 (insn)
struct hash_entry *h;
h = lookup_hash (insn);
- OP[0] = ((insn & 0x3f) | (((insn >> 17) & 0x7fff) << 6)) << 1;
+ OP[0] = (((insn & 0x3f) << 15) | ((insn >> 17) & 0x7fff)) << 1;
OP[1] = (insn >> 11) & 0x1f;
(h->ops->func) ();
}
@@ -233,7 +236,6 @@ sim_size (power)
fprintf (stderr,"Memory allocation failed.\n");
exit(1);
}
- printf ("Allocated %d bytes memory and\n",1<<MEM_SIZE);
}
static void
@@ -344,7 +346,7 @@ sim_resume (step, siggnal)
do_format_4 (inst & 0xffff);
PC += 2;
}
- else if ((opcode & 0x3C) == 0x23)
+ else if ((opcode & 0x3C) == 0x2C)
{
do_format_3 (inst & 0xffff);
/* No PC update, it's done in the instruction. */
@@ -412,25 +414,23 @@ void
sim_set_callbacks(p)
host_callback *p;
{
- /* callback = p; */
+ v850_callback = p;
}
+/* All the code for exiting, signals, etc needs to be revamped. */
+
+ This is enough to get c-torture limping though. */
void
sim_stop_reason (reason, sigrc)
enum sim_stop *reason;
int *sigrc;
{
+ *reason = sim_stopped;
if (State.exception == SIGQUIT)
- {
- *reason = sim_exited;
- *sigrc = State.exception;
- }
+ *sigrc = 0;
else
- {
- *reason = sim_stopped;
- *sigrc = State.exception;
- }
+ *sigrc = State.exception;
}
void
diff --git a/sim/v850/simops.c b/sim/v850/simops.c
index 5ab83dc..2cd088a 100644
--- a/sim/v850/simops.c
+++ b/sim/v850/simops.c
@@ -191,8 +191,7 @@ OP_580 ()
unsigned int op0, psw;
int temp;
- temp = (State.regs[OP[0]] << 23) >> 23;
- op0 = temp;
+ op0 = ((signed)OP[0] << 23) >> 23;
psw = State.sregs[5];
if ((psw & PSW_OV) != 0)
@@ -208,8 +207,7 @@ OP_581 ()
unsigned int op0, psw;
int temp;
- temp = (State.regs[OP[0]] << 23) >> 23;
- op0 = temp;
+ op0 = ((signed)OP[0] << 23) >> 23;
psw = State.sregs[5];
if ((psw & PSW_CY) != 0)
@@ -225,8 +223,7 @@ OP_582 ()
unsigned int op0, psw;
int temp;
- temp = (State.regs[OP[0]] << 23) >> 23;
- op0 = temp;
+ op0 = ((signed)OP[0] << 23) >> 23;
psw = State.sregs[5];
if ((psw & PSW_Z) != 0)
@@ -242,8 +239,7 @@ OP_583 ()
unsigned int op0, psw;
int temp;
- temp = (State.regs[OP[0]] << 23) >> 23;
- op0 = temp;
+ op0 = ((signed)OP[0] << 23) >> 23;
psw = State.sregs[5];
if ((((psw & PSW_CY) != 0) | ((psw & PSW_Z) != 0)) != 0)
@@ -259,8 +255,7 @@ OP_584 ()
unsigned int op0, psw;
int temp;
- temp = (State.regs[OP[0]] << 23) >> 23;
- op0 = temp;
+ op0 = ((signed)OP[0] << 23) >> 23;
psw = State.sregs[5];
if ((psw & PSW_S) != 0)
@@ -276,8 +271,7 @@ OP_585 ()
unsigned int op0;
int temp;
- temp = (State.regs[OP[0]] << 23) >> 23;
- op0 = temp;
+ op0 = ((signed)OP[0] << 23) >> 23;
State.pc += op0;
}
@@ -288,8 +282,7 @@ OP_586 ()
unsigned int op0, psw;
int temp;
- temp = (State.regs[OP[0]] << 23) >> 23;
- op0 = temp;
+ op0 = ((signed)OP[0] << 23) >> 23;
psw = State.sregs[5];
if ((((psw & PSW_S) != 0) ^ ((psw & PSW_OV) != 0)) != 0)
@@ -305,8 +298,7 @@ OP_587 ()
unsigned int op0, psw;
int temp;
- temp = (State.regs[OP[0]] << 23) >> 23;
- op0 = temp;
+ op0 = ((signed)OP[0] << 23) >> 23;
psw = State.sregs[5];
if ((((psw & PSW_Z) != 0)
@@ -323,8 +315,7 @@ OP_588 ()
unsigned int op0, psw;
int temp;
- temp = (State.regs[OP[0]] << 23) >> 23;
- op0 = temp;
+ op0 = ((signed)OP[0] << 23) >> 23;
psw = State.sregs[5];
if ((psw & PSW_OV) == 0)
@@ -340,8 +331,7 @@ OP_589 ()
unsigned int op0, psw;
int temp;
- temp = (State.regs[OP[0]] << 23) >> 23;
- op0 = temp;
+ op0 = ((signed)OP[0] << 23) >> 23;
psw = State.sregs[5];
if ((psw & PSW_CY) == 0)
@@ -357,8 +347,7 @@ OP_58A ()
unsigned int op0, psw;
int temp;
- temp = (State.regs[OP[0]] << 23) >> 23;
- op0 = temp;
+ op0 = ((signed)OP[0] << 23) >> 23;
psw = State.sregs[5];
if ((psw & PSW_Z) == 0)
@@ -374,8 +363,7 @@ OP_58B ()
unsigned int op0, psw;
int temp;
- temp = (State.regs[OP[0]] << 23) >> 23;
- op0 = temp;
+ op0 = ((signed)OP[0] << 23) >> 23;
psw = State.sregs[5];
if ((((psw & PSW_CY) != 0) | ((psw & PSW_Z) != 0)) == 0)
@@ -391,8 +379,7 @@ OP_58C ()
unsigned int op0, psw;
int temp;
- temp = (State.regs[OP[0]] << 23) >> 23;
- op0 = temp;
+ op0 = ((signed)OP[0] << 23) >> 23;
psw = State.sregs[5];
if ((psw & PSW_S) == 0)
@@ -408,8 +395,7 @@ OP_58D ()
unsigned int op0, psw;
int temp;
- temp = (State.regs[OP[0]] << 23) >> 23;
- op0 = temp;
+ op0 = ((signed)OP[0] << 23) >> 23;
psw = State.sregs[5];
if ((psw & PSW_SAT) != 0)
@@ -425,8 +411,7 @@ OP_58E ()
unsigned int op0, psw;
int temp;
- temp = (State.regs[OP[0]] << 23) >> 23;
- op0 = temp;
+ op0 = ((signed)OP[0] << 23) >> 23;
psw = State.sregs[5];
if ((((psw & PSW_S) != 0) ^ ((psw & PSW_OV) != 0)) == 0)
@@ -442,8 +427,7 @@ OP_58F ()
unsigned int op0, psw;
int temp;
- temp = (State.regs[OP[0]] << 23) >> 23;
- op0 = temp;
+ op0 = ((signed)OP[0] << 23) >> 23;
psw = State.sregs[5];
if ((((psw & PSW_Z) != 0)
@@ -498,6 +482,10 @@ OP_1C0 ()
ov = ((op0 & 0x80000000) == (op1 & 0x80000000)
&& (op0 & 0x80000000) != (result & 0x80000000));
+ /* According to the manual, 's' is inverted if 'ov'
+ is set. */
+ s = ov ? !s : s;
+
/* Store the result and condition codes. */
State.regs[OP[1]] = result;
State.sregs[5] &= ~(PSW_Z | PSW_S | PSW_CY | PSW_OV);
@@ -526,6 +514,10 @@ OP_240 ()
ov = ((op0 & 0x80000000) == (op1 & 0x80000000)
&& (op0 & 0x80000000) != (result & 0x80000000));
+ /* According to the manual, 's' is inverted if 'ov'
+ is set. */
+ s = ov ? !s : s;
+
/* Store the result and condition codes. */
State.regs[OP[1]] = result;
State.sregs[5] &= ~(PSW_Z | PSW_S | PSW_CY | PSW_OV);
@@ -554,6 +546,10 @@ OP_600 ()
ov = ((op0 & 0x80000000) == (op1 & 0x80000000)
&& (op0 & 0x80000000) != (result & 0x80000000));
+ /* According to the manual, 's' is inverted if 'ov'
+ is set. */
+ s = ov ? !s : s;
+
/* Store the result and condition codes. */
State.regs[OP[2]] = result;
State.sregs[5] &= ~(PSW_Z | PSW_S | PSW_CY | PSW_OV);
@@ -575,10 +571,14 @@ OP_1A0 ()
/* Compute the condition codes. */
z = (result == 0);
s = (result & 0x80000000);
- cy = (result < -op0);
+ cy = (op1 < op0);
ov = ((op1 & 0x80000000) != (op0 & 0x80000000)
&& (op1 & 0x80000000) != (result & 0x80000000));
+ /* According to the manual, 's' is inverted if 'ov'
+ is set. */
+ s = ov ? !s : s;
+
/* Store the result and condition codes. */
State.regs[OP[1]] = result;
State.sregs[5] &= ~(PSW_Z | PSW_S | PSW_CY | PSW_OV);
@@ -600,10 +600,14 @@ OP_180 ()
/* Compute the condition codes. */
z = (result == 0);
s = (result & 0x80000000);
- cy = (result < -op1);
+ cy = (op0 < op1);
ov = ((op0 & 0x80000000) != (op1 & 0x80000000)
&& (op0 & 0x80000000) != (result & 0x80000000));
+ /* According to the manual, 's' is inverted if 'ov'
+ is set. */
+ s = ov ? !s : s;
+
/* Store the result and condition codes. */
State.regs[OP[1]] = result;
State.sregs[5] &= ~(PSW_Z | PSW_S | PSW_CY | PSW_OV);
@@ -694,7 +698,7 @@ OP_1E0 ()
/* Compute the condition codes. */
z = (result == 0);
s = (result & 0x80000000);
- cy = (result < -op0);
+ cy = (op1 < op0);
ov = ((op1 & 0x80000000) != (op0 & 0x80000000)
&& (op1 & 0x80000000) != (result & 0x80000000));
@@ -721,7 +725,7 @@ OP_260 ()
/* Compute the condition codes. */
z = (result == 0);
s = (result & 0x80000000);
- cy = (result < -op0);
+ cy = (op1 < op0);
ov = ((op1 & 0x80000000) != (op0 & 0x80000000)
&& (op1 & 0x80000000) != (result & 0x80000000));
@@ -883,7 +887,7 @@ OP_A0 ()
/* Compute the condition codes. */
z = (result == 0);
s = (result & 0x80000000);
- cy = (result < -op0);
+ cy = (op1 < op0);
ov = ((op1 & 0x80000000) != (op0 & 0x80000000)
&& (op1 & 0x80000000) != (result & 0x80000000));
sat = ov;
@@ -919,7 +923,7 @@ OP_660 ()
/* Compute the condition codes. */
z = (result == 0);
s = (result & 0x80000000);
- cy = (result < -op0);
+ cy = (op1 < op0);
ov = ((op1 & 0x80000000) != (op0 & 0x80000000)
&& (op1 & 0x80000000) != (result & 0x80000000));
sat = ov;
@@ -951,7 +955,7 @@ OP_80 ()
/* Compute the condition codes. */
z = (result == 0);
s = (result & 0x80000000);
- cy = (result < -op0);
+ cy = (result < op0);
ov = ((op1 & 0x80000000) != (op0 & 0x80000000)
&& (op1 & 0x80000000) != (result & 0x80000000));
sat = ov;
@@ -1400,7 +1404,7 @@ OP_16087E0 ()
void
OP_12007E0 ()
{
- abort ();
+ State.exception = SIGQUIT;
}
/* reti, not supported */
@@ -1414,7 +1418,158 @@ OP_14007E0 ()
void
OP_10007E0 ()
{
- abort ();
+ extern int errno;
+
+ /* Trap 0 is used for simulating low-level I/O */
+
+ if (OP[0] == 0)
+ {
+#if 0
+ char *fstr = State.regs[2] + State.imem;
+ printf (fstr,State.regs[3],State.regs[4],State.regs[5]);
+#else
+ int save_errno = errno;
+ errno = 0;
+
+/* Registers passed to trap 0 */
+
+#define FUNC State.regs[6] /* function number, return value */
+#define PARM1 State.regs[7] /* optional parm 1 */
+#define PARM2 State.regs[8] /* optional parm 2 */
+#define PARM3 State.regs[9] /* optional parm 3 */
+
+/* Registers set by trap 0 */
+
+#define RETVAL State.regs[10] /* return value */
+#define RETERR State.regs[11] /* return error code */
+
+/* Turn a pointer in a register into a pointer into real memory. */
+
+#define MEMPTR(x) ((char *)((x) + State.mem))
+
+
+ switch (FUNC)
+ {
+#if 0
+#if !defined(__GO32__) && !defined(_WIN32)
+ case SYS_fork:
+ RETVAL = fork ();
+ break;
+ case SYS_execve:
+ RETVAL = execve (MEMPTR (PARM1), (char **) MEMPTR (PARM2),
+ (char **)MEMPTR (PARM3));
+ break;
+ case SYS_execv:
+ RETVAL = execve (MEMPTR (PARM1), (char **) MEMPTR (PARM2), NULL);
+ break;
+ case SYS_pipe:
+ {
+ reg_t buf;
+ int host_fd[2];
+
+ buf = PARM1;
+ RETVAL = pipe (host_fd);
+ SW (buf, host_fd[0]);
+ buf += sizeof(uint16);
+ SW (buf, host_fd[1]);
+ }
+ break;
+
+ case SYS_wait:
+ {
+ int status;
+
+ RETVAL = wait (&status);
+ SW (PARM1, status);
+ }
+ break;
+#endif
+
+ case SYS_read:
+ RETVAL = v850_callback->read (v850_callback, PARM1, MEMPTR (PARM2),
+ PARM3);
+ break;
+#endif
+ 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;
+#if 0
+ case SYS_lseek:
+ RETVAL = v850_callback->lseek (v850_callback, PARM1, PARM2, PARM3);
+ break;
+ case SYS_close:
+ RETVAL = v850_callback->close (v850_callback, PARM1);
+ break;
+ case SYS_open:
+ RETVAL = v850_callback->open (v850_callback, MEMPTR (PARM1), PARM2);
+ break;
+#endif
+ case SYS_exit:
+ /* EXIT - caller can look in PARM1 to work out the
+ reason */
+ if (PARM1 == 0xdead || PARM1 == 0x1)
+ State.exception = SIGABRT;
+ else
+ State.exception = SIGQUIT;
+ break;
+
+#if 0
+ case SYS_stat: /* added at hmsi */
+ /* stat system call */
+ {
+ struct stat host_stat;
+ reg_t buf;
+
+ RETVAL = stat (MEMPTR (PARM1), &host_stat);
+
+ buf = PARM2;
+
+ /* The hard-coded offsets and sizes were determined by using
+ * the D10V compiler on a test program that used struct stat.
+ */
+ SW (buf, host_stat.st_dev);
+ SW (buf+2, host_stat.st_ino);
+ SW (buf+4, host_stat.st_mode);
+ SW (buf+6, host_stat.st_nlink);
+ SW (buf+8, host_stat.st_uid);
+ SW (buf+10, host_stat.st_gid);
+ SW (buf+12, host_stat.st_rdev);
+ SLW (buf+16, host_stat.st_size);
+ SLW (buf+20, host_stat.st_atime);
+ SLW (buf+28, host_stat.st_mtime);
+ SLW (buf+36, host_stat.st_ctime);
+ }
+ break;
+
+ case SYS_chown:
+ RETVAL = chown (MEMPTR (PARM1), PARM2, PARM3);
+ break;
+ case SYS_chmod:
+ RETVAL = chmod (MEMPTR (PARM1), PARM2);
+ break;
+ 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));
+ break;
+#endif
+ default:
+ abort ();
+ }
+ RETERR = errno;
+ errno = save_errno;
+#endif
+ }
+ else if (OP[0] == 1 )
+ {
+ char *fstr = State.regs[2] + State.mem;
+ puts (fstr);
+ }
}
/* ldsr, reg,reg */
diff --git a/sim/v850/v850_sim.h b/sim/v850/v850_sim.h
index be0f1b6..e4b7746 100644
--- a/sim/v850/v850_sim.h
+++ b/sim/v850/v850_sim.h
@@ -1,8 +1,11 @@
#include <stdio.h>
#include <ctype.h>
#include "ansidecl.h"
+#include "callback.h"
#include "opcode/v850.h"
+extern host_callback *v850_callback;
+
/* FIXME: host defines */
typedef unsigned char uint8;
typedef unsigned short uint16;
@@ -29,12 +32,11 @@ struct _state
reg_t regs[32]; /* general-purpose registers */
reg_t sregs[32]; /* system regsiters, including psw */
reg_t pc;
- uint8 *imem;
- uint8 *dmem;
+ uint8 *mem;
int exception;
} State;
-extern uint16 OP[4];
+extern uint32 OP[4];
extern struct simops Simops[];
#define PC (State.pc)
@@ -78,33 +80,22 @@ extern struct simops Simops[];
#define INC_ADDR(x,i) x = ((State.MD && x == MOD_E) ? MOD_S : (x)+(i))
-#define RB(x) (*((uint8 *)((x)+State.imem)))
+#define RB(x) (*((uint8 *)((x)+State.mem)))
#define SB(addr,data) ( RB(addr) = (data & 0xff))
#ifdef WORDS_BIGENDIAN
-#define RW(x) (*((uint16 *)((x)+State.imem)))
-#define RLW(x) (*((uint32 *)((x)+State.imem)))
-#define SW(addr,data) RW(addr)=data
-#define READ_16(x) (*((int16 *)(x)))
-#define WRITE_16(addr,data) (*(int16 *)(addr)=data)
-#define READ_64(x) (*((int64 *)(x)))
-#define WRITE_64(addr,data) (*(int64 *)(addr)=data)
+uint32 get_word PARAMS ((uint8 *));
+uint16 get_half PARAMS ((uint8 *));
+uint8 get_byte PARAMS ((uint8 *));
+#define RLW(x) (*((uint32 *)((x)+State.mem)))
#else
-uint32 get_longword PARAMS ((uint8 *));
-uint16 get_word PARAMS ((uint8 *));
-int64 get_longlong PARAMS ((uint8 *));
-void write_word PARAMS ((uint8 *addr, uint16 data));
-void write_longlong PARAMS ((uint8 *addr, int64 data));
-
-#define SW(addr,data) write_word((long)(addr)+State.imem,data)
-#define RW(x) get_word((long)(x)+State.imem)
-#define RLW(x) get_longword((long)(x)+State.imem)
-#define READ_16(x) get_word(x)
-#define WRITE_16(addr,data) write_word(addr,data)
-#define READ_64(x) get_longlong(x)
-#define WRITE_64(addr,data) write_longlong(addr,data)
+uint32 get_word PARAMS ((uint8 *));
+uint16 get_half PARAMS ((uint8 *));
+uint8 get_byte PARAMS ((uint8 *));
+
+#define RLW(x) get_word((long)(x)+State.mem)
#endif /* not WORDS_BIGENDIAN */