* 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) 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 shift support.
* simops.c: Add multiply & divide support. Abort for system * simops.c: Add multiply & divide support. Abort for system

View File

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

View File

@ -28,12 +28,28 @@ static long
hash(insn) hash(insn)
long insn; long insn;
{ {
/* XXX This isn't right for 32bit opcodes, hell it isn't even if ((insn & 0x30) == 0
right for 16bit opcodes! */ || (insn & 0x38) == 0x10)
if (insn & 0x0600) return (insn & 0x07e0) >> 5;
return ((insn & 0x3F000000) >> 24); if ((insn & 0x3c) == 0x18
else || (insn & 0x3c) == 0x1c
return((insn & 0x07E0) >> 5); || (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 * static struct hash_entry *
@ -42,10 +58,7 @@ lookup_hash (ins)
{ {
struct hash_entry *h; struct hash_entry *h;
if (ins & 0x0f00) h = &hash_table[hash(ins)];
h = &hash_table[(ins & 0x3F000000) >> 24];
else
h = &hash_table[(ins & 0x07E0) >> 5];
while ( (ins & h->mask) != h->opcode) while ( (ins & h->mask) != h->opcode)
{ {
@ -60,56 +73,108 @@ lookup_hash (ins)
} }
uint32 uint32
get_longword_swap (x) get_longword (x)
uint16 x; uint8 *x;
{ {
uint8 *a = (uint8 *)(x + State.imem); uint8 *a = x;
return (a[0]<<24) + (a[1]<<16) + (a[2]<<8) + (a[3]); 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 uint16
get_word_swap (x) get_word (x)
uint16 x; uint8 *x;
{ {
uint8 *a = (uint8 *)(x + State.imem); uint8 *a = x;
return (a[0]<<8) + a[1]; return ((uint16)a[0]<<8) + a[1];
} }
void void
write_word_swap (addr, data) write_word (addr, data)
uint16 addr, data; uint8 *addr;
uint16 data;
{ {
uint8 *a = (uint8 *)(addr + State.imem); uint8 *a = addr;
a[0] = data >> 8; a[0] = data >> 8;
a[1] = data & 0xff; a[1] = data & 0xff;
} }
static void void
do_format_1 (insn) write_longword (addr, data)
uint32 insn; 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 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; 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 static void
do_format_3 (insn) do_format_3 (insn)
uint32 insn; uint32 insn;
{ {
printf("format 3 0x%x\n", insn >> 16); printf("format 3 0x%x\n", insn);
} }
static void static void
do_format_4 (insn) do_format_4 (insn)
uint32 insn; uint32 insn;
{ {
printf("format 4 0x%x\n", insn >> 16); printf("format 4 0x%x\n", insn);
} }
static void static void
@ -123,7 +188,14 @@ static void
do_format_6 (insn) do_format_6 (insn)
uint32 insn; uint32 insn;
{ {
struct hash_entry *h;
printf("format 6 0x%x\n", insn); 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 static void
@ -144,7 +216,13 @@ static void
do_formats_9_10 (insn) do_formats_9_10 (insn)
uint32 insn; uint32 insn;
{ {
struct hash_entry *h;
printf("formats 9 and 10 0x%x\n", insn); 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 void
@ -263,15 +341,11 @@ sim_resume (step, siggnal)
{ {
inst = RLW (PC); inst = RLW (PC);
oldpc = PC; oldpc = PC;
opcode = (inst & 0x07e00000) >> 21; opcode = (inst & 0x07e0) >> 5;
if ((opcode & 0x30) == 0) if ((opcode & 0x30) == 0
|| (opcode & 0x38) == 0x10)
{ {
do_format_1 (inst >> 16); do_format_1_2 (inst & 0xffff);
PC += 2;
}
else if ((opcode & 0x38) == 0x10)
{
do_format_2 (inst >> 16);
PC += 2; PC += 2;
} }
else if ((opcode & 0x3C) == 0x18 else if ((opcode & 0x3C) == 0x18
@ -280,13 +354,13 @@ sim_resume (step, siggnal)
|| (opcode & 0x3C) == 0x24 || (opcode & 0x3C) == 0x24
|| (opcode & 0x3C) == 0x28) || (opcode & 0x3C) == 0x28)
{ {
do_format_4 (inst >> 16); do_format_4 (inst & 0xffff);
PC += 2; PC += 2;
} }
else if ((opcode& 0x3C) == 0x23) else if ((opcode & 0x3C) == 0x23)
{ {
do_format_3 (inst >> 16); do_format_3 (inst & 0xffff);
PC += 2; /* No PC update, it's done in the instruction. */
} }
else if ((opcode & 0x38) == 0x30) else if ((opcode & 0x38) == 0x30)
{ {
@ -303,7 +377,7 @@ sim_resume (step, siggnal)
do_format_5 (inst); do_format_5 (inst);
PC += 4; PC += 4;
} }
else if ((opcode & 0x3E) == 0x3C) else if ((opcode & 0x3F) == 0x3E)
{ {
do_format_8 (inst); do_format_8 (inst);
PC += 4; PC += 4;

View File

@ -123,39 +123,85 @@ OP_660 ()
} }
/* add reg, reg /* add reg, reg */
XXX condition codes. */
void void
OP_1C0 () 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 /* add sign_extend(imm5), reg */
XXX condition codes. */
void void
OP_240 () OP_240 ()
{ {
int value = OP[0]; unsigned int op0, op1, result, z, s, cy, ov;
int temp;
value = (value << 27) >> 27; /* Compute the result. */
temp = (OP[0] & 0x1f);
temp = (temp << 27) >> 27;
op0 = temp;
op1 = State.regs[OP[1]];
result = op0 + op1;
State.regs[OP[1]] += value; /* 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 /* addi sign_extend(imm16), reg, reg */
XXX condition codes. */
void void
OP_600 () OP_600 ()
{ {
int value = OP[0]; unsigned int op0, op1, result, z, s, cy, ov;
int temp;
value = (value << 16) >> 16; /* Compute the result. */
temp = (OP[0] & 0xffff);
temp = (temp << 16) >> 16;
op0 = temp;
op1 = State.regs[OP[1]];
result = op0 + op1;
State.regs[OP[2]] = State.regs[OP[1]] + value; /* 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 /* 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 /* sar zero_extend(imm5),reg1
XXX condition codes. */ XXX condition codes. */
@ -413,70 +450,148 @@ OP_7E0 ()
{ {
} }
/* or reg, reg /* or reg, reg */
XXX condition codes. */
void void
OP_100 () 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 /* ori zero_extend(imm16), reg, reg */
XXX condition codes */
void void
OP_680 () OP_680 ()
{ {
int value = OP[0]; unsigned int op0, op1, result, z, s, cy, ov;
value &= 0xffff; op0 = OP[0] & 0xffff;
op1 = State.regs[OP[1]];
result = op0 | op1;
State.regs[OP[2]] = State.regs[OP[1]] | value; /* 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 /* and reg, reg */
XXX condition codes. */
void void
OP_140 () 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 /* andi zero_extend(imm16), reg, reg */
XXX condition codes. */
void void
OP_6C0 () OP_6C0 ()
{ {
int value = OP[0]; unsigned int op0, op1, result, z, s, cy, ov;
value &= 0xffff; op0 = OP[0] & 0xffff;
op1 = State.regs[OP[1]];
result = op0 & op1;
State.regs[OP[2]] = State.regs[OP[1]] & value; /* 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 /* xor reg, reg */
XXX condition codes. */
void void
OP_120 () 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 /* xori zero_extend(imm16), reg, reg */
XXX condition codes. */
void void
OP_6A0 () OP_6A0 ()
{ {
int value = OP[0]; unsigned int op0, op1, result, z, s, cy, ov;
value &= 0xffff; op0 = OP[0] & 0xffff;
op1 = State.regs[OP[1]];
result = op0 ^ op1;
State.regs[OP[2]] = State.regs[OP[1]] ^ value; /* 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 void

View File

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