aboutsummaryrefslogtreecommitdiff
path: root/tcg/tcg-op.c
diff options
context:
space:
mode:
authorPhilippe Mathieu-Daudé <philmd@linaro.org>2023-08-23 16:55:40 +0200
committerRichard Henderson <richard.henderson@linaro.org>2023-08-24 11:22:42 -0700
commitb8976aa5fe65e335af2eb5243a67d3b7fcd5442e (patch)
tree76b5bbf901039bcb0d75a58284742ebed4eb0455 /tcg/tcg-op.c
parent95180e750b16ab21556b1073c3051a848911093a (diff)
tcg/tcg-op: Document hswap_i32/64() byte pattern
Document hswap_i32() and hswap_i64(), added in commit 46be8425ff ("tcg: Implement tcg_gen_{h,w}swap_{i32,i64}"). Reviewed-by: Richard Henderson <richard.henderson@linaro.org> Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org> Message-Id: <20230823145542.79633-7-philmd@linaro.org> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
Diffstat (limited to 'tcg/tcg-op.c')
-rw-r--r--tcg/tcg-op.c25
1 files changed, 18 insertions, 7 deletions
diff --git a/tcg/tcg-op.c b/tcg/tcg-op.c
index 22c682c28e..58572526b7 100644
--- a/tcg/tcg-op.c
+++ b/tcg/tcg-op.c
@@ -1108,6 +1108,11 @@ void tcg_gen_bswap32_i32(TCGv_i32 ret, TCGv_i32 arg)
}
}
+/*
+ * hswap_i32: Swap 16-bit halfwords within a 32-bit value.
+ *
+ * Byte pattern: abcd -> cdab
+ */
void tcg_gen_hswap_i32(TCGv_i32 ret, TCGv_i32 arg)
{
/* Swapping 2 16-bit elements is a rotate. */
@@ -1921,19 +1926,25 @@ void tcg_gen_bswap64_i64(TCGv_i64 ret, TCGv_i64 arg)
}
}
+/*
+ * hswap_i64: Swap 16-bit halfwords within a 64-bit value.
+ * See also include/qemu/bitops.h, hswap64.
+ *
+ * Byte pattern: abcdefgh -> ghefcdab
+ */
void tcg_gen_hswap_i64(TCGv_i64 ret, TCGv_i64 arg)
{
uint64_t m = 0x0000ffff0000ffffull;
TCGv_i64 t0 = tcg_temp_ebb_new_i64();
TCGv_i64 t1 = tcg_temp_ebb_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);
+ /* arg = abcdefgh */
+ tcg_gen_rotli_i64(t1, arg, 32); /* t1 = efghabcd */
+ tcg_gen_andi_i64(t0, t1, m); /* t0 = ..gh..cd */
+ tcg_gen_shli_i64(t0, t0, 16); /* t0 = gh..cd.. */
+ tcg_gen_shri_i64(t1, t1, 16); /* t1 = ..efghab */
+ tcg_gen_andi_i64(t1, t1, m); /* t1 = ..ef..ab */
+ tcg_gen_or_i64(ret, t0, t1); /* ret = ghefcdab */
tcg_temp_free_i64(t0);
tcg_temp_free_i64(t1);