[Patch] Add PC-relative branch support to Moxie simulator
Anthony Green
green@moxielogic.com
Thu Jun 11 11:35:00 GMT 2009
The Moxie ISA was recently changed to include support for PC-relative
branch instructions, and the old 48-bit branch instructions have been
removed. Binutils has already been updated. This patch teaches the
simulator about our new instructions.
I am checking this patch in.
Thanks,
AG
2009-06-11 Anthony Green <green@moxielogic.com>
* interp.c (INST2OFFSET): Define.
(sim_resume): Support new PC relative branch instructions.
Index: sim/moxie/interp.c
===================================================================
RCS file: /cvs/src/src/sim/moxie/interp.c,v
retrieving revision 1.2
diff -u -r1.2 interp.c
--- sim/moxie/interp.c 10 May 2009 13:25:57 -0000 1.2
+++ sim/moxie/interp.c 10 Jun 2009 15:34:51 -0000
@@ -35,6 +35,8 @@
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 +426,86 @@
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 +733,22 @@
cpu.asregs.cc = cc;
}
break;
- case 0x0f: /* beq */
- {
- unsigned int tgt = EXTRACT_WORD(&memory[pc+2]);
- TRACE("beq");
- if (cpu.asregs.cc & CC_EQ)
- {
- pc = tgt - 2;
- }
- else
- pc += 4;
- }
- 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;
+ case 0x0f:
+ case 0x10:
+ case 0x11:
+ case 0x12:
+ case 0x13:
+ case 0x14:
+ case 0x15:
+ case 0x16:
+ case 0x17:
+ case 0x18:
+ {
+ opc = opcode;
+ TRACE("SIGILL0");
+ cpu.asregs.exception = SIGILL;
+ break;
}
- 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];
More information about the Gdb-patches
mailing list