summaryrefslogtreecommitdiff
path: root/compiler/optimizing
diff options
context:
space:
mode:
Diffstat (limited to 'compiler/optimizing')
-rw-r--r--compiler/optimizing/code_generator_x86.cc30
-rw-r--r--compiler/optimizing/code_generator_x86_64.cc60
-rw-r--r--compiler/optimizing/intrinsics.cc2
3 files changed, 62 insertions, 30 deletions
diff --git a/compiler/optimizing/code_generator_x86.cc b/compiler/optimizing/code_generator_x86.cc
index e15eff9056..0569565bdd 100644
--- a/compiler/optimizing/code_generator_x86.cc
+++ b/compiler/optimizing/code_generator_x86.cc
@@ -2348,7 +2348,12 @@ void LocationsBuilderX86::VisitMul(HMul* mul) {
case Primitive::kPrimInt:
locations->SetInAt(0, Location::RequiresRegister());
locations->SetInAt(1, Location::Any());
- locations->SetOut(Location::SameAsFirstInput());
+ if (mul->InputAt(1)->IsIntConstant()) {
+ // Can use 3 operand multiply.
+ locations->SetOut(Location::RequiresRegister(), Location::kNoOutputOverlap);
+ } else {
+ locations->SetOut(Location::SameAsFirstInput());
+ }
break;
case Primitive::kPrimLong: {
locations->SetInAt(0, Location::RequiresRegister());
@@ -2376,21 +2381,24 @@ void InstructionCodeGeneratorX86::VisitMul(HMul* mul) {
LocationSummary* locations = mul->GetLocations();
Location first = locations->InAt(0);
Location second = locations->InAt(1);
- DCHECK(first.Equals(locations->Out()));
+ Location out = locations->Out();
switch (mul->GetResultType()) {
- case Primitive::kPrimInt: {
- if (second.IsRegister()) {
+ case Primitive::kPrimInt:
+ // The constant may have ended up in a register, so test explicitly to avoid
+ // problems where the output may not be the same as the first operand.
+ if (mul->InputAt(1)->IsIntConstant()) {
+ Immediate imm(mul->InputAt(1)->AsIntConstant()->GetValue());
+ __ imull(out.AsRegister<Register>(), first.AsRegister<Register>(), imm);
+ } else if (second.IsRegister()) {
+ DCHECK(first.Equals(out));
__ imull(first.AsRegister<Register>(), second.AsRegister<Register>());
- } else if (second.IsConstant()) {
- Immediate imm(second.GetConstant()->AsIntConstant()->GetValue());
- __ imull(first.AsRegister<Register>(), imm);
} else {
DCHECK(second.IsStackSlot());
+ DCHECK(first.Equals(out));
__ imull(first.AsRegister<Register>(), Address(ESP, second.GetStackIndex()));
}
break;
- }
case Primitive::kPrimLong: {
Register in1_hi = first.AsRegisterPairHigh<Register>();
@@ -4535,7 +4543,11 @@ void ParallelMoveResolverX86::EmitSwap(size_t index) {
Location destination = move->GetDestination();
if (source.IsRegister() && destination.IsRegister()) {
- __ xchgl(destination.AsRegister<Register>(), source.AsRegister<Register>());
+ // Use XOR swap algorithm to avoid serializing XCHG instruction or using a temporary.
+ DCHECK_NE(destination.AsRegister<Register>(), source.AsRegister<Register>());
+ __ xorl(destination.AsRegister<Register>(), source.AsRegister<Register>());
+ __ xorl(source.AsRegister<Register>(), destination.AsRegister<Register>());
+ __ xorl(destination.AsRegister<Register>(), source.AsRegister<Register>());
} else if (source.IsRegister() && destination.IsStackSlot()) {
Exchange(source.AsRegister<Register>(), destination.GetStackIndex());
} else if (source.IsStackSlot() && destination.IsRegister()) {
diff --git a/compiler/optimizing/code_generator_x86_64.cc b/compiler/optimizing/code_generator_x86_64.cc
index a95ce68657..287737b4c8 100644
--- a/compiler/optimizing/code_generator_x86_64.cc
+++ b/compiler/optimizing/code_generator_x86_64.cc
@@ -2535,13 +2535,19 @@ void LocationsBuilderX86_64::VisitMul(HMul* mul) {
case Primitive::kPrimInt: {
locations->SetInAt(0, Location::RequiresRegister());
locations->SetInAt(1, Location::Any());
- locations->SetOut(Location::SameAsFirstInput());
+ if (mul->InputAt(1)->IsIntConstant()) {
+ // Can use 3 operand multiply.
+ locations->SetOut(Location::RequiresRegister(), Location::kNoOutputOverlap);
+ } else {
+ locations->SetOut(Location::SameAsFirstInput());
+ }
break;
}
case Primitive::kPrimLong: {
locations->SetInAt(0, Location::RequiresRegister());
- locations->SetInAt(1, Location::RegisterOrInt32LongConstant(mul->InputAt(1)));
- if (locations->InAt(1).IsConstant()) {
+ locations->SetInAt(1, Location::Any());
+ if (mul->InputAt(1)->IsLongConstant() &&
+ IsInt<32>(mul->InputAt(1)->AsLongConstant()->GetValue())) {
// Can use 3 operand multiply.
locations->SetOut(Location::RequiresRegister(), Location::kNoOutputOverlap);
} else {
@@ -2566,37 +2572,51 @@ void InstructionCodeGeneratorX86_64::VisitMul(HMul* mul) {
LocationSummary* locations = mul->GetLocations();
Location first = locations->InAt(0);
Location second = locations->InAt(1);
+ Location out = locations->Out();
switch (mul->GetResultType()) {
- case Primitive::kPrimInt: {
- DCHECK(first.Equals(locations->Out()));
- if (second.IsRegister()) {
+ case Primitive::kPrimInt:
+ // The constant may have ended up in a register, so test explicitly to avoid
+ // problems where the output may not be the same as the first operand.
+ if (mul->InputAt(1)->IsIntConstant()) {
+ Immediate imm(mul->InputAt(1)->AsIntConstant()->GetValue());
+ __ imull(out.AsRegister<CpuRegister>(), first.AsRegister<CpuRegister>(), imm);
+ } else if (second.IsRegister()) {
+ DCHECK(first.Equals(out));
__ imull(first.AsRegister<CpuRegister>(), second.AsRegister<CpuRegister>());
- } else if (second.IsConstant()) {
- Immediate imm(second.GetConstant()->AsIntConstant()->GetValue());
- __ imull(first.AsRegister<CpuRegister>(), imm);
} else {
+ DCHECK(first.Equals(out));
DCHECK(second.IsStackSlot());
__ imull(first.AsRegister<CpuRegister>(),
Address(CpuRegister(RSP), second.GetStackIndex()));
}
break;
- }
case Primitive::kPrimLong: {
- if (second.IsConstant()) {
- int64_t value = second.GetConstant()->AsLongConstant()->GetValue();
- DCHECK(IsInt<32>(value));
- __ imulq(locations->Out().AsRegister<CpuRegister>(),
- first.AsRegister<CpuRegister>(),
- Immediate(static_cast<int32_t>(value)));
- } else {
- DCHECK(first.Equals(locations->Out()));
+ // The constant may have ended up in a register, so test explicitly to avoid
+ // problems where the output may not be the same as the first operand.
+ if (mul->InputAt(1)->IsLongConstant()) {
+ int64_t value = mul->InputAt(1)->AsLongConstant()->GetValue();
+ if (IsInt<32>(value)) {
+ __ imulq(out.AsRegister<CpuRegister>(), first.AsRegister<CpuRegister>(),
+ Immediate(static_cast<int32_t>(value)));
+ } else {
+ // Have to use the constant area.
+ DCHECK(first.Equals(out));
+ __ imulq(first.AsRegister<CpuRegister>(), codegen_->LiteralInt64Address(value));
+ }
+ } else if (second.IsRegister()) {
+ DCHECK(first.Equals(out));
__ imulq(first.AsRegister<CpuRegister>(), second.AsRegister<CpuRegister>());
+ } else {
+ DCHECK(second.IsDoubleStackSlot());
+ DCHECK(first.Equals(out));
+ __ imulq(first.AsRegister<CpuRegister>(),
+ Address(CpuRegister(RSP), second.GetStackIndex()));
}
break;
}
case Primitive::kPrimFloat: {
- DCHECK(first.Equals(locations->Out()));
+ DCHECK(first.Equals(out));
if (second.IsFpuRegister()) {
__ mulss(first.AsFpuRegister<XmmRegister>(), second.AsFpuRegister<XmmRegister>());
} else if (second.IsConstant()) {
@@ -2611,7 +2631,7 @@ void InstructionCodeGeneratorX86_64::VisitMul(HMul* mul) {
}
case Primitive::kPrimDouble: {
- DCHECK(first.Equals(locations->Out()));
+ DCHECK(first.Equals(out));
if (second.IsFpuRegister()) {
__ mulsd(first.AsFpuRegister<XmmRegister>(), second.AsFpuRegister<XmmRegister>());
} else if (second.IsConstant()) {
diff --git a/compiler/optimizing/intrinsics.cc b/compiler/optimizing/intrinsics.cc
index 8ef13e125e..bc7da802b1 100644
--- a/compiler/optimizing/intrinsics.cc
+++ b/compiler/optimizing/intrinsics.cc
@@ -359,7 +359,7 @@ void IntrinsicsRecognizer::Run() {
std::ostream& operator<<(std::ostream& os, const Intrinsics& intrinsic) {
switch (intrinsic) {
case Intrinsics::kNone:
- os << "No intrinsic.";
+ os << "None";
break;
#define OPTIMIZING_INTRINSICS(Name, IsStatic) \
case Intrinsics::k ## Name: \