* interp.c (hash): Update to be more accurate.

(lookup_hash): Call hash rather than computing the hash
        code here.
        (do_format_1_2): Handle format 1 and format 2 instructions.
        Get operands correctly and call the target function.
        (do_format_6): Get operands correctly and call the target
        function.
        (do_formats_9_10): Rough cut so shift ops will work.
        (sim_resume): Tweak to deal with format 1 and format 2
        handling in a single funtion.  Don't update the PC
        for format 3 insns.  Fix typos.
        * simops.c: Slightly reorganize.  Add condition code handling
        to "add", "addi", "and", "andi", "or", "ori", "xor", "xori"
        and "not" instructions.
        * v850_sim.h (reg_t): Registers are 32bits.
        (_state): The V850 has 32 general registers.  Add a 32bit
        psw and pc register too.  Add accessor macros
Fixing lots of stuff.  Starting to add condition code support.  Basically
check pointing the work to date.
This commit is contained in:
Jeff Law 1996-08-29 23:39:23 +00:00
parent 7fa565a6d3
commit 0ef0eba580
5 changed files with 348 additions and 138 deletions

View File

@ -1,5 +1,26 @@
Thu Aug 29 13:53:29 1996 Jeffrey A Law (law@cygnus.com)
* interp.c (hash): Update to be more accurate.
(lookup_hash): Call hash rather than computing the hash
code here.
(do_format_1_2): Handle format 1 and format 2 instructions.
Get operands correctly and call the target function.
(do_format_6): Get operands correctly and call the target
function.
(do_formats_9_10): Rough cut so shift ops will work.
(sim_resume): Tweak to deal with format 1 and format 2
handling in a single funtion. Don't update the PC
for format 3 insns. Fix typos.
* simops.c: Slightly reorganize. Add condition code handling
to "add", "addi", "and", "andi", "or", "ori", "xor", "xori"
and "not" instructions.
* v850_sim.h (reg_t): Registers are 32bits.
(_state): The V850 has 32 general registers. Add a 32bit
psw and pc register too. Add accessor macros
* Makefile.in, interp.c, v850_sim.h: Bring over endianness
changes from the d10v simulator.
* simops.c: Add shift support.
* simops.c: Add multiply & divide support. Abort for system

View File

@ -56,7 +56,7 @@ INSTALL_XFORM1= $(INSTALL_XFORM) -b=.1
AR = @AR@
AR_FLAGS = rc
CC = @CC@
CFLAGS = @CFLAGS@
CFLAGS = @CFLAGS@ @DEFS@
MAKEINFO = makeinfo
RANLIB = @RANLIB@
CC_FOR_BUILD = @CC_FOR_BUILD@

View File

@ -28,12 +28,28 @@ static long
hash(insn)
long insn;
{
/* XXX This isn't right for 32bit opcodes, hell it isn't even
right for 16bit opcodes! */
if (insn & 0x0600)
return ((insn & 0x3F000000) >> 24);
else
return((insn & 0x07E0) >> 5);
if ((insn & 0x30) == 0
|| (insn & 0x38) == 0x10)
return (insn & 0x07e0) >> 5;
if ((insn & 0x3c) == 0x18
|| (insn & 0x3c) == 0x1c
|| (insn & 0x3c) == 0x20
|| (insn & 0x3c) == 0x24
|| (insn & 0x3c) == 0x28
|| (insn & 0x3c) == 0x23)
return (insn & 0x07c0) >> 6;
if ((insn & 0x38) == 0x30)
return (insn & 0x07e0) >> 5;
/* What about sub-op field? XXX */
if ((insn & 0x38) == 0x38)
return (insn & 0x07e0) >> 5;
if ((insn & 0x3e) == 0x3c)
return (insn & 0x07c0) >> 6;
if ((insn & 0x3f) == 0x3e)
return (insn & 0xc7e0) >> 5;
/* Not really correct. XXX */
return insn & 0xffffffff;
}
static struct hash_entry *
@ -42,10 +58,7 @@ lookup_hash (ins)
{
struct hash_entry *h;
if (ins & 0x0f00)
h = &hash_table[(ins & 0x3F000000) >> 24];
else
h = &hash_table[(ins & 0x07E0) >> 5];
h = &hash_table[hash(ins)];
while ( (ins & h->mask) != h->opcode)
{
@ -60,56 +73,108 @@ lookup_hash (ins)
}
uint32
get_longword_swap (x)
uint16 x;
get_longword (x)
uint8 *x;
{
uint8 *a = (uint8 *)(x + State.imem);
return (a[0]<<24) + (a[1]<<16) + (a[2]<<8) + (a[3]);
uint8 *a = x;
return (a[3]<<24) + (a[2]<<16) + (a[1]<<8) + (a[0]);
}
int64
get_longlong (x)
uint8 *x;
{
uint8 *a = x;
return ((int64)a[0]<<56) + ((int64)a[1]<<48) + ((int64)a[2]<<40) + ((int64)a[3]<<32) +
((int64)a[4]<< 24) + ((int64)a[5]<<16) + ((int64)a[6]<<8) + (int64)a[7];
}
uint16
get_word_swap (x)
uint16 x;
get_word (x)
uint8 *x;
{
uint8 *a = (uint8 *)(x + State.imem);
return (a[0]<<8) + a[1];
uint8 *a = x;
return ((uint16)a[0]<<8) + a[1];
}
void
write_word_swap (addr, data)
uint16 addr, data;
write_word (addr, data)
uint8 *addr;
uint16 data;
{
uint8 *a = (uint8 *)(addr + State.imem);
uint8 *a = addr;
a[0] = data >> 8;
a[1] = data & 0xff;
}
static void
do_format_1 (insn)
uint32 insn;
void
write_longword (addr, data)
uint8 *addr;
uint32 data;
{
printf("format 1 0x%x\n", insn >> 16);
addr[0] = (data >> 24) & 0xff;
addr[1] = (data >> 16) & 0xff;
addr[2] = (data >> 8) & 0xff;
addr[3] = data & 0xff;
}
void
write_longlong (addr, data)
uint8 *addr;
int64 data;
{
uint8 *a = addr;
a[0] = data >> 56;
a[1] = (data >> 48) & 0xff;
a[2] = (data >> 40) & 0xff;
a[3] = (data >> 32) & 0xff;
a[4] = (data >> 24) & 0xff;
a[5] = (data >> 16) & 0xff;
a[6] = (data >> 8) & 0xff;
a[7] = data & 0xff;
}
static void
do_format_2 (insn)
get_operands (struct simops *s, uint32 ins)
{
int i, shift, bits, flags;
uint32 mask;
for (i=0; i < s->numops; i++)
{
shift = s->operands[3*i];
bits = s->operands[3*i+1];
flags = s->operands[3*i+2];
mask = 0x7FFFFFFF >> (31 - bits);
OP[i] = (ins >> shift) & mask;
}
}
static void
do_format_1_2 (insn)
uint32 insn;
{
printf("format 2 0x%x\n", insn >> 16);
struct hash_entry *h;
printf("format 1 or 2 0x%x\n", insn);
h = lookup_hash (insn);
OP[0] = insn & 0x1f;
OP[1] = (insn >> 11) & 0x1f;
(h->ops->func) ();
}
static void
do_format_3 (insn)
uint32 insn;
{
printf("format 3 0x%x\n", insn >> 16);
printf("format 3 0x%x\n", insn);
}
static void
do_format_4 (insn)
uint32 insn;
{
printf("format 4 0x%x\n", insn >> 16);
printf("format 4 0x%x\n", insn);
}
static void
@ -123,7 +188,14 @@ static void
do_format_6 (insn)
uint32 insn;
{
struct hash_entry *h;
printf("format 6 0x%x\n", insn);
h = lookup_hash (insn);
OP[0] = (insn >> 16) & 0xffff;
OP[1] = insn & 0x1f;
OP[2] = (insn >> 11) & 0x1f;
(h->ops->func) ();
}
static void
@ -144,7 +216,13 @@ static void
do_formats_9_10 (insn)
uint32 insn;
{
struct hash_entry *h;
printf("formats 9 and 10 0x%x\n", insn);
h = lookup_hash (insn);
OP[0] = insn & 0x1f;
OP[1] = (insn >> 11) & 0x1f;
(h->ops->func) ();
}
void
@ -263,15 +341,11 @@ sim_resume (step, siggnal)
{
inst = RLW (PC);
oldpc = PC;
opcode = (inst & 0x07e00000) >> 21;
if ((opcode & 0x30) == 0)
opcode = (inst & 0x07e0) >> 5;
if ((opcode & 0x30) == 0
|| (opcode & 0x38) == 0x10)
{
do_format_1 (inst >> 16);
PC += 2;
}
else if ((opcode & 0x38) == 0x10)
{
do_format_2 (inst >> 16);
do_format_1_2 (inst & 0xffff);
PC += 2;
}
else if ((opcode & 0x3C) == 0x18
@ -280,13 +354,13 @@ sim_resume (step, siggnal)
|| (opcode & 0x3C) == 0x24
|| (opcode & 0x3C) == 0x28)
{
do_format_4 (inst >> 16);
do_format_4 (inst & 0xffff);
PC += 2;
}
else if ((opcode& 0x3C) == 0x23)
else if ((opcode & 0x3C) == 0x23)
{
do_format_3 (inst >> 16);
PC += 2;
do_format_3 (inst & 0xffff);
/* No PC update, it's done in the instruction. */
}
else if ((opcode & 0x38) == 0x30)
{
@ -303,7 +377,7 @@ sim_resume (step, siggnal)
do_format_5 (inst);
PC += 4;
}
else if ((opcode & 0x3E) == 0x3C)
else if ((opcode & 0x3F) == 0x3E)
{
do_format_8 (inst);
PC += 4;

View File

@ -123,39 +123,85 @@ OP_660 ()
}
/* add reg, reg
XXX condition codes. */
/* add reg, reg */
void
OP_1C0 ()
{
State.regs[OP[1]] += State.regs[OP[0]];
unsigned int op0, op1, result, z, s, cy, ov;
/* Compute the result. */
op0 = State.regs[OP[0]];
op1 = State.regs[OP[1]];
result = op0 + op1;
/* Compute the condition codes. */
z = (result == 0);
s = (result & 0x80000000);
cy = (result < op0 || result < op1);
ov = ((op0 & 0x80000000) == (op1 & 0x80000000)
&& (op0 & 0x80000000) != (result & 0x80000000));
/* Store the result and condition codes. */
State.regs[OP[1]] = result;
State.psw &= ~(PSW_Z | PSW_S | PSW_CY | PSW_OV);
State.psw |= ((z ? PSW_Z : 0) | (s ? PSW_S : 0)
| (cy ? PSW_CY : 0) | (ov ? PSW_OV : 0));
}
/* add sign_extend(imm5), reg
XXX condition codes. */
/* add sign_extend(imm5), reg */
void
OP_240 ()
{
int value = OP[0];
value = (value << 27) >> 27;
unsigned int op0, op1, result, z, s, cy, ov;
int temp;
State.regs[OP[1]] += value;
/* Compute the result. */
temp = (OP[0] & 0x1f);
temp = (temp << 27) >> 27;
op0 = temp;
op1 = State.regs[OP[1]];
result = op0 + op1;
/* Compute the condition codes. */
z = (result == 0);
s = (result & 0x80000000);
cy = (result < op0 || result < op1);
ov = ((op0 & 0x80000000) == (op1 & 0x80000000)
&& (op0 & 0x80000000) != (result & 0x80000000));
/* Store the result and condition codes. */
State.regs[OP[1]] = result;
State.psw &= ~(PSW_Z | PSW_S | PSW_CY | PSW_OV);
State.psw |= ((z ? PSW_Z : 0) | (s ? PSW_S : 0)
| (cy ? PSW_CY : 0) | (ov ? PSW_OV : 0));
}
/* addi sign_extend(imm16), reg, reg
XXX condition codes. */
/* addi sign_extend(imm16), reg, reg */
void
OP_600 ()
{
int value = OP[0];
value = (value << 16) >> 16;
unsigned int op0, op1, result, z, s, cy, ov;
int temp;
State.regs[OP[2]] = State.regs[OP[1]] + value;
/* Compute the result. */
temp = (OP[0] & 0xffff);
temp = (temp << 16) >> 16;
op0 = temp;
op1 = State.regs[OP[1]];
result = op0 + op1;
/* Compute the condition codes. */
z = (result == 0);
s = (result & 0x80000000);
cy = (result < op0 || result < op1);
ov = ((op0 & 0x80000000) == (op1 & 0x80000000)
&& (op0 & 0x80000000) != (result & 0x80000000));
/* Store the result and condition codes. */
State.regs[OP[2]] = result;
State.psw &= ~(PSW_Z | PSW_S | PSW_CY | PSW_OV);
State.psw |= ((z ? PSW_Z : 0) | (s ? PSW_S : 0)
| (cy ? PSW_CY : 0) | (ov ? PSW_OV : 0));
}
/* sub reg1, reg2
@ -327,15 +373,6 @@ OP_80 ()
{
}
/* not reg1, reg2
XXX condition codes */
void
OP_20 ()
{
State.regs[OP[1]] = ~State.regs[OP[0]];
}
/* sar zero_extend(imm5),reg1
XXX condition codes. */
@ -413,70 +450,148 @@ OP_7E0 ()
{
}
/* or reg, reg
XXX condition codes. */
/* or reg, reg */
void
OP_100 ()
{
State.regs[OP[1]] |= State.regs[OP[0]];
unsigned int op0, op1, result, z, s, cy, ov;
/* Compute the result. */
op0 = State.regs[OP[0]];
op1 = State.regs[OP[1]];
result = op0 | op1;
/* Compute the condition codes. */
z = (result == 0);
s = (result & 0x80000000);
/* Store the result and condition codes. */
State.regs[OP[1]] = result;
State.psw &= ~(PSW_Z | PSW_S | PSW_OV);
State.psw |= ((z ? PSW_Z : 0) | (s ? PSW_S : 0));
}
/* ori zero_extend(imm16), reg, reg
XXX condition codes */
/* ori zero_extend(imm16), reg, reg */
void
OP_680 ()
{
int value = OP[0];
value &= 0xffff;
unsigned int op0, op1, result, z, s, cy, ov;
State.regs[OP[2]] = State.regs[OP[1]] | value;
op0 = OP[0] & 0xffff;
op1 = State.regs[OP[1]];
result = op0 | op1;
/* Compute the condition codes. */
z = (result == 0);
s = (result & 0x80000000);
/* Store the result and condition codes. */
State.regs[OP[2]] = result;
State.psw &= ~(PSW_Z | PSW_S | PSW_OV);
State.psw |= ((z ? PSW_Z : 0) | (s ? PSW_S : 0));
State.psw |= (z ? PSW_Z : 0);
}
/* and reg, reg
XXX condition codes. */
/* and reg, reg */
void
OP_140 ()
{
State.regs[OP[1]] &= State.regs[OP[0]];
unsigned int op0, op1, result, z, s, cy, ov;
/* Compute the result. */
op0 = State.regs[OP[0]];
op1 = State.regs[OP[1]];
result = op0 & op1;
/* Compute the condition codes. */
z = (result == 0);
s = (result & 0x80000000);
/* Store the result and condition codes. */
State.regs[OP[1]] = result;
State.psw &= ~(PSW_Z | PSW_S | PSW_OV);
State.psw |= ((z ? PSW_Z : 0) | (s ? PSW_S : 0));
}
/* andi zero_extend(imm16), reg, reg
XXX condition codes. */
/* andi zero_extend(imm16), reg, reg */
void
OP_6C0 ()
{
int value = OP[0];
value &= 0xffff;
unsigned int op0, op1, result, z, s, cy, ov;
State.regs[OP[2]] = State.regs[OP[1]] & value;
op0 = OP[0] & 0xffff;
op1 = State.regs[OP[1]];
result = op0 & op1;
/* Compute the condition codes. */
z = (result == 0);
/* Store the result and condition codes. */
State.regs[OP[2]] = result;
State.psw &= ~(PSW_Z | PSW_S | PSW_OV);
State.psw |= (z ? PSW_Z : 0);
}
/* xor reg, reg
XXX condition codes. */
/* xor reg, reg */
void
OP_120 ()
{
State.regs[OP[1]] ^= State.regs[OP[0]];
unsigned int op0, op1, result, z, s, cy, ov;
/* Compute the result. */
op0 = State.regs[OP[0]];
op1 = State.regs[OP[1]];
result = op0 ^ op1;
/* Compute the condition codes. */
z = (result == 0);
s = (result & 0x80000000);
/* Store the result and condition codes. */
State.regs[OP[1]] = result;
State.psw &= ~(PSW_Z | PSW_S | PSW_OV);
State.psw |= ((z ? PSW_Z : 0) | (s ? PSW_S : 0));
}
/* xori zero_extend(imm16), reg, reg
XXX condition codes. */
/* xori zero_extend(imm16), reg, reg */
void
OP_6A0 ()
{
int value = OP[0];
value &= 0xffff;
unsigned int op0, op1, result, z, s, cy, ov;
State.regs[OP[2]] = State.regs[OP[1]] ^ value;
op0 = OP[0] & 0xffff;
op1 = State.regs[OP[1]];
result = op0 ^ op1;
/* Compute the condition codes. */
z = (result == 0);
s = (result & 0x80000000);
/* Store the result and condition codes. */
State.regs[OP[2]] = result;
State.psw &= ~(PSW_Z | PSW_S | PSW_OV);
State.psw |= ((z ? PSW_Z : 0) | (s ? PSW_S : 0));
State.psw |= (z ? PSW_Z : 0);
}
/* not reg1, reg2 */
void
OP_20 ()
{
unsigned int op0, result, z, s, cy, ov;
/* Compute the result. */
op0 = State.regs[OP[0]];
result = ~op0;
/* Compute the condition codes. */
z = (result == 0);
s = (result & 0x80000000);
/* Store the result and condition codes. */
State.regs[OP[1]] = result;
State.psw &= ~(PSW_Z | PSW_S | PSW_OV);
State.psw |= ((z ? PSW_Z : 0) | (s ? PSW_S : 0));
}
void

View File

@ -13,7 +13,7 @@ typedef signed int int32;
typedef signed long long int64;
/* FIXME: V850 defines */
typedef uint16 reg_t;
typedef uint32 reg_t;
struct simops
{
@ -26,21 +26,9 @@ struct simops
struct _state
{
reg_t regs[16]; /* general-purpose registers */
reg_t cregs[16]; /* control registers */
int64 a[2]; /* accumulators */
uint8 SM;
uint8 EA;
uint8 DB;
uint8 IE;
uint8 RP;
uint8 MD;
uint8 FX;
uint8 ST;
uint8 F0;
uint8 F1;
uint8 C;
uint8 exe;
reg_t regs[32]; /* general-purpose registers */
reg_t pc;
reg_t psw;
uint8 *imem;
uint8 *dmem;
int exception;
@ -49,16 +37,17 @@ struct _state
extern uint16 OP[4];
extern struct simops Simops[];
#define PC (State.cregs[2])
#define PSW (State.cregs[0])
#define BPSW (State.cregs[1])
#define BPC (State.cregs[3])
#define RPT_C (State.cregs[7])
#define RPT_S (State.cregs[8])
#define RPT_E (State.cregs[9])
#define MOD_S (State.cregs[10])
#define MOD_E (State.cregs[11])
#define IBA (State.cregs[14])
#define PC (State.pc)
#define PSW (State.psw)
#define PSW_NP 0x80
#define PSW_EP 0x40
#define PSW_ID 0x20
#define PSW_SAT 0x10
#define PSW_CY 0x8
#define PSW_OV 0x4
#define PSW_S 0x2
#define PSW_Z 0x1
#define SEXT3(x) ((((x)&0x7)^(~3))+4)
@ -95,17 +84,28 @@ extern struct simops Simops[];
#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 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)
#else
uint32 get_longword_swap PARAMS ((uint16 x));
uint16 get_word_swap PARAMS ((uint16 x));
void write_word_swap PARAMS ((uint16 addr, uint16 data));
#define SW(addr,data) write_word_swap(addr,data)
#define RW(x) get_word_swap(x)
#define RLW(x) get_longword_swap(x)
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)
#endif /* not WORDS_BIGENDIAN */