diff options
author | Richard Henderson <richard.henderson@linaro.org> | 2022-04-28 11:46:59 +0200 |
---|---|---|
committer | Thomas Huth <thuth@redhat.com> | 2022-05-04 08:47:19 +0200 |
commit | 46be8425fff0cc7f86ee7e1102aa3451fdae9ec8 (patch) | |
tree | edf172ae8cc3723508ad92be6e3a22cf515aafa2 /tcg | |
parent | d98ed7d96e2951b5e5c92b0f1de9aa2e58889019 (diff) |
tcg: Implement tcg_gen_{h,w}swap_{i32,i64}
Swap half-words (16-bit) and words (32-bit) within a larger value.
Mirrors functions of the same names within include/qemu/bitops.h.
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
Signed-off-by: David Hildenbrand <david@redhat.com>
Reviewed-by: David Miller <dmiller423@gmail.com>
Reviewed-by: David Hildenbrand <david@redhat.com>
Message-Id: <20220428094708.84835-5-david@redhat.com>
Signed-off-by: Thomas Huth <thuth@redhat.com>
Diffstat (limited to 'tcg')
-rw-r--r-- | tcg/tcg-op.c | 30 |
1 files changed, 30 insertions, 0 deletions
diff --git a/tcg/tcg-op.c b/tcg/tcg-op.c index 5d48537927..019fab00cc 100644 --- a/tcg/tcg-op.c +++ b/tcg/tcg-op.c @@ -1056,6 +1056,12 @@ void tcg_gen_bswap32_i32(TCGv_i32 ret, TCGv_i32 arg) } } +void tcg_gen_hswap_i32(TCGv_i32 ret, TCGv_i32 arg) +{ + /* Swapping 2 16-bit elements is a rotate. */ + tcg_gen_rotli_i32(ret, arg, 16); +} + void tcg_gen_smin_i32(TCGv_i32 ret, TCGv_i32 a, TCGv_i32 b) { tcg_gen_movcond_i32(TCG_COND_LT, ret, a, b, a, b); @@ -1792,6 +1798,30 @@ void tcg_gen_bswap64_i64(TCGv_i64 ret, TCGv_i64 arg) } } +void tcg_gen_hswap_i64(TCGv_i64 ret, TCGv_i64 arg) +{ + uint64_t m = 0x0000ffff0000ffffull; + TCGv_i64 t0 = tcg_temp_new_i64(); + TCGv_i64 t1 = tcg_temp_new_i64(); + + /* See include/qemu/bitops.h, hswap64. */ + tcg_gen_rotli_i64(t1, arg, 32); + tcg_gen_andi_i64(t0, t1, m); + tcg_gen_shli_i64(t0, t0, 16); + tcg_gen_shri_i64(t1, t1, 16); + tcg_gen_andi_i64(t1, t1, m); + tcg_gen_or_i64(ret, t0, t1); + + tcg_temp_free_i64(t0); + tcg_temp_free_i64(t1); +} + +void tcg_gen_wswap_i64(TCGv_i64 ret, TCGv_i64 arg) +{ + /* Swapping 2 32-bit elements is a rotate. */ + tcg_gen_rotli_i64(ret, arg, 32); +} + void tcg_gen_not_i64(TCGv_i64 ret, TCGv_i64 arg) { if (TCG_TARGET_REG_BITS == 32) { |