From 9bfb43c668848a4850d5805b9adb8ad18e7f43b6 Mon Sep 17 00:00:00 2001 From: Chih-Min Chao <48193236+chihminchao@users.noreply.github.com> Date: Mon, 18 Jan 2021 15:56:00 +0800 Subject: rvb: add xperm.[nbhw] (#629) Signed-off-by: Chih-Min Chao --- riscv/arith.h | 18 ++++++++++++++++++ riscv/encoding.h | 14 +++++++++++++- riscv/insns/xperm_b.h | 2 ++ riscv/insns/xperm_h.h | 2 ++ riscv/insns/xperm_n.h | 2 ++ riscv/insns/xperm_w.h | 3 +++ riscv/riscv.mk.in | 4 ++++ 7 files changed, 44 insertions(+), 1 deletion(-) create mode 100644 riscv/insns/xperm_b.h create mode 100644 riscv/insns/xperm_h.h create mode 100644 riscv/insns/xperm_n.h create mode 100644 riscv/insns/xperm_w.h (limited to 'riscv') diff --git a/riscv/arith.h b/riscv/arith.h index b900e27..398217e 100644 --- a/riscv/arith.h +++ b/riscv/arith.h @@ -6,6 +6,7 @@ #include #include #include +#include inline uint64_t mulhu(uint64_t a, uint64_t b) { @@ -174,4 +175,21 @@ static inline int log2(uint64_t val) return 63 - clz(val); } +static inline uint64_t xperm(uint64_t rs1, uint64_t rs2, size_t sz_log2, size_t len) +{ + uint64_t r = 0; + uint64_t sz = 1LL << sz_log2; + uint64_t mask = (1LL << sz) - 1; + + assert(sz_log2 <= 6 && len <= 64); + + for (size_t i = 0; i < len; i += sz) { + uint64_t pos = ((rs2 >> i) & mask) << sz_log2; + if (pos < len) + r |= ((rs1 >> pos) & mask) << i; + } + + return r; +} + #endif diff --git a/riscv/encoding.h b/riscv/encoding.h index 448d6af..af2b786 100644 --- a/riscv/encoding.h +++ b/riscv/encoding.h @@ -1,6 +1,6 @@ /* * This file is auto-generated by running 'make ../riscv-isa-sim/riscv/encoding.h' in - * https://github.com/riscv/riscv-opcodes (2aa7492) + * https://github.com/riscv/riscv-opcodes (c4d2cc0) */ /* See LICENSE for license details. */ @@ -838,6 +838,12 @@ #define MASK_SHFLI 0xfe00707f #define MATCH_UNSHFLI 0x8005013 #define MASK_UNSHFLI 0xfe00707f +#define MATCH_XPERM_N 0x28002033 +#define MASK_XPERM_N 0xfe00707f +#define MATCH_XPERM_B 0x28004033 +#define MASK_XPERM_B 0xfe00707f +#define MATCH_XPERM_H 0x28006033 +#define MASK_XPERM_H 0xfe00707f #define MATCH_BMATFLIP 0x60301013 #define MASK_BMATFLIP 0xfff0707f #define MATCH_CRC32_D 0x61301013 @@ -920,6 +926,8 @@ #define MASK_PACKUW 0xfe00707f #define MATCH_BFPW 0x4800703b #define MASK_BFPW 0xfe00707f +#define MATCH_XPERM_W 0x28000033 +#define MASK_XPERM_W 0xfe00707f #define MATCH_ECALL 0x73 #define MASK_ECALL 0xffffffff #define MATCH_EBREAK 0x100073 @@ -2630,6 +2638,9 @@ 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) +DECLARE_INSN(xperm_n, MATCH_XPERM_N, MASK_XPERM_N) +DECLARE_INSN(xperm_b, MATCH_XPERM_B, MASK_XPERM_B) +DECLARE_INSN(xperm_h, MATCH_XPERM_H, MASK_XPERM_H) DECLARE_INSN(bmatflip, MATCH_BMATFLIP, MASK_BMATFLIP) DECLARE_INSN(crc32_d, MATCH_CRC32_D, MASK_CRC32_D) DECLARE_INSN(crc32c_d, MATCH_CRC32C_D, MASK_CRC32C_D) @@ -2671,6 +2682,7 @@ DECLARE_INSN(bdecompressw, MATCH_BDECOMPRESSW, MASK_BDECOMPRESSW) DECLARE_INSN(packw, MATCH_PACKW, MASK_PACKW) DECLARE_INSN(packuw, MATCH_PACKUW, MASK_PACKUW) DECLARE_INSN(bfpw, MATCH_BFPW, MASK_BFPW) +DECLARE_INSN(xperm_w, MATCH_XPERM_W, MASK_XPERM_W) DECLARE_INSN(ecall, MATCH_ECALL, MASK_ECALL) DECLARE_INSN(ebreak, MATCH_EBREAK, MASK_EBREAK) DECLARE_INSN(uret, MATCH_URET, MASK_URET) diff --git a/riscv/insns/xperm_b.h b/riscv/insns/xperm_b.h new file mode 100644 index 0000000..49f6476 --- /dev/null +++ b/riscv/insns/xperm_b.h @@ -0,0 +1,2 @@ +require_extension('B'); +WRITE_RD(xperm(RS1, RS2, 3, xlen)); diff --git a/riscv/insns/xperm_h.h b/riscv/insns/xperm_h.h new file mode 100644 index 0000000..d01a7cd --- /dev/null +++ b/riscv/insns/xperm_h.h @@ -0,0 +1,2 @@ +require_extension('B'); +WRITE_RD(xperm(RS1, RS2, 4, xlen)); diff --git a/riscv/insns/xperm_n.h b/riscv/insns/xperm_n.h new file mode 100644 index 0000000..23924ec --- /dev/null +++ b/riscv/insns/xperm_n.h @@ -0,0 +1,2 @@ +require_extension('B'); +WRITE_RD(xperm(RS1, RS2, 2, xlen)); diff --git a/riscv/insns/xperm_w.h b/riscv/insns/xperm_w.h new file mode 100644 index 0000000..b02f4c6 --- /dev/null +++ b/riscv/insns/xperm_w.h @@ -0,0 +1,3 @@ +require_rv64; +require_extension('B'); +WRITE_RD(xperm(RS1, RS2, 5, xlen)); diff --git a/riscv/riscv.mk.in b/riscv/riscv.mk.in index bdf9f37..f02f9ba 100644 --- a/riscv/riscv.mk.in +++ b/riscv/riscv.mk.in @@ -426,6 +426,10 @@ riscv_insn_ext_b = \ unshfli \ unshflw \ xnor \ + xperm_n \ + xperm_b \ + xperm_h \ + xperm_w \ riscv_insn_ext_v_alu_int = \ vaadd_vv \ -- cgit v1.1