aboutsummaryrefslogtreecommitdiff
path: root/riscv/insns
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 /riscv/insns
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.
Diffstat (limited to 'riscv/insns')
-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
54 files changed, 113 insertions, 76 deletions
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);