aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrew Waterman <waterman@s141.Millennium.Berkeley.EDU>2011-01-18 17:51:52 -0800
committerAndrew Waterman <waterman@s141.Millennium.Berkeley.EDU>2011-01-18 17:51:52 -0800
commit21ce327f5d60d6805b5d9328b68f7ad2c261a859 (patch)
tree22ee7ac3dfb4d00662ff6f0d1f057481efc67772
parent5ddec097b858aafe783eb3aff551d00e9c8c8a37 (diff)
downloadspike-21ce327f5d60d6805b5d9328b68f7ad2c261a859.zip
spike-21ce327f5d60d6805b5d9328b68f7ad2c261a859.tar.gz
spike-21ce327f5d60d6805b5d9328b68f7ad2c261a859.tar.bz2
[opcodes, sim, xcc] made *w insns illegal in RV32
now generic variants behave differently in RV32 and RV64.
-rw-r--r--riscv/decode.h57
-rw-r--r--riscv/execute.h10
-rw-r--r--riscv/insns/add.h3
-rw-r--r--riscv/insns/addi.h3
-rw-r--r--riscv/insns/addiw.h1
-rw-r--r--riscv/insns/addw.h2
-rw-r--r--riscv/insns/amo_add.h2
-rw-r--r--riscv/insns/amo_and.h2
-rw-r--r--riscv/insns/amo_max.h2
-rw-r--r--riscv/insns/amo_maxu.h2
-rw-r--r--riscv/insns/amo_min.h2
-rw-r--r--riscv/insns/amo_minu.h2
-rw-r--r--riscv/insns/amo_or.h2
-rw-r--r--riscv/insns/amo_swap.h2
-rw-r--r--riscv/insns/cvt_d_l.h2
-rw-r--r--riscv/insns/cvt_l_d.h2
-rw-r--r--riscv/insns/cvt_l_s.h2
-rw-r--r--riscv/insns/cvt_s_l.h2
-rw-r--r--riscv/insns/cvtu_d_l.h2
-rw-r--r--riscv/insns/cvtu_l_d.h2
-rw-r--r--riscv/insns/cvtu_l_s.h2
-rw-r--r--riscv/insns/cvtu_s_l.h2
-rw-r--r--riscv/insns/div.h10
-rw-r--r--riscv/insns/divu.h3
-rw-r--r--riscv/insns/divuw.h7
-rw-r--r--riscv/insns/divw.h9
-rw-r--r--riscv/insns/ld.h2
-rw-r--r--riscv/insns/mfcr.h2
-rw-r--r--riscv/insns/mff_d.h2
-rw-r--r--riscv/insns/mfpcr.h2
-rw-r--r--riscv/insns/mtf_d.h2
-rw-r--r--riscv/insns/mul.h3
-rw-r--r--riscv/insns/mulh.h12
-rw-r--r--riscv/insns/mulhu.h6
-rw-r--r--riscv/insns/mulhuw.h2
-rw-r--r--riscv/insns/mulhw.h2
-rw-r--r--riscv/insns/mulw.h2
-rw-r--r--riscv/insns/rem.h7
-rw-r--r--riscv/insns/remu.h5
-rw-r--r--riscv/insns/remuw.h7
-rw-r--r--riscv/insns/remw.h9
-rw-r--r--riscv/insns/sd.h2
-rw-r--r--riscv/insns/sll.h3
-rw-r--r--riscv/insns/slli.h10
-rw-r--r--riscv/insns/slliw.h1
-rw-r--r--riscv/insns/sllw.h1
-rw-r--r--riscv/insns/sra.h3
-rw-r--r--riscv/insns/srai.h10
-rw-r--r--riscv/insns/sraiw.h1
-rw-r--r--riscv/insns/sraw.h1
-rw-r--r--riscv/insns/srl.h6
-rw-r--r--riscv/insns/srli.h10
-rw-r--r--riscv/insns/srliw.h1
-rw-r--r--riscv/insns/srlw.h1
-rw-r--r--riscv/insns/sub.h3
-rw-r--r--riscv/insns/subw.h1
-rw-r--r--riscv/processor.cc22
-rw-r--r--riscv/processor.h8
-rw-r--r--riscv/sim.cc6
59 files changed, 155 insertions, 137 deletions
diff --git a/riscv/decode.h b/riscv/decode.h
index 5348ccc..fff6e0e 100644
--- a/riscv/decode.h
+++ b/riscv/decode.h
@@ -6,19 +6,6 @@
#include "config.h"
-#ifdef RISCV_ENABLE_64BIT
-# define support_64bit 1
-#else
-# define support_64bit 0
-#endif
-
-#ifdef RISCV_ENABLE_FPU
-# define support_fp 1
-#else
-# define support_fp 0
-#endif
-
-
typedef int int128_t __attribute__((mode(TI)));
typedef unsigned int uint128_t __attribute__((mode(TI)));
@@ -28,9 +15,8 @@ typedef uint64_t freg_t;
const int OPCODE_BITS = 7;
-const int GPR_BITS = 8*sizeof(reg_t);
-const int GPRID_BITS = 5;
-const int NGPR = 1 << GPRID_BITS;
+const int XPRID_BITS = 5;
+const int NXPR = 1 << XPRID_BITS;
const int FPR_BITS = 64;
const int FPRID_BITS = 5;
@@ -87,8 +73,8 @@ struct itype_t
unsigned opcode : OPCODE_BITS;
unsigned funct : FUNCT_BITS;
signed imm12 : IMM_BITS;
- unsigned rs1 : GPRID_BITS;
- unsigned rd : GPRID_BITS;
+ unsigned rs1 : XPRID_BITS;
+ unsigned rd : XPRID_BITS;
};
struct btype_t
@@ -96,8 +82,8 @@ struct btype_t
unsigned opcode : OPCODE_BITS;
unsigned funct : FUNCT_BITS;
unsigned immlo : IMMLO_BITS;
- unsigned rs2 : GPRID_BITS;
- unsigned rs1 : GPRID_BITS;
+ unsigned rs2 : XPRID_BITS;
+ unsigned rs1 : XPRID_BITS;
signed immhi : IMM_BITS-IMMLO_BITS;
};
@@ -112,16 +98,16 @@ struct rtype_t
unsigned opcode : OPCODE_BITS;
unsigned funct : FUNCT_BITS;
unsigned functr : FUNCTR_BITS;
- unsigned rs2 : GPRID_BITS;
- unsigned rs1 : GPRID_BITS;
- unsigned rd : GPRID_BITS;
+ unsigned rs2 : XPRID_BITS;
+ unsigned rs1 : XPRID_BITS;
+ unsigned rd : XPRID_BITS;
};
struct ltype_t
{
unsigned opcode : OPCODE_BITS;
unsigned bigimm : BIGIMM_BITS;
- unsigned rd : GPRID_BITS;
+ unsigned rd : XPRID_BITS;
};
struct ftype_t
@@ -170,14 +156,14 @@ private:
#endif
// helpful macros, etc
-#define RS1 R[insn.rtype.rs1]
-#define RS2 R[insn.rtype.rs2]
-#define RD do_writeback(R,insn.rtype.rd)
-#define RA do_writeback(R,1)
-#define FRS1 FR[insn.ftype.rs1]
-#define FRS2 FR[insn.ftype.rs2]
-#define FRS3 FR[insn.ftype.rs3]
-#define FRD FR[insn.ftype.rd]
+#define RS1 XPR[insn.rtype.rs1]
+#define RS2 XPR[insn.rtype.rs2]
+#define RD do_writeback(XPR,insn.rtype.rd)
+#define RA do_writeback(XPR,1)
+#define FRS1 FPR[insn.ftype.rs1]
+#define FRS2 FPR[insn.ftype.rs2]
+#define FRS3 FPR[insn.ftype.rs3]
+#define FRD FPR[insn.ftype.rd]
#define BIGIMM insn.ltype.bigimm
#define SIMM insn.itype.imm12
#define BIMM ((signed)insn.btype.immlo | (insn.btype.immhi << IMMLO_BITS))
@@ -190,9 +176,10 @@ private:
((fsr & FSR_RD) >> FSR_RD_SHIFT))
#define require_supervisor if(!(sr & SR_S)) throw trap_privileged_instruction
-#define require64 if(gprlen != 64) throw trap_illegal_instruction
+#define xpr64 (xprlen == 64)
+#define require_xpr64 if(!xpr64) throw trap_illegal_instruction
#define require_fp if(!(sr & SR_EF)) throw trap_fp_disabled
-#define cmp_trunc(reg) (reg_t(reg) << (64-gprlen))
+#define cmp_trunc(reg) (reg_t(reg) << (64-xprlen))
#define set_fp_exceptions ({ set_fsr(fsr | \
(softfloat_exceptionFlags << FSR_AEXC_SHIFT)); \
softfloat_exceptionFlags = 0; })
@@ -202,4 +189,6 @@ static inline sreg_t sext32(int32_t arg)
return arg;
}
+#define sext_xprlen(x) ((sreg_t(x) << (64-xprlen)) >> (64-xprlen))
+
#endif
diff --git a/riscv/execute.h b/riscv/execute.h
index ddc7b42..b8e396a 100644
--- a/riscv/execute.h
+++ b/riscv/execute.h
@@ -768,11 +768,6 @@ switch((insn.bits >> 0x0) & 0x7f)
#include "insns/divuw.h"
break;
}
- if((insn.bits & 0x1ffff) == 0xcf7)
- {
- #include "insns/mulhuw.h"
- break;
- }
if((insn.bits & 0x1ffff) == 0xf7)
{
#include "insns/mulw.h"
@@ -783,11 +778,6 @@ switch((insn.bits >> 0x0) & 0x7f)
#include "insns/remw.h"
break;
}
- if((insn.bits & 0x1ffff) == 0x8f7)
- {
- #include "insns/mulhw.h"
- break;
- }
if((insn.bits & 0x1ffff) == 0x10f7)
{
#include "insns/divw.h"
diff --git a/riscv/insns/add.h b/riscv/insns/add.h
index a7ec78d..34d49ff 100644
--- a/riscv/insns/add.h
+++ b/riscv/insns/add.h
@@ -1,2 +1 @@
-require64;
-RD = RS1 + RS2;
+RD = sext_xprlen(RS1 + RS2);
diff --git a/riscv/insns/addi.h b/riscv/insns/addi.h
index 2b9bae3..88881e5 100644
--- a/riscv/insns/addi.h
+++ b/riscv/insns/addi.h
@@ -1,2 +1 @@
-require64;
-RD = SIMM + RS1;
+RD = sext_xprlen(RS1 + SIMM);
diff --git a/riscv/insns/addiw.h b/riscv/insns/addiw.h
index cf97d34..23ae278 100644
--- a/riscv/insns/addiw.h
+++ b/riscv/insns/addiw.h
@@ -1 +1,2 @@
+require_xpr64;
RD = sext32(SIMM + RS1);
diff --git a/riscv/insns/addw.h b/riscv/insns/addw.h
index f8715e3..4e2ed56 100644
--- a/riscv/insns/addw.h
+++ b/riscv/insns/addw.h
@@ -1,2 +1,2 @@
+require_xpr64;
RD = sext32(RS1 + RS2);
-
diff --git a/riscv/insns/amo_add.h b/riscv/insns/amo_add.h
index 3b59ffd..b8450bf 100644
--- a/riscv/insns/amo_add.h
+++ b/riscv/insns/amo_add.h
@@ -1,4 +1,4 @@
-require64;
+require_xpr64;
reg_t v = mmu.load_uint64(RS1);
mmu.store_uint64(RS1, RS2 + v);
RD = v;
diff --git a/riscv/insns/amo_and.h b/riscv/insns/amo_and.h
index 7295501..586eb7f 100644
--- a/riscv/insns/amo_and.h
+++ b/riscv/insns/amo_and.h
@@ -1,4 +1,4 @@
-require64;
+require_xpr64;
reg_t v = mmu.load_uint64(RS1);
mmu.store_uint64(RS1, RS2 & v);
RD = v;
diff --git a/riscv/insns/amo_max.h b/riscv/insns/amo_max.h
index f67f1a3..1a0bc8a 100644
--- a/riscv/insns/amo_max.h
+++ b/riscv/insns/amo_max.h
@@ -1,4 +1,4 @@
-require64;
+require_xpr64;
sreg_t v = mmu.load_int64(RS1);
mmu.store_uint64(RS1, std::max(sreg_t(RS2),v));
RD = v;
diff --git a/riscv/insns/amo_maxu.h b/riscv/insns/amo_maxu.h
index 9a3d9f6..ccfaf1d 100644
--- a/riscv/insns/amo_maxu.h
+++ b/riscv/insns/amo_maxu.h
@@ -1,4 +1,4 @@
-require64;
+require_xpr64;
reg_t v = mmu.load_uint64(RS1);
mmu.store_uint64(RS1, std::max(RS2,v));
RD = v;
diff --git a/riscv/insns/amo_min.h b/riscv/insns/amo_min.h
index 4acfe74..4f3b6d6 100644
--- a/riscv/insns/amo_min.h
+++ b/riscv/insns/amo_min.h
@@ -1,4 +1,4 @@
-require64;
+require_xpr64;
sreg_t v = mmu.load_int64(RS1);
mmu.store_uint64(RS1, std::min(sreg_t(RS2),v));
RD = v;
diff --git a/riscv/insns/amo_minu.h b/riscv/insns/amo_minu.h
index 5af3b9d..c09c51a 100644
--- a/riscv/insns/amo_minu.h
+++ b/riscv/insns/amo_minu.h
@@ -1,4 +1,4 @@
-require64;
+require_xpr64;
reg_t v = mmu.load_uint64(RS1);
mmu.store_uint64(RS1, std::min(RS2,v));
RD = v;
diff --git a/riscv/insns/amo_or.h b/riscv/insns/amo_or.h
index df4f2fe..76a4508 100644
--- a/riscv/insns/amo_or.h
+++ b/riscv/insns/amo_or.h
@@ -1,4 +1,4 @@
-require64;
+require_xpr64;
reg_t v = mmu.load_uint64(RS1);
mmu.store_uint64(RS1, RS2 | v);
RD = v;
diff --git a/riscv/insns/amo_swap.h b/riscv/insns/amo_swap.h
index 6889055..43e3538 100644
--- a/riscv/insns/amo_swap.h
+++ b/riscv/insns/amo_swap.h
@@ -1,4 +1,4 @@
-require64;
+require_xpr64;
reg_t v = mmu.load_uint64(RS1);
mmu.store_uint64(RS1, RS2);
RD = v;
diff --git a/riscv/insns/cvt_d_l.h b/riscv/insns/cvt_d_l.h
index 84c1a71..68c0482 100644
--- a/riscv/insns/cvt_d_l.h
+++ b/riscv/insns/cvt_d_l.h
@@ -1,4 +1,4 @@
-require64;
+require_xpr64;
require_fp;
softfloat_roundingMode = RM;
FRD = i64_to_f64(RS1);
diff --git a/riscv/insns/cvt_l_d.h b/riscv/insns/cvt_l_d.h
index 2747d67..bd460d5 100644
--- a/riscv/insns/cvt_l_d.h
+++ b/riscv/insns/cvt_l_d.h
@@ -1,4 +1,4 @@
-require64;
+require_xpr64;
require_fp;
softfloat_roundingMode = RM;
RD = f64_to_i64_r_minMag(FRS1,true);
diff --git a/riscv/insns/cvt_l_s.h b/riscv/insns/cvt_l_s.h
index f5b053c..1ed4594 100644
--- a/riscv/insns/cvt_l_s.h
+++ b/riscv/insns/cvt_l_s.h
@@ -1,4 +1,4 @@
-require64;
+require_xpr64;
require_fp;
softfloat_roundingMode = RM;
RD = f32_to_i64_r_minMag(FRS1,true);
diff --git a/riscv/insns/cvt_s_l.h b/riscv/insns/cvt_s_l.h
index 79fbc97..f149229 100644
--- a/riscv/insns/cvt_s_l.h
+++ b/riscv/insns/cvt_s_l.h
@@ -1,4 +1,4 @@
-require64;
+require_xpr64;
require_fp;
softfloat_roundingMode = RM;
FRD = i64_to_f32(RS1);
diff --git a/riscv/insns/cvtu_d_l.h b/riscv/insns/cvtu_d_l.h
index 84c1a71..68c0482 100644
--- a/riscv/insns/cvtu_d_l.h
+++ b/riscv/insns/cvtu_d_l.h
@@ -1,4 +1,4 @@
-require64;
+require_xpr64;
require_fp;
softfloat_roundingMode = RM;
FRD = i64_to_f64(RS1);
diff --git a/riscv/insns/cvtu_l_d.h b/riscv/insns/cvtu_l_d.h
index 2747d67..bd460d5 100644
--- a/riscv/insns/cvtu_l_d.h
+++ b/riscv/insns/cvtu_l_d.h
@@ -1,4 +1,4 @@
-require64;
+require_xpr64;
require_fp;
softfloat_roundingMode = RM;
RD = f64_to_i64_r_minMag(FRS1,true);
diff --git a/riscv/insns/cvtu_l_s.h b/riscv/insns/cvtu_l_s.h
index f5b053c..1ed4594 100644
--- a/riscv/insns/cvtu_l_s.h
+++ b/riscv/insns/cvtu_l_s.h
@@ -1,4 +1,4 @@
-require64;
+require_xpr64;
require_fp;
softfloat_roundingMode = RM;
RD = f32_to_i64_r_minMag(FRS1,true);
diff --git a/riscv/insns/cvtu_s_l.h b/riscv/insns/cvtu_s_l.h
index 79fbc97..f149229 100644
--- a/riscv/insns/cvtu_s_l.h
+++ b/riscv/insns/cvtu_s_l.h
@@ -1,4 +1,4 @@
-require64;
+require_xpr64;
require_fp;
softfloat_roundingMode = RM;
FRD = i64_to_f32(RS1);
diff --git a/riscv/insns/div.h b/riscv/insns/div.h
index 1f61cf1..aa67134 100644
--- a/riscv/insns/div.h
+++ b/riscv/insns/div.h
@@ -1,5 +1,9 @@
-require64;
if(RS2 == 0 || (sreg_t(RS1) == INT64_MIN && sreg_t(RS2) == -1))
- RD = sreg_t(RS1) < 0 ? INT64_MIN : INT64_MAX;
+{
+ if(xpr64)
+ RD = sreg_t(RS1) < 0 ? INT64_MIN : INT64_MAX;
+ else
+ RD = sreg_t(RS1) < 0 ? sext32(INT32_MIN) : INT32_MAX;
+}
else
- RD = sreg_t(RS1) / sreg_t(RS2);
+ RD = sext_xprlen(sreg_t(RS1) / sreg_t(RS2));
diff --git a/riscv/insns/divu.h b/riscv/insns/divu.h
index 86792a2..d4a4eca 100644
--- a/riscv/insns/divu.h
+++ b/riscv/insns/divu.h
@@ -1,5 +1,4 @@
-require64;
if(RS2 == 0)
RD = UINT64_MAX;
else
- RD = RS1 / RS2;
+ RD = sext_xprlen(RS1 / RS2);
diff --git a/riscv/insns/divuw.h b/riscv/insns/divuw.h
index 296bb9e..4d64be3 100644
--- a/riscv/insns/divuw.h
+++ b/riscv/insns/divuw.h
@@ -1,4 +1,5 @@
-if(uint32_t(RS2) == 0)
- RD = sext32(UINT32_MAX);
+require_xpr64;
+if(RS2 == 0)
+ RD = UINT64_MAX;
else
- RD = sext32(uint32_t(RS1)/uint32_t(RS2));
+ RD = sext32(RS1 / RS2);
diff --git a/riscv/insns/divw.h b/riscv/insns/divw.h
index bfc982a..9c732b5 100644
--- a/riscv/insns/divw.h
+++ b/riscv/insns/divw.h
@@ -1,4 +1,7 @@
-if(int32_t(RS2) == 0 || (int32_t(RS1) == INT32_MIN && int32_t(RS2) == -1))
- RD = sext32(int32_t(RS1) < 0 ? INT32_MIN : INT32_MAX);
+require_xpr64;
+// INT64_MIN/-1 corner case shouldn't occur in correct code, since
+// INT64_MIN is not a proper 32-bit signed value
+if(RS2 == 0 || (sreg_t(RS1) == INT64_MIN && sreg_t(RS2) == -1))
+ RD = sext32(sreg_t(RS1) < 0 ? INT32_MIN : INT32_MAX);
else
- RD = sext32(int32_t(RS1)/int32_t(RS2));
+ RD = sext32(sreg_t(RS1) / sreg_t(RS2));
diff --git a/riscv/insns/ld.h b/riscv/insns/ld.h
index 973a8b3..940d348 100644
--- a/riscv/insns/ld.h
+++ b/riscv/insns/ld.h
@@ -1,2 +1,2 @@
-require64;
+require_xpr64;
RD = mmu.load_int64(RS1+SIMM);
diff --git a/riscv/insns/mfcr.h b/riscv/insns/mfcr.h
index 6209e6f..f3bd81e 100644
--- a/riscv/insns/mfcr.h
+++ b/riscv/insns/mfcr.h
@@ -15,4 +15,4 @@ switch(insn.rtype.rs2)
val = -1;
}
-RD = gprlen == 64 ? val : sext32(val);
+RD = sext_xprlen(val);
diff --git a/riscv/insns/mff_d.h b/riscv/insns/mff_d.h
index ba53561..31be4cb 100644
--- a/riscv/insns/mff_d.h
+++ b/riscv/insns/mff_d.h
@@ -1,3 +1,3 @@
-require64;
+require_xpr64;
require_fp;
RD = FRS2;
diff --git a/riscv/insns/mfpcr.h b/riscv/insns/mfpcr.h
index 54c62ed..e9d5350 100644
--- a/riscv/insns/mfpcr.h
+++ b/riscv/insns/mfpcr.h
@@ -45,4 +45,4 @@ switch(insn.rtype.rs2)
val = -1;
}
-RD = gprlen == 64 ? val : sext32(val);
+RD = sext_xprlen(val);
diff --git a/riscv/insns/mtf_d.h b/riscv/insns/mtf_d.h
index 44daa9e..29792ec 100644
--- a/riscv/insns/mtf_d.h
+++ b/riscv/insns/mtf_d.h
@@ -1,3 +1,3 @@
-require64;
+require_xpr64;
require_fp;
FRD = RS1;
diff --git a/riscv/insns/mul.h b/riscv/insns/mul.h
index ff1e034..770d733 100644
--- a/riscv/insns/mul.h
+++ b/riscv/insns/mul.h
@@ -1,2 +1 @@
-require64;
-RD = RS1 * RS2;
+RD = sext_xprlen(RS1 * RS2);
diff --git a/riscv/insns/mulh.h b/riscv/insns/mulh.h
index ed9c1a8..ceefccd 100644
--- a/riscv/insns/mulh.h
+++ b/riscv/insns/mulh.h
@@ -1,4 +1,8 @@
-require64;
-int64_t rb = RS1;
-int64_t ra = RS2;
-RD = (int128_t(rb) * int128_t(ra)) >> 64;
+if(xpr64)
+{
+ int64_t a = RS1;
+ int64_t b = RS2;
+ RD = (int128_t(a) * int128_t(b)) >> 64;
+}
+else
+ RD = sext32((sreg_t(RS1) * sreg_t(RS2)) >> 32);
diff --git a/riscv/insns/mulhu.h b/riscv/insns/mulhu.h
index 17c610d..b6f45dd 100644
--- a/riscv/insns/mulhu.h
+++ b/riscv/insns/mulhu.h
@@ -1,2 +1,4 @@
-require64;
-RD = (uint128_t(RS1) * uint128_t(RS2)) >> 64;
+if(xpr64)
+ RD = (uint128_t(RS1) * uint128_t(RS2)) >> 64;
+else
+ RD = sext32((RS1 * RS2) >> 32);
diff --git a/riscv/insns/mulhuw.h b/riscv/insns/mulhuw.h
deleted file mode 100644
index 9260a24..0000000
--- a/riscv/insns/mulhuw.h
+++ /dev/null
@@ -1,2 +0,0 @@
-RD = sext32((RS1 * RS2) >> 32);
-
diff --git a/riscv/insns/mulhw.h b/riscv/insns/mulhw.h
deleted file mode 100644
index a47aa1e..0000000
--- a/riscv/insns/mulhw.h
+++ /dev/null
@@ -1,2 +0,0 @@
-RD = sext32((sreg_t(RS1) * sreg_t(RS2)) >> 32);
-
diff --git a/riscv/insns/mulw.h b/riscv/insns/mulw.h
index 81285a2..7b0a934 100644
--- a/riscv/insns/mulw.h
+++ b/riscv/insns/mulw.h
@@ -1,2 +1,2 @@
+require_xpr64;
RD = sext32(RS1 * RS2);
-
diff --git a/riscv/insns/rem.h b/riscv/insns/rem.h
index 1bc94f2..db7e0a9 100644
--- a/riscv/insns/rem.h
+++ b/riscv/insns/rem.h
@@ -1,5 +1,6 @@
-require64;
-if(RS2 == 0 || (sreg_t(RS1) == INT64_MIN && sreg_t(RS2) == -1))
+if(RS2 == 0)
+ RD = RS1;
+else if(sreg_t(RS1) == INT64_MIN && sreg_t(RS2) == -1)
RD = 0;
else
- RD = sreg_t(RS1) % sreg_t(RS2);
+ RD = sext_xprlen(sreg_t(RS1) % sreg_t(RS2));
diff --git a/riscv/insns/remu.h b/riscv/insns/remu.h
index 3b6c44f..04499ab 100644
--- a/riscv/insns/remu.h
+++ b/riscv/insns/remu.h
@@ -1,5 +1,4 @@
-require64;
if(RS2 == 0)
- RD = 0;
+ RD = RS1;
else
- RD = RS1 % RS2;
+ RD = sext_xprlen(RS1 % RS2);
diff --git a/riscv/insns/remuw.h b/riscv/insns/remuw.h
index 820a396..ae28fa5 100644
--- a/riscv/insns/remuw.h
+++ b/riscv/insns/remuw.h
@@ -1,4 +1,5 @@
-if(uint32_t(RS2) == 0)
- RD = 0;
+require_xpr64;
+if(RS2 == 0)
+ RD = RS1;
else
- RD = sext32(uint32_t(RS1) % uint32_t(RS2));
+ RD = sext32(RS1 % RS2);
diff --git a/riscv/insns/remw.h b/riscv/insns/remw.h
index eb23ef1..784baa3 100644
--- a/riscv/insns/remw.h
+++ b/riscv/insns/remw.h
@@ -1,4 +1,9 @@
-if(int32_t(RS2) == 0 || (int32_t(RS1) == INT32_MIN && int32_t(RS2) == -1))
+require_xpr64;
+// INT64_MIN/-1 corner case shouldn't occur in correct code, since
+// INT64_MIN is not a proper 32-bit signed value
+if(RS2 == 0)
+ RD = RS1;
+else if(sreg_t(RS1) == INT64_MIN && sreg_t(RS2) == -1)
RD = 0;
else
- RD = sext32(int32_t(RS1) % int32_t(RS2));
+ RD = sext32(sreg_t(RS1) % sreg_t(RS2));
diff --git a/riscv/insns/sd.h b/riscv/insns/sd.h
index f4ece21..2009149 100644
--- a/riscv/insns/sd.h
+++ b/riscv/insns/sd.h
@@ -1,2 +1,2 @@
-require64;
+require_xpr64;
mmu.store_uint64(RS1+BIMM, RS2);
diff --git a/riscv/insns/sll.h b/riscv/insns/sll.h
index ae38f16..86eb966 100644
--- a/riscv/insns/sll.h
+++ b/riscv/insns/sll.h
@@ -1,2 +1 @@
-require64;
-RD = RS1 << (RS2 & 0x3F);
+RD = sext_xprlen(RS1 << (RS2 & (xprlen-1)));
diff --git a/riscv/insns/slli.h b/riscv/insns/slli.h
index f7ba310..bfaf430 100644
--- a/riscv/insns/slli.h
+++ b/riscv/insns/slli.h
@@ -1,2 +1,8 @@
-require64;
-RD = RS1 << SHAMT;
+if(xpr64)
+ RD = RS1 << SHAMT;
+else
+{
+ if(SHAMT & 0x20)
+ throw trap_illegal_instruction;
+ RD = sext32(RS1 << SHAMT);
+}
diff --git a/riscv/insns/slliw.h b/riscv/insns/slliw.h
index 41be30f..1f6e50d 100644
--- a/riscv/insns/slliw.h
+++ b/riscv/insns/slliw.h
@@ -1 +1,2 @@
+require_xpr64;
RD = sext32(RS1 << SHAMTW);
diff --git a/riscv/insns/sllw.h b/riscv/insns/sllw.h
index 90e5c4c..f3356d8 100644
--- a/riscv/insns/sllw.h
+++ b/riscv/insns/sllw.h
@@ -1 +1,2 @@
+require_xpr64;
RD = sext32(RS1 << (RS2 & 0x1F));
diff --git a/riscv/insns/sra.h b/riscv/insns/sra.h
index 4a78916..8bbdc09 100644
--- a/riscv/insns/sra.h
+++ b/riscv/insns/sra.h
@@ -1,2 +1 @@
-require64;
-RD = sreg_t(RS1) >> (RS2 & 0x3F);
+RD = sext_xprlen(sreg_t(RS1) >> (RS2 & (xprlen-1)));
diff --git a/riscv/insns/srai.h b/riscv/insns/srai.h
index 1f0dde2..18fc55b 100644
--- a/riscv/insns/srai.h
+++ b/riscv/insns/srai.h
@@ -1,2 +1,8 @@
-require64;
-RD = sreg_t(RS1) >> SHAMT;
+if(xpr64)
+ RD = sreg_t(RS1) >> SHAMT;
+else
+{
+ if(SHAMT & 0x20)
+ throw trap_illegal_instruction;
+ RD = sext32(sreg_t(RS1) >> SHAMT);
+}
diff --git a/riscv/insns/sraiw.h b/riscv/insns/sraiw.h
index 24a9eae..42d0fc3 100644
--- a/riscv/insns/sraiw.h
+++ b/riscv/insns/sraiw.h
@@ -1 +1,2 @@
+require_xpr64;
RD = sext32(sreg_t(RS1) >> SHAMTW);
diff --git a/riscv/insns/sraw.h b/riscv/insns/sraw.h
index f8946fb..103f03a 100644
--- a/riscv/insns/sraw.h
+++ b/riscv/insns/sraw.h
@@ -1 +1,2 @@
+require_xpr64;
RD = sext32(sreg_t(RS1) >> (RS2 & 0x1F));
diff --git a/riscv/insns/srl.h b/riscv/insns/srl.h
index 87138da..8230d27 100644
--- a/riscv/insns/srl.h
+++ b/riscv/insns/srl.h
@@ -1,2 +1,4 @@
-require64;
-RD = RS1 >> (RS2 & 0x3F);
+if(xpr64)
+ RD = RS1 >> (RS2 & 0x3F);
+else
+ RD = sext32((uint32_t)RS1 >> (RS2 & 0x1F));
diff --git a/riscv/insns/srli.h b/riscv/insns/srli.h
index e0d8ae0..5378fd1 100644
--- a/riscv/insns/srli.h
+++ b/riscv/insns/srli.h
@@ -1,2 +1,8 @@
-require64;
-RD = RS1 >> SHAMT;
+if(xpr64)
+ RD = RS1 >> SHAMT;
+else
+{
+ if(SHAMT & 0x20)
+ throw trap_illegal_instruction;
+ RD = sext32((uint32_t)RS1 >> SHAMT);
+}
diff --git a/riscv/insns/srliw.h b/riscv/insns/srliw.h
index 2a2bb31..c400507 100644
--- a/riscv/insns/srliw.h
+++ b/riscv/insns/srliw.h
@@ -1 +1,2 @@
+require_xpr64;
RD = sext32((uint32_t)RS1 >> SHAMTW);
diff --git a/riscv/insns/srlw.h b/riscv/insns/srlw.h
index a0058ae..b206f7c 100644
--- a/riscv/insns/srlw.h
+++ b/riscv/insns/srlw.h
@@ -1 +1,2 @@
+require_xpr64;
RD = sext32((uint32_t)RS1 >> (RS2 & 0x1F));
diff --git a/riscv/insns/sub.h b/riscv/insns/sub.h
index e7736c9..2b1e057 100644
--- a/riscv/insns/sub.h
+++ b/riscv/insns/sub.h
@@ -1,2 +1 @@
-require64;
-RD = RS1 - RS2;
+RD = sext_xprlen(RS1 - RS2);
diff --git a/riscv/insns/subw.h b/riscv/insns/subw.h
index 958cc5d..28db334 100644
--- a/riscv/insns/subw.h
+++ b/riscv/insns/subw.h
@@ -1,2 +1,3 @@
+require_xpr64;
RD = sext32(RS1 - RS2);
diff --git a/riscv/processor.cc b/riscv/processor.cc
index eed85da..6f36653 100644
--- a/riscv/processor.cc
+++ b/riscv/processor.cc
@@ -12,8 +12,8 @@
processor_t::processor_t(sim_t* _sim, char* _mem, size_t _memsz)
: sim(_sim), mmu(_mem,_memsz)
{
- memset(R,0,sizeof(R));
- memset(FR,0,sizeof(FR));
+ memset(XPR,0,sizeof(XPR));
+ memset(FPR,0,sizeof(FPR));
pc = 0;
evec = 0;
epc = 0;
@@ -26,7 +26,7 @@ processor_t::processor_t(sim_t* _sim, char* _mem, size_t _memsz)
count = 0;
compare = 0;
interrupts_pending = 0;
- set_sr(SR_S | (support_64bit ? SR_SX : 0));
+ set_sr(SR_S | SR_SX); // SX ignored if 64b mode not supported
set_fsr(0);
memset(counters,0,sizeof(counters));
@@ -48,12 +48,14 @@ void processor_t::init(uint32_t _id)
void processor_t::set_sr(uint32_t val)
{
sr = val & ~SR_ZERO;
- if(!support_64bit)
- sr &= ~(SR_SX | SR_UX);
- if(!support_fp)
- sr &= ~SR_EF;
-
- gprlen = ((sr & SR_S) ? (sr & SR_SX) : (sr & SR_UX)) ? 64 : 32;
+#ifndef RISCV_ENABLE_64BIT
+ sr &= ~(SR_SX | SR_UX);
+#endif
+#ifndef RISCV_ENABLE_64BIT
+ sr &= ~SR_EF;
+#endif
+
+ xprlen = ((sr & SR_S) ? (sr & SR_SX) : (sr & SR_UX)) ? 64 : 32;
}
void processor_t::set_fsr(uint32_t val)
@@ -86,7 +88,7 @@ void processor_t::step(size_t n, bool noisy)
#include "execute.h"
pc = npc;
- R[0] = 0;
+ XPR[0] = 0;
if(count++ == compare)
interrupts_pending |= 1 << TIMER_IRQ;
diff --git a/riscv/processor.h b/riscv/processor.h
index 9ccfbb4..b548038 100644
--- a/riscv/processor.h
+++ b/riscv/processor.h
@@ -19,8 +19,8 @@ private:
sim_t* sim;
// architected state
- reg_t R[NGPR];
- freg_t FR[NFPR];
+ reg_t XPR[NXPR];
+ freg_t FPR[NFPR];
// privileged control registers
reg_t pc;
@@ -41,8 +41,8 @@ private:
// unprivileged control registers
uint32_t fsr;
- // 32-bit or 64-bit mode (redundant with sr)
- int gprlen;
+ // # of bits in an XPR (32 or 64). (redundant with sr)
+ int xprlen;
// shared memory
mmu_t mmu;
diff --git a/riscv/sim.cc b/riscv/sim.cc
index ffcb186..f788021 100644
--- a/riscv/sim.cc
+++ b/riscv/sim.cc
@@ -163,10 +163,10 @@ reg_t sim_t::get_reg(const std::vector<std::string>& args)
int p = atoi(args[0].c_str());
int r = atoi(args[1].c_str());
- if(p >= (int)procs.size() || r >= NGPR)
+ if(p >= (int)procs.size() || r >= NXPR)
throw trap_illegal_instruction;
- return procs[p].R[r];
+ return procs[p].XPR[r];
}
reg_t sim_t::get_freg(const std::vector<std::string>& args)
@@ -179,7 +179,7 @@ reg_t sim_t::get_freg(const std::vector<std::string>& args)
if(p >= (int)procs.size() || r >= NFPR)
throw trap_illegal_instruction;
- return procs[p].FR[r];
+ return procs[p].FPR[r];
}
reg_t sim_t::get_tohost(const std::vector<std::string>& args)