aboutsummaryrefslogtreecommitdiff
path: root/riscv/insns
diff options
context:
space:
mode:
authorAndrew Waterman <waterman@cs.berkeley.edu>2015-05-31 16:38:24 -0700
committerAndrew Waterman <waterman@cs.berkeley.edu>2015-05-31 18:29:45 -0700
commit56701b230823f52c252ce6ab69c18639daa02a14 (patch)
tree96935c7b7154db38f675210f94b5dea34bef84f2 /riscv/insns
parent5235a77475ff00aecafb9db4c1b003043d2d7f20 (diff)
downloadriscv-isa-sim-56701b230823f52c252ce6ab69c18639daa02a14.zip
riscv-isa-sim-56701b230823f52c252ce6ab69c18639daa02a14.tar.gz
riscv-isa-sim-56701b230823f52c252ce6ab69c18639daa02a14.tar.bz2
Add rest of RV32C instructions
Diffstat (limited to 'riscv/insns')
-rw-r--r--riscv/insns/c_addiw.h9
-rw-r--r--riscv/insns/c_ldsp.h10
-rw-r--r--riscv/insns/c_sd.h39
-rw-r--r--riscv/insns/c_sdsp.h8
-rw-r--r--riscv/insns/c_slliw.h16
5 files changed, 68 insertions, 14 deletions
diff --git a/riscv/insns/c_addiw.h b/riscv/insns/c_addiw.h
index 27ffd8f..ae4980e 100644
--- a/riscv/insns/c_addiw.h
+++ b/riscv/insns/c_addiw.h
@@ -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()));
+}
diff --git a/riscv/insns/c_ldsp.h b/riscv/insns/c_ldsp.h
index 7047d53..aa98f33 100644
--- a/riscv/insns/c_ldsp.h
+++ b/riscv/insns/c_ldsp.h
@@ -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()));
+}
diff --git a/riscv/insns/c_sd.h b/riscv/insns/c_sd.h
index 9262d04..4551ced 100644
--- a/riscv/insns/c_sd.h
+++ b/riscv/insns/c_sd.h
@@ -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);
+}
diff --git a/riscv/insns/c_sdsp.h b/riscv/insns/c_sdsp.h
index e59e00b..db504ec 100644
--- a/riscv/insns/c_sdsp.h
+++ b/riscv/insns/c_sdsp.h
@@ -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);
+}
diff --git a/riscv/insns/c_slliw.h b/riscv/insns/c_slliw.h
index 87a5901..643bf74 100644
--- a/riscv/insns/c_slliw.h
+++ b/riscv/insns/c_slliw.h
@@ -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()));
+}