[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [PULL 47/65] tcg/i386: Allow bmi2 shiftx to have non-matchi
From: |
Richard Henderson |
Subject: |
[Qemu-devel] [PULL 47/65] tcg/i386: Allow bmi2 shiftx to have non-matching operands |
Date: |
Tue, 10 Jan 2017 18:18:02 -0800 |
Previously we could not have different constraints for different ISA levels,
which prevented us from eliding the matching constraint for shifts.
We do now have to make sure that the operands match for constant shifts.
We can also handle some small left shifts via lea.
Signed-off-by: Richard Henderson <address@hidden>
---
tcg/i386/tcg-target.inc.c | 33 +++++++++++++++++++--------------
1 file changed, 19 insertions(+), 14 deletions(-)
diff --git a/tcg/i386/tcg-target.inc.c b/tcg/i386/tcg-target.inc.c
index 83572ac..651d96c 100644
--- a/tcg/i386/tcg-target.inc.c
+++ b/tcg/i386/tcg-target.inc.c
@@ -179,7 +179,6 @@ static const char *target_parse_constraint(TCGArgConstraint
*ct,
tcg_regset_set_reg(ct->u.regs, TCG_REG_EBX);
break;
case 'c':
- case_c:
ct->ct |= TCG_CT_REG;
tcg_regset_set_reg(ct->u.regs, TCG_REG_ECX);
break;
@@ -208,7 +207,6 @@ static const char *target_parse_constraint(TCGArgConstraint
*ct,
tcg_regset_set32(ct->u.regs, 0, 0xf);
break;
case 'r':
- case_r:
ct->ct |= TCG_CT_REG;
if (TCG_TARGET_REG_BITS == 64) {
tcg_regset_set32(ct->u.regs, 0, 0xffff);
@@ -216,13 +214,6 @@ static const char
*target_parse_constraint(TCGArgConstraint *ct,
tcg_regset_set32(ct->u.regs, 0, 0xff);
}
break;
- case 'C':
- /* With SHRX et al, we need not use ECX as shift count register. */
- if (have_bmi2) {
- goto case_r;
- } else {
- goto case_c;
- }
/* qemu_ld/st address constraint */
case 'L':
@@ -1959,6 +1950,17 @@ static inline void tcg_out_op(TCGContext *s, TCGOpcode
opc,
break;
OP_32_64(shl):
+ /* For small constant 3-operand shift, use LEA. */
+ if (const_a2 && a0 != a1 && (a2 - 1) < 3) {
+ if (a2 - 1 == 0) {
+ /* shl $1,a1,a0 -> lea (a1,a1),a0 */
+ tcg_out_modrm_sib_offset(s, OPC_LEA + rexw, a0, a1, a1, 0, 0);
+ } else {
+ /* shl $n,a1,a0 -> lea 0(,a1,n),a0 */
+ tcg_out_modrm_sib_offset(s, OPC_LEA + rexw, a0, -1, a1, a2, 0);
+ }
+ break;
+ }
c = SHIFT_SHL;
vexop = OPC_SHLX;
goto gen_shift_maybe_vex;
@@ -1977,9 +1979,12 @@ static inline void tcg_out_op(TCGContext *s, TCGOpcode
opc,
c = SHIFT_ROR;
goto gen_shift;
gen_shift_maybe_vex:
- if (have_bmi2 && !const_a2) {
- tcg_out_vex_modrm(s, vexop + rexw, a0, a2, a1);
- break;
+ if (have_bmi2) {
+ if (!const_a2) {
+ tcg_out_vex_modrm(s, vexop + rexw, a0, a2, a1);
+ break;
+ }
+ tcg_out_mov(s, rexw ? TCG_TYPE_I64 : TCG_TYPE_I32, a0, a1);
}
/* FALLTHRU */
gen_shift:
@@ -2190,9 +2195,9 @@ static const TCGTargetOpDef *tcg_target_op_def(TCGOpcode
op)
static const TCGTargetOpDef r_q = { .args_ct_str = { "r", "q" } };
static const TCGTargetOpDef r_re = { .args_ct_str = { "r", "re" } };
static const TCGTargetOpDef r_0 = { .args_ct_str = { "r", "0" } };
+ static const TCGTargetOpDef r_r_ri = { .args_ct_str = { "r", "r", "ri" } };
static const TCGTargetOpDef r_r_re = { .args_ct_str = { "r", "r", "re" } };
static const TCGTargetOpDef r_0_re = { .args_ct_str = { "r", "0", "re" } };
- static const TCGTargetOpDef r_0_Ci = { .args_ct_str = { "r", "0", "Ci" } };
static const TCGTargetOpDef r_0_ci = { .args_ct_str = { "r", "0", "ci" } };
static const TCGTargetOpDef r_L = { .args_ct_str = { "r", "L" } };
static const TCGTargetOpDef L_L = { .args_ct_str = { "L", "L" } };
@@ -2266,7 +2271,7 @@ static const TCGTargetOpDef *tcg_target_op_def(TCGOpcode
op)
case INDEX_op_shr_i64:
case INDEX_op_sar_i32:
case INDEX_op_sar_i64:
- return &r_0_Ci;
+ return have_bmi2 ? &r_r_ri : &r_0_ci;
case INDEX_op_rotl_i32:
case INDEX_op_rotl_i64:
case INDEX_op_rotr_i32:
--
2.9.3
- [Qemu-devel] [PULL 38/65] target-arm: Use clz opcode, (continued)
- [Qemu-devel] [PULL 38/65] target-arm: Use clz opcode, Richard Henderson, 2017/01/10
- [Qemu-devel] [PULL 32/65] target-ppc: Use clz and ctz opcodes, Richard Henderson, 2017/01/10
- [Qemu-devel] [PULL 35/65] target-tricore: Use clz opcode, Richard Henderson, 2017/01/10
- [Qemu-devel] [PULL 37/65] target-xtensa: Use clz opcode, Richard Henderson, 2017/01/10
- [Qemu-devel] [PULL 39/65] target-i386: Use clz and ctz opcodes, Richard Henderson, 2017/01/10
- [Qemu-devel] [PULL 41/65] tcg/aarch64: Handle ctz and clz opcodes, Richard Henderson, 2017/01/10
- [Qemu-devel] [PULL 40/65] tcg/ppc: Handle ctz and clz opcodes, Richard Henderson, 2017/01/10
- [Qemu-devel] [PULL 42/65] tcg/arm: Handle ctz and clz opcodes, Richard Henderson, 2017/01/10
- [Qemu-devel] [PULL 43/65] tcg/mips: Handle clz opcode, Richard Henderson, 2017/01/10
- [Qemu-devel] [PULL 44/65] tcg/s390: Handle clz opcode, Richard Henderson, 2017/01/10
- [Qemu-devel] [PULL 47/65] tcg/i386: Allow bmi2 shiftx to have non-matching operands,
Richard Henderson <=
- [Qemu-devel] [PULL 45/65] tcg/i386: Fuly convert tcg_target_op_def, Richard Henderson, 2017/01/10
- [Qemu-devel] [PULL 46/65] tcg/i386: Hoist common arguments in tcg_out_op, Richard Henderson, 2017/01/10
- [Qemu-devel] [PULL 49/65] tcg/i386: Rely on undefined/undocumented behaviour of BSF/BSR, Richard Henderson, 2017/01/10
- [Qemu-devel] [PULL 48/65] tcg/i386: Handle ctz and clz opcodes, Richard Henderson, 2017/01/10
- [Qemu-devel] [PULL 51/65] target-arm: Use clrsb helper, Richard Henderson, 2017/01/10
- [Qemu-devel] [PULL 50/65] tcg: Add helpers for clrsb, Richard Henderson, 2017/01/10
- [Qemu-devel] [PULL 52/65] target-tricore: Use clrsb helper, Richard Henderson, 2017/01/10
- [Qemu-devel] [PULL 55/65] target-alpha: Use ctpop helper, Richard Henderson, 2017/01/10
- [Qemu-devel] [PULL 57/65] target-s390x: Avoid a loop for popcnt, Richard Henderson, 2017/01/10
- [Qemu-devel] [PULL 56/65] target-ppc: Use ctpop helper, Richard Henderson, 2017/01/10