mirror of
https://github.com/Motorhead1991/qemu.git
synced 2025-08-06 17:23:56 -06:00
tcg: Convert extract2 to TCGOutOpExtract2
Reviewed-by: Pierrick Bouvier <pierrick.bouvier@linaro.org> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
This commit is contained in:
parent
4d137ff819
commit
c8f9f70047
23 changed files with 97 additions and 77 deletions
|
@ -13,13 +13,11 @@
|
||||||
#define have_lse2 (cpuinfo & CPUINFO_LSE2)
|
#define have_lse2 (cpuinfo & CPUINFO_LSE2)
|
||||||
|
|
||||||
/* optional instructions */
|
/* optional instructions */
|
||||||
#define TCG_TARGET_HAS_extract2_i32 1
|
|
||||||
#define TCG_TARGET_HAS_add2_i32 1
|
#define TCG_TARGET_HAS_add2_i32 1
|
||||||
#define TCG_TARGET_HAS_sub2_i32 1
|
#define TCG_TARGET_HAS_sub2_i32 1
|
||||||
#define TCG_TARGET_HAS_extr_i64_i32 0
|
#define TCG_TARGET_HAS_extr_i64_i32 0
|
||||||
#define TCG_TARGET_HAS_qemu_st8_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_add2_i64 1
|
||||||
#define TCG_TARGET_HAS_sub2_i64 1
|
#define TCG_TARGET_HAS_sub2_i64 1
|
||||||
|
|
||||||
|
|
|
@ -2634,6 +2634,17 @@ static const TCGOutOpExtract outop_sextract = {
|
||||||
.out_rr = tgen_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,
|
static void tcg_out_op(TCGContext *s, TCGOpcode opc, TCGType ext,
|
||||||
const TCGArg args[TCG_MAX_OP_ARGS],
|
const TCGArg args[TCG_MAX_OP_ARGS],
|
||||||
const int const_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);
|
tcg_out_qemu_ldst_i128(s, a0, a1, a2, args[3], false);
|
||||||
break;
|
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:
|
case INDEX_op_add2_i32:
|
||||||
tcg_out_addsub2(s, TCG_TYPE_I32, a0, a1, a2, args[3],
|
tcg_out_addsub2(s, TCG_TYPE_I32, a0, a1, a2, args[3],
|
||||||
(int32_t)args[4], args[5], const_args[4],
|
(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:
|
case INDEX_op_qemu_st_i128:
|
||||||
return C_O0_I3(rz, rz, r);
|
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_i32:
|
||||||
case INDEX_op_add2_i64:
|
case INDEX_op_add2_i64:
|
||||||
case INDEX_op_sub2_i32:
|
case INDEX_op_sub2_i32:
|
||||||
|
|
|
@ -24,7 +24,6 @@ extern bool use_neon_instructions;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* optional instructions */
|
/* optional instructions */
|
||||||
#define TCG_TARGET_HAS_extract2_i32 1
|
|
||||||
#define TCG_TARGET_HAS_qemu_st8_i32 0
|
#define TCG_TARGET_HAS_qemu_st8_i32 0
|
||||||
|
|
||||||
#define TCG_TARGET_HAS_qemu_ldst_i128 0
|
#define TCG_TARGET_HAS_qemu_ldst_i128 0
|
||||||
|
|
|
@ -2317,6 +2317,20 @@ static const TCGOutOpSetcond2 outop_setcond2 = {
|
||||||
.out = tgen_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,
|
static void tcg_out_op(TCGContext *s, TCGOpcode opc, TCGType type,
|
||||||
const TCGArg args[TCG_MAX_OP_ARGS],
|
const TCGArg args[TCG_MAX_OP_ARGS],
|
||||||
const int const_args[TCG_MAX_OP_ARGS])
|
const int const_args[TCG_MAX_OP_ARGS])
|
||||||
|
@ -2411,28 +2425,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);
|
tcg_out_qemu_st(s, args[0], args[1], args[2], args[3], TCG_TYPE_I64);
|
||||||
break;
|
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:
|
case INDEX_op_mb:
|
||||||
tcg_out_mb(s, args[0]);
|
tcg_out_mb(s, args[0]);
|
||||||
break;
|
break;
|
||||||
|
@ -2464,8 +2456,6 @@ tcg_target_op_def(TCGOpcode op, TCGType type, unsigned flags)
|
||||||
case INDEX_op_st_i32:
|
case INDEX_op_st_i32:
|
||||||
return C_O0_I2(r, r);
|
return C_O0_I2(r, r);
|
||||||
|
|
||||||
case INDEX_op_extract2_i32:
|
|
||||||
return C_O1_I2(r, rZ, rZ);
|
|
||||||
case INDEX_op_add2_i32:
|
case INDEX_op_add2_i32:
|
||||||
return C_O2_I4(r, r, r, r, rIN, rIK);
|
return C_O2_I4(r, r, r, r, rIN, rIK);
|
||||||
case INDEX_op_sub2_i32:
|
case INDEX_op_sub2_i32:
|
||||||
|
|
|
@ -26,14 +26,12 @@
|
||||||
#define have_avx512vbmi2 ((cpuinfo & CPUINFO_AVX512VBMI2) && have_avx512vl)
|
#define have_avx512vbmi2 ((cpuinfo & CPUINFO_AVX512VBMI2) && have_avx512vl)
|
||||||
|
|
||||||
/* optional instructions */
|
/* optional instructions */
|
||||||
#define TCG_TARGET_HAS_extract2_i32 1
|
|
||||||
#define TCG_TARGET_HAS_add2_i32 1
|
#define TCG_TARGET_HAS_add2_i32 1
|
||||||
#define TCG_TARGET_HAS_sub2_i32 1
|
#define TCG_TARGET_HAS_sub2_i32 1
|
||||||
|
|
||||||
#if TCG_TARGET_REG_BITS == 64
|
#if TCG_TARGET_REG_BITS == 64
|
||||||
/* Keep 32-bit values zero-extended in a register. */
|
/* Keep 32-bit values zero-extended in a register. */
|
||||||
#define TCG_TARGET_HAS_extr_i64_i32 1
|
#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_add2_i64 1
|
||||||
#define TCG_TARGET_HAS_sub2_i64 1
|
#define TCG_TARGET_HAS_sub2_i64 1
|
||||||
#define TCG_TARGET_HAS_qemu_st8_i32 0
|
#define TCG_TARGET_HAS_qemu_st8_i32 0
|
||||||
|
|
|
@ -3261,6 +3261,21 @@ static const TCGOutOpExtract outop_sextract = {
|
||||||
.out_rr = tgen_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,
|
static void tcg_out_op(TCGContext *s, TCGOpcode opc, TCGType type,
|
||||||
const TCGArg args[TCG_MAX_OP_ARGS],
|
const TCGArg args[TCG_MAX_OP_ARGS],
|
||||||
|
@ -3414,12 +3429,6 @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc, TCGType type,
|
||||||
break;
|
break;
|
||||||
#endif
|
#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:
|
case INDEX_op_mb:
|
||||||
tcg_out_mb(s, a0);
|
tcg_out_mb(s, a0);
|
||||||
break;
|
break;
|
||||||
|
@ -4008,10 +4017,6 @@ tcg_target_op_def(TCGOpcode op, TCGType type, unsigned flags)
|
||||||
case INDEX_op_st_i64:
|
case INDEX_op_st_i64:
|
||||||
return C_O0_I2(re, r);
|
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_i32:
|
||||||
case INDEX_op_add2_i64:
|
case INDEX_op_add2_i64:
|
||||||
case INDEX_op_sub2_i32:
|
case INDEX_op_sub2_i32:
|
||||||
|
|
|
@ -10,13 +10,11 @@
|
||||||
#include "host/cpuinfo.h"
|
#include "host/cpuinfo.h"
|
||||||
|
|
||||||
/* optional instructions */
|
/* optional instructions */
|
||||||
#define TCG_TARGET_HAS_extract2_i32 0
|
|
||||||
#define TCG_TARGET_HAS_add2_i32 0
|
#define TCG_TARGET_HAS_add2_i32 0
|
||||||
#define TCG_TARGET_HAS_sub2_i32 0
|
#define TCG_TARGET_HAS_sub2_i32 0
|
||||||
#define TCG_TARGET_HAS_qemu_st8_i32 0
|
#define TCG_TARGET_HAS_qemu_st8_i32 0
|
||||||
|
|
||||||
/* 64-bit operations */
|
/* 64-bit operations */
|
||||||
#define TCG_TARGET_HAS_extract2_i64 0
|
|
||||||
#define TCG_TARGET_HAS_extr_i64_i32 1
|
#define TCG_TARGET_HAS_extr_i64_i32 1
|
||||||
#define TCG_TARGET_HAS_add2_i64 0
|
#define TCG_TARGET_HAS_add2_i64 0
|
||||||
#define TCG_TARGET_HAS_sub2_i64 0
|
#define TCG_TARGET_HAS_sub2_i64 0
|
||||||
|
|
|
@ -1868,6 +1868,11 @@ static const TCGOutOpExtract outop_sextract = {
|
||||||
.out_rr = tgen_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,
|
static void tcg_out_op(TCGContext *s, TCGOpcode opc, TCGType type,
|
||||||
const TCGArg args[TCG_MAX_OP_ARGS],
|
const TCGArg args[TCG_MAX_OP_ARGS],
|
||||||
const int const_args[TCG_MAX_OP_ARGS])
|
const int const_args[TCG_MAX_OP_ARGS])
|
||||||
|
|
|
@ -51,13 +51,7 @@ extern bool use_mips32r2_instructions;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* optional instructions detected at runtime */
|
/* optional instructions detected at runtime */
|
||||||
#define TCG_TARGET_HAS_extract2_i32 0
|
|
||||||
#define TCG_TARGET_HAS_qemu_st8_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_qemu_ldst_i128 0
|
||||||
#define TCG_TARGET_HAS_tst 0
|
#define TCG_TARGET_HAS_tst 0
|
||||||
|
|
||||||
|
|
|
@ -2273,6 +2273,11 @@ static const TCGOutOpExtract outop_sextract = {
|
||||||
.out_rr = tgen_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,
|
static void tcg_out_op(TCGContext *s, TCGOpcode opc, TCGType type,
|
||||||
const TCGArg args[TCG_MAX_OP_ARGS],
|
const TCGArg args[TCG_MAX_OP_ARGS],
|
||||||
const int const_args[TCG_MAX_OP_ARGS])
|
const int const_args[TCG_MAX_OP_ARGS])
|
||||||
|
|
|
@ -17,14 +17,12 @@
|
||||||
#define have_vsx (cpuinfo & CPUINFO_VSX)
|
#define have_vsx (cpuinfo & CPUINFO_VSX)
|
||||||
|
|
||||||
/* optional instructions */
|
/* optional instructions */
|
||||||
#define TCG_TARGET_HAS_extract2_i32 0
|
|
||||||
#define TCG_TARGET_HAS_qemu_st8_i32 0
|
#define TCG_TARGET_HAS_qemu_st8_i32 0
|
||||||
|
|
||||||
#if TCG_TARGET_REG_BITS == 64
|
#if TCG_TARGET_REG_BITS == 64
|
||||||
#define TCG_TARGET_HAS_add2_i32 0
|
#define TCG_TARGET_HAS_add2_i32 0
|
||||||
#define TCG_TARGET_HAS_sub2_i32 0
|
#define TCG_TARGET_HAS_sub2_i32 0
|
||||||
#define TCG_TARGET_HAS_extr_i64_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_add2_i64 1
|
||||||
#define TCG_TARGET_HAS_sub2_i64 1
|
#define TCG_TARGET_HAS_sub2_i64 1
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -3495,6 +3495,10 @@ static const TCGOutOpExtract outop_sextract = {
|
||||||
.out_rr = tgen_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,
|
static void tcg_out_op(TCGContext *s, TCGOpcode opc, TCGType type,
|
||||||
const TCGArg args[TCG_MAX_OP_ARGS],
|
const TCGArg args[TCG_MAX_OP_ARGS],
|
||||||
|
|
|
@ -10,12 +10,10 @@
|
||||||
#include "host/cpuinfo.h"
|
#include "host/cpuinfo.h"
|
||||||
|
|
||||||
/* optional instructions */
|
/* optional instructions */
|
||||||
#define TCG_TARGET_HAS_extract2_i32 0
|
|
||||||
#define TCG_TARGET_HAS_add2_i32 1
|
#define TCG_TARGET_HAS_add2_i32 1
|
||||||
#define TCG_TARGET_HAS_sub2_i32 1
|
#define TCG_TARGET_HAS_sub2_i32 1
|
||||||
#define TCG_TARGET_HAS_qemu_st8_i32 0
|
#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_extr_i64_i32 1
|
||||||
#define TCG_TARGET_HAS_add2_i64 1
|
#define TCG_TARGET_HAS_add2_i64 1
|
||||||
#define TCG_TARGET_HAS_sub2_i64 1
|
#define TCG_TARGET_HAS_sub2_i64 1
|
||||||
|
|
|
@ -2542,6 +2542,11 @@ static const TCGOutOpExtract outop_sextract = {
|
||||||
.out_rr = tgen_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,
|
static void tcg_out_op(TCGContext *s, TCGOpcode opc, TCGType type,
|
||||||
const TCGArg args[TCG_MAX_OP_ARGS],
|
const TCGArg args[TCG_MAX_OP_ARGS],
|
||||||
const int const_args[TCG_MAX_OP_ARGS])
|
const int const_args[TCG_MAX_OP_ARGS])
|
||||||
|
|
|
@ -29,13 +29,11 @@ extern uint64_t s390_facilities[3];
|
||||||
((s390_facilities[FACILITY_##X / 64] >> (63 - FACILITY_##X % 64)) & 1)
|
((s390_facilities[FACILITY_##X / 64] >> (63 - FACILITY_##X % 64)) & 1)
|
||||||
|
|
||||||
/* optional instructions */
|
/* optional instructions */
|
||||||
#define TCG_TARGET_HAS_extract2_i32 0
|
|
||||||
#define TCG_TARGET_HAS_add2_i32 1
|
#define TCG_TARGET_HAS_add2_i32 1
|
||||||
#define TCG_TARGET_HAS_sub2_i32 1
|
#define TCG_TARGET_HAS_sub2_i32 1
|
||||||
#define TCG_TARGET_HAS_extr_i64_i32 0
|
#define TCG_TARGET_HAS_extr_i64_i32 0
|
||||||
#define TCG_TARGET_HAS_qemu_st8_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_add2_i64 1
|
||||||
#define TCG_TARGET_HAS_sub2_i64 1
|
#define TCG_TARGET_HAS_sub2_i64 1
|
||||||
|
|
||||||
|
|
|
@ -1637,6 +1637,10 @@ static const TCGOutOpExtract outop_sextract = {
|
||||||
.out_rr = tgen_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)
|
static void tgen_gotoi(TCGContext *s, int cc, const tcg_insn_unit *dest)
|
||||||
{
|
{
|
||||||
ptrdiff_t off = tcg_pcrel_diff(s, dest) >> 1;
|
ptrdiff_t off = tcg_pcrel_diff(s, dest) >> 1;
|
||||||
|
|
|
@ -14,13 +14,11 @@ extern bool use_vis3_instructions;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* optional instructions */
|
/* optional instructions */
|
||||||
#define TCG_TARGET_HAS_extract2_i32 0
|
|
||||||
#define TCG_TARGET_HAS_add2_i32 1
|
#define TCG_TARGET_HAS_add2_i32 1
|
||||||
#define TCG_TARGET_HAS_sub2_i32 1
|
#define TCG_TARGET_HAS_sub2_i32 1
|
||||||
#define TCG_TARGET_HAS_qemu_st8_i32 0
|
#define TCG_TARGET_HAS_qemu_st8_i32 0
|
||||||
|
|
||||||
#define TCG_TARGET_HAS_extr_i64_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_add2_i64 1
|
||||||
#define TCG_TARGET_HAS_sub2_i64 1
|
#define TCG_TARGET_HAS_sub2_i64 1
|
||||||
|
|
||||||
|
|
|
@ -1795,6 +1795,10 @@ static const TCGOutOpExtract outop_sextract = {
|
||||||
.out_rr = tgen_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,
|
static void tcg_out_op(TCGContext *s, TCGOpcode opc, TCGType type,
|
||||||
const TCGArg args[TCG_MAX_OP_ARGS],
|
const TCGArg args[TCG_MAX_OP_ARGS],
|
||||||
const int const_args[TCG_MAX_OP_ARGS])
|
const int const_args[TCG_MAX_OP_ARGS])
|
||||||
|
|
|
@ -12,7 +12,6 @@
|
||||||
#if TCG_TARGET_REG_BITS == 32
|
#if TCG_TARGET_REG_BITS == 32
|
||||||
/* Turn some undef macros into false macros. */
|
/* Turn some undef macros into false macros. */
|
||||||
#define TCG_TARGET_HAS_extr_i64_i32 0
|
#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_add2_i64 0
|
||||||
#define TCG_TARGET_HAS_sub2_i64 0
|
#define TCG_TARGET_HAS_sub2_i64 0
|
||||||
/* Turn some undef macros into true macros. */
|
/* Turn some undef macros into true macros. */
|
||||||
|
|
12
tcg/tcg-op.c
12
tcg/tcg-op.c
|
@ -921,7 +921,7 @@ void tcg_gen_deposit_i32(TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 arg2,
|
||||||
|
|
||||||
t1 = tcg_temp_ebb_new_i32();
|
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) {
|
if (ofs + len == 32) {
|
||||||
tcg_gen_shli_i32(t1, arg1, len);
|
tcg_gen_shli_i32(t1, arg1, len);
|
||||||
tcg_gen_extract2_i32(ret, t1, arg2, 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);
|
tcg_gen_mov_i32(ret, ah);
|
||||||
} else if (al == ah) {
|
} else if (al == ah) {
|
||||||
tcg_gen_rotri_i32(ret, al, ofs);
|
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);
|
tcg_gen_op4i_i32(INDEX_op_extract2_i32, ret, al, ah, ofs);
|
||||||
} else {
|
} else {
|
||||||
TCGv_i32 t0 = tcg_temp_ebb_new_i32();
|
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);
|
tcg_gen_movi_i32(TCGV_LOW(ret), 0);
|
||||||
}
|
}
|
||||||
} else if (right) {
|
} 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),
|
tcg_gen_extract2_i32(TCGV_LOW(ret),
|
||||||
TCGV_LOW(arg1), TCGV_HIGH(arg1), c);
|
TCGV_LOW(arg1), TCGV_HIGH(arg1), c);
|
||||||
} else {
|
} 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);
|
tcg_gen_shri_i32(TCGV_HIGH(ret), TCGV_HIGH(arg1), c);
|
||||||
}
|
}
|
||||||
} else {
|
} 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),
|
tcg_gen_extract2_i32(TCGV_HIGH(ret),
|
||||||
TCGV_LOW(arg1), TCGV_HIGH(arg1), 32 - c);
|
TCGV_LOW(arg1), TCGV_HIGH(arg1), 32 - c);
|
||||||
} else {
|
} 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();
|
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) {
|
if (ofs + len == 64) {
|
||||||
tcg_gen_shli_i64(t1, arg1, len);
|
tcg_gen_shli_i64(t1, arg1, len);
|
||||||
tcg_gen_extract2_i64(ret, t1, arg2, 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);
|
tcg_gen_mov_i64(ret, ah);
|
||||||
} else if (al == ah) {
|
} else if (al == ah) {
|
||||||
tcg_gen_rotri_i64(ret, al, ofs);
|
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);
|
tcg_gen_op4i_i64(INDEX_op_extract2_i64, ret, al, ah, ofs);
|
||||||
} else {
|
} else {
|
||||||
TCGv_i64 t0 = tcg_temp_ebb_new_i64();
|
TCGv_i64 t0 = tcg_temp_ebb_new_i64();
|
||||||
|
|
24
tcg/tcg.c
24
tcg/tcg.c
|
@ -1029,6 +1029,12 @@ typedef struct TCGOutOpExtract {
|
||||||
unsigned ofs, unsigned len);
|
unsigned ofs, unsigned len);
|
||||||
} TCGOutOpExtract;
|
} 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 {
|
typedef struct TCGOutOpMovcond {
|
||||||
TCGOutOp base;
|
TCGOutOp base;
|
||||||
void (*out)(TCGContext *s, TCGType type, TCGCond cond,
|
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_divu2, TCGOutOpDivRem, outop_divu2),
|
||||||
OUTOP(INDEX_op_eqv, TCGOutOpBinary, outop_eqv),
|
OUTOP(INDEX_op_eqv, TCGOutOpBinary, outop_eqv),
|
||||||
OUTOP(INDEX_op_extract, TCGOutOpExtract, outop_extract),
|
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_movcond, TCGOutOpMovcond, outop_movcond),
|
||||||
OUTOP(INDEX_op_mul, TCGOutOpBinary, outop_mul),
|
OUTOP(INDEX_op_mul, TCGOutOpBinary, outop_mul),
|
||||||
OUTOP(INDEX_op_muls2, TCGOutOpMul2, outop_muls2),
|
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:
|
case INDEX_op_st_i32:
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
case INDEX_op_extract2_i32:
|
|
||||||
return TCG_TARGET_HAS_extract2_i32;
|
|
||||||
case INDEX_op_add2_i32:
|
case INDEX_op_add2_i32:
|
||||||
return TCG_TARGET_HAS_add2_i32;
|
return TCG_TARGET_HAS_add2_i32;
|
||||||
case INDEX_op_sub2_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:
|
case INDEX_op_extrh_i64_i32:
|
||||||
return TCG_TARGET_REG_BITS == 64;
|
return TCG_TARGET_REG_BITS == 64;
|
||||||
|
|
||||||
case INDEX_op_extract2_i64:
|
|
||||||
return TCG_TARGET_HAS_extract2_i64;
|
|
||||||
case INDEX_op_add2_i64:
|
case INDEX_op_add2_i64:
|
||||||
return TCG_TARGET_HAS_add2_i64;
|
return TCG_TARGET_HAS_add2_i64;
|
||||||
case INDEX_op_sub2_i64:
|
case INDEX_op_sub2_i64:
|
||||||
|
@ -5593,6 +5597,18 @@ static void tcg_reg_alloc_op(TCGContext *s, const TCGOp *op)
|
||||||
}
|
}
|
||||||
break;
|
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_muls2:
|
||||||
case INDEX_op_mulu2:
|
case INDEX_op_mulu2:
|
||||||
{
|
{
|
||||||
|
|
|
@ -7,12 +7,10 @@
|
||||||
#ifndef TCG_TARGET_HAS_H
|
#ifndef TCG_TARGET_HAS_H
|
||||||
#define TCG_TARGET_HAS_H
|
#define TCG_TARGET_HAS_H
|
||||||
|
|
||||||
#define TCG_TARGET_HAS_extract2_i32 0
|
|
||||||
#define TCG_TARGET_HAS_qemu_st8_i32 0
|
#define TCG_TARGET_HAS_qemu_st8_i32 0
|
||||||
|
|
||||||
#if TCG_TARGET_REG_BITS == 64
|
#if TCG_TARGET_REG_BITS == 64
|
||||||
#define TCG_TARGET_HAS_extr_i64_i32 0
|
#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_add2_i32 1
|
||||||
#define TCG_TARGET_HAS_sub2_i32 1
|
#define TCG_TARGET_HAS_sub2_i32 1
|
||||||
#define TCG_TARGET_HAS_add2_i64 1
|
#define TCG_TARGET_HAS_add2_i64 1
|
||||||
|
|
|
@ -447,6 +447,10 @@ static const TCGOutOpExtract outop_sextract = {
|
||||||
.out_rr = tcg_out_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)
|
static void tcg_out_ext8s(TCGContext *s, TCGType type, TCGReg rd, TCGReg rs)
|
||||||
{
|
{
|
||||||
tcg_out_sextract(s, type, rd, rs, 0, 8);
|
tcg_out_sextract(s, type, rd, rs, 0, 8);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue