aboutsummaryrefslogtreecommitdiff
path: root/riscv
diff options
context:
space:
mode:
authorAndy Wright <acwright@mit.edu>2016-05-21 16:39:21 -0400
committerAndrew Waterman <waterman@eecs.berkeley.edu>2016-05-21 13:39:21 -0700
commit8981e571623dba178d3aac147696772c8f9050bd (patch)
tree85117e7fcafc14eb305fd94678b5f57fe8dcba0f /riscv
parent07d2edff33bb0acf87305a6c54c0fcc5522c81e4 (diff)
downloadriscv-isa-sim-8981e571623dba178d3aac147696772c8f9050bd.zip
riscv-isa-sim-8981e571623dba178d3aac147696772c8f9050bd.tar.gz
riscv-isa-sim-8981e571623dba178d3aac147696772c8f9050bd.tar.bz2
Some bugfixes for CSR reading and setting FS for fflags updates (#43)
* csrrc[i] and csrrs[i] don't write CSRs if rs/zimm == 0 * Dirty fp state when setting new fp exceptions * Set FS to dirty for all non-zero fflags writes.
Diffstat (limited to 'riscv')
-rw-r--r--riscv/decode.h5
-rw-r--r--riscv/insns/csrrc.h7
-rw-r--r--riscv/insns/csrrci.h7
-rw-r--r--riscv/insns/csrrs.h7
-rw-r--r--riscv/insns/csrrsi.h7
5 files changed, 24 insertions, 9 deletions
diff --git a/riscv/decode.h b/riscv/decode.h
index f4d6b6c..6e54431 100644
--- a/riscv/decode.h
+++ b/riscv/decode.h
@@ -184,7 +184,10 @@ private:
#define require_fp require((STATE.mstatus & MSTATUS_FS) != 0)
#define require_accelerator require((STATE.mstatus & MSTATUS_XS) != 0)
-#define set_fp_exceptions ({ STATE.fflags |= softfloat_exceptionFlags; \
+#define set_fp_exceptions ({ if (softfloat_exceptionFlags) { \
+ dirty_fp_state; \
+ STATE.fflags |= softfloat_exceptionFlags; \
+ } \
softfloat_exceptionFlags = 0; })
#define sext32(x) ((sreg_t)(int32_t)(x))
diff --git a/riscv/insns/csrrc.h b/riscv/insns/csrrc.h
index 74a6872..eae91fe 100644
--- a/riscv/insns/csrrc.h
+++ b/riscv/insns/csrrc.h
@@ -1,4 +1,7 @@
-int csr = validate_csr(insn.csr(), true);
+bool write = insn.rs1() != 0;
+int csr = validate_csr(insn.csr(), write);
reg_t old = p->get_csr(csr);
-p->set_csr(csr, old & ~RS1);
+if (write) {
+ p->set_csr(csr, old & ~RS1);
+}
WRITE_RD(sext_xlen(old));
diff --git a/riscv/insns/csrrci.h b/riscv/insns/csrrci.h
index 993f2d8..986d601 100644
--- a/riscv/insns/csrrci.h
+++ b/riscv/insns/csrrci.h
@@ -1,4 +1,7 @@
-int csr = validate_csr(insn.csr(), true);
+bool write = insn.rs1() != 0;
+int csr = validate_csr(insn.csr(), write);
reg_t old = p->get_csr(csr);
-p->set_csr(csr, old & ~(reg_t)insn.rs1());
+if (write) {
+ p->set_csr(csr, old & ~(reg_t)insn.rs1());
+}
WRITE_RD(sext_xlen(old));
diff --git a/riscv/insns/csrrs.h b/riscv/insns/csrrs.h
index 72b49bb..ec61b42 100644
--- a/riscv/insns/csrrs.h
+++ b/riscv/insns/csrrs.h
@@ -1,4 +1,7 @@
-int csr = validate_csr(insn.csr(), insn.rs1() != 0);
+bool write = insn.rs1() != 0;
+int csr = validate_csr(insn.csr(), write);
reg_t old = p->get_csr(csr);
-p->set_csr(csr, old | RS1);
+if (write) {
+ p->set_csr(csr, old | RS1);
+}
WRITE_RD(sext_xlen(old));
diff --git a/riscv/insns/csrrsi.h b/riscv/insns/csrrsi.h
index 90a4436..aa44dcc 100644
--- a/riscv/insns/csrrsi.h
+++ b/riscv/insns/csrrsi.h
@@ -1,4 +1,7 @@
-int csr = validate_csr(insn.csr(), true);
+bool write = insn.rs1() != 0;
+int csr = validate_csr(insn.csr(), write);
reg_t old = p->get_csr(csr);
-p->set_csr(csr, old | insn.rs1());
+if (write) {
+ p->set_csr(csr, old | insn.rs1());
+}
WRITE_RD(sext_xlen(old));