[xcc,pk,sim,opcodes] added first RVC instruction
authorAndrew Waterman <waterman@s144.Millennium.Berkeley.EDU>
Sun, 10 Apr 2011 00:37:42 +0000 (17:37 -0700)
committerAndrew Waterman <waterman@s144.Millennium.Berkeley.EDU>
Sun, 10 Apr 2011 00:37:42 +0000 (17:37 -0700)
riscv/decode.h
riscv/execute.h
riscv/insns/c_addi.h [new file with mode: 0644]
riscv/insns/unimp.h [deleted file]
riscv/mmu.h
riscv/processor.cc

index d0b92ddc470f7ff8f858b50b6bb4e56cccd827a5..8d96ab9da02e319f54ddcf3e5819cb81990f16d2 100644 (file)
@@ -34,13 +34,15 @@ const int BRANCH_ALIGN_BITS = 1;
 const int JUMP_ALIGN_BITS = 1;
 
 #define SR_ET    0x0000000000000001ULL
+#define SR_EF    0x0000000000000002ULL
 #define SR_PS    0x0000000000000004ULL
 #define SR_S     0x0000000000000008ULL
-#define SR_EF    0x0000000000000010ULL
-#define SR_UX    0x0000000000000020ULL
-#define SR_SX    0x0000000000000040ULL
+#define SR_UX    0x0000000000000010ULL
+#define SR_SX    0x0000000000000020ULL
+#define SR_UC    0x0000000000000040ULL
+#define SR_SC    0x0000000000000080ULL
 #define SR_IM    0x000000000000FF00ULL
-#define SR_ZERO  ~(SR_ET | SR_PS | SR_S | SR_EF | SR_UX | SR_SX | SR_IM)
+#define SR_ZERO  ~(SR_ET|SR_EF|SR_PS|SR_S|SR_UX|SR_SX|SR_UC|SR_SC|SR_IM)
 #define SR_IM_SHIFT 8
 #define TIMER_IRQ 7
 
@@ -193,11 +195,16 @@ private:
                                (softfloat_exceptionFlags << FSR_AEXC_SHIFT)); \
                              softfloat_exceptionFlags = 0; })
 
-static inline sreg_t sext32(int32_t arg)
-{
-  return arg;
-}
+#define rvc_mode ((sr & SR_S) ? (sr & SR_SC) : (sr & SR_UC))
+#define require_rvc if(!rvc_mode) throw trap_illegal_instruction
 
+#define sext32(x) ((sreg_t)(int32_t)(x))
+#define insn_length(x) (((x).bits & 0x3) < 0x3 ? 2 : 4)
 #define sext_xprlen(x) ((sreg_t(x) << (64-xprlen)) >> (64-xprlen))
 
+// RVC stuff
+
+#define CRD do_writeback(XPR,(insn.bits >> 5) & 0x1f)
+#define CIMM6 ((int32_t)((insn.bits >> 10) & 0x3f) << 26 >> 26)
+
 #endif
index b1e0e03bab4e389b8b8cb9548f9db496663129e5..2fb595e4860de1e7595b264e27f8286d02fcaaa1 100644 (file)
@@ -3,22 +3,7 @@ switch((insn.bits >> 0x0) & 0x7f)
 {
   case 0x0:
   {
-    switch((insn.bits >> 0x7) & 0x7)
-    {
-      case 0x0:
-      {
-        if((insn.bits & 0xffffffff) == 0x0)
-        {
-          #include "insns/unimp.h"
-          break;
-        }
-        #include "insns/unimp.h"
-      }
-      default:
-      {
-        #include "insns/unimp.h"
-      }
-    }
+    #include "insns/c_addi.h"
     break;
   }
   case 0x3:
@@ -62,7 +47,7 @@ switch((insn.bits >> 0x0) & 0x7f)
       }
       default:
       {
-        #include "insns/unimp.h"
+        throw trap_illegal_instruction;
       }
     }
     break;
@@ -83,7 +68,7 @@ switch((insn.bits >> 0x0) & 0x7f)
       }
       default:
       {
-        #include "insns/unimp.h"
+        throw trap_illegal_instruction;
       }
     }
     break;
@@ -134,7 +119,7 @@ switch((insn.bits >> 0x0) & 0x7f)
           #include "insns/sb_v.h"
           break;
         }
-        #include "insns/unimp.h"
+        throw trap_illegal_instruction;
       }
       case 0x1:
       {
@@ -178,7 +163,7 @@ switch((insn.bits >> 0x0) & 0x7f)
           #include "insns/shst_v.h"
           break;
         }
-        #include "insns/unimp.h"
+        throw trap_illegal_instruction;
       }
       case 0x2:
       {
@@ -252,7 +237,7 @@ switch((insn.bits >> 0x0) & 0x7f)
           #include "insns/lwst_v.h"
           break;
         }
-        #include "insns/unimp.h"
+        throw trap_illegal_instruction;
       }
       case 0x3:
       {
@@ -326,7 +311,7 @@ switch((insn.bits >> 0x0) & 0x7f)
           #include "insns/sdst_v.h"
           break;
         }
-        #include "insns/unimp.h"
+        throw trap_illegal_instruction;
       }
       case 0x4:
       {
@@ -345,15 +330,10 @@ switch((insn.bits >> 0x0) & 0x7f)
           #include "insns/lbust_v.h"
           break;
         }
-        #include "insns/unimp.h"
+        throw trap_illegal_instruction;
       }
       case 0x5:
       {
-        if((insn.bits & 0x1ffff) == 0x228b)
-        {
-          #include "insns/lhuseg_v.h"
-          break;
-        }
         if((insn.bits & 0x1ffff) == 0x128b)
         {
           #include "insns/lhust_v.h"
@@ -364,7 +344,12 @@ switch((insn.bits >> 0x0) & 0x7f)
           #include "insns/lhu_v.h"
           break;
         }
-        #include "insns/unimp.h"
+        if((insn.bits & 0x1ffff) == 0x228b)
+        {
+          #include "insns/lhuseg_v.h"
+          break;
+        }
+        throw trap_illegal_instruction;
       }
       case 0x6:
       {
@@ -383,11 +368,11 @@ switch((insn.bits >> 0x0) & 0x7f)
           #include "insns/lwust_v.h"
           break;
         }
-        #include "insns/unimp.h"
+        throw trap_illegal_instruction;
       }
       default:
       {
-        #include "insns/unimp.h"
+        throw trap_illegal_instruction;
       }
     }
     break;
@@ -408,7 +393,7 @@ switch((insn.bits >> 0x0) & 0x7f)
           #include "insns/lbsegst_v.h"
           break;
         }
-        #include "insns/unimp.h"
+        throw trap_illegal_instruction;
       }
       case 0x1:
       {
@@ -422,7 +407,7 @@ switch((insn.bits >> 0x0) & 0x7f)
           #include "insns/lhsegst_v.h"
           break;
         }
-        #include "insns/unimp.h"
+        throw trap_illegal_instruction;
       }
       case 0x2:
       {
@@ -446,7 +431,7 @@ switch((insn.bits >> 0x0) & 0x7f)
           #include "insns/swsegst_v.h"
           break;
         }
-        #include "insns/unimp.h"
+        throw trap_illegal_instruction;
       }
       case 0x3:
       {
@@ -470,7 +455,7 @@ switch((insn.bits >> 0x0) & 0x7f)
           #include "insns/fsdsegst_v.h"
           break;
         }
-        #include "insns/unimp.h"
+        throw trap_illegal_instruction;
       }
       case 0x4:
       {
@@ -479,7 +464,7 @@ switch((insn.bits >> 0x0) & 0x7f)
           #include "insns/lbusegst_v.h"
           break;
         }
-        #include "insns/unimp.h"
+        throw trap_illegal_instruction;
       }
       case 0x5:
       {
@@ -488,7 +473,7 @@ switch((insn.bits >> 0x0) & 0x7f)
           #include "insns/lhusegst_v.h"
           break;
         }
-        #include "insns/unimp.h"
+        throw trap_illegal_instruction;
       }
       case 0x6:
       {
@@ -497,11 +482,11 @@ switch((insn.bits >> 0x0) & 0x7f)
           #include "insns/lwusegst_v.h"
           break;
         }
-        #include "insns/unimp.h"
+        throw trap_illegal_instruction;
       }
       default:
       {
-        #include "insns/unimp.h"
+        throw trap_illegal_instruction;
       }
     }
     break;
@@ -522,7 +507,7 @@ switch((insn.bits >> 0x0) & 0x7f)
           #include "insns/slli.h"
           break;
         }
-        #include "insns/unimp.h"
+        throw trap_illegal_instruction;
       }
       case 0x2:
       {
@@ -551,7 +536,7 @@ switch((insn.bits >> 0x0) & 0x7f)
           #include "insns/srai.h"
           break;
         }
-        #include "insns/unimp.h"
+        throw trap_illegal_instruction;
       }
       case 0x6:
       {
@@ -565,7 +550,7 @@ switch((insn.bits >> 0x0) & 0x7f)
       }
       default:
       {
-        #include "insns/unimp.h"
+        throw trap_illegal_instruction;
       }
     }
     break;
@@ -586,7 +571,7 @@ switch((insn.bits >> 0x0) & 0x7f)
           #include "insns/slliw.h"
           break;
         }
-        #include "insns/unimp.h"
+        throw trap_illegal_instruction;
       }
       case 0x5:
       {
@@ -600,15 +585,20 @@ switch((insn.bits >> 0x0) & 0x7f)
           #include "insns/sraiw.h"
           break;
         }
-        #include "insns/unimp.h"
+        throw trap_illegal_instruction;
       }
       default:
       {
-        #include "insns/unimp.h"
+        throw trap_illegal_instruction;
       }
     }
     break;
   }
+  case 0x20:
+  {
+    #include "insns/c_addi.h"
+    break;
+  }
   case 0x23:
   {
     switch((insn.bits >> 0x7) & 0x7)
@@ -635,7 +625,7 @@ switch((insn.bits >> 0x0) & 0x7f)
       }
       default:
       {
-        #include "insns/unimp.h"
+        throw trap_illegal_instruction;
       }
     }
     break;
@@ -656,7 +646,7 @@ switch((insn.bits >> 0x0) & 0x7f)
       }
       default:
       {
-        #include "insns/unimp.h"
+        throw trap_illegal_instruction;
       }
     }
     break;
@@ -707,7 +697,7 @@ switch((insn.bits >> 0x0) & 0x7f)
           #include "insns/amoswap_w.h"
           break;
         }
-        #include "insns/unimp.h"
+        throw trap_illegal_instruction;
       }
       case 0x3:
       {
@@ -751,11 +741,11 @@ switch((insn.bits >> 0x0) & 0x7f)
           #include "insns/amomin_d.h"
           break;
         }
-        #include "insns/unimp.h"
+        throw trap_illegal_instruction;
       }
       default:
       {
-        #include "insns/unimp.h"
+        throw trap_illegal_instruction;
       }
     }
     break;
@@ -796,7 +786,7 @@ switch((insn.bits >> 0x0) & 0x7f)
       }
       default:
       {
-        #include "insns/unimp.h"
+        throw trap_illegal_instruction;
       }
     }
     break;
@@ -822,7 +812,7 @@ switch((insn.bits >> 0x0) & 0x7f)
           #include "insns/sub.h"
           break;
         }
-        #include "insns/unimp.h"
+        throw trap_illegal_instruction;
       }
       case 0x1:
       {
@@ -836,7 +826,7 @@ switch((insn.bits >> 0x0) & 0x7f)
           #include "insns/mulh.h"
           break;
         }
-        #include "insns/unimp.h"
+        throw trap_illegal_instruction;
       }
       case 0x2:
       {
@@ -850,7 +840,7 @@ switch((insn.bits >> 0x0) & 0x7f)
           #include "insns/slt.h"
           break;
         }
-        #include "insns/unimp.h"
+        throw trap_illegal_instruction;
       }
       case 0x3:
       {
@@ -864,7 +854,7 @@ switch((insn.bits >> 0x0) & 0x7f)
           #include "insns/mulhu.h"
           break;
         }
-        #include "insns/unimp.h"
+        throw trap_illegal_instruction;
       }
       case 0x4:
       {
@@ -878,7 +868,7 @@ switch((insn.bits >> 0x0) & 0x7f)
           #include "insns/xor.h"
           break;
         }
-        #include "insns/unimp.h"
+        throw trap_illegal_instruction;
       }
       case 0x5:
       {
@@ -897,7 +887,7 @@ switch((insn.bits >> 0x0) & 0x7f)
           #include "insns/divu.h"
           break;
         }
-        #include "insns/unimp.h"
+        throw trap_illegal_instruction;
       }
       case 0x6:
       {
@@ -911,7 +901,7 @@ switch((insn.bits >> 0x0) & 0x7f)
           #include "insns/or.h"
           break;
         }
-        #include "insns/unimp.h"
+        throw trap_illegal_instruction;
       }
       case 0x7:
       {
@@ -925,11 +915,11 @@ switch((insn.bits >> 0x0) & 0x7f)
           #include "insns/and.h"
           break;
         }
-        #include "insns/unimp.h"
+        throw trap_illegal_instruction;
       }
       default:
       {
-        #include "insns/unimp.h"
+        throw trap_illegal_instruction;
       }
     }
     break;
@@ -960,7 +950,7 @@ switch((insn.bits >> 0x0) & 0x7f)
           #include "insns/subw.h"
           break;
         }
-        #include "insns/unimp.h"
+        throw trap_illegal_instruction;
       }
       case 0x1:
       {
@@ -969,7 +959,7 @@ switch((insn.bits >> 0x0) & 0x7f)
           #include "insns/sllw.h"
           break;
         }
-        #include "insns/unimp.h"
+        throw trap_illegal_instruction;
       }
       case 0x4:
       {
@@ -978,7 +968,7 @@ switch((insn.bits >> 0x0) & 0x7f)
           #include "insns/divw.h"
           break;
         }
-        #include "insns/unimp.h"
+        throw trap_illegal_instruction;
       }
       case 0x5:
       {
@@ -997,7 +987,7 @@ switch((insn.bits >> 0x0) & 0x7f)
           #include "insns/sraw.h"
           break;
         }
-        #include "insns/unimp.h"
+        throw trap_illegal_instruction;
       }
       case 0x6:
       {
@@ -1006,7 +996,7 @@ switch((insn.bits >> 0x0) & 0x7f)
           #include "insns/remw.h"
           break;
         }
-        #include "insns/unimp.h"
+        throw trap_illegal_instruction;
       }
       case 0x7:
       {
@@ -1015,15 +1005,20 @@ switch((insn.bits >> 0x0) & 0x7f)
           #include "insns/remuw.h"
           break;
         }
-        #include "insns/unimp.h"
+        throw trap_illegal_instruction;
       }
       default:
       {
-        #include "insns/unimp.h"
+        throw trap_illegal_instruction;
       }
     }
     break;
   }
+  case 0x40:
+  {
+    #include "insns/c_addi.h"
+    break;
+  }
   case 0x43:
   {
     switch((insn.bits >> 0x7) & 0x7)
@@ -1050,7 +1045,7 @@ switch((insn.bits >> 0x0) & 0x7f)
       }
       default:
       {
-        #include "insns/unimp.h"
+        throw trap_illegal_instruction;
       }
     }
     break;
@@ -1081,7 +1076,7 @@ switch((insn.bits >> 0x0) & 0x7f)
       }
       default:
       {
-        #include "insns/unimp.h"
+        throw trap_illegal_instruction;
       }
     }
     break;
@@ -1112,7 +1107,7 @@ switch((insn.bits >> 0x0) & 0x7f)
       }
       default:
       {
-        #include "insns/unimp.h"
+        throw trap_illegal_instruction;
       }
     }
     break;
@@ -1143,7 +1138,7 @@ switch((insn.bits >> 0x0) & 0x7f)
       }
       default:
       {
-        #include "insns/unimp.h"
+        throw trap_illegal_instruction;
       }
     }
     break;
@@ -1284,7 +1279,7 @@ switch((insn.bits >> 0x0) & 0x7f)
           #include "insns/fadd_s.h"
           break;
         }
-        #include "insns/unimp.h"
+        throw trap_illegal_instruction;
       }
       case 0x1:
       {
@@ -1408,7 +1403,7 @@ switch((insn.bits >> 0x0) & 0x7f)
           #include "insns/fdiv_d.h"
           break;
         }
-        #include "insns/unimp.h"
+        throw trap_illegal_instruction;
       }
       case 0x4:
       {
@@ -1482,7 +1477,7 @@ switch((insn.bits >> 0x0) & 0x7f)
           #include "insns/fadd_s.h"
           break;
         }
-        #include "insns/unimp.h"
+        throw trap_illegal_instruction;
       }
       case 0x5:
       {
@@ -1541,15 +1536,20 @@ switch((insn.bits >> 0x0) & 0x7f)
           #include "insns/fdiv_d.h"
           break;
         }
-        #include "insns/unimp.h"
+        throw trap_illegal_instruction;
       }
       default:
       {
-        #include "insns/unimp.h"
+        throw trap_illegal_instruction;
       }
     }
     break;
   }
+  case 0x60:
+  {
+    #include "insns/c_addi.h"
+    break;
+  }
   case 0x63:
   {
     switch((insn.bits >> 0x7) & 0x7)
@@ -1586,7 +1586,7 @@ switch((insn.bits >> 0x0) & 0x7f)
       }
       default:
       {
-        #include "insns/unimp.h"
+        throw trap_illegal_instruction;
       }
     }
     break;
@@ -1622,11 +1622,11 @@ switch((insn.bits >> 0x0) & 0x7f)
           #include "insns/rdnpc.h"
           break;
         }
-        #include "insns/unimp.h"
+        throw trap_illegal_instruction;
       }
       default:
       {
-        #include "insns/unimp.h"
+        throw trap_illegal_instruction;
       }
     }
     break;
@@ -1652,7 +1652,7 @@ switch((insn.bits >> 0x0) & 0x7f)
           #include "insns/setvl.h"
           break;
         }
-        #include "insns/unimp.h"
+        throw trap_illegal_instruction;
       }
       case 0x2:
       {
@@ -1661,11 +1661,11 @@ switch((insn.bits >> 0x0) & 0x7f)
           #include "insns/vf.h"
           break;
         }
-        #include "insns/unimp.h"
+        throw trap_illegal_instruction;
       }
       default:
       {
-        #include "insns/unimp.h"
+        throw trap_illegal_instruction;
       }
     }
     break;
@@ -1681,7 +1681,7 @@ switch((insn.bits >> 0x0) & 0x7f)
           #include "insns/syscall.h"
           break;
         }
-        #include "insns/unimp.h"
+        throw trap_illegal_instruction;
       }
       case 0x1:
       {
@@ -1690,7 +1690,7 @@ switch((insn.bits >> 0x0) & 0x7f)
           #include "insns/break.h"
           break;
         }
-        #include "insns/unimp.h"
+        throw trap_illegal_instruction;
       }
       case 0x2:
       {
@@ -1699,7 +1699,7 @@ switch((insn.bits >> 0x0) & 0x7f)
           #include "insns/stop.h"
           break;
         }
-        #include "insns/unimp.h"
+        throw trap_illegal_instruction;
       }
       case 0x3:
       {
@@ -1708,11 +1708,11 @@ switch((insn.bits >> 0x0) & 0x7f)
           #include "insns/utidx.h"
           break;
         }
-        #include "insns/unimp.h"
+        throw trap_illegal_instruction;
       }
       default:
       {
-        #include "insns/unimp.h"
+        throw trap_illegal_instruction;
       }
     }
     break;
@@ -1728,7 +1728,7 @@ switch((insn.bits >> 0x0) & 0x7f)
           #include "insns/ei.h"
           break;
         }
-        #include "insns/unimp.h"
+        throw trap_illegal_instruction;
       }
       case 0x1:
       {
@@ -1737,7 +1737,7 @@ switch((insn.bits >> 0x0) & 0x7f)
           #include "insns/di.h"
           break;
         }
-        #include "insns/unimp.h"
+        throw trap_illegal_instruction;
       }
       case 0x2:
       {
@@ -1746,7 +1746,7 @@ switch((insn.bits >> 0x0) & 0x7f)
           #include "insns/mfpcr.h"
           break;
         }
-        #include "insns/unimp.h"
+        throw trap_illegal_instruction;
       }
       case 0x3:
       {
@@ -1755,7 +1755,7 @@ switch((insn.bits >> 0x0) & 0x7f)
           #include "insns/mtpcr.h"
           break;
         }
-        #include "insns/unimp.h"
+        throw trap_illegal_instruction;
       }
       case 0x4:
       {
@@ -1764,17 +1764,17 @@ switch((insn.bits >> 0x0) & 0x7f)
           #include "insns/eret.h"
           break;
         }
-        #include "insns/unimp.h"
+        throw trap_illegal_instruction;
       }
       default:
       {
-        #include "insns/unimp.h"
+        throw trap_illegal_instruction;
       }
     }
     break;
   }
   default:
   {
-    #include "insns/unimp.h"
+    throw trap_illegal_instruction;
   }
 }
diff --git a/riscv/insns/c_addi.h b/riscv/insns/c_addi.h
new file mode 100644 (file)
index 0000000..2694a0a
--- /dev/null
@@ -0,0 +1,2 @@
+require_rvc;
+CRD = sext_xprlen(CRD + SIMM);
diff --git a/riscv/insns/unimp.h b/riscv/insns/unimp.h
deleted file mode 100644 (file)
index 96f2a74..0000000
+++ /dev/null
@@ -1 +0,0 @@
-throw trap_illegal_instruction;
index 1b8a422e20a45e5f787839b517062e99c0bb843c..5d516bc59981d7c6584febf0924b93a626e3b949 100644 (file)
@@ -18,10 +18,15 @@ public:
       *(type##_t*)(mem+addr) = val; \
     }
 
-  insn_t load_insn(reg_t addr)
+  insn_t load_insn(reg_t addr, bool rvc)
   {
-    check_align_and_bounds(addr, sizeof(insn_t), false, true);
-    return *(insn_t*)(mem+addr);
+    check_align_and_bounds(addr, rvc ? 2 : 4, false, true);
+    uint16_t lo = *(uint16_t*)(mem+addr);
+    uint16_t hi = *(uint16_t*)(mem+addr+2);
+
+    insn_t insn; 
+    insn.bits = ((uint32_t)hi << 16) | lo;
+    return insn;
   }
 
   load_func(uint8)
index 61f4ec181079ee7f6c6acdd88ed3337b25c86d9b..81ac42a7398360329ff44fb521ea2af5993313da 100644 (file)
@@ -52,9 +52,12 @@ void processor_t::set_sr(uint32_t val)
 #ifndef RISCV_ENABLE_64BIT
   sr &= ~(SR_SX | SR_UX);
 #endif
-#ifndef RISCV_ENABLE_64BIT
+#ifndef RISCV_ENABLE_FPU
   sr &= ~SR_EF;
 #endif
+#ifdef RISCV_ENABLE_RVC
+  sr &= ~SR_C;
+#endif
 
   xprlen = ((sr & SR_S) ? (sr & SR_SX) : (sr & SR_UX)) ? 64 : 32;
 }
@@ -76,9 +79,9 @@ void processor_t::step(size_t n, bool noisy)
       if(interrupts && (sr & SR_ET))
         take_trap(trap_interrupt,noisy);
 
-      insn_t insn = mmu.load_insn(pc);
+      insn_t insn = mmu.load_insn(pc, rvc_mode);
   
-      reg_t npc = pc+sizeof(insn);
+      reg_t npc = pc + insn_length(insn);
 
       if(noisy)
         disasm(insn,pc);