Add rest of RV32C instructions
authorAndrew Waterman <waterman@cs.berkeley.edu>
Sun, 31 May 2015 23:38:24 +0000 (16:38 -0700)
committerAndrew Waterman <waterman@cs.berkeley.edu>
Mon, 1 Jun 2015 01:29:45 +0000 (18:29 -0700)
riscv/decode.h
riscv/encoding.h
riscv/insns/c_addiw.h
riscv/insns/c_ldsp.h
riscv/insns/c_sd.h
riscv/insns/c_sdsp.h
riscv/insns/c_slliw.h

index 4f5765612f663b0fc34d6c212022484bd6353ad0..91ad73ee593e9b598c7204681f679bef22b9d569 100644 (file)
@@ -85,6 +85,7 @@ public:
   int64_t rvc_ld_imm() { return (x(10, 3) << 3) + (x(5, 2) << 6); }
   int64_t rvc_j_imm() { return (x(3, 4) << 1) + (x(2, 1) << 5) + (xs(7, 6) << 6); }
   int64_t rvc_b_imm() { return (x(3, 4) << 1) + (x(2, 1) << 5) + (xs(10, 3) << 6); }
+  int64_t rvc_simm3() { return x(10, 3); }
   uint64_t rvc_rd() { return rd(); }
   uint64_t rvc_rs1() { return rd(); }
   uint64_t rvc_rs2() { return x(2, 5); }
index cfe8b38f4c3aea8bede3bb5ba7b7b726ba5057ac..a95f4632fcdb008e282ba98542f1fba92c5ed63f 100644 (file)
 #define MATCH_C_SLLI 0x1
 #define MASK_C_SLLI  0xe003
 #define MATCH_C_SLLIW 0x8001
-#define MASK_C_SLLIW  0xf003
+#define MASK_C_SLLIW  0xe003
 #define MATCH_C_SRAI 0x2000
 #define MASK_C_SRAI  0xe003
 #define MATCH_C_SRLI 0x2001
index 27ffd8f52bfba5f9bbddf203f7b182f80bfea63a..ae4980edce24b3bf7650c2ba34a8bd1aedb46c42 100644 (file)
@@ -1,4 +1,7 @@
 require_extension('C');
-require_rv64;
-require(insn.rvc_rd() != 0);
-WRITE_RD(sext32(RVC_RS1 + insn.rvc_imm()));
+if (xlen == 32) {
+  WRITE_RD(RVC_RS1 & insn.rvc_imm()); // c.andi
+} else {
+  require(insn.rvc_rd() != 0);
+  WRITE_RD(sext32(RVC_RS1 + insn.rvc_imm()));
+}
index 7047d530d0fd155b801e54b0fb3aeace33ea8396..aa98f3365daa3005c3ad6c318dce0b90ba38f536 100644 (file)
@@ -1,4 +1,8 @@
 require_extension('C');
-require_rv64;
-require(insn.rvc_rd() != 0);
-WRITE_RD(MMU.load_int64(RVC_SP + insn.rvc_ldsp_imm()));
+if (xlen == 32) {
+  if (sreg_t(RVC_RS1S) >= 0) // c.bgez
+    set_pc(pc + insn.rvc_b_imm());
+} else {
+  require(insn.rvc_rd() != 0);
+  WRITE_RD(MMU.load_int64(RVC_SP + insn.rvc_ldsp_imm()));
+}
index 9262d044792c94947d234af5d1d73136fe25ac98..4551ced495b14867c9e67a8bab2f5dfcee6c03ce 100644 (file)
@@ -1,3 +1,38 @@
 require_extension('C');
-require_rv64;
-MMU.store_uint64(RVC_RS1S + insn.rvc_ld_imm(), RVC_RS2S);
+if (xlen == 32) {
+  int32_t res;
+  switch ((insn.bits() >> 10) & 7) {
+    case 0:
+      switch ((insn.bits() >> 5) & 3) {
+        case 0: res = RVC_RS1S ^ RVC_RS2S; // c.xor
+        case 1: res = int32_t(RVC_RS1S) >> (RVC_RS2S & 0x1f); // c.sra
+        default: require(0);
+      }
+      WRITE_RVC_RS1S(res);
+      break;
+
+    case 1:
+      switch ((insn.bits() >> 5) & 3) {
+        case 0: res = RVC_RS1S << (RVC_RS2S & 0x1f); // c.sll
+        case 1: res = uint32_t(RVC_RS1S) >> (RVC_RS2S & 0x1f); // c.srl
+        case 2: res = int32_t(RVC_RS1S) < int32_t(RVC_RS2S); // c.slt
+        case 3: res = uint32_t(RVC_RS1S) < uint32_t(RVC_RS2S); // c.sltu
+      }
+      WRITE_RVC_RS1S(res);
+      break;
+
+    case 3:
+      switch ((insn.bits() >> 5) & 3) {
+        case 0: res = RVC_RS1S << (RVC_RS2S & 0x1f); // c.sllr
+        case 1: res = uint32_t(RVC_RS1S) >> (RVC_RS2S & 0x1f); // c.srlr
+        case 2: res = int32_t(RVC_RS1S) < int32_t(RVC_RS2S); // c.sltr
+        case 3: res = uint32_t(RVC_RS1S) < uint32_t(RVC_RS2S); // c.sltur
+      }
+      WRITE_RVC_RS2S(res);
+      break;
+
+    default: require(0);
+  }
+} else {
+  MMU.store_uint64(RVC_RS1S + insn.rvc_ld_imm(), RVC_RS2S);
+}
index e59e00b1a74056d62616abb2700354771721de25..db504ec40cd9bd34d94d988ede92941a1bf2212f 100644 (file)
@@ -1,3 +1,7 @@
 require_extension('C');
-require_rv64;
-MMU.store_uint64(RVC_SP + insn.rvc_sdsp_imm(), RVC_RS2);
+if (xlen == 32) {
+  if (sreg_t(RVC_RS1S) < 0) // c.bltz
+    set_pc(pc + insn.rvc_b_imm());
+} else {
+  MMU.store_uint64(RVC_SP + insn.rvc_sdsp_imm(), RVC_RS2);
+}
index 87a59010a78d259a163ef0d5a509bdb9b5de12f2..643bf7445c8da09520f582d7e16caf3e50138a1c 100644 (file)
@@ -1,5 +1,13 @@
 require_extension('C');
-require_rv64;
-require(insn.rvc_rd() != 0);
-require(insn.rvc_imm() < 32);
-WRITE_RD(sext32(RVC_RS1 << insn.rvc_imm()));
+if (xlen == 32) {
+  switch ((insn.bits() >> 5) & 3) {
+    case 0: WRITE_RVC_RS2S(sext_xlen(RVC_RS1S + insn.rvc_simm3())); // c.addin
+    case 1: WRITE_RVC_RS2S(sext_xlen(RVC_RS1S ^ insn.rvc_simm3())); // c.xorin
+    case 2: WRITE_RVC_RS2S(sext_xlen(RVC_RS1S | insn.rvc_simm3())); // c.orin
+    case 3: WRITE_RVC_RS2S(sext_xlen(RVC_RS1S & insn.rvc_simm3())); // c.andin
+  }
+} else {
+  require(insn.rvc_rd() != 0);
+  require(insn.rvc_imm() < 32);
+  WRITE_RD(sext32(RVC_RS1 << insn.rvc_imm()));
+}