[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