diff options
author | Roland Levillain <rpl@google.com> | 2015-04-29 11:12:59 +0000 |
---|---|---|
committer | Gerrit Code Review <noreply-gerritcodereview@google.com> | 2015-04-29 11:13:00 +0000 |
commit | e761b911b24e9001ac50667462b4f936ebee7369 (patch) | |
tree | fc794b7c75ad480a4fab984099bd75a32210042f | |
parent | 7386f983a67cf73c91cfb9a69a3919f95b25f276 (diff) | |
parent | 2a7a1d7808f003bea908023ebd11eb442d2fca39 (diff) | |
download | art-e761b911b24e9001ac50667462b4f936ebee7369.tar.gz art-e761b911b24e9001ac50667462b4f936ebee7369.tar.bz2 art-e761b911b24e9001ac50667462b4f936ebee7369.zip |
Merge "Revert "Revert "Revert "[optimizing] Improve x86 shifts""""
-rw-r--r-- | compiler/optimizing/code_generator_x86.cc | 118 | ||||
-rw-r--r-- | compiler/optimizing/code_generator_x86.h | 3 | ||||
-rw-r--r-- | compiler/utils/x86/assembler_x86.cc | 70 | ||||
-rw-r--r-- | compiler/utils/x86/assembler_x86.h | 12 |
4 files changed, 30 insertions, 173 deletions
diff --git a/compiler/optimizing/code_generator_x86.cc b/compiler/optimizing/code_generator_x86.cc index 099b71c9e..7df4b53cb 100644 --- a/compiler/optimizing/code_generator_x86.cc +++ b/compiler/optimizing/code_generator_x86.cc @@ -2740,15 +2740,20 @@ void LocationsBuilderX86::HandleShift(HBinaryOperation* op) { new (GetGraph()->GetArena()) LocationSummary(op, LocationSummary::kNoCall); switch (op->GetResultType()) { - case Primitive::kPrimInt: - case Primitive::kPrimLong: { - // Can't have Location::Any() and output SameAsFirstInput() + case Primitive::kPrimInt: { locations->SetInAt(0, Location::RequiresRegister()); - // The shift count needs to be in CL or a constant. + // The shift count needs to be in CL. locations->SetInAt(1, Location::ByteRegisterOrConstant(ECX, op->InputAt(1))); locations->SetOut(Location::SameAsFirstInput()); break; } + case Primitive::kPrimLong: { + locations->SetInAt(0, Location::RequiresRegister()); + // The shift count needs to be in CL. + locations->SetInAt(1, Location::RegisterLocation(ECX)); + locations->SetOut(Location::SameAsFirstInput()); + break; + } default: LOG(FATAL) << "Unexpected op type " << op->GetResultType(); } @@ -2764,7 +2769,6 @@ void InstructionCodeGeneratorX86::HandleShift(HBinaryOperation* op) { switch (op->GetResultType()) { case Primitive::kPrimInt: { - DCHECK(first.IsRegister()); Register first_reg = first.AsRegister<Register>(); if (second.IsRegister()) { Register second_reg = second.AsRegister<Register>(); @@ -2777,11 +2781,7 @@ void InstructionCodeGeneratorX86::HandleShift(HBinaryOperation* op) { __ shrl(first_reg, second_reg); } } else { - int32_t shift = second.GetConstant()->AsIntConstant()->GetValue() & kMaxIntShiftValue; - if (shift == 0) { - return; - } - Immediate imm(shift); + Immediate imm(second.GetConstant()->AsIntConstant()->GetValue() & kMaxIntShiftValue); if (op->IsShl()) { __ shll(first_reg, imm); } else if (op->IsShr()) { @@ -2793,29 +2793,14 @@ void InstructionCodeGeneratorX86::HandleShift(HBinaryOperation* op) { break; } case Primitive::kPrimLong: { - if (second.IsRegister()) { - Register second_reg = second.AsRegister<Register>(); - DCHECK_EQ(ECX, second_reg); - if (op->IsShl()) { - GenerateShlLong(first, second_reg); - } else if (op->IsShr()) { - GenerateShrLong(first, second_reg); - } else { - GenerateUShrLong(first, second_reg); - } + Register second_reg = second.AsRegister<Register>(); + DCHECK_EQ(ECX, second_reg); + if (op->IsShl()) { + GenerateShlLong(first, second_reg); + } else if (op->IsShr()) { + GenerateShrLong(first, second_reg); } else { - // Shift by a constant. - int shift = second.GetConstant()->AsIntConstant()->GetValue() & kMaxLongShiftValue; - // Nothing to do if the shift is 0, as the input is already the output. - if (shift != 0) { - if (op->IsShl()) { - GenerateShlLong(first, shift); - } else if (op->IsShr()) { - GenerateShrLong(first, shift); - } else { - GenerateUShrLong(first, shift); - } - } + GenerateUShrLong(first, second_reg); } break; } @@ -2824,30 +2809,6 @@ void InstructionCodeGeneratorX86::HandleShift(HBinaryOperation* op) { } } -void InstructionCodeGeneratorX86::GenerateShlLong(const Location& loc, int shift) { - Register low = loc.AsRegisterPairLow<Register>(); - Register high = loc.AsRegisterPairHigh<Register>(); - if (shift == 32) { - // Shift by 32 is easy. High gets low, and low gets 0. - codegen_->EmitParallelMoves( - loc.ToLow(), - loc.ToHigh(), - Primitive::kPrimInt, - Location::ConstantLocation(GetGraph()->GetIntConstant(0)), - loc.ToLow(), - Primitive::kPrimInt); - } else if (shift > 32) { - // Low part becomes 0. High part is low part << (shift-32). - __ movl(high, low); - __ shll(high, Immediate(shift - 32)); - __ xorl(low, low); - } else { - // Between 1 and 31. - __ shld(high, low, Immediate(shift)); - __ shll(low, Immediate(shift)); - } -} - void InstructionCodeGeneratorX86::GenerateShlLong(const Location& loc, Register shifter) { Label done; __ shld(loc.AsRegisterPairHigh<Register>(), loc.AsRegisterPairLow<Register>(), shifter); @@ -2859,27 +2820,6 @@ void InstructionCodeGeneratorX86::GenerateShlLong(const Location& loc, Register __ Bind(&done); } -void InstructionCodeGeneratorX86::GenerateShrLong(const Location& loc, int shift) { - Register low = loc.AsRegisterPairLow<Register>(); - Register high = loc.AsRegisterPairHigh<Register>(); - if (shift == 32) { - // Need to copy the sign. - DCHECK_NE(low, high); - __ movl(low, high); - __ sarl(high, Immediate(31)); - } else if (shift > 32) { - DCHECK_NE(low, high); - // High part becomes sign. Low part is shifted by shift - 32. - __ movl(low, high); - __ sarl(high, Immediate(31)); - __ shrl(low, Immediate(shift - 32)); - } else { - // Between 1 and 31. - __ shrd(low, high, Immediate(shift)); - __ sarl(high, Immediate(shift)); - } -} - void InstructionCodeGeneratorX86::GenerateShrLong(const Location& loc, Register shifter) { Label done; __ shrd(loc.AsRegisterPairLow<Register>(), loc.AsRegisterPairHigh<Register>(), shifter); @@ -2891,30 +2831,6 @@ void InstructionCodeGeneratorX86::GenerateShrLong(const Location& loc, Register __ Bind(&done); } -void InstructionCodeGeneratorX86::GenerateUShrLong(const Location& loc, int shift) { - Register low = loc.AsRegisterPairLow<Register>(); - Register high = loc.AsRegisterPairHigh<Register>(); - if (shift == 32) { - // Shift by 32 is easy. Low gets high, and high gets 0. - codegen_->EmitParallelMoves( - loc.ToHigh(), - loc.ToLow(), - Primitive::kPrimInt, - Location::ConstantLocation(GetGraph()->GetIntConstant(0)), - loc.ToHigh(), - Primitive::kPrimInt); - } else if (shift > 32) { - // Low part is high >> (shift - 32). High part becomes 0. - __ movl(low, high); - __ shrl(low, Immediate(shift - 32)); - __ xorl(high, high); - } else { - // Between 1 and 31. - __ shrd(low, high, Immediate(shift)); - __ shrl(high, Immediate(shift)); - } -} - void InstructionCodeGeneratorX86::GenerateUShrLong(const Location& loc, Register shifter) { Label done; __ shrd(loc.AsRegisterPairLow<Register>(), loc.AsRegisterPairHigh<Register>(), shifter); diff --git a/compiler/optimizing/code_generator_x86.h b/compiler/optimizing/code_generator_x86.h index a41d538ac..8bd3cd358 100644 --- a/compiler/optimizing/code_generator_x86.h +++ b/compiler/optimizing/code_generator_x86.h @@ -171,9 +171,6 @@ class InstructionCodeGeneratorX86 : public HGraphVisitor { void GenerateShlLong(const Location& loc, Register shifter); void GenerateShrLong(const Location& loc, Register shifter); void GenerateUShrLong(const Location& loc, Register shifter); - void GenerateShlLong(const Location& loc, int shift); - void GenerateShrLong(const Location& loc, int shift); - void GenerateUShrLong(const Location& loc, int shift); void GenerateMemoryBarrier(MemBarrierKind kind); void HandleFieldSet(HInstruction* instruction, const FieldInfo& field_info); void HandleFieldGet(HInstruction* instruction, const FieldInfo& field_info); diff --git a/compiler/utils/x86/assembler_x86.cc b/compiler/utils/x86/assembler_x86.cc index f2541a211..329698ce1 100644 --- a/compiler/utils/x86/assembler_x86.cc +++ b/compiler/utils/x86/assembler_x86.cc @@ -1292,62 +1292,32 @@ void X86Assembler::decl(const Address& address) { void X86Assembler::shll(Register reg, const Immediate& imm) { - EmitGenericShift(4, Operand(reg), imm); + EmitGenericShift(4, reg, imm); } void X86Assembler::shll(Register operand, Register shifter) { - EmitGenericShift(4, Operand(operand), shifter); -} - - -void X86Assembler::shll(const Address& address, const Immediate& imm) { - EmitGenericShift(4, address, imm); -} - - -void X86Assembler::shll(const Address& address, Register shifter) { - EmitGenericShift(4, address, shifter); + EmitGenericShift(4, operand, shifter); } void X86Assembler::shrl(Register reg, const Immediate& imm) { - EmitGenericShift(5, Operand(reg), imm); + EmitGenericShift(5, reg, imm); } void X86Assembler::shrl(Register operand, Register shifter) { - EmitGenericShift(5, Operand(operand), shifter); -} - - -void X86Assembler::shrl(const Address& address, const Immediate& imm) { - EmitGenericShift(5, address, imm); -} - - -void X86Assembler::shrl(const Address& address, Register shifter) { - EmitGenericShift(5, address, shifter); + EmitGenericShift(5, operand, shifter); } void X86Assembler::sarl(Register reg, const Immediate& imm) { - EmitGenericShift(7, Operand(reg), imm); + EmitGenericShift(7, reg, imm); } void X86Assembler::sarl(Register operand, Register shifter) { - EmitGenericShift(7, Operand(operand), shifter); -} - - -void X86Assembler::sarl(const Address& address, const Immediate& imm) { - EmitGenericShift(7, address, imm); -} - - -void X86Assembler::sarl(const Address& address, Register shifter) { - EmitGenericShift(7, address, shifter); + EmitGenericShift(7, operand, shifter); } @@ -1360,15 +1330,6 @@ void X86Assembler::shld(Register dst, Register src, Register shifter) { } -void X86Assembler::shld(Register dst, Register src, const Immediate& imm) { - AssemblerBuffer::EnsureCapacity ensured(&buffer_); - EmitUint8(0x0F); - EmitUint8(0xA4); - EmitRegisterOperand(src, dst); - EmitUint8(imm.value() & 0xFF); -} - - void X86Assembler::shrd(Register dst, Register src, Register shifter) { DCHECK_EQ(ECX, shifter); AssemblerBuffer::EnsureCapacity ensured(&buffer_); @@ -1378,15 +1339,6 @@ void X86Assembler::shrd(Register dst, Register src, Register shifter) { } -void X86Assembler::shrd(Register dst, Register src, const Immediate& imm) { - AssemblerBuffer::EnsureCapacity ensured(&buffer_); - EmitUint8(0x0F); - EmitUint8(0xAC); - EmitRegisterOperand(src, dst); - EmitUint8(imm.value() & 0xFF); -} - - void X86Assembler::negl(Register reg) { AssemblerBuffer::EnsureCapacity ensured(&buffer_); EmitUint8(0xF7); @@ -1670,28 +1622,28 @@ void X86Assembler::EmitLabelLink(Label* label) { void X86Assembler::EmitGenericShift(int reg_or_opcode, - const Operand& operand, + Register reg, const Immediate& imm) { AssemblerBuffer::EnsureCapacity ensured(&buffer_); CHECK(imm.is_int8()); if (imm.value() == 1) { EmitUint8(0xD1); - EmitOperand(reg_or_opcode, operand); + EmitOperand(reg_or_opcode, Operand(reg)); } else { EmitUint8(0xC1); - EmitOperand(reg_or_opcode, operand); + EmitOperand(reg_or_opcode, Operand(reg)); EmitUint8(imm.value() & 0xFF); } } void X86Assembler::EmitGenericShift(int reg_or_opcode, - const Operand& operand, + Register operand, Register shifter) { AssemblerBuffer::EnsureCapacity ensured(&buffer_); CHECK_EQ(shifter, ECX); EmitUint8(0xD3); - EmitOperand(reg_or_opcode, operand); + EmitOperand(reg_or_opcode, Operand(operand)); } static dwarf::Reg DWARFReg(Register reg) { diff --git a/compiler/utils/x86/assembler_x86.h b/compiler/utils/x86/assembler_x86.h index 946c96de7..7fc8ef081 100644 --- a/compiler/utils/x86/assembler_x86.h +++ b/compiler/utils/x86/assembler_x86.h @@ -430,20 +430,12 @@ class X86Assembler FINAL : public Assembler { void shll(Register reg, const Immediate& imm); void shll(Register operand, Register shifter); - void shll(const Address& address, const Immediate& imm); - void shll(const Address& address, Register shifter); void shrl(Register reg, const Immediate& imm); void shrl(Register operand, Register shifter); - void shrl(const Address& address, const Immediate& imm); - void shrl(const Address& address, Register shifter); void sarl(Register reg, const Immediate& imm); void sarl(Register operand, Register shifter); - void sarl(const Address& address, const Immediate& imm); - void sarl(const Address& address, Register shifter); void shld(Register dst, Register src, Register shifter); - void shld(Register dst, Register src, const Immediate& imm); void shrd(Register dst, Register src, Register shifter); - void shrd(Register dst, Register src, const Immediate& imm); void negl(Register reg); void notl(Register reg); @@ -628,8 +620,8 @@ class X86Assembler FINAL : public Assembler { void EmitLabelLink(Label* label); void EmitNearLabelLink(Label* label); - void EmitGenericShift(int rm, const Operand& operand, const Immediate& imm); - void EmitGenericShift(int rm, const Operand& operand, Register shifter); + void EmitGenericShift(int rm, Register reg, const Immediate& imm); + void EmitGenericShift(int rm, Register operand, Register shifter); DISALLOW_COPY_AND_ASSIGN(X86Assembler); }; |