[xcc,sim,opcodes] more rvc instructions and bug fixes
authorAndrew Waterman <waterman@s144.Millennium.Berkeley.EDU>
Tue, 12 Apr 2011 00:09:50 +0000 (17:09 -0700)
committerAndrew Waterman <waterman@s144.Millennium.Berkeley.EDU>
Tue, 12 Apr 2011 00:09:50 +0000 (17:09 -0700)
riscv/decode.h
riscv/execute.h
riscv/insns/c_addi.h
riscv/insns/c_j.h [new file with mode: 0644]
riscv/insns/c_li.h
riscv/insns/c_move.h [new file with mode: 0644]
riscv/mmu.h
riscv/processor.cc

index c2702a602e76d5923668cf866f4d151eec402c62..cf2ee575ed1c39da3527a74add3629edef4dd48a 100644 (file)
@@ -204,8 +204,14 @@ private:
 
 // RVC stuff
 
+#define INSN_IS_RVC(x) (((x) & 0x3) < 0x3)
+
 #define CRD do_writeback(XPR,(insn.bits >> 5) & 0x1f)
+#define CRS1 XPR[(insn.bits >> 10) & 0x1f]
+#define CRS2 XPR[(insn.bits >> 5) & 0x1f]
 #define CIMM6 ((int32_t)((insn.bits >> 10) & 0x3f) << 26 >> 26)
+#define CIMM10 ((int32_t)((insn.bits >> 5) & 0x3ff) << 22 >> 22)
+#define CJUMP_TARGET (pc + (CIMM10 << JUMP_ALIGN_BITS))
 
 // vector stuff
 #define VL vl
index 9427ee9b340f2d9dfee9e7f5920479710c494539..ad21a0bd25f6622cfc34c50cd50fe0511d61bd12 100644 (file)
@@ -11,6 +11,129 @@ switch((insn.bits >> 0x0) & 0x7f)
     #include "insns/c_li.h"
     break;
   }
+  case 0x2:
+  {
+    switch((insn.bits >> 0x7) & 0x7)
+    {
+      case 0x0:
+      {
+        if((insn.bits & 0x801f) == 0x2)
+        {
+          #include "insns/c_move.h"
+          break;
+        }
+        if((insn.bits & 0x801f) == 0x8002)
+        {
+          #include "insns/c_j.h"
+          break;
+        }
+        throw trap_illegal_instruction;
+      }
+      case 0x1:
+      {
+        if((insn.bits & 0x801f) == 0x2)
+        {
+          #include "insns/c_move.h"
+          break;
+        }
+        if((insn.bits & 0x801f) == 0x8002)
+        {
+          #include "insns/c_j.h"
+          break;
+        }
+        throw trap_illegal_instruction;
+      }
+      case 0x2:
+      {
+        if((insn.bits & 0x801f) == 0x2)
+        {
+          #include "insns/c_move.h"
+          break;
+        }
+        if((insn.bits & 0x801f) == 0x8002)
+        {
+          #include "insns/c_j.h"
+          break;
+        }
+        throw trap_illegal_instruction;
+      }
+      case 0x3:
+      {
+        if((insn.bits & 0x801f) == 0x2)
+        {
+          #include "insns/c_move.h"
+          break;
+        }
+        if((insn.bits & 0x801f) == 0x8002)
+        {
+          #include "insns/c_j.h"
+          break;
+        }
+        throw trap_illegal_instruction;
+      }
+      case 0x4:
+      {
+        if((insn.bits & 0x801f) == 0x2)
+        {
+          #include "insns/c_move.h"
+          break;
+        }
+        if((insn.bits & 0x801f) == 0x8002)
+        {
+          #include "insns/c_j.h"
+          break;
+        }
+        throw trap_illegal_instruction;
+      }
+      case 0x5:
+      {
+        if((insn.bits & 0x801f) == 0x2)
+        {
+          #include "insns/c_move.h"
+          break;
+        }
+        if((insn.bits & 0x801f) == 0x8002)
+        {
+          #include "insns/c_j.h"
+          break;
+        }
+        throw trap_illegal_instruction;
+      }
+      case 0x6:
+      {
+        if((insn.bits & 0x801f) == 0x2)
+        {
+          #include "insns/c_move.h"
+          break;
+        }
+        if((insn.bits & 0x801f) == 0x8002)
+        {
+          #include "insns/c_j.h"
+          break;
+        }
+        throw trap_illegal_instruction;
+      }
+      case 0x7:
+      {
+        if((insn.bits & 0x801f) == 0x2)
+        {
+          #include "insns/c_move.h"
+          break;
+        }
+        if((insn.bits & 0x801f) == 0x8002)
+        {
+          #include "insns/c_j.h"
+          break;
+        }
+        throw trap_illegal_instruction;
+      }
+      default:
+      {
+        throw trap_illegal_instruction;
+      }
+    }
+    break;
+  }
   case 0x3:
   {
     switch((insn.bits >> 0x7) & 0x7)
@@ -609,6 +732,129 @@ switch((insn.bits >> 0x0) & 0x7f)
     #include "insns/c_li.h"
     break;
   }
+  case 0x22:
+  {
+    switch((insn.bits >> 0x7) & 0x7)
+    {
+      case 0x0:
+      {
+        if((insn.bits & 0x801f) == 0x2)
+        {
+          #include "insns/c_move.h"
+          break;
+        }
+        if((insn.bits & 0x801f) == 0x8002)
+        {
+          #include "insns/c_j.h"
+          break;
+        }
+        throw trap_illegal_instruction;
+      }
+      case 0x1:
+      {
+        if((insn.bits & 0x801f) == 0x2)
+        {
+          #include "insns/c_move.h"
+          break;
+        }
+        if((insn.bits & 0x801f) == 0x8002)
+        {
+          #include "insns/c_j.h"
+          break;
+        }
+        throw trap_illegal_instruction;
+      }
+      case 0x2:
+      {
+        if((insn.bits & 0x801f) == 0x2)
+        {
+          #include "insns/c_move.h"
+          break;
+        }
+        if((insn.bits & 0x801f) == 0x8002)
+        {
+          #include "insns/c_j.h"
+          break;
+        }
+        throw trap_illegal_instruction;
+      }
+      case 0x3:
+      {
+        if((insn.bits & 0x801f) == 0x2)
+        {
+          #include "insns/c_move.h"
+          break;
+        }
+        if((insn.bits & 0x801f) == 0x8002)
+        {
+          #include "insns/c_j.h"
+          break;
+        }
+        throw trap_illegal_instruction;
+      }
+      case 0x4:
+      {
+        if((insn.bits & 0x801f) == 0x2)
+        {
+          #include "insns/c_move.h"
+          break;
+        }
+        if((insn.bits & 0x801f) == 0x8002)
+        {
+          #include "insns/c_j.h"
+          break;
+        }
+        throw trap_illegal_instruction;
+      }
+      case 0x5:
+      {
+        if((insn.bits & 0x801f) == 0x2)
+        {
+          #include "insns/c_move.h"
+          break;
+        }
+        if((insn.bits & 0x801f) == 0x8002)
+        {
+          #include "insns/c_j.h"
+          break;
+        }
+        throw trap_illegal_instruction;
+      }
+      case 0x6:
+      {
+        if((insn.bits & 0x801f) == 0x2)
+        {
+          #include "insns/c_move.h"
+          break;
+        }
+        if((insn.bits & 0x801f) == 0x8002)
+        {
+          #include "insns/c_j.h"
+          break;
+        }
+        throw trap_illegal_instruction;
+      }
+      case 0x7:
+      {
+        if((insn.bits & 0x801f) == 0x2)
+        {
+          #include "insns/c_move.h"
+          break;
+        }
+        if((insn.bits & 0x801f) == 0x8002)
+        {
+          #include "insns/c_j.h"
+          break;
+        }
+        throw trap_illegal_instruction;
+      }
+      default:
+      {
+        throw trap_illegal_instruction;
+      }
+    }
+    break;
+  }
   case 0x23:
   {
     switch((insn.bits >> 0x7) & 0x7)
@@ -1034,6 +1280,129 @@ switch((insn.bits >> 0x0) & 0x7f)
     #include "insns/c_li.h"
     break;
   }
+  case 0x42:
+  {
+    switch((insn.bits >> 0x7) & 0x7)
+    {
+      case 0x0:
+      {
+        if((insn.bits & 0x801f) == 0x2)
+        {
+          #include "insns/c_move.h"
+          break;
+        }
+        if((insn.bits & 0x801f) == 0x8002)
+        {
+          #include "insns/c_j.h"
+          break;
+        }
+        throw trap_illegal_instruction;
+      }
+      case 0x1:
+      {
+        if((insn.bits & 0x801f) == 0x2)
+        {
+          #include "insns/c_move.h"
+          break;
+        }
+        if((insn.bits & 0x801f) == 0x8002)
+        {
+          #include "insns/c_j.h"
+          break;
+        }
+        throw trap_illegal_instruction;
+      }
+      case 0x2:
+      {
+        if((insn.bits & 0x801f) == 0x2)
+        {
+          #include "insns/c_move.h"
+          break;
+        }
+        if((insn.bits & 0x801f) == 0x8002)
+        {
+          #include "insns/c_j.h"
+          break;
+        }
+        throw trap_illegal_instruction;
+      }
+      case 0x3:
+      {
+        if((insn.bits & 0x801f) == 0x2)
+        {
+          #include "insns/c_move.h"
+          break;
+        }
+        if((insn.bits & 0x801f) == 0x8002)
+        {
+          #include "insns/c_j.h"
+          break;
+        }
+        throw trap_illegal_instruction;
+      }
+      case 0x4:
+      {
+        if((insn.bits & 0x801f) == 0x2)
+        {
+          #include "insns/c_move.h"
+          break;
+        }
+        if((insn.bits & 0x801f) == 0x8002)
+        {
+          #include "insns/c_j.h"
+          break;
+        }
+        throw trap_illegal_instruction;
+      }
+      case 0x5:
+      {
+        if((insn.bits & 0x801f) == 0x2)
+        {
+          #include "insns/c_move.h"
+          break;
+        }
+        if((insn.bits & 0x801f) == 0x8002)
+        {
+          #include "insns/c_j.h"
+          break;
+        }
+        throw trap_illegal_instruction;
+      }
+      case 0x6:
+      {
+        if((insn.bits & 0x801f) == 0x2)
+        {
+          #include "insns/c_move.h"
+          break;
+        }
+        if((insn.bits & 0x801f) == 0x8002)
+        {
+          #include "insns/c_j.h"
+          break;
+        }
+        throw trap_illegal_instruction;
+      }
+      case 0x7:
+      {
+        if((insn.bits & 0x801f) == 0x2)
+        {
+          #include "insns/c_move.h"
+          break;
+        }
+        if((insn.bits & 0x801f) == 0x8002)
+        {
+          #include "insns/c_j.h"
+          break;
+        }
+        throw trap_illegal_instruction;
+      }
+      default:
+      {
+        throw trap_illegal_instruction;
+      }
+    }
+    break;
+  }
   case 0x43:
   {
     switch((insn.bits >> 0x7) & 0x7)
@@ -1570,6 +1939,129 @@ switch((insn.bits >> 0x0) & 0x7f)
     #include "insns/c_li.h"
     break;
   }
+  case 0x62:
+  {
+    switch((insn.bits >> 0x7) & 0x7)
+    {
+      case 0x0:
+      {
+        if((insn.bits & 0x801f) == 0x2)
+        {
+          #include "insns/c_move.h"
+          break;
+        }
+        if((insn.bits & 0x801f) == 0x8002)
+        {
+          #include "insns/c_j.h"
+          break;
+        }
+        throw trap_illegal_instruction;
+      }
+      case 0x1:
+      {
+        if((insn.bits & 0x801f) == 0x2)
+        {
+          #include "insns/c_move.h"
+          break;
+        }
+        if((insn.bits & 0x801f) == 0x8002)
+        {
+          #include "insns/c_j.h"
+          break;
+        }
+        throw trap_illegal_instruction;
+      }
+      case 0x2:
+      {
+        if((insn.bits & 0x801f) == 0x2)
+        {
+          #include "insns/c_move.h"
+          break;
+        }
+        if((insn.bits & 0x801f) == 0x8002)
+        {
+          #include "insns/c_j.h"
+          break;
+        }
+        throw trap_illegal_instruction;
+      }
+      case 0x3:
+      {
+        if((insn.bits & 0x801f) == 0x2)
+        {
+          #include "insns/c_move.h"
+          break;
+        }
+        if((insn.bits & 0x801f) == 0x8002)
+        {
+          #include "insns/c_j.h"
+          break;
+        }
+        throw trap_illegal_instruction;
+      }
+      case 0x4:
+      {
+        if((insn.bits & 0x801f) == 0x2)
+        {
+          #include "insns/c_move.h"
+          break;
+        }
+        if((insn.bits & 0x801f) == 0x8002)
+        {
+          #include "insns/c_j.h"
+          break;
+        }
+        throw trap_illegal_instruction;
+      }
+      case 0x5:
+      {
+        if((insn.bits & 0x801f) == 0x2)
+        {
+          #include "insns/c_move.h"
+          break;
+        }
+        if((insn.bits & 0x801f) == 0x8002)
+        {
+          #include "insns/c_j.h"
+          break;
+        }
+        throw trap_illegal_instruction;
+      }
+      case 0x6:
+      {
+        if((insn.bits & 0x801f) == 0x2)
+        {
+          #include "insns/c_move.h"
+          break;
+        }
+        if((insn.bits & 0x801f) == 0x8002)
+        {
+          #include "insns/c_j.h"
+          break;
+        }
+        throw trap_illegal_instruction;
+      }
+      case 0x7:
+      {
+        if((insn.bits & 0x801f) == 0x2)
+        {
+          #include "insns/c_move.h"
+          break;
+        }
+        if((insn.bits & 0x801f) == 0x8002)
+        {
+          #include "insns/c_j.h"
+          break;
+        }
+        throw trap_illegal_instruction;
+      }
+      default:
+      {
+        throw trap_illegal_instruction;
+      }
+    }
+    break;
+  }
   case 0x63:
   {
     switch((insn.bits >> 0x7) & 0x7)
index 2694a0acc59ef33bacb00d1c44e27b58135c2f14..4a5a0af20df78c3c35cf892c6487b9131356c6cf 100644 (file)
@@ -1,2 +1,2 @@
 require_rvc;
-CRD = sext_xprlen(CRD + SIMM);
+CRD = sext_xprlen(CRS2 + CIMM6);
diff --git a/riscv/insns/c_j.h b/riscv/insns/c_j.h
new file mode 100644 (file)
index 0000000..87ee015
--- /dev/null
@@ -0,0 +1,2 @@
+require_rvc;
+npc = CJUMP_TARGET;
index 892f4734a921650dd8b24257c537250f76b1de57..e65614ed6d022cb398ea0209980b3ee0dc1edc50 100644 (file)
@@ -1,2 +1,2 @@
 require_rvc;
-CRD = SIMM;
+CRD = CIMM6;
diff --git a/riscv/insns/c_move.h b/riscv/insns/c_move.h
new file mode 100644 (file)
index 0000000..b0aef33
--- /dev/null
@@ -0,0 +1,2 @@
+require_rvc;
+CRD = CRS1;
index efaea3e3da839ab8ffe31de3299215a3c697483e..c61eb80af2fc94118f6e1a73f216eaf4f7a173c4 100644 (file)
@@ -25,9 +25,7 @@ public:
     uint16_t hi = *(uint16_t*)(mem+addr+2);
 
     insn_t insn; 
-    insn.bits = lo;
-    if((lo & 0x3) == 0x3)
-      insn.bits |= (uint32_t)hi << 16;
+    insn.bits = lo | ((uint32_t)hi << 16);
 
     return insn;
   }
index f9c8bea1900c846e7964a05e65f8964570975909..360b7553689607d4ac7788e3e410469f35453088 100644 (file)
@@ -180,7 +180,8 @@ void processor_t::disasm(insn_t insn, reg_t pc)
   info.buffer_length = sizeof(insn);
   info.buffer_vma = pc;
 
-  demand(print_insn_little_mips(pc, &info) == sizeof(insn), "disasm bug!");
+  int ret = print_insn_little_mips(pc, &info);
+  demand(ret == (INSN_IS_RVC(insn.bits) ? 2 : 4), "disasm bug!");
   #else
   printf("unknown");
   #endif