[PATCH v2 09/18] target/riscv: Add packed SIMD pack, merge and count-leading instructions
Molly Chen <[email protected]>
| Newsgroups | org.nongnu.qemu-riscv,org.nongnu.qemu-devel |
|---|---|
| Message-ID | <c7576a6619a66f64eff13e6861e214b54e85d448.1784280142.git.xiaoou@iscas.ac.cn> |
Signed-off-by: Molly Chen <[email protected]> --- target/riscv/helper.h | 41 ++++++ target/riscv/insn32.decode | 41 ++++++ target/riscv/tcg/insn_trans/trans_rvp.c.inc | 41 ++++++ target/riscv/tcg/psimd_helper.c | 148 ++++++++++++++++++++ 4 files changed, 271 insertions(+) diff --git a/target/riscv/helper.h b/target/riscv/helper.h index 5fe650c5d71..f83af437d40 100644 --- a/target/riscv/helper.h +++ b/target/riscv/helper.h @@ -1520,3 +1520,44 @@ DEF_HELPER_3(predsum_hs, tl, env, tl, tl) DEF_HELPER_3(predsumu_hs, tl, env, tl, tl) DEF_HELPER_3(predsum_ws, i64, env, i64, i64) DEF_HELPER_3(predsumu_ws, i64, env, i64, i64) + +/* Packed SIMD - Pack, Unpack, and Merge Operations */ +DEF_HELPER_3(ppaire_b, tl, env, tl, tl) +DEF_HELPER_3(ppaireo_b, tl, env, tl, tl) +DEF_HELPER_3(ppairoe_b, tl, env, tl, tl) +DEF_HELPER_3(ppairo_b, tl, env, tl, tl) +DEF_HELPER_3(ppaire_h, i64, env, i64, i64) +DEF_HELPER_3(ppaireo_h, tl, env, tl, tl) +DEF_HELPER_3(ppairoe_h, tl, env, tl, tl) +DEF_HELPER_3(ppairo_h, tl, env, tl, tl) +DEF_HELPER_3(ppaireo_w, i64, env, i64, i64) +DEF_HELPER_3(ppairoe_w, i64, env, i64, i64) +DEF_HELPER_3(ppairo_w, i64, env, i64, i64) +DEF_HELPER_2(psext_h_b, tl, env, tl) +DEF_HELPER_2(psext_w_b, i64, env, i64) +DEF_HELPER_2(psext_w_h, i64, env, i64) +DEF_HELPER_2(rev, tl, env, tl) +DEF_HELPER_2(rev16, i64, env, i64) +DEF_HELPER_3(zip8p, i64, env, i64, i64) +DEF_HELPER_3(zip8hp, i64, env, i64, i64) +DEF_HELPER_3(unzip8p, i64, env, i64, i64) +DEF_HELPER_3(unzip8hp, i64, env, i64, i64) +DEF_HELPER_3(zip16p, i64, env, i64, i64) +DEF_HELPER_3(zip16hp, i64, env, i64, i64) +DEF_HELPER_3(unzip16p, i64, env, i64, i64) +DEF_HELPER_3(unzip16hp, i64, env, i64, i64) +DEF_HELPER_4(slx, tl, env, tl, tl, tl) +DEF_HELPER_4(srx, tl, env, tl, tl, tl) +DEF_HELPER_4(mvm, tl, env, tl, tl, tl) +DEF_HELPER_4(mvmn, tl, env, tl, tl, tl) +DEF_HELPER_4(merge, tl, env, tl, tl, tl) +DEF_HELPER_3(pnclipp_b, i64, env, i64, i64) +DEF_HELPER_3(pnclipup_b, i64, env, i64, i64) +DEF_HELPER_3(pnclipp_h, i64, env, i64, i64) +DEF_HELPER_3(pnclipup_h, i64, env, i64, i64) +DEF_HELPER_3(pnclipp_w, i64, env, i64, i64) +DEF_HELPER_3(pnclipup_w, i64, env, i64, i64) + +/* Packed SIMD - Count Leading Operations */ +DEF_HELPER_2(cls, tl, env, tl) +DEF_HELPER_2(clsw, i64, env, i64) diff --git a/target/riscv/insn32.decode b/target/riscv/insn32.decode index 9d0f5c48b6d..14dab4cb641 100644 --- a/target/riscv/insn32.decode +++ b/target/riscv/insn32.decode @@ -1296,3 +1296,44 @@ predsum_hs 1001100 ..... ..... 100 ..... 0011011 @r predsumu_hs 1011100 ..... ..... 100 ..... 0011011 @r predsum_ws 1001101 ..... ..... 100 ..... 0011011 @r predsumu_ws 1011101 ..... ..... 100 ..... 0011011 @r + +# Packed SIMD - Pack, Unpack, and Merge Operations +ppaire_b 1000000 ..... ..... 100 ..... 0111011 @r +ppaireo_b 1001000 ..... ..... 100 ..... 0111011 @r +ppairoe_b 1010000 ..... ..... 100 ..... 0111011 @r +ppairo_b 1011000 ..... ..... 100 ..... 0111011 @r +ppaireo_h 1001001 ..... ..... 100 ..... 0111011 @r +ppairoe_h 1010001 ..... ..... 100 ..... 0111011 @r +ppairo_h 1011001 ..... ..... 100 ..... 0111011 @r +ppaire_h 1000001 ..... ..... 100 ..... 0111011 @r +ppaireo_w 1001011 ..... ..... 100 ..... 0111011 @r +ppairoe_w 1010011 ..... ..... 100 ..... 0111011 @r +ppairo_w 1011011 ..... ..... 100 ..... 0111011 @r +psext_h_b 1110000 00100 ..... 010 ..... 0011011 @r2 +psext_w_b 1110001 00100 ..... 010 ..... 0011011 @r2 +psext_w_h 1110001 00101 ..... 010 ..... 0011011 @r2 +rev 01101 0111111 ..... 101 ..... 0010011 @r2 +rev16 01101 0110000 ..... 101 ..... 0010011 @r2 +zip8p 1111000 ..... ..... 010 ..... 0111011 @r +zip8hp 1111010 ..... ..... 010 ..... 0111011 @r +unzip8p 1110000 ..... ..... 010 ..... 0111011 @r +unzip8hp 1110010 ..... ..... 010 ..... 0111011 @r +zip16p 1111001 ..... ..... 010 ..... 0111011 @r +zip16hp 1111011 ..... ..... 010 ..... 0111011 @r +unzip16p 1110001 ..... ..... 010 ..... 0111011 @r +unzip16hp 1110011 ..... ..... 010 ..... 0111011 @r +slx 1000111 ..... ..... 001 ..... 0111011 @r +srx 1010111 ..... ..... 001 ..... 0111011 @r +mvm 1010100 ..... ..... 001 ..... 0111011 @r +mvmn 1010101 ..... ..... 001 ..... 0111011 @r +merge 1010110 ..... ..... 001 ..... 0111011 @r +pnclipp_b 1100000 ..... ..... 010 ..... 0111011 @r +pnclipup_b 1000000 ..... ..... 010 ..... 0111011 @r +pnclipp_h 1100001 ..... ..... 010 ..... 0111011 @r +pnclipup_h 1000001 ..... ..... 010 ..... 0111011 @r +pnclipp_w 1100011 ..... ..... 010 ..... 0111011 @r +pnclipup_w 1000011 ..... ..... 010 ..... 0111011 @r + +# Packed SIMD - Count Leading Operations +cls 01100 0000011 ..... 001 ..... 0010011 @r2 +clsw 01100 0000011 ..... 001 ..... 0011011 @r2 diff --git a/target/riscv/tcg/insn_trans/trans_rvp.c.inc b/target/riscv/tcg/insn_trans/trans_rvp.c.inc index 9f2ae9da1d1..486184eeaf3 100644 --- a/target/riscv/tcg/insn_trans/trans_rvp.c.inc +++ b/target/riscv/tcg/insn_trans/trans_rvp.c.inc @@ -666,3 +666,44 @@ GEN_SIMD_TRANS(predsumu_hs) GEN_SIMD_TRANS_64(predsum_ws) GEN_SIMD_TRANS_64(predsumu_ws) +/* Packed SIMD - Pack, Unpack, and Merge Operations */ +GEN_SIMD_TRANS(ppaire_b) +GEN_SIMD_TRANS(ppaireo_b) +GEN_SIMD_TRANS(ppairoe_b) +GEN_SIMD_TRANS(ppairo_b) +GEN_SIMD_TRANS_64(ppaire_h) +GEN_SIMD_TRANS(ppaireo_h) +GEN_SIMD_TRANS(ppairoe_h) +GEN_SIMD_TRANS(ppairo_h) +GEN_SIMD_TRANS_64(ppaireo_w) +GEN_SIMD_TRANS_64(ppairoe_w) +GEN_SIMD_TRANS_64(ppairo_w) +GEN_SIMD_TRANS_R1(psext_h_b) +GEN_SIMD_TRANS_R1_64(psext_w_b) +GEN_SIMD_TRANS_R1_64(psext_w_h) +GEN_SIMD_TRANS_R1(rev) +GEN_SIMD_TRANS_R1_64(rev16) +GEN_SIMD_TRANS_64(zip8p) +GEN_SIMD_TRANS_64(zip8hp) +GEN_SIMD_TRANS_64(unzip8p) +GEN_SIMD_TRANS_64(unzip8hp) +GEN_SIMD_TRANS_64(zip16p) +GEN_SIMD_TRANS_64(zip16hp) +GEN_SIMD_TRANS_64(unzip16p) +GEN_SIMD_TRANS_64(unzip16hp) +GEN_SIMD_TRANS_ACC(slx) +GEN_SIMD_TRANS_ACC(srx) +GEN_SIMD_TRANS_ACC(mvm) +GEN_SIMD_TRANS_ACC(mvmn) +GEN_SIMD_TRANS_ACC(merge) +GEN_SIMD_TRANS_64_VXSAT(pnclipp_b) +GEN_SIMD_TRANS_64_VXSAT(pnclipup_b) +GEN_SIMD_TRANS_64_VXSAT(pnclipp_h) +GEN_SIMD_TRANS_64_VXSAT(pnclipup_h) +GEN_SIMD_TRANS_64_VXSAT(pnclipp_w) +GEN_SIMD_TRANS_64_VXSAT(pnclipup_w) + +/* Packed SIMD - Count Leading Operations */ +GEN_SIMD_TRANS_R1(cls) +GEN_SIMD_TRANS_R1_64(clsw) + diff --git a/target/riscv/tcg/psimd_helper.c b/target/riscv/tcg/psimd_helper.c index 0acf0414bf9..99f11f084f2 100644 --- a/target/riscv/tcg/psimd_helper.c +++ b/target/riscv/tcg/psimd_helper.c @@ -2111,3 +2111,151 @@ GEN_PSIMD_REDSUM(predsum_ws, uint64_t, int64_t, int32_t, GEN_PSIMD_REDSUM(predsumu_ws, uint64_t, uint64_t, uint32_t, EXTRACT32, ELEMS_W, rs2) +/* Packing/unpacking operations */ + +GEN_PSIMD_PAIR_PACK(ppaire_b, target_ulong, uint16_t, + EXTRACT16, INSERT16, ELEMS_H, 0x00ff, 8, + PSIMD_PAIR_LO, PSIMD_PAIR_LO) +GEN_PSIMD_PAIR_PACK(ppaireo_b, target_ulong, uint16_t, + EXTRACT16, INSERT16, ELEMS_H, 0x00ff, 8, + PSIMD_PAIR_HI, PSIMD_PAIR_LO) +GEN_PSIMD_PAIR_PACK(ppairoe_b, target_ulong, uint16_t, + EXTRACT16, INSERT16, ELEMS_H, 0x00ff, 8, + PSIMD_PAIR_LO, PSIMD_PAIR_HI) +GEN_PSIMD_PAIR_PACK(ppairo_b, target_ulong, uint16_t, + EXTRACT16, INSERT16, ELEMS_H, 0x00ff, 8, + PSIMD_PAIR_HI, PSIMD_PAIR_HI) + +GEN_PSIMD_PAIR_PACK(ppaire_h, uint64_t, uint32_t, + EXTRACT32, INSERT32, ELEMS_W, 0x0000ffff, 16, + PSIMD_PAIR_LO, PSIMD_PAIR_LO) +GEN_PSIMD_PAIR_PACK(ppaireo_h, target_ulong, uint32_t, + EXTRACT32, INSERT32, ELEMS_W, 0x0000ffff, 16, + PSIMD_PAIR_HI, PSIMD_PAIR_LO) +GEN_PSIMD_PAIR_PACK(ppairoe_h, target_ulong, uint32_t, + EXTRACT32, INSERT32, ELEMS_W, 0x0000ffff, 16, + PSIMD_PAIR_LO, PSIMD_PAIR_HI) +GEN_PSIMD_PAIR_PACK(ppairo_h, target_ulong, uint32_t, + EXTRACT32, INSERT32, ELEMS_W, 0x0000ffff, 16, + PSIMD_PAIR_HI, PSIMD_PAIR_HI) + +GEN_PSIMD_PAIR_WORD(ppaireo_w, 0, 1) +GEN_PSIMD_PAIR_WORD(ppairoe_w, 1, 0) +GEN_PSIMD_PAIR_WORD(ppairo_w, 1, 1) + +GEN_PSIMD_SIGN_EXTEND(psext_h_b, target_ulong, int8_t, int16_t, + EXTRACT8, INSERT16, ELEMS_H, 2) +GEN_PSIMD_SIGN_EXTEND(psext_w_b, uint64_t, int8_t, int32_t, + EXTRACT8, INSERT32, ELEMS_W, 4) +GEN_PSIMD_SIGN_EXTEND(psext_w_h, uint64_t, int16_t, int32_t, + EXTRACT16, INSERT32, ELEMS_W, 2) + +/** + * REV - Reverse all bits + */ +target_ulong HELPER(rev)(CPURISCVState *env, target_ulong rs1) +{ + target_ulong rd = 0; + + for (int i = 0; i < TARGET_LONG_BITS; i++) { + rd = (rd << 1) | (rs1 & 1); + rs1 >>= 1; + } + + return rd; +} + +/** + * REV16 - Reverse 16-bit chunks (RV64 only) + */ +uint64_t HELPER(rev16)(CPURISCVState *env, uint64_t rs1) +{ + uint64_t rd = 0; + + for (int i = 0; i < 4; i++) { + uint16_t chunk = EXTRACT16(rs1, i); + rd = (rd << 16) | chunk; + } + + return rd; +} + +GEN_PSIMD_ZIP(zip8p, uint8_t, EXTRACT8, 4, 8, 3) +GEN_PSIMD_ZIP(zip8hp, uint8_t, EXTRACT8, 4, 8, 7) +GEN_PSIMD_UNZIP(unzip8p, EXTRACT8, 4, 8, 0) +GEN_PSIMD_UNZIP(unzip8hp, EXTRACT8, 4, 8, 1) + +GEN_PSIMD_ZIP(zip16p, uint16_t, EXTRACT16, 2, 16, 1) +GEN_PSIMD_ZIP(zip16hp, uint16_t, EXTRACT16, 2, 16, 3) +GEN_PSIMD_UNZIP(unzip16p, EXTRACT16, 2, 16, 0) +GEN_PSIMD_UNZIP(unzip16hp, EXTRACT16, 2, 16, 1) + +/* Merge and mask operations */ + +/** + * SLX - Shift left extended (concatenate rd and rs1, shift left, take upper) + */ +target_ulong HELPER(slx)(CPURISCVState *env, target_ulong rs1, + target_ulong rs2, target_ulong rd) +{ + int shamt = (TARGET_LONG_BITS == 32) ? (rs2 & 0x1F) : (rs2 & 0x3F); + target_ulong xrs1 = 0; + target_ulong xrd = 0; + + if (shamt <= TARGET_LONG_BITS) { + xrs1 = rs1 >> (TARGET_LONG_BITS - shamt); + xrd = (rd << shamt) + xrs1; + } else { + xrd = rs1 << (shamt - TARGET_LONG_BITS); + } + + return xrd; +} + +/** + * SRX - Shift right extended (concatenate rs1 and rd, shift right, take lower) + */ +target_ulong HELPER(srx)(CPURISCVState *env, target_ulong rs1, + target_ulong rs2, target_ulong rd) +{ + int shamt = (TARGET_LONG_BITS == 32) ? (rs2 & 0x1F) : (rs2 & 0x3F); + target_ulong xrs1 = 0; + target_ulong xrd = 0; + + if (shamt <= TARGET_LONG_BITS) { + xrs1 = rs1 << (TARGET_LONG_BITS - shamt); + xrd = (rd >> shamt) + xrs1; + } else { + xrd = rs1 >> (shamt - TARGET_LONG_BITS); + } + + return xrd; +} + +GEN_PSIMD_BIT_SELECT(mvm, rs2, rs1, rd) +GEN_PSIMD_BIT_SELECT(mvmn, rs2, rd, rs1) +GEN_PSIMD_BIT_SELECT(merge, rd, rs2, rs1) + +GEN_PSIMD_NCLIP_PACK(pnclipp_b, int16_t, int8_t, + EXTRACT16, INSERT8, 4, signed_saturate_b) +GEN_PSIMD_NCLIP_PACK(pnclipup_b, uint16_t, uint8_t, + EXTRACT16, INSERT8, 4, unsigned_saturate_b) +GEN_PSIMD_NCLIP_PACK(pnclipp_h, int32_t, int16_t, + EXTRACT32, INSERT16, 2, signed_saturate_h) +GEN_PSIMD_NCLIP_PACK(pnclipup_h, uint32_t, uint16_t, + EXTRACT32, INSERT16, 2, unsigned_saturate_h) +GEN_PSIMD_NCLIP_PACK(pnclipp_w, int64_t, int32_t, + EXTRACT64, INSERT32_64, 1, signed_saturate_w) +GEN_PSIMD_NCLIP_PACK(pnclipup_w, uint64_t, uint32_t, + EXTRACT64, INSERT32_64, 1, unsigned_saturate_w) + +/* Count leading operations */ + +#if TARGET_LONG_BITS == 64 +GEN_PSIMD_CLS(cls, target_ulong, uint64_t, clrsb64) +#else +GEN_PSIMD_CLS(cls, target_ulong, uint32_t, clrsb32) +#endif + +GEN_PSIMD_CLS(clsw, uint64_t, uint32_t, clrsb32) + -- 2.34.1