summaryrefslogtreecommitdiff
path: root/sim/moxie/interp.c
diff options
context:
space:
mode:
authorAnthony Green <green@redhat.com>2009-06-11 11:36:14 +0000
committerAnthony Green <green@redhat.com>2009-06-11 11:36:14 +0000
commit865662004136ecc8f9f45c41fcd20bd9a3573bbf (patch)
treeb7b65387df742f3e26732215035c630a05598b2e /sim/moxie/interp.c
parentf865a31d1ed571ccb8d17653b150e3a30f22b30d (diff)
downloadbinutils-865662004136ecc8f9f45c41fcd20bd9a3573bbf.tar.gz
binutils-865662004136ecc8f9f45c41fcd20bd9a3573bbf.tar.bz2
binutils-865662004136ecc8f9f45c41fcd20bd9a3573bbf.zip
Add PC-relative branch support to moxie sim.
Diffstat (limited to 'sim/moxie/interp.c')
-rw-r--r--sim/moxie/interp.c220
1 files changed, 98 insertions, 122 deletions
diff --git a/sim/moxie/interp.c b/sim/moxie/interp.c
index dd87648b5ff..4980ff1b8c5 100644
--- a/sim/moxie/interp.c
+++ b/sim/moxie/interp.c
@@ -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];