We'll need this for other generic expansions.
Signed-off-by: Richard Henderson <[email protected]>
---
tcg/tcg-op.c | 61 ++++++++++++++++++++++++----------------------------
1 file changed, 28 insertions(+), 33 deletions(-)
diff --git a/tcg/tcg-op.c b/tcg/tcg-op.c
index c1b696c8193..1882c0b5f3c 100644
--- a/tcg/tcg-op.c
+++ b/tcg/tcg-op.c
@@ -382,6 +382,7 @@ void tcg_gen_plugin_mem_cb(TCGv_i64 addr, unsigned meminfo)
#undef DEF5
#undef DEF6
+static void gen_bitswap(TCGType, TCGTemp *dst, TCGTemp *src, uint64_t mask);
static void gen_extrh_i64_i32(TCGTemp *dst, TCGTemp *src);
static void gen_extrl_i64_i32(TCGTemp *dst, TCGTemp *src);
static void gen_ext_i32_i64(TCGTemp *dst, TCGTemp *src);
@@ -513,6 +514,29 @@ static void gen_andc(TCGType type, TCGTemp *dst, TCGTemp
*src1, TCGTemp *src2)
}
}
+/*
+ * Internal helper for bit and byte reversal.
+ * Given a repeating matched block of 1's and 0's, swap the bits within
+ * those two blocks. E.g. mask=00ff00ff, shift the input bits left and
+ * right 8 bits.
+ */
+static void gen_bitswap(TCGType type, TCGTemp *dst, TCGTemp *src, uint64_t
mask)
+{
+ TCGTemp *t0 = tcg_temp_new_internal(type, TEMP_EBB);
+ TCGTemp *t1 = tcg_temp_new_internal(type, TEMP_EBB);
+ TCGTemp *tmask = tcg_constant_internal(type, mask);
+ TCGTemp *tshift = tcg_constant_internal(type, cto64(mask));
+
+ gen_and(type, t0, src, tmask);
+ gen_shr(type, t1, src, tshift);
+ gen_shl(type, t0, t0, tshift);
+ gen_and(type, t1, t1, tmask);
+ gen_or(type, dst, t0, t1);
+
+ tcg_temp_free_internal(t0);
+ tcg_temp_free_internal(t1);
+}
+
static void gen_brcond(TCGType type, TCGCond cond, TCGTemp *src1,
TCGTemp *src2, TCGLabel *l)
{
@@ -1450,43 +1474,14 @@ void tcg_gen_mulsu2_i32(TCGv_i32 rl, TCGv_i32 rh,
TCGv_i32 arg1, TCGv_i32 arg2)
tcg_temp_free_i64(t1);
}
-/*
- * Internal helper for bit and byte reversal.
- * Given a repeating matched block of 1's and 0's, swap the bits within
- * those two blocks. E.g. mask=00ff00ff, shift the input bits left and
- * right 8 bits.
- */
-static void gen_bitswap_i32(TCGv_i32 ret, TCGv_i32 arg, uint32_t mask)
+static void gen_bitswap_i32(TCGv_i32 dst, TCGv_i32 src, uint32_t mask)
{
- TCGv_i32 t0 = tcg_temp_ebb_new_i32();
- TCGv_i32 t1 = tcg_temp_ebb_new_i32();
- int sh = cto32(mask);
-
- tcg_gen_andi_i32(t0, arg, mask);
- tcg_gen_shri_i32(t1, arg, sh);
- tcg_gen_shli_i32(t0, t0, sh);
- tcg_gen_andi_i32(t1, t1, mask);
- tcg_gen_or_i32(ret, t0, t1);
-
- tcg_temp_free_i32(t0);
- tcg_temp_free_i32(t1);
+ gen_bitswap(TCG_TYPE_I32, tcgv_i32_temp(dst), tcgv_i32_temp(src), mask);
}
-/* Similarly for 64-bit operands. */
-static void gen_bitswap_i64(TCGv_i64 ret, TCGv_i64 arg, uint64_t mask)
+static void gen_bitswap_i64(TCGv_i64 dst, TCGv_i64 src, uint64_t mask)
{
- TCGv_i64 t0 = tcg_temp_ebb_new_i64();
- TCGv_i64 t1 = tcg_temp_ebb_new_i64();
- int sh = cto64(mask);
-
- tcg_gen_andi_i64(t0, arg, mask);
- tcg_gen_shri_i64(t1, arg, sh);
- tcg_gen_shli_i64(t0, t0, sh);
- tcg_gen_andi_i64(t1, t1, mask);
- tcg_gen_or_i64(ret, t0, t1);
-
- tcg_temp_free_i64(t0);
- tcg_temp_free_i64(t1);
+ gen_bitswap(TCG_TYPE_I64, tcgv_i64_temp(dst), tcgv_i64_temp(src), mask);
}
/*
--
2.53.0