aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--riscv/encoding.h31
-rw-r--r--riscv/insns/bfp.h16
-rw-r--r--riscv/insns/bfpw.h12
-rw-r--r--riscv/insns/packh.h4
-rw-r--r--riscv/insns/packu.h4
-rw-r--r--riscv/insns/packuw.h4
-rw-r--r--riscv/insns/sext_b.h2
-rw-r--r--riscv/insns/sext_h.h2
-rw-r--r--riscv/riscv.mk.in5
9 files changed, 57 insertions, 23 deletions
diff --git a/riscv/encoding.h b/riscv/encoding.h
index ee0a184..6654183 100644
--- a/riscv/encoding.h
+++ b/riscv/encoding.h
@@ -508,6 +508,10 @@
#define MASK_CTZ 0xfff0707f
#define MATCH_PCNT 0x60201013
#define MASK_PCNT 0xfff0707f
+#define MATCH_SEXT_B 0x60401013
+#define MASK_SEXT_B 0xfff0707f
+#define MATCH_SEXT_H 0x60501013
+#define MASK_SEXT_H 0xfff0707f
#define MATCH_CRC32_B 0x61001013
#define MASK_CRC32_B 0xfff0707f
#define MATCH_CRC32_H 0x61101013
@@ -538,13 +542,17 @@
#define MASK_SHFL 0xfe00707f
#define MATCH_UNSHFL 0x8005033
#define MASK_UNSHFL 0xfe00707f
-#define MATCH_BDEP 0x8002033
-#define MASK_BDEP 0xfe00707f
#define MATCH_BEXT 0x8006033
#define MASK_BEXT 0xfe00707f
+#define MATCH_BDEP 0x48006033
+#define MASK_BDEP 0xfe00707f
#define MATCH_PACK 0x8004033
#define MASK_PACK 0xfe00707f
-#define MATCH_BFP 0x8007033
+#define MATCH_PACKU 0x48004033
+#define MASK_PACKU 0xfe00707f
+#define MATCH_PACKH 0x8007033
+#define MASK_PACKH 0xfe00707f
+#define MATCH_BFP 0x48007033
#define MASK_BFP 0xfe00707f
#define MATCH_SHFLI 0x8001013
#define MASK_SHFLI 0xfe00707f
@@ -630,13 +638,15 @@
#define MASK_SHFLW 0xfe00707f
#define MATCH_UNSHFLW 0x800503b
#define MASK_UNSHFLW 0xfe00707f
-#define MATCH_BDEPW 0x800203b
-#define MASK_BDEPW 0xfe00707f
#define MATCH_BEXTW 0x800603b
#define MASK_BEXTW 0xfe00707f
+#define MATCH_BDEPW 0x4800603b
+#define MASK_BDEPW 0xfe00707f
#define MATCH_PACKW 0x800403b
#define MASK_PACKW 0xfe00707f
-#define MATCH_BFPW 0x800703b
+#define MATCH_PACKUW 0x4800403b
+#define MASK_PACKUW 0xfe00707f
+#define MATCH_BFPW 0x4800703b
#define MASK_BFPW 0xfe00707f
#define MATCH_AMOADD_W 0x202f
#define MASK_AMOADD_W 0xf800707f
@@ -2443,6 +2453,8 @@ DECLARE_INSN(fsri, MATCH_FSRI, MASK_FSRI)
DECLARE_INSN(clz, MATCH_CLZ, MASK_CLZ)
DECLARE_INSN(ctz, MATCH_CTZ, MASK_CTZ)
DECLARE_INSN(pcnt, MATCH_PCNT, MASK_PCNT)
+DECLARE_INSN(sext_b, MATCH_SEXT_B, MASK_SEXT_B)
+DECLARE_INSN(sext_h, MATCH_SEXT_H, MASK_SEXT_H)
DECLARE_INSN(crc32_b, MATCH_CRC32_B, MASK_CRC32_B)
DECLARE_INSN(crc32_h, MATCH_CRC32_H, MASK_CRC32_H)
DECLARE_INSN(crc32_w, MATCH_CRC32_W, MASK_CRC32_W)
@@ -2458,9 +2470,11 @@ DECLARE_INSN(minu, MATCH_MINU, MASK_MINU)
DECLARE_INSN(maxu, MATCH_MAXU, MASK_MAXU)
DECLARE_INSN(shfl, MATCH_SHFL, MASK_SHFL)
DECLARE_INSN(unshfl, MATCH_UNSHFL, MASK_UNSHFL)
-DECLARE_INSN(bdep, MATCH_BDEP, MASK_BDEP)
DECLARE_INSN(bext, MATCH_BEXT, MASK_BEXT)
+DECLARE_INSN(bdep, MATCH_BDEP, MASK_BDEP)
DECLARE_INSN(pack, MATCH_PACK, MASK_PACK)
+DECLARE_INSN(packu, MATCH_PACKU, MASK_PACKU)
+DECLARE_INSN(packh, MATCH_PACKH, MASK_PACKH)
DECLARE_INSN(bfp, MATCH_BFP, MASK_BFP)
DECLARE_INSN(shfli, MATCH_SHFLI, MASK_SHFLI)
DECLARE_INSN(unshfli, MATCH_UNSHFLI, MASK_UNSHFLI)
@@ -2504,9 +2518,10 @@ DECLARE_INSN(clmulrw, MATCH_CLMULRW, MASK_CLMULRW)
DECLARE_INSN(clmulhw, MATCH_CLMULHW, MASK_CLMULHW)
DECLARE_INSN(shflw, MATCH_SHFLW, MASK_SHFLW)
DECLARE_INSN(unshflw, MATCH_UNSHFLW, MASK_UNSHFLW)
-DECLARE_INSN(bdepw, MATCH_BDEPW, MASK_BDEPW)
DECLARE_INSN(bextw, MATCH_BEXTW, MASK_BEXTW)
+DECLARE_INSN(bdepw, MATCH_BDEPW, MASK_BDEPW)
DECLARE_INSN(packw, MATCH_PACKW, MASK_PACKW)
+DECLARE_INSN(packuw, MATCH_PACKUW, MASK_PACKUW)
DECLARE_INSN(bfpw, MATCH_BFPW, MASK_BFPW)
DECLARE_INSN(amoadd_w, MATCH_AMOADD_W, MASK_AMOADD_W)
DECLARE_INSN(amoxor_w, MATCH_AMOXOR_W, MASK_AMOXOR_W)
diff --git a/riscv/insns/bfp.h b/riscv/insns/bfp.h
index 705fed0..96e6cfc 100644
--- a/riscv/insns/bfp.h
+++ b/riscv/insns/bfp.h
@@ -1,10 +1,10 @@
require_extension('B');
-int len = (RS2 >> 24) & 15;
-int off = (RS2 >> 16) & (xlen-1);
-int roff = -off & (xlen-1);
-len = len ? len : 16;
-reg_t mask = (1 << len) - 1;
-reg_t data = zext_xlen(RS2);
-mask = (mask << off) | (mask >> roff);
-data = (data << off) | (data >> roff);
+reg_t cfg = RS2 >> (xlen/2);
+if ((cfg >> 30) == 2)
+ cfg = cfg >> 16;
+int len = (cfg >> 8) & (xlen/2-1);
+int off = cfg & (xlen-1);
+len = len ? len : xlen/2;
+reg_t mask = ~(~reg_t(0) << len) << off;
+reg_t data = RS2 << off;
WRITE_RD(sext_xlen((data & mask) | (RS1 & ~mask)));
diff --git a/riscv/insns/bfpw.h b/riscv/insns/bfpw.h
index 1411b88..2a19ac1 100644
--- a/riscv/insns/bfpw.h
+++ b/riscv/insns/bfpw.h
@@ -1,10 +1,8 @@
require_extension('B');
-int len = (RS2 >> 24) & 15;
-int off = (RS2 >> 16) & 31;
-int roff = -off & 31;
+reg_t cfg = RS2 >> 16;
+int len = (cfg >> 8) & 15;
+int off = cfg & 31;
len = len ? len : 16;
-reg_t mask = (1 << len) - 1;
-reg_t data = zext32(RS2);
-mask = (mask << off) | (mask >> roff);
-data = (data << off) | (data >> roff);
+reg_t mask = ~(~reg_t(0) << len) << off;
+reg_t data = RS2 << off;
WRITE_RD(sext32((data & mask) | (RS1 & ~mask)));
diff --git a/riscv/insns/packh.h b/riscv/insns/packh.h
new file mode 100644
index 0000000..34a95c8
--- /dev/null
+++ b/riscv/insns/packh.h
@@ -0,0 +1,4 @@
+require_extension('B');
+reg_t lo = zext_xlen(RS1 << (xlen-8)) >> (xlen-8);
+reg_t hi = zext_xlen(RS2 << (xlen-8)) >> (xlen-16);
+WRITE_RD(sext_xlen(lo | hi));
diff --git a/riscv/insns/packu.h b/riscv/insns/packu.h
new file mode 100644
index 0000000..25cc9c2
--- /dev/null
+++ b/riscv/insns/packu.h
@@ -0,0 +1,4 @@
+require_extension('B');
+reg_t lo = zext_xlen(RS1) >> (xlen/2);
+reg_t hi = zext_xlen(RS2) >> (xlen/2) << (xlen/2);
+WRITE_RD(sext_xlen(lo | hi));
diff --git a/riscv/insns/packuw.h b/riscv/insns/packuw.h
new file mode 100644
index 0000000..b4a2f50
--- /dev/null
+++ b/riscv/insns/packuw.h
@@ -0,0 +1,4 @@
+require_extension('B');
+reg_t lo = zext32(RS1) >> 16;
+reg_t hi = zext32(RS2) >> 16 << 16;
+WRITE_RD(sext32(lo | hi));
diff --git a/riscv/insns/sext_b.h b/riscv/insns/sext_b.h
new file mode 100644
index 0000000..566e6f8
--- /dev/null
+++ b/riscv/insns/sext_b.h
@@ -0,0 +1,2 @@
+require_extension('B');
+WRITE_RD((sreg_t)(int8_t)(RS1));
diff --git a/riscv/insns/sext_h.h b/riscv/insns/sext_h.h
new file mode 100644
index 0000000..bd1fde2
--- /dev/null
+++ b/riscv/insns/sext_h.h
@@ -0,0 +1,2 @@
+require_extension('B');
+WRITE_RD((sreg_t)(int16_t)(RS1));
diff --git a/riscv/riscv.mk.in b/riscv/riscv.mk.in
index 04c35da..4cc82d0 100644
--- a/riscv/riscv.mk.in
+++ b/riscv/riscv.mk.in
@@ -387,6 +387,9 @@ riscv_insn_ext_b = \
minu \
orn \
pack \
+ packh \
+ packu \
+ packuw \
packw \
pcnt \
pcntw \
@@ -411,6 +414,8 @@ riscv_insn_ext_b = \
sbseti \
sbsetiw \
sbsetw \
+ sext_b \
+ sext_h \
shfl \
shfli \
shflw \