aboutsummaryrefslogtreecommitdiff
path: root/sim/v850/interp.c
diff options
context:
space:
mode:
authorJeff Law <law@redhat.com>1996-08-29 23:39:23 +0000
committerJeff Law <law@redhat.com>1996-08-29 23:39:23 +0000
commit0ef0eba580c6ef4450878098fdbe71681de42bb4 (patch)
tree1fbacc3637051ba634c98e9c0725c1fe2d47a500 /sim/v850/interp.c
parent7fa565a6d3edf64e76b48407a769e0aa7f9b6cee (diff)
downloadgdb-0ef0eba580c6ef4450878098fdbe71681de42bb4.zip
gdb-0ef0eba580c6ef4450878098fdbe71681de42bb4.tar.gz
gdb-0ef0eba580c6ef4450878098fdbe71681de42bb4.tar.bz2
* 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.
Diffstat (limited to 'sim/v850/interp.c')
-rw-r--r--sim/v850/interp.c156
1 files changed, 115 insertions, 41 deletions
diff --git a/sim/v850/interp.c b/sim/v850/interp.c
index 0e9d102..bcbb982 100644
--- a/sim/v850/interp.c
+++ b/sim/v850/interp.c
@@ -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;
}
+void
+write_longword (addr, data)
+ uint8 *addr;
+ uint32 data;
+{
+ 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_1 (insn)
- uint32 insn;
+get_operands (struct simops *s, uint32 ins)
{
- printf("format 1 0x%x\n", insn >> 16);
+ 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_2 (insn)
+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)
- {
- do_format_1 (inst >> 16);
- PC += 2;
- }
- else if ((opcode & 0x38) == 0x10)
+ opcode = (inst & 0x07e0) >> 5;
+ if ((opcode & 0x30) == 0
+ || (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;