aboutsummaryrefslogtreecommitdiff
path: root/target/arm/tcg/gengvec.c
diff options
context:
space:
mode:
authorRichard Henderson <richard.henderson@linaro.org>2024-12-11 10:30:09 -0600
committerPeter Maydell <peter.maydell@linaro.org>2024-12-13 13:39:23 +0000
commit38f9950c8e0315d7b26803018a3f73d5f42e6703 (patch)
tree2fe4b55cc123ed3c25f9a119afc50d7b69e05e81 /target/arm/tcg/gengvec.c
parent72040d9200f64960aefd9c88a539ecd8d9b3adcf (diff)
downloadqemu-38f9950c8e0315d7b26803018a3f73d5f42e6703.zip
qemu-38f9950c8e0315d7b26803018a3f73d5f42e6703.tar.gz
qemu-38f9950c8e0315d7b26803018a3f73d5f42e6703.tar.bz2
target/arm: Introduce gen_gvec_rev{16,32,64}
Reviewed-by: Peter Maydell <peter.maydell@linaro.org> Signed-off-by: Richard Henderson <richard.henderson@linaro.org> Message-id: 20241211163036.2297116-43-richard.henderson@linaro.org Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Diffstat (limited to 'target/arm/tcg/gengvec.c')
-rw-r--r--target/arm/tcg/gengvec.c58
1 files changed, 58 insertions, 0 deletions
diff --git a/target/arm/tcg/gengvec.c b/target/arm/tcg/gengvec.c
index 85a0b50..33c0a94 100644
--- a/target/arm/tcg/gengvec.c
+++ b/target/arm/tcg/gengvec.c
@@ -2409,3 +2409,61 @@ void gen_gvec_rbit(unsigned vece, uint32_t rd_ofs, uint32_t rn_ofs,
tcg_gen_gvec_2_ool(rd_ofs, rn_ofs, opr_sz, max_sz, 0,
gen_helper_gvec_rbit_b);
}
+
+void gen_gvec_rev16(unsigned vece, uint32_t rd_ofs, uint32_t rn_ofs,
+ uint32_t opr_sz, uint32_t max_sz)
+{
+ assert(vece == MO_8);
+ tcg_gen_gvec_rotli(MO_16, rd_ofs, rn_ofs, 8, opr_sz, max_sz);
+}
+
+static void gen_bswap32_i64(TCGv_i64 d, TCGv_i64 n)
+{
+ tcg_gen_bswap64_i64(d, n);
+ tcg_gen_rotli_i64(d, d, 32);
+}
+
+void gen_gvec_rev32(unsigned vece, uint32_t rd_ofs, uint32_t rn_ofs,
+ uint32_t opr_sz, uint32_t max_sz)
+{
+ static const GVecGen2 g = {
+ .fni8 = gen_bswap32_i64,
+ .fni4 = tcg_gen_bswap32_i32,
+ .prefer_i64 = TCG_TARGET_REG_BITS == 64,
+ .vece = MO_32
+ };
+
+ switch (vece) {
+ case MO_16:
+ tcg_gen_gvec_rotli(MO_32, rd_ofs, rn_ofs, 16, opr_sz, max_sz);
+ break;
+ case MO_8:
+ tcg_gen_gvec_2(rd_ofs, rn_ofs, opr_sz, max_sz, &g);
+ break;
+ default:
+ g_assert_not_reached();
+ }
+}
+
+void gen_gvec_rev64(unsigned vece, uint32_t rd_ofs, uint32_t rn_ofs,
+ uint32_t opr_sz, uint32_t max_sz)
+{
+ static const GVecGen2 g[] = {
+ { .fni8 = tcg_gen_bswap64_i64,
+ .vece = MO_64 },
+ { .fni8 = tcg_gen_hswap_i64,
+ .vece = MO_64 },
+ };
+
+ switch (vece) {
+ case MO_32:
+ tcg_gen_gvec_rotli(MO_64, rd_ofs, rn_ofs, 32, opr_sz, max_sz);
+ break;
+ case MO_8:
+ case MO_16:
+ tcg_gen_gvec_2(rd_ofs, rn_ofs, opr_sz, max_sz, &g[vece]);
+ break;
+ default:
+ g_assert_not_reached();
+ }
+}