Add PC-relative branch support to moxie sim.

This commit is contained in:
Anthony Green 2009-06-11 11:36:14 +00:00
parent f865a31d1e
commit 8656620041
2 changed files with 103 additions and 122 deletions

View File

@ -1,3 +1,8 @@
2009-06-11 Anthony Green <green@moxielogic.com>
* interp.c (INST2OFFSET): Define.
(sim_resume): Support new PC relative branch instructions.
2009-05-09 Anthony Green <green@moxielogic.com>
* interp.c (sim_resume): Add missing breaks in switch.

View File

@ -35,6 +35,10 @@ host_callback * callback;
FILE *tracefile;
/* Extract the signed 10-bit offset from a 16-bit branch
instruction. */
#define INST2OFFSET(o) ((((signed short)((o & ((1<<10)-1))<<6))>>6)<<1)
#define EXTRACT_WORD(addr) (((addr)[0] << 24) \
+ ((addr)[1] << 16) \
+ ((addr)[2] << 8) \
@ -424,10 +428,86 @@ sim_resume (sd, step, siggnal)
if (inst & (1 << 14))
{
/* This is a Form 3 instruction. */
/* We haven't implemented any yet, so just SIGILL for now. */
TRACE("SIGILL3");
cpu.asregs.exception = SIGILL;
break;
int opcode = (inst >> 10 & 0xf);
switch (opcode)
{
case 0x00: /* beq */
{
TRACE("beq");
if (cpu.asregs.cc & CC_EQ)
pc += INST2OFFSET(inst) - 2;
}
break;
case 0x01: /* bne */
{
TRACE("bne");
if (! (cpu.asregs.cc & CC_EQ))
pc += INST2OFFSET(inst) - 2;
}
break;
case 0x02: /* blt */
{
TRACE("blt");
if (cpu.asregs.cc & CC_LT)
pc += INST2OFFSET(inst) - 2;
} break;
case 0x03: /* bgt */
{
TRACE("bgt");
if (cpu.asregs.cc & CC_GT)
pc += INST2OFFSET(inst) - 2;
}
break;
case 0x04: /* bltu */
{
TRACE("bltu");
if (cpu.asregs.cc & CC_LTU)
pc += INST2OFFSET(inst) - 2;
}
break;
case 0x05: /* bgtu */
{
TRACE("bgtu");
if (cpu.asregs.cc & CC_GTU)
pc += INST2OFFSET(inst) - 2;
}
break;
case 0x06: /* bge */
{
TRACE("bge");
if (cpu.asregs.cc & (CC_GT | CC_EQ))
pc += INST2OFFSET(inst) - 2;
}
break;
case 0x07: /* ble */
{
TRACE("ble");
if (cpu.asregs.cc & (CC_LT | CC_EQ))
pc += INST2OFFSET(inst) - 2;
}
break;
case 0x08: /* bgeu */
{
TRACE("bgeu");
if (cpu.asregs.cc & (CC_GTU | CC_EQ))
pc += INST2OFFSET(inst) - 2;
}
break;
case 0x09: /* bleu */
{
TRACE("bleu");
if (cpu.asregs.cc & (CC_LTU | CC_EQ))
pc += INST2OFFSET(inst) - 2;
}
break;
default:
{
TRACE("SIGILL3");
cpu.asregs.exception = SIGILL;
break;
}
}
}
else
{
@ -655,126 +735,22 @@ sim_resume (sd, step, siggnal)
cpu.asregs.cc = cc;
}
break;
case 0x0f: /* beq */
case 0x0f:
case 0x10:
case 0x11:
case 0x12:
case 0x13:
case 0x14:
case 0x15:
case 0x16:
case 0x17:
case 0x18:
{
unsigned int tgt = EXTRACT_WORD(&memory[pc+2]);
TRACE("beq");
if (cpu.asregs.cc & CC_EQ)
{
pc = tgt - 2;
}
else
pc += 4;
opc = opcode;
TRACE("SIGILL0");
cpu.asregs.exception = SIGILL;
break;
}
break;
case 0x10: /* bne */
{
unsigned int tgt = EXTRACT_WORD(&memory[pc+2]);
TRACE("bne");
if (! (cpu.asregs.cc & CC_EQ))
{
pc = tgt - 2;
}
else
pc += 4;
}
break;
case 0x11: /* blt */
{
unsigned int tgt = EXTRACT_WORD(&memory[pc+2]);
TRACE("blt");
if (cpu.asregs.cc & CC_LT)
{
pc = tgt - 2;
}
else
pc += 4;
}
break;
case 0x12: /* bgt */
{
unsigned int tgt = EXTRACT_WORD(&memory[pc+2]);
TRACE("bgt");
if (cpu.asregs.cc & CC_GT)
{
pc = tgt - 2;
}
else
pc += 4;
}
break;
case 0x13: /* bltu */
{
unsigned int tgt = EXTRACT_WORD(&memory[pc+2]);
TRACE("bltu");
if (cpu.asregs.cc & CC_LTU)
{
pc = tgt - 2;
}
else
pc += 4;
}
break;
case 0x14: /* bgtu */
{
unsigned int tgt = EXTRACT_WORD(&memory[pc+2]);
TRACE("bgtu");
if (cpu.asregs.cc & CC_GTU)
{
pc = tgt - 2;
}
else
pc += 4;
}
break;
case 0x15: /* bge */
{
unsigned int tgt = EXTRACT_WORD(&memory[pc+2]);
TRACE("bge");
if ((cpu.asregs.cc & CC_GT) || (cpu.asregs.cc & CC_EQ))
{
pc = tgt - 2;
}
else
pc += 4;
}
break;
case 0x16: /* ble */
{
unsigned int tgt = EXTRACT_WORD(&memory[pc+2]);
TRACE("ble");
if ((cpu.asregs.cc & CC_LT) || (cpu.asregs.cc & CC_EQ))
{
pc = tgt - 2;
}
else
pc += 4;
}
break;
case 0x17: /* bgeu */
{
unsigned int tgt = EXTRACT_WORD(&memory[pc+2]);
TRACE("bgeu");
if ((cpu.asregs.cc & CC_GTU) || (cpu.asregs.cc & CC_EQ))
{
pc = tgt - 2;
}
else
pc += 4;
}
break;
case 0x18: /* bleu */
{
unsigned int tgt = EXTRACT_WORD(&memory[pc+2]);
TRACE("bleu");
if ((cpu.asregs.cc & CC_LTU) || (cpu.asregs.cc & CC_EQ))
{
pc = tgt - 2;
}
else
pc += 4;
}
break;
case 0x19: /* jsr */
{
unsigned int fn = cpu.asregs.regs[(inst >> 4) & 0xf];