@@ -13,13 +13,11 @@
#define have_lse2 (cpuinfo & CPUINFO_LSE2)
/* optional instructions */
-#define TCG_TARGET_HAS_extract2_i32 1
#define TCG_TARGET_HAS_add2_i32 1
#define TCG_TARGET_HAS_sub2_i32 1
#define TCG_TARGET_HAS_extr_i64_i32 0
#define TCG_TARGET_HAS_qemu_st8_i32 0
-#define TCG_TARGET_HAS_extract2_i64 1
#define TCG_TARGET_HAS_add2_i64 1
#define TCG_TARGET_HAS_sub2_i64 1
@@ -24,7 +24,6 @@ extern bool use_neon_instructions;
#endif
/* optional instructions */
-#define TCG_TARGET_HAS_extract2_i32 1
#define TCG_TARGET_HAS_qemu_st8_i32 0
#define TCG_TARGET_HAS_qemu_ldst_i128 0
@@ -26,14 +26,12 @@
#define have_avx512vbmi2 ((cpuinfo & CPUINFO_AVX512VBMI2) && have_avx512vl)
/* optional instructions */
-#define TCG_TARGET_HAS_extract2_i32 1
#define TCG_TARGET_HAS_add2_i32 1
#define TCG_TARGET_HAS_sub2_i32 1
#if TCG_TARGET_REG_BITS == 64
/* Keep 32-bit values zero-extended in a register. */
#define TCG_TARGET_HAS_extr_i64_i32 1
-#define TCG_TARGET_HAS_extract2_i64 1
#define TCG_TARGET_HAS_add2_i64 1
#define TCG_TARGET_HAS_sub2_i64 1
#define TCG_TARGET_HAS_qemu_st8_i32 0
@@ -10,13 +10,11 @@
#include "host/cpuinfo.h"
/* optional instructions */
-#define TCG_TARGET_HAS_extract2_i32 0
#define TCG_TARGET_HAS_add2_i32 0
#define TCG_TARGET_HAS_sub2_i32 0
#define TCG_TARGET_HAS_qemu_st8_i32 0
/* 64-bit operations */
-#define TCG_TARGET_HAS_extract2_i64 0
#define TCG_TARGET_HAS_extr_i64_i32 1
#define TCG_TARGET_HAS_add2_i64 0
#define TCG_TARGET_HAS_sub2_i64 0
@@ -51,13 +51,7 @@ extern bool use_mips32r2_instructions;
#endif
/* optional instructions detected at runtime */
-#define TCG_TARGET_HAS_extract2_i32 0
#define TCG_TARGET_HAS_qemu_st8_i32 0
-
-#if TCG_TARGET_REG_BITS == 64
-#define TCG_TARGET_HAS_extract2_i64 0
-#endif
-
#define TCG_TARGET_HAS_qemu_ldst_i128 0
#define TCG_TARGET_HAS_tst 0
@@ -17,14 +17,12 @@
#define have_vsx (cpuinfo & CPUINFO_VSX)
/* optional instructions */
-#define TCG_TARGET_HAS_extract2_i32 0
#define TCG_TARGET_HAS_qemu_st8_i32 0
#if TCG_TARGET_REG_BITS == 64
#define TCG_TARGET_HAS_add2_i32 0
#define TCG_TARGET_HAS_sub2_i32 0
#define TCG_TARGET_HAS_extr_i64_i32 0
-#define TCG_TARGET_HAS_extract2_i64 0
#define TCG_TARGET_HAS_add2_i64 1
#define TCG_TARGET_HAS_sub2_i64 1
#endif
@@ -10,12 +10,10 @@
#include "host/cpuinfo.h"
/* optional instructions */
-#define TCG_TARGET_HAS_extract2_i32 0
#define TCG_TARGET_HAS_add2_i32 1
#define TCG_TARGET_HAS_sub2_i32 1
#define TCG_TARGET_HAS_qemu_st8_i32 0
-#define TCG_TARGET_HAS_extract2_i64 0
#define TCG_TARGET_HAS_extr_i64_i32 1
#define TCG_TARGET_HAS_add2_i64 1
#define TCG_TARGET_HAS_sub2_i64 1
@@ -29,13 +29,11 @@ extern uint64_t s390_facilities[3];
((s390_facilities[FACILITY_##X / 64] >> (63 - FACILITY_##X % 64)) & 1)
/* optional instructions */
-#define TCG_TARGET_HAS_extract2_i32 0
#define TCG_TARGET_HAS_add2_i32 1
#define TCG_TARGET_HAS_sub2_i32 1
#define TCG_TARGET_HAS_extr_i64_i32 0
#define TCG_TARGET_HAS_qemu_st8_i32 0
-#define TCG_TARGET_HAS_extract2_i64 0
#define TCG_TARGET_HAS_add2_i64 1
#define TCG_TARGET_HAS_sub2_i64 1
@@ -14,13 +14,11 @@ extern bool use_vis3_instructions;
#endif
/* optional instructions */
-#define TCG_TARGET_HAS_extract2_i32 0
#define TCG_TARGET_HAS_add2_i32 1
#define TCG_TARGET_HAS_sub2_i32 1
#define TCG_TARGET_HAS_qemu_st8_i32 0
#define TCG_TARGET_HAS_extr_i64_i32 0
-#define TCG_TARGET_HAS_extract2_i64 0
#define TCG_TARGET_HAS_add2_i64 1
#define TCG_TARGET_HAS_sub2_i64 1
@@ -12,7 +12,6 @@
#if TCG_TARGET_REG_BITS == 32
/* Turn some undef macros into false macros. */
#define TCG_TARGET_HAS_extr_i64_i32 0
-#define TCG_TARGET_HAS_extract2_i64 0
#define TCG_TARGET_HAS_add2_i64 0
#define TCG_TARGET_HAS_sub2_i64 0
/* Turn some undef macros into true macros. */
@@ -7,12 +7,10 @@
#ifndef TCG_TARGET_HAS_H
#define TCG_TARGET_HAS_H
-#define TCG_TARGET_HAS_extract2_i32 0
#define TCG_TARGET_HAS_qemu_st8_i32 0
#if TCG_TARGET_REG_BITS == 64
#define TCG_TARGET_HAS_extr_i64_i32 0
-#define TCG_TARGET_HAS_extract2_i64 0
#define TCG_TARGET_HAS_add2_i32 1
#define TCG_TARGET_HAS_sub2_i32 1
#define TCG_TARGET_HAS_add2_i64 1
@@ -921,7 +921,7 @@ void tcg_gen_deposit_i32(TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 arg2,
t1 = tcg_temp_ebb_new_i32();
- if (TCG_TARGET_HAS_extract2_i32) {
+ if (tcg_op_supported(INDEX_op_extract2_i32, TCG_TYPE_I32, 0)) {
if (ofs + len == 32) {
tcg_gen_shli_i32(t1, arg1, len);
tcg_gen_extract2_i32(ret, t1, arg2, len);
@@ -1077,7 +1077,7 @@ void tcg_gen_extract2_i32(TCGv_i32 ret, TCGv_i32 al, TCGv_i32 ah,
tcg_gen_mov_i32(ret, ah);
} else if (al == ah) {
tcg_gen_rotri_i32(ret, al, ofs);
- } else if (TCG_TARGET_HAS_extract2_i32) {
+ } else if (tcg_op_supported(INDEX_op_extract2_i32, TCG_TYPE_I32, 0)) {
tcg_gen_op4i_i32(INDEX_op_extract2_i32, ret, al, ah, ofs);
} else {
TCGv_i32 t0 = tcg_temp_ebb_new_i32();
@@ -1799,7 +1799,7 @@ static inline void tcg_gen_shifti_i64(TCGv_i64 ret, TCGv_i64 arg1,
tcg_gen_movi_i32(TCGV_LOW(ret), 0);
}
} else if (right) {
- if (TCG_TARGET_HAS_extract2_i32) {
+ if (tcg_op_supported(INDEX_op_extract2_i32, TCG_TYPE_I32, 0)) {
tcg_gen_extract2_i32(TCGV_LOW(ret),
TCGV_LOW(arg1), TCGV_HIGH(arg1), c);
} else {
@@ -1813,7 +1813,7 @@ static inline void tcg_gen_shifti_i64(TCGv_i64 ret, TCGv_i64 arg1,
tcg_gen_shri_i32(TCGV_HIGH(ret), TCGV_HIGH(arg1), c);
}
} else {
- if (TCG_TARGET_HAS_extract2_i32) {
+ if (tcg_op_supported(INDEX_op_extract2_i32, TCG_TYPE_I32, 0)) {
tcg_gen_extract2_i32(TCGV_HIGH(ret),
TCGV_LOW(arg1), TCGV_HIGH(arg1), 32 - c);
} else {
@@ -2553,7 +2553,7 @@ void tcg_gen_deposit_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2,
t1 = tcg_temp_ebb_new_i64();
- if (TCG_TARGET_HAS_extract2_i64) {
+ if (tcg_op_supported(INDEX_op_extract2_i64, TCG_TYPE_I64, 0)) {
if (ofs + len == 64) {
tcg_gen_shli_i64(t1, arg1, len);
tcg_gen_extract2_i64(ret, t1, arg2, len);
@@ -2781,7 +2781,7 @@ void tcg_gen_extract2_i64(TCGv_i64 ret, TCGv_i64 al, TCGv_i64 ah,
tcg_gen_mov_i64(ret, ah);
} else if (al == ah) {
tcg_gen_rotri_i64(ret, al, ofs);
- } else if (TCG_TARGET_HAS_extract2_i64) {
+ } else if (tcg_op_supported(INDEX_op_extract2_i64, TCG_TYPE_I64, 0)) {
tcg_gen_op4i_i64(INDEX_op_extract2_i64, ret, al, ah, ofs);
} else {
TCGv_i64 t0 = tcg_temp_ebb_new_i64();
@@ -1029,6 +1029,12 @@ typedef struct TCGOutOpExtract {
unsigned ofs, unsigned len);
} TCGOutOpExtract;
+typedef struct TCGOutOpExtract2 {
+ TCGOutOp base;
+ void (*out_rrr)(TCGContext *s, TCGType type, TCGReg a0, TCGReg a1,
+ TCGReg a2, unsigned shr);
+} TCGOutOpExtract2;
+
typedef struct TCGOutOpMovcond {
TCGOutOp base;
void (*out)(TCGContext *s, TCGType type, TCGCond cond,
@@ -1140,6 +1146,8 @@ static const TCGOutOp * const all_outop[NB_OPS] = {
OUTOP(INDEX_op_divu2, TCGOutOpDivRem, outop_divu2),
OUTOP(INDEX_op_eqv, TCGOutOpBinary, outop_eqv),
OUTOP(INDEX_op_extract, TCGOutOpExtract, outop_extract),
+ OUTOP(INDEX_op_extract2_i32, TCGOutOpExtract2, outop_extract2),
+ OUTOP(INDEX_op_extract2_i64, TCGOutOpExtract2, outop_extract2),
OUTOP(INDEX_op_movcond, TCGOutOpMovcond, outop_movcond),
OUTOP(INDEX_op_mul, TCGOutOpBinary, outop_mul),
OUTOP(INDEX_op_muls2, TCGOutOpMul2, outop_muls2),
@@ -2399,8 +2407,6 @@ bool tcg_op_supported(TCGOpcode op, TCGType type, unsigned flags)
case INDEX_op_st_i32:
return true;
- case INDEX_op_extract2_i32:
- return TCG_TARGET_HAS_extract2_i32;
case INDEX_op_add2_i32:
return TCG_TARGET_HAS_add2_i32;
case INDEX_op_sub2_i32:
@@ -2427,8 +2433,6 @@ bool tcg_op_supported(TCGOpcode op, TCGType type, unsigned flags)
case INDEX_op_extrh_i64_i32:
return TCG_TARGET_REG_BITS == 64;
- case INDEX_op_extract2_i64:
- return TCG_TARGET_HAS_extract2_i64;
case INDEX_op_add2_i64:
return TCG_TARGET_HAS_add2_i64;
case INDEX_op_sub2_i64:
@@ -5581,6 +5585,18 @@ static void tcg_reg_alloc_op(TCGContext *s, const TCGOp *op)
}
break;
+ case INDEX_op_extract2_i32:
+ case INDEX_op_extract2_i64:
+ {
+ const TCGOutOpExtract2 *out = &outop_extract2;
+
+ tcg_debug_assert(!const_args[1]);
+ tcg_debug_assert(!const_args[2]);
+ out->out_rrr(s, type, new_args[0], new_args[1],
+ new_args[2], new_args[3]);
+ }
+ break;
+
case INDEX_op_muls2:
case INDEX_op_mulu2:
{
@@ -2634,6 +2634,17 @@ static const TCGOutOpExtract outop_sextract = {
.out_rr = tgen_sextract,
};
+static void tgen_extract2(TCGContext *s, TCGType type, TCGReg a0,
+ TCGReg a1, TCGReg a2, unsigned shr)
+{
+ tcg_out_extr(s, type, a0, a2, a1, shr);
+}
+
+static const TCGOutOpExtract2 outop_extract2 = {
+ .base.static_constraint = C_O1_I2(r, rz, rz),
+ .out_rrr = tgen_extract2,
+};
+
static void tcg_out_op(TCGContext *s, TCGOpcode opc, TCGType ext,
const TCGArg args[TCG_MAX_OP_ARGS],
const int const_args[TCG_MAX_OP_ARGS])
@@ -2714,11 +2725,6 @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc, TCGType ext,
tcg_out_qemu_ldst_i128(s, a0, a1, a2, args[3], false);
break;
- case INDEX_op_extract2_i64:
- case INDEX_op_extract2_i32:
- tcg_out_extr(s, ext, a0, a2, a1, args[3]);
- break;
-
case INDEX_op_add2_i32:
tcg_out_addsub2(s, TCG_TYPE_I32, a0, a1, a2, args[3],
(int32_t)args[4], args[5], const_args[4],
@@ -3231,10 +3237,6 @@ tcg_target_op_def(TCGOpcode op, TCGType type, unsigned flags)
case INDEX_op_qemu_st_i128:
return C_O0_I3(rz, rz, r);
- case INDEX_op_extract2_i32:
- case INDEX_op_extract2_i64:
- return C_O1_I2(r, rz, rz);
-
case INDEX_op_add2_i32:
case INDEX_op_add2_i64:
case INDEX_op_sub2_i32:
@@ -2323,6 +2323,20 @@ static const TCGOutOpSetcond2 outop_setcond2 = {
.out = tgen_setcond2,
};
+static void tgen_extract2(TCGContext *s, TCGType type, TCGReg a0,
+ TCGReg a1, TCGReg a2, unsigned shr)
+{
+ /* We can do extract2 in 2 insns, vs the 3 required otherwise. */
+ tgen_shli(s, TCG_TYPE_I32, TCG_REG_TMP, a2, 32 - shr);
+ tcg_out_dat_reg(s, COND_AL, ARITH_ORR, a0, TCG_REG_TMP,
+ a1, SHIFT_IMM_LSR(shr));
+}
+
+static const TCGOutOpExtract2 outop_extract2 = {
+ .base.static_constraint = C_O1_I2(r, r, r),
+ .out_rrr = tgen_extract2,
+};
+
static void tcg_out_op(TCGContext *s, TCGOpcode opc, TCGType type,
const TCGArg args[TCG_MAX_OP_ARGS],
const int const_args[TCG_MAX_OP_ARGS])
@@ -2417,28 +2431,6 @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc, TCGType type,
tcg_out_qemu_st(s, args[0], args[1], args[2], args[3], TCG_TYPE_I64);
break;
- case INDEX_op_extract2_i32:
- /* ??? These optimization vs zero should be generic. */
- /* ??? But we can't substitute 2 for 1 in the opcode stream yet. */
- if (const_args[1]) {
- if (const_args[2]) {
- tcg_out_movi(s, TCG_TYPE_REG, args[0], 0);
- } else {
- tcg_out_dat_reg(s, COND_AL, ARITH_MOV, args[0], 0,
- args[2], SHIFT_IMM_LSL(32 - args[3]));
- }
- } else if (const_args[2]) {
- tcg_out_dat_reg(s, COND_AL, ARITH_MOV, args[0], 0,
- args[1], SHIFT_IMM_LSR(args[3]));
- } else {
- /* We can do extract2 in 2 insns, vs the 3 required otherwise. */
- tcg_out_dat_reg(s, COND_AL, ARITH_MOV, TCG_REG_TMP, 0,
- args[2], SHIFT_IMM_LSL(32 - args[3]));
- tcg_out_dat_reg(s, COND_AL, ARITH_ORR, args[0], TCG_REG_TMP,
- args[1], SHIFT_IMM_LSR(args[3]));
- }
- break;
-
case INDEX_op_mb:
tcg_out_mb(s, args[0]);
break;
@@ -2470,8 +2462,6 @@ tcg_target_op_def(TCGOpcode op, TCGType type, unsigned flags)
case INDEX_op_st_i32:
return C_O0_I2(r, r);
- case INDEX_op_extract2_i32:
- return C_O1_I2(r, rZ, rZ);
case INDEX_op_add2_i32:
return C_O2_I4(r, r, r, r, rIN, rIK);
case INDEX_op_sub2_i32:
@@ -3261,6 +3261,21 @@ static const TCGOutOpExtract outop_sextract = {
.out_rr = tgen_sextract,
};
+static void tgen_extract2(TCGContext *s, TCGType type, TCGReg a0,
+ TCGReg a1, TCGReg a2, unsigned shr)
+{
+ int rexw = type == TCG_TYPE_I32 ? 0 : P_REXW;
+
+ /* Note that SHRD outputs to the r/m operand. */
+ tcg_out_modrm(s, OPC_SHRD_Ib + rexw, a2, a0);
+ tcg_out8(s, shr);
+}
+
+static const TCGOutOpExtract2 outop_extract2 = {
+ .base.static_constraint = C_O1_I2(r, 0, r),
+ .out_rrr = tgen_extract2,
+};
+
static void tcg_out_op(TCGContext *s, TCGOpcode opc, TCGType type,
const TCGArg args[TCG_MAX_OP_ARGS],
@@ -3414,12 +3429,6 @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc, TCGType type,
break;
#endif
- OP_32_64(extract2):
- /* Note that SHRD outputs to the r/m operand. */
- tcg_out_modrm(s, OPC_SHRD_Ib + rexw, a2, a0);
- tcg_out8(s, args[3]);
- break;
-
case INDEX_op_mb:
tcg_out_mb(s, a0);
break;
@@ -4008,10 +4017,6 @@ tcg_target_op_def(TCGOpcode op, TCGType type, unsigned flags)
case INDEX_op_st_i64:
return C_O0_I2(re, r);
- case INDEX_op_extract2_i32:
- case INDEX_op_extract2_i64:
- return C_O1_I2(r, 0, r);
-
case INDEX_op_add2_i32:
case INDEX_op_add2_i64:
case INDEX_op_sub2_i32:
@@ -1856,6 +1856,11 @@ static const TCGOutOpExtract outop_sextract = {
.out_rr = tgen_sextract,
};
+static const TCGOutOpExtract2 outop_extract2 = {
+ .base.static_constraint = C_NotImplemented,
+};
+
+
static void tcg_out_op(TCGContext *s, TCGOpcode opc, TCGType type,
const TCGArg args[TCG_MAX_OP_ARGS],
const int const_args[TCG_MAX_OP_ARGS])
@@ -2279,6 +2279,11 @@ static const TCGOutOpExtract outop_sextract = {
.out_rr = tgen_sextract,
};
+static const TCGOutOpExtract2 outop_extract2 = {
+ .base.static_constraint = C_NotImplemented,
+};
+
+
static void tcg_out_op(TCGContext *s, TCGOpcode opc, TCGType type,
const TCGArg args[TCG_MAX_OP_ARGS],
const int const_args[TCG_MAX_OP_ARGS])
@@ -3495,6 +3495,10 @@ static const TCGOutOpExtract outop_sextract = {
.out_rr = tgen_sextract,
};
+static const TCGOutOpExtract2 outop_extract2 = {
+ .base.static_constraint = C_NotImplemented,
+};
+
static void tcg_out_op(TCGContext *s, TCGOpcode opc, TCGType type,
const TCGArg args[TCG_MAX_OP_ARGS],
@@ -2542,6 +2542,11 @@ static const TCGOutOpExtract outop_sextract = {
.out_rr = tgen_sextract,
};
+static const TCGOutOpExtract2 outop_extract2 = {
+ .base.static_constraint = C_NotImplemented,
+};
+
+
static void tcg_out_op(TCGContext *s, TCGOpcode opc, TCGType type,
const TCGArg args[TCG_MAX_OP_ARGS],
const int const_args[TCG_MAX_OP_ARGS])
@@ -1637,6 +1637,10 @@ static const TCGOutOpExtract outop_sextract = {
.out_rr = tgen_sextract,
};
+static const TCGOutOpExtract2 outop_extract2 = {
+ .base.static_constraint = C_NotImplemented,
+};
+
static void tgen_gotoi(TCGContext *s, int cc, const tcg_insn_unit *dest)
{
ptrdiff_t off = tcg_pcrel_diff(s, dest) >> 1;
@@ -1795,6 +1795,10 @@ static const TCGOutOpExtract outop_sextract = {
.out_rr = tgen_sextract,
};
+static const TCGOutOpExtract2 outop_extract2 = {
+ .base.static_constraint = C_NotImplemented,
+};
+
static void tcg_out_op(TCGContext *s, TCGOpcode opc, TCGType type,
const TCGArg args[TCG_MAX_OP_ARGS],
const int const_args[TCG_MAX_OP_ARGS])
@@ -447,6 +447,10 @@ static const TCGOutOpExtract outop_sextract = {
.out_rr = tcg_out_sextract,
};
+static const TCGOutOpExtract2 outop_extract2 = {
+ .base.static_constraint = C_NotImplemented,
+};
+
static void tcg_out_ext8s(TCGContext *s, TCGType type, TCGReg rd, TCGReg rs)
{
tcg_out_sextract(s, type, rd, rs, 0, 8);
Signed-off-by: Richard Henderson <richard.henderson@linaro.org> --- tcg/aarch64/tcg-target-has.h | 2 -- tcg/arm/tcg-target-has.h | 1 - tcg/i386/tcg-target-has.h | 2 -- tcg/loongarch64/tcg-target-has.h | 2 -- tcg/mips/tcg-target-has.h | 6 ----- tcg/ppc/tcg-target-has.h | 2 -- tcg/riscv/tcg-target-has.h | 2 -- tcg/s390x/tcg-target-has.h | 2 -- tcg/sparc64/tcg-target-has.h | 2 -- tcg/tcg-has.h | 1 - tcg/tci/tcg-target-has.h | 2 -- tcg/tcg-op.c | 12 +++++----- tcg/tcg.c | 24 ++++++++++++++++---- tcg/aarch64/tcg-target.c.inc | 20 +++++++++-------- tcg/arm/tcg-target.c.inc | 38 ++++++++++++-------------------- tcg/i386/tcg-target.c.inc | 25 ++++++++++++--------- tcg/loongarch64/tcg-target.c.inc | 5 +++++ tcg/mips/tcg-target.c.inc | 5 +++++ tcg/ppc/tcg-target.c.inc | 4 ++++ tcg/riscv/tcg-target.c.inc | 5 +++++ tcg/s390x/tcg-target.c.inc | 4 ++++ tcg/sparc64/tcg-target.c.inc | 4 ++++ tcg/tci/tcg-target.c.inc | 4 ++++ 23 files changed, 97 insertions(+), 77 deletions(-)