diff options
author | Anthony Green <green@redhat.com> | 2009-06-11 11:36:14 +0000 |
---|---|---|
committer | Anthony Green <green@redhat.com> | 2009-06-11 11:36:14 +0000 |
commit | 865662004136ecc8f9f45c41fcd20bd9a3573bbf (patch) | |
tree | b7b65387df742f3e26732215035c630a05598b2e /sim/moxie/interp.c | |
parent | f865a31d1ed571ccb8d17653b150e3a30f22b30d (diff) | |
download | binutils-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.c | 220 |
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]; |