Signed-off-by: Richard Henderson <[email protected]>
---
include/tcg/tcg-op-common.h | 2 -
include/tcg/tcg-op-def.h.inc | 1 +
tcg/tcg-op.c | 129 ++++++++++++-----------------------
3 files changed, 44 insertions(+), 88 deletions(-)
diff --git a/include/tcg/tcg-op-common.h b/include/tcg/tcg-op-common.h
index ee26d4c9d54..c36ad34b0d2 100644
--- a/include/tcg/tcg-op-common.h
+++ b/include/tcg/tcg-op-common.h
@@ -133,7 +133,6 @@ void tcg_gen_plugin_mem_cb(TCGv_i64 addr, unsigned meminfo);
/* 32 bit ops */
void tcg_gen_mulsu2_i32(TCGv_i32 rl, TCGv_i32 rh, TCGv_i32 arg1, TCGv_i32
arg2);
-void tcg_gen_bswap16_i32(TCGv_i32 ret, TCGv_i32 arg, unsigned flags);
void tcg_gen_bswap32_i32(TCGv_i32 ret, TCGv_i32 arg);
void tcg_gen_hswap_i32(TCGv_i32 ret, TCGv_i32 arg);
void tcg_gen_revbit8_i32(TCGv_i32 ret, TCGv_i32 arg);
@@ -158,7 +157,6 @@ void tcg_gen_addN_i64(int n, TCGv_i64 *r, TCGv_i64 *a,
TCGv_i64 *b);
void tcg_gen_mulsu2_i64(TCGv_i64 rl, TCGv_i64 rh, TCGv_i64 arg1, TCGv_i64
arg2);
void tcg_gen_ext32s_i64(TCGv_i64 ret, TCGv_i64 arg);
void tcg_gen_ext32u_i64(TCGv_i64 ret, TCGv_i64 arg);
-void tcg_gen_bswap16_i64(TCGv_i64 ret, TCGv_i64 arg, unsigned flags);
void tcg_gen_bswap32_i64(TCGv_i64 ret, TCGv_i64 arg, unsigned flags);
void tcg_gen_bswap64_i64(TCGv_i64 ret, TCGv_i64 arg);
void tcg_gen_hswap_i64(TCGv_i64 ret, TCGv_i64 arg);
diff --git a/include/tcg/tcg-op-def.h.inc b/include/tcg/tcg-op-def.h.inc
index 5e169258ea3..28cfa68db3e 100644
--- a/include/tcg/tcg-op-def.h.inc
+++ b/include/tcg/tcg-op-def.h.inc
@@ -10,6 +10,7 @@ DEF3(andi, TCGV, TCGV, TINT)
DEF3(andc, TCGV, TCGV, TCGV)
DEF4(brcond, TCGCond, TCGV, TCGV, TCGLabelPtr)
DEF4(brcondi, TCGCond, TCGV, TINT, TCGLabelPtr)
+DEF3(bswap16, TCGV, TCGV, unsigned)
DEF2(clrsb, TCGV, TCGV)
DEF3(clz, TCGV, TCGV, TCGV)
DEF3(clzi, TCGV, TCGV, TINT)
diff --git a/tcg/tcg-op.c b/tcg/tcg-op.c
index b1b29de74ac..c1b696c8193 100644
--- a/tcg/tcg-op.c
+++ b/tcg/tcg-op.c
@@ -109,6 +109,12 @@ static void gen_op_tt(TCGOpcode opc, TCGType type, TCGTemp
*t0, TCGTemp *t1)
tcg_gen_op2(opc, type, temp_arg(t0), temp_arg(t1));
}
+static TCGOp *gen_op_tti(TCGOpcode opc, TCGType type,
+ TCGTemp *t0, TCGTemp *t1, TCGArg a2)
+{
+ return tcg_gen_op3(opc, type, temp_arg(t0), temp_arg(t1), a2);
+}
+
static TCGOp *gen_op_ttt(TCGOpcode opc, TCGType type,
TCGTemp *t0, TCGTemp *t1, TCGTemp *t2)
{
@@ -525,6 +531,43 @@ static void gen_brcondi(TCGType type, TCGCond cond,
TCGTemp *src1,
gen_brcond(type, cond, src1, tcg_constant_internal(type, src2), l);
}
+static void gen_bswap16(TCGType type, TCGTemp *dst,
+ TCGTemp *src, unsigned flags)
+{
+ /* Only one extension flag may be present. */
+ tcg_debug_assert(!(flags & TCG_BSWAP_OS) || !(flags & TCG_BSWAP_OZ));
+
+ if (tcg_op_supported(INDEX_op_bswap16, type, 0)) {
+ gen_op_tti(INDEX_op_bswap16, type, dst, src, flags);
+ } else {
+ TCGTemp *t0 = tcg_temp_new_internal(type, TEMP_EBB);
+ TCGTemp *t1 = tcg_temp_new_internal(type, TEMP_EBB);
+ int width = tcg_type_size(type) * 8;
+
+ if (flags & TCG_BSWAP_IZ) { /* t0 = ...a */
+ gen_shri(type, t0, src, 8);
+ } else {
+ gen_extract(type, t0, src, 8, 8);
+ }
+
+ if (flags & TCG_BSWAP_OS) {
+ gen_shli(type, t1, src, width - 8); /* t1 = b... */
+ gen_sari(type, t1, t1, width - 16); /* t1 = ssb. */
+ } else if (flags & TCG_BSWAP_OZ) {
+ gen_ext8u(type, t1, src); /* t1 = ...b */
+ gen_shli(type, t1, t1, 8); /* t1 = ..b. */
+ } else {
+ gen_shli(type, t1, src, 8); /* t1 = xab. */
+ }
+
+ gen_or(type, dst, t0, t1); /* ret = ..ba (OZ) */
+ /* = ssba (OS) */
+ /* = xaba (no flag) */
+ tcg_temp_free_internal(t0);
+ tcg_temp_free_internal(t1);
+ }
+}
+
static void gen_clrsb(TCGType type, TCGTemp *dst, TCGTemp *src)
{
if (tcg_op_supported(INDEX_op_clz, TCG_TYPE_REG, 0)) {
@@ -1446,49 +1489,6 @@ static void gen_bitswap_i64(TCGv_i64 ret, TCGv_i64 arg,
uint64_t mask)
tcg_temp_free_i64(t1);
}
-/*
- * bswap16_i32: 16-bit byte swap on the low bits of a 32-bit value.
- *
- * Byte pattern: xxab -> yyba
- *
- * With TCG_BSWAP_IZ, x == zero, else undefined.
- * With TCG_BSWAP_OZ, y == zero, with TCG_BSWAP_OS y == sign, else undefined.
- */
-void tcg_gen_bswap16_i32(TCGv_i32 ret, TCGv_i32 arg, unsigned flags)
-{
- /* Only one extension flag may be present. */
- tcg_debug_assert(!(flags & TCG_BSWAP_OS) || !(flags & TCG_BSWAP_OZ));
-
- if (tcg_op_supported(INDEX_op_bswap16, TCG_TYPE_I32, 0)) {
- tcg_gen_op3i_i32(INDEX_op_bswap16, ret, arg, flags);
- } else {
- TCGv_i32 t0 = tcg_temp_ebb_new_i32();
- TCGv_i32 t1 = tcg_temp_ebb_new_i32();
-
- /* arg = ..ab (IZ) xxab (!IZ) */
- tcg_gen_shri_i32(t0, arg, 8); /* t0 = ...a (IZ) .xxa (!IZ) */
- if (!(flags & TCG_BSWAP_IZ)) {
- tcg_gen_ext8u_i32(t0, t0); /* t0 = ...a */
- }
-
- if (flags & TCG_BSWAP_OS) {
- tcg_gen_shli_i32(t1, arg, 24); /* t1 = b... */
- tcg_gen_sari_i32(t1, t1, 16); /* t1 = ssb. */
- } else if (flags & TCG_BSWAP_OZ) {
- tcg_gen_ext8u_i32(t1, arg); /* t1 = ...b */
- tcg_gen_shli_i32(t1, t1, 8); /* t1 = ..b. */
- } else {
- tcg_gen_shli_i32(t1, arg, 8); /* t1 = xab. */
- }
-
- tcg_gen_or_i32(ret, t0, t1); /* ret = ..ba (OZ) */
- /* = ssba (OS) */
- /* = xaba (no flag) */
- tcg_temp_free_i32(t0);
- tcg_temp_free_i32(t1);
- }
-}
-
/*
* bswap32_i32: 32-bit byte swap on a 32-bit value.
*
@@ -1647,49 +1647,6 @@ void tcg_gen_ext32u_i64(TCGv_i64 ret, TCGv_i64 arg)
tcg_gen_extract_i64(ret, arg, 0, 32);
}
-/*
- * bswap16_i64: 16-bit byte swap on the low bits of a 64-bit value.
- *
- * Byte pattern: xxxxxxxxab -> yyyyyyyyba
- *
- * With TCG_BSWAP_IZ, x == zero, else undefined.
- * With TCG_BSWAP_OZ, y == zero, with TCG_BSWAP_OS y == sign, else undefined.
- */
-void tcg_gen_bswap16_i64(TCGv_i64 ret, TCGv_i64 arg, unsigned flags)
-{
- /* Only one extension flag may be present. */
- tcg_debug_assert(!(flags & TCG_BSWAP_OS) || !(flags & TCG_BSWAP_OZ));
-
- if (tcg_op_supported(INDEX_op_bswap16, TCG_TYPE_I64, 0)) {
- tcg_gen_op3i_i64(INDEX_op_bswap16, ret, arg, flags);
- } else {
- TCGv_i64 t0 = tcg_temp_ebb_new_i64();
- TCGv_i64 t1 = tcg_temp_ebb_new_i64();
-
- /* arg = ......ab or xxxxxxab */
- tcg_gen_shri_i64(t0, arg, 8); /* t0 = .......a or .xxxxxxa */
- if (!(flags & TCG_BSWAP_IZ)) {
- tcg_gen_ext8u_i64(t0, t0); /* t0 = .......a */
- }
-
- if (flags & TCG_BSWAP_OS) {
- tcg_gen_shli_i64(t1, arg, 56); /* t1 = b....... */
- tcg_gen_sari_i64(t1, t1, 48); /* t1 = ssssssb. */
- } else if (flags & TCG_BSWAP_OZ) {
- tcg_gen_ext8u_i64(t1, arg); /* t1 = .......b */
- tcg_gen_shli_i64(t1, t1, 8); /* t1 = ......b. */
- } else {
- tcg_gen_shli_i64(t1, arg, 8); /* t1 = xxxxxab. */
- }
-
- tcg_gen_or_i64(ret, t0, t1); /* ret = ......ba (OZ) */
- /* ssssssba (OS) */
- /* xxxxxaba (no flag) */
- tcg_temp_free_i64(t0);
- tcg_temp_free_i64(t1);
- }
-}
-
/*
* bswap32_i64: 32-bit byte swap on the low bits of a 64-bit value.
*
--
2.53.0