summaryrefslogtreecommitdiffstats
path: root/compiler/optimizing/code_generator_x86.cc
diff options
context:
space:
mode:
Diffstat (limited to 'compiler/optimizing/code_generator_x86.cc')
-rw-r--r--compiler/optimizing/code_generator_x86.cc747
1 files changed, 509 insertions, 238 deletions
diff --git a/compiler/optimizing/code_generator_x86.cc b/compiler/optimizing/code_generator_x86.cc
index b0f36ce0b4..fd794f95d1 100644
--- a/compiler/optimizing/code_generator_x86.cc
+++ b/compiler/optimizing/code_generator_x86.cc
@@ -143,7 +143,9 @@ class BoundsCheckSlowPathX86 : public SlowPathCodeX86 {
BoundsCheckSlowPathX86(HBoundsCheck* instruction,
Location index_location,
Location length_location)
- : instruction_(instruction), index_location_(index_location), length_location_(length_location) {}
+ : instruction_(instruction),
+ index_location_(index_location),
+ length_location_(length_location) {}
virtual void EmitNativeCode(CodeGenerator* codegen) OVERRIDE {
CodeGeneratorX86* x86_codegen = down_cast<CodeGeneratorX86*>(codegen);
@@ -311,7 +313,8 @@ class TypeCheckSlowPathX86 : public SlowPathCodeX86 {
Location::RegisterLocation(calling_convention.GetRegisterAt(1)));
if (instruction_->IsInstanceOf()) {
- __ fs()->call(Address::Absolute(QUICK_ENTRYPOINT_OFFSET(kX86WordSize, pInstanceofNonTrivial)));
+ __ fs()->call(Address::Absolute(QUICK_ENTRYPOINT_OFFSET(kX86WordSize,
+ pInstanceofNonTrivial)));
} else {
DCHECK(instruction_->IsCheckCast());
__ fs()->call(Address::Absolute(QUICK_ENTRYPOINT_OFFSET(kX86WordSize, pCheckCast)));
@@ -464,7 +467,8 @@ void CodeGeneratorX86::GenerateFrameEntry() {
static const int kFakeReturnRegister = 8;
core_spill_mask_ |= (1 << kFakeReturnRegister);
- bool skip_overflow_check = IsLeafMethod() && !FrameNeedsStackCheck(GetFrameSize(), InstructionSet::kX86);
+ bool skip_overflow_check =
+ IsLeafMethod() && !FrameNeedsStackCheck(GetFrameSize(), InstructionSet::kX86);
if (!skip_overflow_check && !kExplicitStackOverflowCheck) {
__ testl(EAX, Address(ESP, -static_cast<int32_t>(GetStackOverflowReservedBytes(kX86))));
RecordPcInfo(nullptr, 0);
@@ -567,28 +571,28 @@ void CodeGeneratorX86::Move32(Location destination, Location source) {
}
if (destination.IsRegister()) {
if (source.IsRegister()) {
- __ movl(destination.As<Register>(), source.As<Register>());
+ __ movl(destination.AsRegister<Register>(), source.AsRegister<Register>());
} else if (source.IsFpuRegister()) {
- __ movd(destination.As<Register>(), source.As<XmmRegister>());
+ __ movd(destination.AsRegister<Register>(), source.AsFpuRegister<XmmRegister>());
} else {
DCHECK(source.IsStackSlot());
- __ movl(destination.As<Register>(), Address(ESP, source.GetStackIndex()));
+ __ movl(destination.AsRegister<Register>(), Address(ESP, source.GetStackIndex()));
}
} else if (destination.IsFpuRegister()) {
if (source.IsRegister()) {
- __ movd(destination.As<XmmRegister>(), source.As<Register>());
+ __ movd(destination.AsFpuRegister<XmmRegister>(), source.AsRegister<Register>());
} else if (source.IsFpuRegister()) {
- __ movaps(destination.As<XmmRegister>(), source.As<XmmRegister>());
+ __ movaps(destination.AsFpuRegister<XmmRegister>(), source.AsFpuRegister<XmmRegister>());
} else {
DCHECK(source.IsStackSlot());
- __ movss(destination.As<XmmRegister>(), Address(ESP, source.GetStackIndex()));
+ __ movss(destination.AsFpuRegister<XmmRegister>(), Address(ESP, source.GetStackIndex()));
}
} else {
DCHECK(destination.IsStackSlot()) << destination;
if (source.IsRegister()) {
- __ movl(Address(ESP, destination.GetStackIndex()), source.As<Register>());
+ __ movl(Address(ESP, destination.GetStackIndex()), source.AsRegister<Register>());
} else if (source.IsFpuRegister()) {
- __ movss(Address(ESP, destination.GetStackIndex()), source.As<XmmRegister>());
+ __ movss(Address(ESP, destination.GetStackIndex()), source.AsFpuRegister<XmmRegister>());
} else {
DCHECK(source.IsStackSlot());
__ pushl(Address(ESP, source.GetStackIndex()));
@@ -603,19 +607,25 @@ void CodeGeneratorX86::Move64(Location destination, Location source) {
}
if (destination.IsRegisterPair()) {
if (source.IsRegisterPair()) {
- __ movl(destination.AsRegisterPairLow<Register>(), source.AsRegisterPairLow<Register>());
- __ movl(destination.AsRegisterPairHigh<Register>(), source.AsRegisterPairHigh<Register>());
+ EmitParallelMoves(
+ Location::RegisterLocation(source.AsRegisterPairHigh<Register>()),
+ Location::RegisterLocation(destination.AsRegisterPairHigh<Register>()),
+ Location::RegisterLocation(source.AsRegisterPairLow<Register>()),
+ Location::RegisterLocation(destination.AsRegisterPairLow<Register>()));
} else if (source.IsFpuRegister()) {
LOG(FATAL) << "Unimplemented";
} else if (source.IsQuickParameter()) {
uint16_t register_index = source.GetQuickParameterRegisterIndex();
uint16_t stack_index = source.GetQuickParameterStackIndex();
InvokeDexCallingConvention calling_convention;
- __ movl(destination.AsRegisterPairLow<Register>(),
- calling_convention.GetRegisterAt(register_index));
- __ movl(destination.AsRegisterPairHigh<Register>(), Address(ESP,
- calling_convention.GetStackOffsetOf(stack_index + 1) + GetFrameSize()));
+ EmitParallelMoves(
+ Location::RegisterLocation(calling_convention.GetRegisterAt(register_index)),
+ Location::RegisterLocation(destination.AsRegisterPairLow<Register>()),
+ Location::StackSlot(
+ calling_convention.GetStackOffsetOf(stack_index + 1) + GetFrameSize()),
+ Location::RegisterLocation(destination.AsRegisterPairHigh<Register>()));
} else {
+ // No conflict possible, so just do the moves.
DCHECK(source.IsDoubleStackSlot());
__ movl(destination.AsRegisterPairLow<Register>(), Address(ESP, source.GetStackIndex()));
__ movl(destination.AsRegisterPairHigh<Register>(),
@@ -625,47 +635,52 @@ void CodeGeneratorX86::Move64(Location destination, Location source) {
InvokeDexCallingConvention calling_convention;
uint16_t register_index = destination.GetQuickParameterRegisterIndex();
uint16_t stack_index = destination.GetQuickParameterStackIndex();
- if (source.IsRegister()) {
- __ movl(calling_convention.GetRegisterAt(register_index), source.AsRegisterPairLow<Register>());
- __ movl(Address(ESP, calling_convention.GetStackOffsetOf(stack_index + 1)),
- source.AsRegisterPairHigh<Register>());
+ if (source.IsRegisterPair()) {
+ LOG(FATAL) << "Unimplemented";
} else if (source.IsFpuRegister()) {
LOG(FATAL) << "Unimplemented";
} else {
DCHECK(source.IsDoubleStackSlot());
- __ movl(calling_convention.GetRegisterAt(register_index),
- Address(ESP, source.GetStackIndex()));
- __ pushl(Address(ESP, source.GetHighStackIndex(kX86WordSize)));
- __ popl(Address(ESP, calling_convention.GetStackOffsetOf(stack_index + 1)));
+ EmitParallelMoves(
+ Location::StackSlot(source.GetStackIndex()),
+ Location::RegisterLocation(calling_convention.GetRegisterAt(register_index)),
+ Location::StackSlot(source.GetHighStackIndex(kX86WordSize)),
+ Location::StackSlot(calling_convention.GetStackOffsetOf(stack_index + 1)));
}
} else if (destination.IsFpuRegister()) {
if (source.IsDoubleStackSlot()) {
- __ movsd(destination.As<XmmRegister>(), Address(ESP, source.GetStackIndex()));
+ __ movsd(destination.AsFpuRegister<XmmRegister>(), Address(ESP, source.GetStackIndex()));
} else {
LOG(FATAL) << "Unimplemented";
}
} else {
DCHECK(destination.IsDoubleStackSlot()) << destination;
if (source.IsRegisterPair()) {
+ // No conflict possible, so just do the moves.
__ movl(Address(ESP, destination.GetStackIndex()), source.AsRegisterPairLow<Register>());
__ movl(Address(ESP, destination.GetHighStackIndex(kX86WordSize)),
source.AsRegisterPairHigh<Register>());
} else if (source.IsQuickParameter()) {
+ // No conflict possible, so just do the move.
InvokeDexCallingConvention calling_convention;
uint16_t register_index = source.GetQuickParameterRegisterIndex();
uint16_t stack_index = source.GetQuickParameterStackIndex();
+ // Just move the low part. The only time a source is a quick parameter is
+ // when moving the parameter to its stack locations. And the (Java) caller
+ // of this method has already done that.
__ movl(Address(ESP, destination.GetStackIndex()),
calling_convention.GetRegisterAt(register_index));
DCHECK_EQ(calling_convention.GetStackOffsetOf(stack_index + 1) + GetFrameSize(),
static_cast<size_t>(destination.GetHighStackIndex(kX86WordSize)));
} else if (source.IsFpuRegister()) {
- __ movsd(Address(ESP, destination.GetStackIndex()), source.As<XmmRegister>());
+ __ movsd(Address(ESP, destination.GetStackIndex()), source.AsFpuRegister<XmmRegister>());
} else {
DCHECK(source.IsDoubleStackSlot());
- __ pushl(Address(ESP, source.GetStackIndex()));
- __ popl(Address(ESP, destination.GetStackIndex()));
- __ pushl(Address(ESP, source.GetHighStackIndex(kX86WordSize)));
- __ popl(Address(ESP, destination.GetHighStackIndex(kX86WordSize)));
+ EmitParallelMoves(
+ Location::StackSlot(source.GetStackIndex()),
+ Location::StackSlot(destination.GetStackIndex()),
+ Location::StackSlot(source.GetHighStackIndex(kX86WordSize)),
+ Location::StackSlot(destination.GetHighStackIndex(kX86WordSize)));
}
}
}
@@ -681,7 +696,7 @@ void CodeGeneratorX86::Move(HInstruction* instruction, Location location, HInstr
if (const_to_move->IsIntConstant()) {
Immediate imm(const_to_move->AsIntConstant()->GetValue());
if (location.IsRegister()) {
- __ movl(location.As<Register>(), imm);
+ __ movl(location.AsRegister<Register>(), imm);
} else if (location.IsStackSlot()) {
__ movl(Address(ESP, location.GetStackIndex()), imm);
} else {
@@ -695,7 +710,8 @@ void CodeGeneratorX86::Move(HInstruction* instruction, Location location, HInstr
__ movl(location.AsRegisterPairHigh<Register>(), Immediate(High32Bits(value)));
} else if (location.IsDoubleStackSlot()) {
__ movl(Address(ESP, location.GetStackIndex()), Immediate(Low32Bits(value)));
- __ movl(Address(ESP, location.GetHighStackIndex(kX86WordSize)), Immediate(High32Bits(value)));
+ __ movl(Address(ESP, location.GetHighStackIndex(kX86WordSize)),
+ Immediate(High32Bits(value)));
} else {
DCHECK(location.IsConstant());
DCHECK_EQ(location.GetConstant(), instruction);
@@ -828,7 +844,7 @@ void InstructionCodeGeneratorX86::VisitIf(HIf* if_instr) {
// Materialized condition, compare against 0.
Location lhs = if_instr->GetLocations()->InAt(0);
if (lhs.IsRegister()) {
- __ cmpl(lhs.As<Register>(), Immediate(0));
+ __ cmpl(lhs.AsRegister<Register>(), Immediate(0));
} else {
__ cmpl(Address(ESP, lhs.GetStackIndex()), Immediate(0));
}
@@ -843,13 +859,13 @@ void InstructionCodeGeneratorX86::VisitIf(HIf* if_instr) {
// LHS is guaranteed to be in a register (see
// LocationsBuilderX86::VisitCondition).
if (rhs.IsRegister()) {
- __ cmpl(lhs.As<Register>(), rhs.As<Register>());
+ __ cmpl(lhs.AsRegister<Register>(), rhs.AsRegister<Register>());
} else if (rhs.IsConstant()) {
HIntConstant* instruction = rhs.GetConstant()->AsIntConstant();
Immediate imm(instruction->AsIntConstant()->GetValue());
- __ cmpl(lhs.As<Register>(), imm);
+ __ cmpl(lhs.AsRegister<Register>(), imm);
} else {
- __ cmpl(lhs.As<Register>(), Address(ESP, rhs.GetStackIndex()));
+ __ cmpl(lhs.AsRegister<Register>(), Address(ESP, rhs.GetStackIndex()));
}
__ j(X86Condition(cond->AsCondition()->GetCondition()),
codegen_->GetLabelOf(if_instr->IfTrueSuccessor()));
@@ -920,18 +936,18 @@ void LocationsBuilderX86::VisitCondition(HCondition* comp) {
void InstructionCodeGeneratorX86::VisitCondition(HCondition* comp) {
if (comp->NeedsMaterialization()) {
LocationSummary* locations = comp->GetLocations();
- Register reg = locations->Out().As<Register>();
+ Register reg = locations->Out().AsRegister<Register>();
// Clear register: setcc only sets the low byte.
__ xorl(reg, reg);
if (locations->InAt(1).IsRegister()) {
- __ cmpl(locations->InAt(0).As<Register>(),
- locations->InAt(1).As<Register>());
+ __ cmpl(locations->InAt(0).AsRegister<Register>(),
+ locations->InAt(1).AsRegister<Register>());
} else if (locations->InAt(1).IsConstant()) {
HConstant* instruction = locations->InAt(1).GetConstant();
Immediate imm(instruction->AsIntConstant()->GetValue());
- __ cmpl(locations->InAt(0).As<Register>(), imm);
+ __ cmpl(locations->InAt(0).AsRegister<Register>(), imm);
} else {
- __ cmpl(locations->InAt(0).As<Register>(),
+ __ cmpl(locations->InAt(0).AsRegister<Register>(),
Address(ESP, locations->InAt(1).GetStackIndex()));
}
__ setb(X86Condition(comp->GetCondition()), reg);
@@ -1078,7 +1094,7 @@ void InstructionCodeGeneratorX86::VisitReturn(HReturn* ret) {
case Primitive::kPrimShort:
case Primitive::kPrimInt:
case Primitive::kPrimNot:
- DCHECK_EQ(ret->GetLocations()->InAt(0).As<Register>(), EAX);
+ DCHECK_EQ(ret->GetLocations()->InAt(0).AsRegister<Register>(), EAX);
break;
case Primitive::kPrimLong:
@@ -1088,7 +1104,7 @@ void InstructionCodeGeneratorX86::VisitReturn(HReturn* ret) {
case Primitive::kPrimFloat:
case Primitive::kPrimDouble:
- DCHECK_EQ(ret->GetLocations()->InAt(0).As<XmmRegister>(), XMM0);
+ DCHECK_EQ(ret->GetLocations()->InAt(0).AsFpuRegister<XmmRegister>(), XMM0);
break;
default:
@@ -1104,7 +1120,7 @@ void LocationsBuilderX86::VisitInvokeStatic(HInvokeStatic* invoke) {
}
void InstructionCodeGeneratorX86::VisitInvokeStatic(HInvokeStatic* invoke) {
- Register temp = invoke->GetLocations()->GetTemp(0).As<Register>();
+ Register temp = invoke->GetLocations()->GetTemp(0).AsRegister<Register>();
// TODO: Implement all kinds of calls:
// 1) boot -> boot
@@ -1120,7 +1136,8 @@ void InstructionCodeGeneratorX86::VisitInvokeStatic(HInvokeStatic* invoke) {
// temp = temp[index_in_cache]
__ movl(temp, Address(temp, CodeGenerator::GetCacheOffset(invoke->GetIndexInDexCache())));
// (temp + offset_of_quick_compiled_code)()
- __ call(Address(temp, mirror::ArtMethod::EntryPointFromQuickCompiledCodeOffset(4).Int32Value()));
+ __ call(Address(
+ temp, mirror::ArtMethod::EntryPointFromQuickCompiledCodeOffset(kX86WordSize).Int32Value()));
DCHECK(!codegen_->IsLeafMethod());
codegen_->RecordPcInfo(invoke, invoke->GetDexPc());
@@ -1168,7 +1185,7 @@ void LocationsBuilderX86::HandleInvoke(HInvoke* invoke) {
}
void InstructionCodeGeneratorX86::VisitInvokeVirtual(HInvokeVirtual* invoke) {
- Register temp = invoke->GetLocations()->GetTemp(0).As<Register>();
+ Register temp = invoke->GetLocations()->GetTemp(0).AsRegister<Register>();
uint32_t method_offset = mirror::Class::EmbeddedVTableOffset().Uint32Value() +
invoke->GetVTableIndex() * sizeof(mirror::Class::VTableEntry);
LocationSummary* locations = invoke->GetLocations();
@@ -1179,12 +1196,13 @@ void InstructionCodeGeneratorX86::VisitInvokeVirtual(HInvokeVirtual* invoke) {
__ movl(temp, Address(ESP, receiver.GetStackIndex()));
__ movl(temp, Address(temp, class_offset));
} else {
- __ movl(temp, Address(receiver.As<Register>(), class_offset));
+ __ movl(temp, Address(receiver.AsRegister<Register>(), class_offset));
}
// temp = temp->GetMethodAt(method_offset);
__ movl(temp, Address(temp, method_offset));
// call temp->GetEntryPoint();
- __ call(Address(temp, mirror::ArtMethod::EntryPointFromQuickCompiledCodeOffset(4).Int32Value()));
+ __ call(Address(
+ temp, mirror::ArtMethod::EntryPointFromQuickCompiledCodeOffset(kX86WordSize).Int32Value()));
DCHECK(!codegen_->IsLeafMethod());
codegen_->RecordPcInfo(invoke, invoke->GetDexPc());
@@ -1198,7 +1216,7 @@ void LocationsBuilderX86::VisitInvokeInterface(HInvokeInterface* invoke) {
void InstructionCodeGeneratorX86::VisitInvokeInterface(HInvokeInterface* invoke) {
// TODO: b/18116999, our IMTs can miss an IncompatibleClassChangeError.
- Register temp = invoke->GetLocations()->GetTemp(0).As<Register>();
+ Register temp = invoke->GetLocations()->GetTemp(0).AsRegister<Register>();
uint32_t method_offset = mirror::Class::EmbeddedImTableOffset().Uint32Value() +
(invoke->GetImtIndex() % mirror::Class::kImtSize) * sizeof(mirror::Class::ImTableEntry);
LocationSummary* locations = invoke->GetLocations();
@@ -1207,20 +1225,20 @@ void InstructionCodeGeneratorX86::VisitInvokeInterface(HInvokeInterface* invoke)
// Set the hidden argument.
__ movl(temp, Immediate(invoke->GetDexMethodIndex()));
- __ movd(invoke->GetLocations()->GetTemp(1).As<XmmRegister>(), temp);
+ __ movd(invoke->GetLocations()->GetTemp(1).AsFpuRegister<XmmRegister>(), temp);
// temp = object->GetClass();
if (receiver.IsStackSlot()) {
__ movl(temp, Address(ESP, receiver.GetStackIndex()));
__ movl(temp, Address(temp, class_offset));
} else {
- __ movl(temp, Address(receiver.As<Register>(), class_offset));
+ __ movl(temp, Address(receiver.AsRegister<Register>(), class_offset));
}
// temp = temp->GetImtEntryAt(method_offset);
__ movl(temp, Address(temp, method_offset));
// call temp->GetEntryPoint();
__ call(Address(temp, mirror::ArtMethod::EntryPointFromQuickCompiledCodeOffset(
- kX86PointerSize).Int32Value()));
+ kX86WordSize).Int32Value()));
DCHECK(!codegen_->IsLeafMethod());
codegen_->RecordPcInfo(invoke, invoke->GetDexPc());
@@ -1237,11 +1255,16 @@ void LocationsBuilderX86::VisitNeg(HNeg* neg) {
break;
case Primitive::kPrimFloat:
+ locations->SetInAt(0, Location::RequiresFpuRegister());
+ locations->SetOut(Location::SameAsFirstInput());
+ locations->AddTemp(Location::RequiresRegister());
+ locations->AddTemp(Location::RequiresFpuRegister());
+ break;
+
case Primitive::kPrimDouble:
locations->SetInAt(0, Location::RequiresFpuRegister());
- // Output overlaps as we need a fresh (zero-initialized)
- // register to perform subtraction from zero.
- locations->SetOut(Location::RequiresFpuRegister());
+ locations->SetOut(Location::SameAsFirstInput());
+ locations->AddTemp(Location::RequiresFpuRegister());
break;
default:
@@ -1257,7 +1280,7 @@ void InstructionCodeGeneratorX86::VisitNeg(HNeg* neg) {
case Primitive::kPrimInt:
DCHECK(in.IsRegister());
DCHECK(in.Equals(out));
- __ negl(out.As<Register>());
+ __ negl(out.AsRegister<Register>());
break;
case Primitive::kPrimLong:
@@ -1273,21 +1296,29 @@ void InstructionCodeGeneratorX86::VisitNeg(HNeg* neg) {
__ negl(out.AsRegisterPairHigh<Register>());
break;
- case Primitive::kPrimFloat:
- DCHECK(!in.Equals(out));
- // out = 0
- __ xorps(out.As<XmmRegister>(), out.As<XmmRegister>());
- // out = out - in
- __ subss(out.As<XmmRegister>(), in.As<XmmRegister>());
+ case Primitive::kPrimFloat: {
+ DCHECK(in.Equals(out));
+ Register constant = locations->GetTemp(0).AsRegister<Register>();
+ XmmRegister mask = locations->GetTemp(1).AsFpuRegister<XmmRegister>();
+ // Implement float negation with an exclusive or with value
+ // 0x80000000 (mask for bit 31, representing the sign of a
+ // single-precision floating-point number).
+ __ movl(constant, Immediate(INT32_C(0x80000000)));
+ __ movd(mask, constant);
+ __ xorps(out.AsFpuRegister<XmmRegister>(), mask);
break;
+ }
- case Primitive::kPrimDouble:
- DCHECK(!in.Equals(out));
- // out = 0
- __ xorpd(out.As<XmmRegister>(), out.As<XmmRegister>());
- // out = out - in
- __ subsd(out.As<XmmRegister>(), in.As<XmmRegister>());
+ case Primitive::kPrimDouble: {
+ DCHECK(in.Equals(out));
+ XmmRegister mask = locations->GetTemp(0).AsFpuRegister<XmmRegister>();
+ // Implement double negation with an exclusive or with value
+ // 0x8000000000000000 (mask for bit 63, representing the sign of
+ // a double-precision floating-point number).
+ __ LoadLongConstant(mask, INT64_C(0x8000000000000000));
+ __ xorpd(out.AsFpuRegister<XmmRegister>(), mask);
break;
+ }
default:
LOG(FATAL) << "Unexpected neg type " << neg->GetResultType();
@@ -1299,6 +1330,7 @@ void LocationsBuilderX86::VisitTypeConversion(HTypeConversion* conversion) {
new (GetGraph()->GetArena()) LocationSummary(conversion, LocationSummary::kNoCall);
Primitive::Type result_type = conversion->GetResultType();
Primitive::Type input_type = conversion->GetInputType();
+ DCHECK_NE(result_type, input_type);
switch (result_type) {
case Primitive::kPrimByte:
switch (input_type) {
@@ -1380,7 +1412,6 @@ void LocationsBuilderX86::VisitTypeConversion(HTypeConversion* conversion) {
case Primitive::kPrimByte:
case Primitive::kPrimShort:
case Primitive::kPrimInt:
- case Primitive::kPrimChar:
// Processing a Dex `int-to-char' instruction.
locations->SetInAt(0, Location::Any());
locations->SetOut(Location::RequiresRegister(), Location::kNoOutputOverlap);
@@ -1404,6 +1435,13 @@ void LocationsBuilderX86::VisitTypeConversion(HTypeConversion* conversion) {
break;
case Primitive::kPrimLong:
+ // Processing a Dex `long-to-float' instruction.
+ locations->SetInAt(0, Location::RequiresRegister());
+ locations->SetOut(Location::RequiresFpuRegister());
+ locations->AddTemp(Location::RequiresFpuRegister());
+ locations->AddTemp(Location::RequiresFpuRegister());
+ break;
+
case Primitive::kPrimDouble:
LOG(FATAL) << "Type conversion from " << input_type
<< " to " << result_type << " not yet implemented";
@@ -1427,6 +1465,13 @@ void LocationsBuilderX86::VisitTypeConversion(HTypeConversion* conversion) {
break;
case Primitive::kPrimLong:
+ // Processing a Dex `long-to-double' instruction.
+ locations->SetInAt(0, Location::RequiresRegister());
+ locations->SetOut(Location::RequiresFpuRegister());
+ locations->AddTemp(Location::RequiresFpuRegister());
+ locations->AddTemp(Location::RequiresFpuRegister());
+ break;
+
case Primitive::kPrimFloat:
LOG(FATAL) << "Type conversion from " << input_type
<< " to " << result_type << " not yet implemented";
@@ -1450,6 +1495,7 @@ void InstructionCodeGeneratorX86::VisitTypeConversion(HTypeConversion* conversio
Location in = locations->InAt(0);
Primitive::Type result_type = conversion->GetResultType();
Primitive::Type input_type = conversion->GetInputType();
+ DCHECK_NE(result_type, input_type);
switch (result_type) {
case Primitive::kPrimByte:
switch (input_type) {
@@ -1458,13 +1504,13 @@ void InstructionCodeGeneratorX86::VisitTypeConversion(HTypeConversion* conversio
case Primitive::kPrimChar:
// Processing a Dex `int-to-byte' instruction.
if (in.IsRegister()) {
- __ movsxb(out.As<Register>(), in.As<ByteRegister>());
+ __ movsxb(out.AsRegister<Register>(), in.AsRegister<ByteRegister>());
} else if (in.IsStackSlot()) {
- __ movsxb(out.As<Register>(), Address(ESP, in.GetStackIndex()));
+ __ movsxb(out.AsRegister<Register>(), Address(ESP, in.GetStackIndex()));
} else {
DCHECK(in.GetConstant()->IsIntConstant());
int32_t value = in.GetConstant()->AsIntConstant()->GetValue();
- __ movl(out.As<Register>(), Immediate(static_cast<int8_t>(value)));
+ __ movl(out.AsRegister<Register>(), Immediate(static_cast<int8_t>(value)));
}
break;
@@ -1481,13 +1527,13 @@ void InstructionCodeGeneratorX86::VisitTypeConversion(HTypeConversion* conversio
case Primitive::kPrimChar:
// Processing a Dex `int-to-short' instruction.
if (in.IsRegister()) {
- __ movsxw(out.As<Register>(), in.As<Register>());
+ __ movsxw(out.AsRegister<Register>(), in.AsRegister<Register>());
} else if (in.IsStackSlot()) {
- __ movsxw(out.As<Register>(), Address(ESP, in.GetStackIndex()));
+ __ movsxw(out.AsRegister<Register>(), Address(ESP, in.GetStackIndex()));
} else {
DCHECK(in.GetConstant()->IsIntConstant());
int32_t value = in.GetConstant()->AsIntConstant()->GetValue();
- __ movl(out.As<Register>(), Immediate(static_cast<int16_t>(value)));
+ __ movl(out.AsRegister<Register>(), Immediate(static_cast<int16_t>(value)));
}
break;
@@ -1502,14 +1548,14 @@ void InstructionCodeGeneratorX86::VisitTypeConversion(HTypeConversion* conversio
case Primitive::kPrimLong:
// Processing a Dex `long-to-int' instruction.
if (in.IsRegisterPair()) {
- __ movl(out.As<Register>(), in.AsRegisterPairLow<Register>());
+ __ movl(out.AsRegister<Register>(), in.AsRegisterPairLow<Register>());
} else if (in.IsDoubleStackSlot()) {
- __ movl(out.As<Register>(), Address(ESP, in.GetStackIndex()));
+ __ movl(out.AsRegister<Register>(), Address(ESP, in.GetStackIndex()));
} else {
DCHECK(in.IsConstant());
DCHECK(in.GetConstant()->IsLongConstant());
int64_t value = in.GetConstant()->AsLongConstant()->GetValue();
- __ movl(out.As<Register>(), Immediate(static_cast<int32_t>(value)));
+ __ movl(out.AsRegister<Register>(), Immediate(static_cast<int32_t>(value)));
}
break;
@@ -1534,7 +1580,7 @@ void InstructionCodeGeneratorX86::VisitTypeConversion(HTypeConversion* conversio
// Processing a Dex `int-to-long' instruction.
DCHECK_EQ(out.AsRegisterPairLow<Register>(), EAX);
DCHECK_EQ(out.AsRegisterPairHigh<Register>(), EDX);
- DCHECK_EQ(in.As<Register>(), EAX);
+ DCHECK_EQ(in.AsRegister<Register>(), EAX);
__ cdq();
break;
@@ -1555,16 +1601,15 @@ void InstructionCodeGeneratorX86::VisitTypeConversion(HTypeConversion* conversio
case Primitive::kPrimByte:
case Primitive::kPrimShort:
case Primitive::kPrimInt:
- case Primitive::kPrimChar:
// Processing a Dex `Process a Dex `int-to-char'' instruction.
if (in.IsRegister()) {
- __ movzxw(out.As<Register>(), in.As<Register>());
+ __ movzxw(out.AsRegister<Register>(), in.AsRegister<Register>());
} else if (in.IsStackSlot()) {
- __ movzxw(out.As<Register>(), Address(ESP, in.GetStackIndex()));
+ __ movzxw(out.AsRegister<Register>(), Address(ESP, in.GetStackIndex()));
} else {
DCHECK(in.GetConstant()->IsIntConstant());
int32_t value = in.GetConstant()->AsIntConstant()->GetValue();
- __ movl(out.As<Register>(), Immediate(static_cast<uint16_t>(value)));
+ __ movl(out.AsRegister<Register>(), Immediate(static_cast<uint16_t>(value)));
}
break;
@@ -1576,15 +1621,48 @@ void InstructionCodeGeneratorX86::VisitTypeConversion(HTypeConversion* conversio
case Primitive::kPrimFloat:
switch (input_type) {
- // Processing a Dex `int-to-float' instruction.
case Primitive::kPrimByte:
case Primitive::kPrimShort:
case Primitive::kPrimInt:
case Primitive::kPrimChar:
- __ cvtsi2ss(out.As<XmmRegister>(), in.As<Register>());
+ // Processing a Dex `int-to-float' instruction.
+ __ cvtsi2ss(out.AsFpuRegister<XmmRegister>(), in.AsRegister<Register>());
break;
- case Primitive::kPrimLong:
+ case Primitive::kPrimLong: {
+ // Processing a Dex `long-to-float' instruction.
+ Register low = in.AsRegisterPairLow<Register>();
+ Register high = in.AsRegisterPairHigh<Register>();
+ XmmRegister result = out.AsFpuRegister<XmmRegister>();
+ XmmRegister temp = locations->GetTemp(0).AsFpuRegister<XmmRegister>();
+ XmmRegister constant = locations->GetTemp(1).AsFpuRegister<XmmRegister>();
+
+ // Operations use doubles for precision reasons (each 32-bit
+ // half of a long fits in the 53-bit mantissa of a double,
+ // but not in the 24-bit mantissa of a float). This is
+ // especially important for the low bits. The result is
+ // eventually converted to float.
+
+ // low = low - 2^31 (to prevent bit 31 of `low` to be
+ // interpreted as a sign bit)
+ __ subl(low, Immediate(0x80000000));
+ // temp = int-to-double(high)
+ __ cvtsi2sd(temp, high);
+ // temp = temp * 2^32
+ __ LoadLongConstant(constant, k2Pow32EncodingForDouble);
+ __ mulsd(temp, constant);
+ // result = int-to-double(low)
+ __ cvtsi2sd(result, low);
+ // result = result + 2^31 (restore the original value of `low`)
+ __ LoadLongConstant(constant, k2Pow31EncodingForDouble);
+ __ addsd(result, constant);
+ // result = result + temp
+ __ addsd(result, temp);
+ // result = double-to-float(result)
+ __ cvtsd2ss(result, result);
+ break;
+ }
+
case Primitive::kPrimDouble:
LOG(FATAL) << "Type conversion from " << input_type
<< " to " << result_type << " not yet implemented";
@@ -1598,15 +1676,40 @@ void InstructionCodeGeneratorX86::VisitTypeConversion(HTypeConversion* conversio
case Primitive::kPrimDouble:
switch (input_type) {
- // Processing a Dex `int-to-double' instruction.
case Primitive::kPrimByte:
case Primitive::kPrimShort:
case Primitive::kPrimInt:
case Primitive::kPrimChar:
- __ cvtsi2sd(out.As<XmmRegister>(), in.As<Register>());
+ // Processing a Dex `int-to-double' instruction.
+ __ cvtsi2sd(out.AsFpuRegister<XmmRegister>(), in.AsRegister<Register>());
break;
- case Primitive::kPrimLong:
+ case Primitive::kPrimLong: {
+ // Processing a Dex `long-to-double' instruction.
+ Register low = in.AsRegisterPairLow<Register>();
+ Register high = in.AsRegisterPairHigh<Register>();
+ XmmRegister result = out.AsFpuRegister<XmmRegister>();
+ XmmRegister temp = locations->GetTemp(0).AsFpuRegister<XmmRegister>();
+ XmmRegister constant = locations->GetTemp(1).AsFpuRegister<XmmRegister>();
+
+ // low = low - 2^31 (to prevent bit 31 of `low` to be
+ // interpreted as a sign bit)
+ __ subl(low, Immediate(0x80000000));
+ // temp = int-to-double(high)
+ __ cvtsi2sd(temp, high);
+ // temp = temp * 2^32
+ __ LoadLongConstant(constant, k2Pow32EncodingForDouble);
+ __ mulsd(temp, constant);
+ // result = int-to-double(low)
+ __ cvtsi2sd(result, low);
+ // result = result + 2^31 (restore the original value of `low`)
+ __ LoadLongConstant(constant, k2Pow31EncodingForDouble);
+ __ addsd(result, constant);
+ // result = result + temp
+ __ addsd(result, temp);
+ break;
+ }
+
case Primitive::kPrimFloat:
LOG(FATAL) << "Type conversion from " << input_type
<< " to " << result_type << " not yet implemented";
@@ -1658,11 +1761,12 @@ void InstructionCodeGeneratorX86::VisitAdd(HAdd* add) {
switch (add->GetResultType()) {
case Primitive::kPrimInt: {
if (second.IsRegister()) {
- __ addl(first.As<Register>(), second.As<Register>());
+ __ addl(first.AsRegister<Register>(), second.AsRegister<Register>());
} else if (second.IsConstant()) {
- __ addl(first.As<Register>(), Immediate(second.GetConstant()->AsIntConstant()->GetValue()));
+ __ addl(first.AsRegister<Register>(),
+ Immediate(second.GetConstant()->AsIntConstant()->GetValue()));
} else {
- __ addl(first.As<Register>(), Address(ESP, second.GetStackIndex()));
+ __ addl(first.AsRegister<Register>(), Address(ESP, second.GetStackIndex()));
}
break;
}
@@ -1681,18 +1785,18 @@ void InstructionCodeGeneratorX86::VisitAdd(HAdd* add) {
case Primitive::kPrimFloat: {
if (second.IsFpuRegister()) {
- __ addss(first.As<XmmRegister>(), second.As<XmmRegister>());
+ __ addss(first.AsFpuRegister<XmmRegister>(), second.AsFpuRegister<XmmRegister>());
} else {
- __ addss(first.As<XmmRegister>(), Address(ESP, second.GetStackIndex()));
+ __ addss(first.AsFpuRegister<XmmRegister>(), Address(ESP, second.GetStackIndex()));
}
break;
}
case Primitive::kPrimDouble: {
if (second.IsFpuRegister()) {
- __ addsd(first.As<XmmRegister>(), second.As<XmmRegister>());
+ __ addsd(first.AsFpuRegister<XmmRegister>(), second.AsFpuRegister<XmmRegister>());
} else {
- __ addsd(first.As<XmmRegister>(), Address(ESP, second.GetStackIndex()));
+ __ addsd(first.AsFpuRegister<XmmRegister>(), Address(ESP, second.GetStackIndex()));
}
break;
}
@@ -1734,11 +1838,12 @@ void InstructionCodeGeneratorX86::VisitSub(HSub* sub) {
switch (sub->GetResultType()) {
case Primitive::kPrimInt: {
if (second.IsRegister()) {
- __ subl(first.As<Register>(), second.As<Register>());
+ __ subl(first.AsRegister<Register>(), second.AsRegister<Register>());
} else if (second.IsConstant()) {
- __ subl(first.As<Register>(), Immediate(second.GetConstant()->AsIntConstant()->GetValue()));
+ __ subl(first.AsRegister<Register>(),
+ Immediate(second.GetConstant()->AsIntConstant()->GetValue()));
} else {
- __ subl(first.As<Register>(), Address(ESP, second.GetStackIndex()));
+ __ subl(first.AsRegister<Register>(), Address(ESP, second.GetStackIndex()));
}
break;
}
@@ -1756,12 +1861,12 @@ void InstructionCodeGeneratorX86::VisitSub(HSub* sub) {
}
case Primitive::kPrimFloat: {
- __ subss(first.As<XmmRegister>(), second.As<XmmRegister>());
+ __ subss(first.AsFpuRegister<XmmRegister>(), second.AsFpuRegister<XmmRegister>());
break;
}
case Primitive::kPrimDouble: {
- __ subsd(first.As<XmmRegister>(), second.As<XmmRegister>());
+ __ subsd(first.AsFpuRegister<XmmRegister>(), second.AsFpuRegister<XmmRegister>());
break;
}
@@ -1816,13 +1921,13 @@ void InstructionCodeGeneratorX86::VisitMul(HMul* mul) {
switch (mul->GetResultType()) {
case Primitive::kPrimInt: {
if (second.IsRegister()) {
- __ imull(first.As<Register>(), second.As<Register>());
+ __ imull(first.AsRegister<Register>(), second.AsRegister<Register>());
} else if (second.IsConstant()) {
Immediate imm(second.GetConstant()->AsIntConstant()->GetValue());
- __ imull(first.As<Register>(), imm);
+ __ imull(first.AsRegister<Register>(), imm);
} else {
DCHECK(second.IsStackSlot());
- __ imull(first.As<Register>(), Address(ESP, second.GetStackIndex()));
+ __ imull(first.AsRegister<Register>(), Address(ESP, second.GetStackIndex()));
}
break;
}
@@ -1834,8 +1939,8 @@ void InstructionCodeGeneratorX86::VisitMul(HMul* mul) {
Register in1_lo = first.AsRegisterPairLow<Register>();
Address in2_hi(ESP, second.GetHighStackIndex(kX86WordSize));
Address in2_lo(ESP, second.GetStackIndex());
- Register eax = locations->GetTemp(0).As<Register>();
- Register edx = locations->GetTemp(1).As<Register>();
+ Register eax = locations->GetTemp(0).AsRegister<Register>();
+ Register edx = locations->GetTemp(1).AsRegister<Register>();
DCHECK_EQ(EAX, eax);
DCHECK_EQ(EDX, edx);
@@ -1866,12 +1971,12 @@ void InstructionCodeGeneratorX86::VisitMul(HMul* mul) {
}
case Primitive::kPrimFloat: {
- __ mulss(first.As<XmmRegister>(), second.As<XmmRegister>());
+ __ mulss(first.AsFpuRegister<XmmRegister>(), second.AsFpuRegister<XmmRegister>());
break;
}
case Primitive::kPrimDouble: {
- __ mulsd(first.As<XmmRegister>(), second.As<XmmRegister>());
+ __ mulsd(first.AsFpuRegister<XmmRegister>(), second.AsFpuRegister<XmmRegister>());
break;
}
@@ -1891,12 +1996,13 @@ void InstructionCodeGeneratorX86::GenerateDivRemIntegral(HBinaryOperation* instr
switch (instruction->GetResultType()) {
case Primitive::kPrimInt: {
- Register second_reg = second.As<Register>();
- DCHECK_EQ(EAX, first.As<Register>());
- DCHECK_EQ(is_div ? EAX : EDX, out.As<Register>());
+ Register second_reg = second.AsRegister<Register>();
+ DCHECK_EQ(EAX, first.AsRegister<Register>());
+ DCHECK_EQ(is_div ? EAX : EDX, out.AsRegister<Register>());
SlowPathCodeX86* slow_path =
- new (GetGraph()->GetArena()) DivRemMinusOneSlowPathX86(out.As<Register>(), is_div);
+ new (GetGraph()->GetArena()) DivRemMinusOneSlowPathX86(out.AsRegister<Register>(),
+ is_div);
codegen_->AddSlowPath(slow_path);
// 0x80000000/-1 triggers an arithmetic exception!
@@ -1995,13 +2101,13 @@ void InstructionCodeGeneratorX86::VisitDiv(HDiv* div) {
case Primitive::kPrimFloat: {
DCHECK(first.Equals(out));
- __ divss(first.As<XmmRegister>(), second.As<XmmRegister>());
+ __ divss(first.AsFpuRegister<XmmRegister>(), second.AsFpuRegister<XmmRegister>());
break;
}
case Primitive::kPrimDouble: {
DCHECK(first.Equals(out));
- __ divsd(first.As<XmmRegister>(), second.As<XmmRegister>());
+ __ divsd(first.AsFpuRegister<XmmRegister>(), second.AsFpuRegister<XmmRegister>());
break;
}
@@ -2095,7 +2201,7 @@ void InstructionCodeGeneratorX86::VisitDivZeroCheck(HDivZeroCheck* instruction)
switch (instruction->GetType()) {
case Primitive::kPrimInt: {
if (value.IsRegister()) {
- __ testl(value.As<Register>(), value.As<Register>());
+ __ testl(value.AsRegister<Register>(), value.AsRegister<Register>());
__ j(kEqual, slow_path->GetEntryLabel());
} else if (value.IsStackSlot()) {
__ cmpl(Address(ESP, value.GetStackIndex()), Immediate(0));
@@ -2110,7 +2216,7 @@ void InstructionCodeGeneratorX86::VisitDivZeroCheck(HDivZeroCheck* instruction)
}
case Primitive::kPrimLong: {
if (value.IsRegisterPair()) {
- Register temp = locations->GetTemp(0).As<Register>();
+ Register temp = locations->GetTemp(0).AsRegister<Register>();
__ movl(temp, value.AsRegisterPairLow<Register>());
__ orl(temp, value.AsRegisterPairHigh<Register>());
__ j(kEqual, slow_path->GetEntryLabel());
@@ -2127,6 +2233,139 @@ void InstructionCodeGeneratorX86::VisitDivZeroCheck(HDivZeroCheck* instruction)
}
}
+void LocationsBuilderX86::HandleShift(HBinaryOperation* op) {
+ DCHECK(op->IsShl() || op->IsShr() || op->IsUShr());
+
+ LocationSummary* locations =
+ new (GetGraph()->GetArena()) LocationSummary(op, LocationSummary::kNoCall);
+
+ switch (op->GetResultType()) {
+ case Primitive::kPrimInt: {
+ locations->SetInAt(0, Location::RequiresRegister());
+ // 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();
+ }
+}
+
+void InstructionCodeGeneratorX86::HandleShift(HBinaryOperation* op) {
+ DCHECK(op->IsShl() || op->IsShr() || op->IsUShr());
+
+ LocationSummary* locations = op->GetLocations();
+ Location first = locations->InAt(0);
+ Location second = locations->InAt(1);
+ DCHECK(first.Equals(locations->Out()));
+
+ switch (op->GetResultType()) {
+ case Primitive::kPrimInt: {
+ Register first_reg = first.AsRegister<Register>();
+ if (second.IsRegister()) {
+ Register second_reg = second.AsRegister<Register>();
+ DCHECK_EQ(ECX, second_reg);
+ if (op->IsShl()) {
+ __ shll(first_reg, second_reg);
+ } else if (op->IsShr()) {
+ __ sarl(first_reg, second_reg);
+ } else {
+ __ shrl(first_reg, second_reg);
+ }
+ } else {
+ Immediate imm(second.GetConstant()->AsIntConstant()->GetValue());
+ if (op->IsShl()) {
+ __ shll(first_reg, imm);
+ } else if (op->IsShr()) {
+ __ sarl(first_reg, imm);
+ } else {
+ __ shrl(first_reg, imm);
+ }
+ }
+ break;
+ }
+ case Primitive::kPrimLong: {
+ 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);
+ }
+ break;
+ }
+ default:
+ LOG(FATAL) << "Unexpected op type " << op->GetResultType();
+ }
+}
+
+void InstructionCodeGeneratorX86::GenerateShlLong(const Location& loc, Register shifter) {
+ Label done;
+ __ shld(loc.AsRegisterPairHigh<Register>(), loc.AsRegisterPairLow<Register>(), shifter);
+ __ shll(loc.AsRegisterPairLow<Register>(), shifter);
+ __ testl(shifter, Immediate(32));
+ __ j(kEqual, &done);
+ __ movl(loc.AsRegisterPairHigh<Register>(), loc.AsRegisterPairLow<Register>());
+ __ movl(loc.AsRegisterPairLow<Register>(), Immediate(0));
+ __ Bind(&done);
+}
+
+void InstructionCodeGeneratorX86::GenerateShrLong(const Location& loc, Register shifter) {
+ Label done;
+ __ shrd(loc.AsRegisterPairLow<Register>(), loc.AsRegisterPairHigh<Register>(), shifter);
+ __ sarl(loc.AsRegisterPairHigh<Register>(), shifter);
+ __ testl(shifter, Immediate(32));
+ __ j(kEqual, &done);
+ __ movl(loc.AsRegisterPairLow<Register>(), loc.AsRegisterPairHigh<Register>());
+ __ sarl(loc.AsRegisterPairHigh<Register>(), Immediate(31));
+ __ Bind(&done);
+}
+
+void InstructionCodeGeneratorX86::GenerateUShrLong(const Location& loc, Register shifter) {
+ Label done;
+ __ shrd(loc.AsRegisterPairLow<Register>(), loc.AsRegisterPairHigh<Register>(), shifter);
+ __ shrl(loc.AsRegisterPairHigh<Register>(), shifter);
+ __ testl(shifter, Immediate(32));
+ __ j(kEqual, &done);
+ __ movl(loc.AsRegisterPairLow<Register>(), loc.AsRegisterPairHigh<Register>());
+ __ movl(loc.AsRegisterPairHigh<Register>(), Immediate(0));
+ __ Bind(&done);
+}
+
+void LocationsBuilderX86::VisitShl(HShl* shl) {
+ HandleShift(shl);
+}
+
+void InstructionCodeGeneratorX86::VisitShl(HShl* shl) {
+ HandleShift(shl);
+}
+
+void LocationsBuilderX86::VisitShr(HShr* shr) {
+ HandleShift(shr);
+}
+
+void InstructionCodeGeneratorX86::VisitShr(HShr* shr) {
+ HandleShift(shr);
+}
+
+void LocationsBuilderX86::VisitUShr(HUShr* ushr) {
+ HandleShift(ushr);
+}
+
+void InstructionCodeGeneratorX86::VisitUShr(HUShr* ushr) {
+ HandleShift(ushr);
+}
+
void LocationsBuilderX86::VisitNewInstance(HNewInstance* instruction) {
LocationSummary* locations =
new (GetGraph()->GetArena()) LocationSummary(instruction, LocationSummary::kCall);
@@ -2200,11 +2439,11 @@ void InstructionCodeGeneratorX86::VisitNot(HNot* not_) {
DCHECK(in.Equals(out));
switch (not_->InputAt(0)->GetType()) {
case Primitive::kPrimBoolean:
- __ xorl(out.As<Register>(), Immediate(1));
+ __ xorl(out.AsRegister<Register>(), Immediate(1));
break;
case Primitive::kPrimInt:
- __ notl(out.As<Register>());
+ __ notl(out.AsRegister<Register>());
break;
case Primitive::kPrimLong:
@@ -2220,20 +2459,36 @@ void InstructionCodeGeneratorX86::VisitNot(HNot* not_) {
void LocationsBuilderX86::VisitCompare(HCompare* compare) {
LocationSummary* locations =
new (GetGraph()->GetArena()) LocationSummary(compare, LocationSummary::kNoCall);
- locations->SetInAt(0, Location::RequiresRegister());
- locations->SetInAt(1, Location::Any());
- locations->SetOut(Location::RequiresRegister(), Location::kNoOutputOverlap);
+ switch (compare->InputAt(0)->GetType()) {
+ case Primitive::kPrimLong: {
+ locations->SetInAt(0, Location::RequiresRegister());
+ // TODO: we set any here but we don't handle constants
+ locations->SetInAt(1, Location::Any());
+ locations->SetOut(Location::RequiresRegister(), Location::kNoOutputOverlap);
+ break;
+ }
+ case Primitive::kPrimFloat:
+ case Primitive::kPrimDouble: {
+ locations->SetInAt(0, Location::RequiresFpuRegister());
+ locations->SetInAt(1, Location::RequiresFpuRegister());
+ locations->SetOut(Location::RequiresRegister());
+ break;
+ }
+ default:
+ LOG(FATAL) << "Unexpected type for compare operation " << compare->InputAt(0)->GetType();
+ }
}
void InstructionCodeGeneratorX86::VisitCompare(HCompare* compare) {
LocationSummary* locations = compare->GetLocations();
+ Register out = locations->Out().AsRegister<Register>();
+ Location left = locations->InAt(0);
+ Location right = locations->InAt(1);
+
+ Label less, greater, done;
switch (compare->InputAt(0)->GetType()) {
case Primitive::kPrimLong: {
- Label less, greater, done;
- Register output = locations->Out().As<Register>();
- Location left = locations->InAt(0);
- Location right = locations->InAt(1);
- if (right.IsRegister()) {
+ if (right.IsRegisterPair()) {
__ cmpl(left.AsRegisterPairHigh<Register>(), right.AsRegisterPairHigh<Register>());
} else {
DCHECK(right.IsDoubleStackSlot());
@@ -2248,23 +2503,33 @@ void InstructionCodeGeneratorX86::VisitCompare(HCompare* compare) {
DCHECK(right.IsDoubleStackSlot());
__ cmpl(left.AsRegisterPairLow<Register>(), Address(ESP, right.GetStackIndex()));
}
- __ movl(output, Immediate(0));
- __ j(kEqual, &done);
- __ j(kBelow, &less); // Unsigned compare.
-
- __ Bind(&greater);
- __ movl(output, Immediate(1));
- __ jmp(&done);
-
- __ Bind(&less);
- __ movl(output, Immediate(-1));
-
- __ Bind(&done);
+ break;
+ }
+ case Primitive::kPrimFloat: {
+ __ ucomiss(left.AsFpuRegister<XmmRegister>(), right.AsFpuRegister<XmmRegister>());
+ __ j(kUnordered, compare->IsGtBias() ? &greater : &less);
+ break;
+ }
+ case Primitive::kPrimDouble: {
+ __ ucomisd(left.AsFpuRegister<XmmRegister>(), right.AsFpuRegister<XmmRegister>());
+ __ j(kUnordered, compare->IsGtBias() ? &greater : &less);
break;
}
default:
- LOG(FATAL) << "Unimplemented compare type " << compare->InputAt(0)->GetType();
+ LOG(FATAL) << "Unexpected type for compare operation " << compare->InputAt(0)->GetType();
}
+ __ movl(out, Immediate(0));
+ __ j(kEqual, &done);
+ __ j(kBelow, &less); // kBelow is for CF (unsigned & floats).
+
+ __ Bind(&greater);
+ __ movl(out, Immediate(1));
+ __ jmp(&done);
+
+ __ Bind(&less);
+ __ movl(out, Immediate(-1));
+
+ __ Bind(&done);
}
void LocationsBuilderX86::VisitPhi(HPhi* instruction) {
@@ -2309,33 +2574,33 @@ void LocationsBuilderX86::VisitInstanceFieldSet(HInstanceFieldSet* instruction)
void InstructionCodeGeneratorX86::VisitInstanceFieldSet(HInstanceFieldSet* instruction) {
LocationSummary* locations = instruction->GetLocations();
- Register obj = locations->InAt(0).As<Register>();
+ Register obj = locations->InAt(0).AsRegister<Register>();
uint32_t offset = instruction->GetFieldOffset().Uint32Value();
Primitive::Type field_type = instruction->GetFieldType();
switch (field_type) {
case Primitive::kPrimBoolean:
case Primitive::kPrimByte: {
- ByteRegister value = locations->InAt(1).As<ByteRegister>();
+ ByteRegister value = locations->InAt(1).AsRegister<ByteRegister>();
__ movb(Address(obj, offset), value);
break;
}
case Primitive::kPrimShort:
case Primitive::kPrimChar: {
- Register value = locations->InAt(1).As<Register>();
+ Register value = locations->InAt(1).AsRegister<Register>();
__ movw(Address(obj, offset), value);
break;
}
case Primitive::kPrimInt:
case Primitive::kPrimNot: {
- Register value = locations->InAt(1).As<Register>();
+ Register value = locations->InAt(1).AsRegister<Register>();
__ movl(Address(obj, offset), value);
if (CodeGenerator::StoreNeedsWriteBarrier(field_type, instruction->InputAt(1))) {
- Register temp = locations->GetTemp(0).As<Register>();
- Register card = locations->GetTemp(1).As<Register>();
+ Register temp = locations->GetTemp(0).AsRegister<Register>();
+ Register card = locations->GetTemp(1).AsRegister<Register>();
codegen_->MarkGCCard(temp, card, obj, value);
}
break;
@@ -2349,13 +2614,13 @@ void InstructionCodeGeneratorX86::VisitInstanceFieldSet(HInstanceFieldSet* instr
}
case Primitive::kPrimFloat: {
- XmmRegister value = locations->InAt(1).As<XmmRegister>();
+ XmmRegister value = locations->InAt(1).AsFpuRegister<XmmRegister>();
__ movss(Address(obj, offset), value);
break;
}
case Primitive::kPrimDouble: {
- XmmRegister value = locations->InAt(1).As<XmmRegister>();
+ XmmRegister value = locations->InAt(1).AsFpuRegister<XmmRegister>();
__ movsd(Address(obj, offset), value);
break;
}
@@ -2387,37 +2652,37 @@ void LocationsBuilderX86::VisitInstanceFieldGet(HInstanceFieldGet* instruction)
void InstructionCodeGeneratorX86::VisitInstanceFieldGet(HInstanceFieldGet* instruction) {
LocationSummary* locations = instruction->GetLocations();
- Register obj = locations->InAt(0).As<Register>();
+ Register obj = locations->InAt(0).AsRegister<Register>();
uint32_t offset = instruction->GetFieldOffset().Uint32Value();
switch (instruction->GetType()) {
case Primitive::kPrimBoolean: {
- Register out = locations->Out().As<Register>();
+ Register out = locations->Out().AsRegister<Register>();
__ movzxb(out, Address(obj, offset));
break;
}
case Primitive::kPrimByte: {
- Register out = locations->Out().As<Register>();
+ Register out = locations->Out().AsRegister<Register>();
__ movsxb(out, Address(obj, offset));
break;
}
case Primitive::kPrimShort: {
- Register out = locations->Out().As<Register>();
+ Register out = locations->Out().AsRegister<Register>();
__ movsxw(out, Address(obj, offset));
break;
}
case Primitive::kPrimChar: {
- Register out = locations->Out().As<Register>();
+ Register out = locations->Out().AsRegister<Register>();
__ movzxw(out, Address(obj, offset));
break;
}
case Primitive::kPrimInt:
case Primitive::kPrimNot: {
- Register out = locations->Out().As<Register>();
+ Register out = locations->Out().AsRegister<Register>();
__ movl(out, Address(obj, offset));
break;
}
@@ -2430,13 +2695,13 @@ void InstructionCodeGeneratorX86::VisitInstanceFieldGet(HInstanceFieldGet* instr
}
case Primitive::kPrimFloat: {
- XmmRegister out = locations->Out().As<XmmRegister>();
+ XmmRegister out = locations->Out().AsFpuRegister<XmmRegister>();
__ movss(out, Address(obj, offset));
break;
}
case Primitive::kPrimDouble: {
- XmmRegister out = locations->Out().As<XmmRegister>();
+ XmmRegister out = locations->Out().AsFpuRegister<XmmRegister>();
__ movsd(out, Address(obj, offset));
break;
}
@@ -2464,7 +2729,7 @@ void InstructionCodeGeneratorX86::VisitNullCheck(HNullCheck* instruction) {
Location obj = locations->InAt(0);
if (obj.IsRegister()) {
- __ cmpl(obj.As<Register>(), Immediate(0));
+ __ cmpl(obj.AsRegister<Register>(), Immediate(0));
} else if (obj.IsStackSlot()) {
__ cmpl(Address(ESP, obj.GetStackIndex()), Immediate(0));
} else {
@@ -2486,54 +2751,54 @@ void LocationsBuilderX86::VisitArrayGet(HArrayGet* instruction) {
void InstructionCodeGeneratorX86::VisitArrayGet(HArrayGet* instruction) {
LocationSummary* locations = instruction->GetLocations();
- Register obj = locations->InAt(0).As<Register>();
+ Register obj = locations->InAt(0).AsRegister<Register>();
Location index = locations->InAt(1);
switch (instruction->GetType()) {
case Primitive::kPrimBoolean: {
uint32_t data_offset = mirror::Array::DataOffset(sizeof(uint8_t)).Uint32Value();
- Register out = locations->Out().As<Register>();
+ Register out = locations->Out().AsRegister<Register>();
if (index.IsConstant()) {
__ movzxb(out, Address(obj,
(index.GetConstant()->AsIntConstant()->GetValue() << TIMES_1) + data_offset));
} else {
- __ movzxb(out, Address(obj, index.As<Register>(), TIMES_1, data_offset));
+ __ movzxb(out, Address(obj, index.AsRegister<Register>(), TIMES_1, data_offset));
}
break;
}
case Primitive::kPrimByte: {
uint32_t data_offset = mirror::Array::DataOffset(sizeof(int8_t)).Uint32Value();
- Register out = locations->Out().As<Register>();
+ Register out = locations->Out().AsRegister<Register>();
if (index.IsConstant()) {
__ movsxb(out, Address(obj,
(index.GetConstant()->AsIntConstant()->GetValue() << TIMES_1) + data_offset));
} else {
- __ movsxb(out, Address(obj, index.As<Register>(), TIMES_1, data_offset));
+ __ movsxb(out, Address(obj, index.AsRegister<Register>(), TIMES_1, data_offset));
}
break;
}
case Primitive::kPrimShort: {
uint32_t data_offset = mirror::Array::DataOffset(sizeof(int16_t)).Uint32Value();
- Register out = locations->Out().As<Register>();
+ Register out = locations->Out().AsRegister<Register>();
if (index.IsConstant()) {
__ movsxw(out, Address(obj,
(index.GetConstant()->AsIntConstant()->GetValue() << TIMES_2) + data_offset));
} else {
- __ movsxw(out, Address(obj, index.As<Register>(), TIMES_2, data_offset));
+ __ movsxw(out, Address(obj, index.AsRegister<Register>(), TIMES_2, data_offset));
}
break;
}
case Primitive::kPrimChar: {
uint32_t data_offset = mirror::Array::DataOffset(sizeof(uint16_t)).Uint32Value();
- Register out = locations->Out().As<Register>();
+ Register out = locations->Out().AsRegister<Register>();
if (index.IsConstant()) {
__ movzxw(out, Address(obj,
(index.GetConstant()->AsIntConstant()->GetValue() << TIMES_2) + data_offset));
} else {
- __ movzxw(out, Address(obj, index.As<Register>(), TIMES_2, data_offset));
+ __ movzxw(out, Address(obj, index.AsRegister<Register>(), TIMES_2, data_offset));
}
break;
}
@@ -2541,12 +2806,12 @@ void InstructionCodeGeneratorX86::VisitArrayGet(HArrayGet* instruction) {
case Primitive::kPrimInt:
case Primitive::kPrimNot: {
uint32_t data_offset = mirror::Array::DataOffset(sizeof(int32_t)).Uint32Value();
- Register out = locations->Out().As<Register>();
+ Register out = locations->Out().AsRegister<Register>();
if (index.IsConstant()) {
__ movl(out, Address(obj,
(index.GetConstant()->AsIntConstant()->GetValue() << TIMES_4) + data_offset));
} else {
- __ movl(out, Address(obj, index.As<Register>(), TIMES_4, data_offset));
+ __ movl(out, Address(obj, index.AsRegister<Register>(), TIMES_4, data_offset));
}
break;
}
@@ -2560,9 +2825,9 @@ void InstructionCodeGeneratorX86::VisitArrayGet(HArrayGet* instruction) {
__ movl(out.AsRegisterPairHigh<Register>(), Address(obj, offset + kX86WordSize));
} else {
__ movl(out.AsRegisterPairLow<Register>(),
- Address(obj, index.As<Register>(), TIMES_8, data_offset));
+ Address(obj, index.AsRegister<Register>(), TIMES_8, data_offset));
__ movl(out.AsRegisterPairHigh<Register>(),
- Address(obj, index.As<Register>(), TIMES_8, data_offset + kX86WordSize));
+ Address(obj, index.AsRegister<Register>(), TIMES_8, data_offset + kX86WordSize));
}
break;
}
@@ -2622,7 +2887,7 @@ void LocationsBuilderX86::VisitArraySet(HArraySet* instruction) {
void InstructionCodeGeneratorX86::VisitArraySet(HArraySet* instruction) {
LocationSummary* locations = instruction->GetLocations();
- Register obj = locations->InAt(0).As<Register>();
+ Register obj = locations->InAt(0).AsRegister<Register>();
Location index = locations->InAt(1);
Location value = locations->InAt(2);
Primitive::Type value_type = instruction->GetComponentType();
@@ -2637,17 +2902,17 @@ void InstructionCodeGeneratorX86::VisitArraySet(HArraySet* instruction) {
if (index.IsConstant()) {
size_t offset = (index.GetConstant()->AsIntConstant()->GetValue() << TIMES_1) + data_offset;
if (value.IsRegister()) {
- __ movb(Address(obj, offset), value.As<ByteRegister>());
+ __ movb(Address(obj, offset), value.AsRegister<ByteRegister>());
} else {
__ movb(Address(obj, offset),
Immediate(value.GetConstant()->AsIntConstant()->GetValue()));
}
} else {
if (value.IsRegister()) {
- __ movb(Address(obj, index.As<Register>(), TIMES_1, data_offset),
- value.As<ByteRegister>());
+ __ movb(Address(obj, index.AsRegister<Register>(), TIMES_1, data_offset),
+ value.AsRegister<ByteRegister>());
} else {
- __ movb(Address(obj, index.As<Register>(), TIMES_1, data_offset),
+ __ movb(Address(obj, index.AsRegister<Register>(), TIMES_1, data_offset),
Immediate(value.GetConstant()->AsIntConstant()->GetValue()));
}
}
@@ -2660,17 +2925,17 @@ void InstructionCodeGeneratorX86::VisitArraySet(HArraySet* instruction) {
if (index.IsConstant()) {
size_t offset = (index.GetConstant()->AsIntConstant()->GetValue() << TIMES_2) + data_offset;
if (value.IsRegister()) {
- __ movw(Address(obj, offset), value.As<Register>());
+ __ movw(Address(obj, offset), value.AsRegister<Register>());
} else {
__ movw(Address(obj, offset),
Immediate(value.GetConstant()->AsIntConstant()->GetValue()));
}
} else {
if (value.IsRegister()) {
- __ movw(Address(obj, index.As<Register>(), TIMES_2, data_offset),
- value.As<Register>());
+ __ movw(Address(obj, index.AsRegister<Register>(), TIMES_2, data_offset),
+ value.AsRegister<Register>());
} else {
- __ movw(Address(obj, index.As<Register>(), TIMES_2, data_offset),
+ __ movw(Address(obj, index.AsRegister<Register>(), TIMES_2, data_offset),
Immediate(value.GetConstant()->AsIntConstant()->GetValue()));
}
}
@@ -2682,9 +2947,10 @@ void InstructionCodeGeneratorX86::VisitArraySet(HArraySet* instruction) {
if (!needs_runtime_call) {
uint32_t data_offset = mirror::Array::DataOffset(sizeof(int32_t)).Uint32Value();
if (index.IsConstant()) {
- size_t offset = (index.GetConstant()->AsIntConstant()->GetValue() << TIMES_4) + data_offset;
+ size_t offset =
+ (index.GetConstant()->AsIntConstant()->GetValue() << TIMES_4) + data_offset;
if (value.IsRegister()) {
- __ movl(Address(obj, offset), value.As<Register>());
+ __ movl(Address(obj, offset), value.AsRegister<Register>());
} else {
DCHECK(value.IsConstant()) << value;
__ movl(Address(obj, offset),
@@ -2693,19 +2959,19 @@ void InstructionCodeGeneratorX86::VisitArraySet(HArraySet* instruction) {
} else {
DCHECK(index.IsRegister()) << index;
if (value.IsRegister()) {
- __ movl(Address(obj, index.As<Register>(), TIMES_4, data_offset),
- value.As<Register>());
+ __ movl(Address(obj, index.AsRegister<Register>(), TIMES_4, data_offset),
+ value.AsRegister<Register>());
} else {
DCHECK(value.IsConstant()) << value;
- __ movl(Address(obj, index.As<Register>(), TIMES_4, data_offset),
+ __ movl(Address(obj, index.AsRegister<Register>(), TIMES_4, data_offset),
Immediate(value.GetConstant()->AsIntConstant()->GetValue()));
}
}
if (needs_write_barrier) {
- Register temp = locations->GetTemp(0).As<Register>();
- Register card = locations->GetTemp(1).As<Register>();
- codegen_->MarkGCCard(temp, card, obj, value.As<Register>());
+ Register temp = locations->GetTemp(0).AsRegister<Register>();
+ Register card = locations->GetTemp(1).AsRegister<Register>();
+ codegen_->MarkGCCard(temp, card, obj, value.AsRegister<Register>());
}
} else {
DCHECK_EQ(value_type, Primitive::kPrimNot);
@@ -2731,16 +2997,16 @@ void InstructionCodeGeneratorX86::VisitArraySet(HArraySet* instruction) {
}
} else {
if (value.IsRegisterPair()) {
- __ movl(Address(obj, index.As<Register>(), TIMES_8, data_offset),
+ __ movl(Address(obj, index.AsRegister<Register>(), TIMES_8, data_offset),
value.AsRegisterPairLow<Register>());
- __ movl(Address(obj, index.As<Register>(), TIMES_8, data_offset + kX86WordSize),
+ __ movl(Address(obj, index.AsRegister<Register>(), TIMES_8, data_offset + kX86WordSize),
value.AsRegisterPairHigh<Register>());
} else {
DCHECK(value.IsConstant());
int64_t val = value.GetConstant()->AsLongConstant()->GetValue();
- __ movl(Address(obj, index.As<Register>(), TIMES_8, data_offset),
+ __ movl(Address(obj, index.AsRegister<Register>(), TIMES_8, data_offset),
Immediate(Low32Bits(val)));
- __ movl(Address(obj, index.As<Register>(), TIMES_8, data_offset + kX86WordSize),
+ __ movl(Address(obj, index.AsRegister<Register>(), TIMES_8, data_offset + kX86WordSize),
Immediate(High32Bits(val)));
}
}
@@ -2767,8 +3033,8 @@ void LocationsBuilderX86::VisitArrayLength(HArrayLength* instruction) {
void InstructionCodeGeneratorX86::VisitArrayLength(HArrayLength* instruction) {
LocationSummary* locations = instruction->GetLocations();
uint32_t offset = mirror::Array::LengthOffset().Uint32Value();
- Register obj = locations->InAt(0).As<Register>();
- Register out = locations->Out().As<Register>();
+ Register obj = locations->InAt(0).AsRegister<Register>();
+ Register out = locations->Out().AsRegister<Register>();
__ movl(out, Address(obj, offset));
}
@@ -2788,8 +3054,8 @@ void InstructionCodeGeneratorX86::VisitBoundsCheck(HBoundsCheck* instruction) {
instruction, locations->InAt(0), locations->InAt(1));
codegen_->AddSlowPath(slow_path);
- Register index = locations->InAt(0).As<Register>();
- Register length = locations->InAt(1).As<Register>();
+ Register index = locations->InAt(0).AsRegister<Register>();
+ Register length = locations->InAt(1).AsRegister<Register>();
__ cmpl(index, length);
__ j(kAboveEqual, slow_path->GetEntryLabel());
@@ -2866,14 +3132,14 @@ void ParallelMoveResolverX86::EmitMove(size_t index) {
if (source.IsRegister()) {
if (destination.IsRegister()) {
- __ movl(destination.As<Register>(), source.As<Register>());
+ __ movl(destination.AsRegister<Register>(), source.AsRegister<Register>());
} else {
DCHECK(destination.IsStackSlot());
- __ movl(Address(ESP, destination.GetStackIndex()), source.As<Register>());
+ __ movl(Address(ESP, destination.GetStackIndex()), source.AsRegister<Register>());
}
} else if (source.IsStackSlot()) {
if (destination.IsRegister()) {
- __ movl(destination.As<Register>(), Address(ESP, source.GetStackIndex()));
+ __ movl(destination.AsRegister<Register>(), Address(ESP, source.GetStackIndex()));
} else {
DCHECK(destination.IsStackSlot());
MoveMemoryToMemory(destination.GetStackIndex(),
@@ -2883,7 +3149,7 @@ void ParallelMoveResolverX86::EmitMove(size_t index) {
HIntConstant* instruction = source.GetConstant()->AsIntConstant();
Immediate imm(instruction->AsIntConstant()->GetValue());
if (destination.IsRegister()) {
- __ movl(destination.As<Register>(), imm);
+ __ movl(destination.AsRegister<Register>(), imm);
} else {
__ movl(Address(ESP, destination.GetStackIndex()), imm);
}
@@ -2925,11 +3191,11 @@ void ParallelMoveResolverX86::EmitSwap(size_t index) {
Location destination = move->GetDestination();
if (source.IsRegister() && destination.IsRegister()) {
- __ xchgl(destination.As<Register>(), source.As<Register>());
+ __ xchgl(destination.AsRegister<Register>(), source.AsRegister<Register>());
} else if (source.IsRegister() && destination.IsStackSlot()) {
- Exchange(source.As<Register>(), destination.GetStackIndex());
+ Exchange(source.AsRegister<Register>(), destination.GetStackIndex());
} else if (source.IsStackSlot() && destination.IsRegister()) {
- Exchange(destination.As<Register>(), source.GetStackIndex());
+ Exchange(destination.AsRegister<Register>(), source.GetStackIndex());
} else if (source.IsStackSlot() && destination.IsStackSlot()) {
Exchange(destination.GetStackIndex(), source.GetStackIndex());
} else {
@@ -2955,7 +3221,7 @@ void LocationsBuilderX86::VisitLoadClass(HLoadClass* cls) {
}
void InstructionCodeGeneratorX86::VisitLoadClass(HLoadClass* cls) {
- Register out = cls->GetLocations()->Out().As<Register>();
+ Register out = cls->GetLocations()->Out().AsRegister<Register>();
if (cls->IsReferrersClass()) {
DCHECK(!cls->CanCallRuntime());
DCHECK(!cls->MustGenerateClinitCheck());
@@ -2994,7 +3260,8 @@ void InstructionCodeGeneratorX86::VisitClinitCheck(HClinitCheck* check) {
SlowPathCodeX86* slow_path = new (GetGraph()->GetArena()) LoadClassSlowPathX86(
check->GetLoadClass(), check, check->GetDexPc(), true);
codegen_->AddSlowPath(slow_path);
- GenerateClassInitializationCheck(slow_path, check->GetLocations()->InAt(0).As<Register>());
+ GenerateClassInitializationCheck(slow_path,
+ check->GetLocations()->InAt(0).AsRegister<Register>());
}
void InstructionCodeGeneratorX86::GenerateClassInitializationCheck(
@@ -3015,37 +3282,37 @@ void LocationsBuilderX86::VisitStaticFieldGet(HStaticFieldGet* instruction) {
void InstructionCodeGeneratorX86::VisitStaticFieldGet(HStaticFieldGet* instruction) {
LocationSummary* locations = instruction->GetLocations();
- Register cls = locations->InAt(0).As<Register>();
+ Register cls = locations->InAt(0).AsRegister<Register>();
uint32_t offset = instruction->GetFieldOffset().Uint32Value();
switch (instruction->GetType()) {
case Primitive::kPrimBoolean: {
- Register out = locations->Out().As<Register>();
+ Register out = locations->Out().AsRegister<Register>();
__ movzxb(out, Address(cls, offset));
break;
}
case Primitive::kPrimByte: {
- Register out = locations->Out().As<Register>();
+ Register out = locations->Out().AsRegister<Register>();
__ movsxb(out, Address(cls, offset));
break;
}
case Primitive::kPrimShort: {
- Register out = locations->Out().As<Register>();
+ Register out = locations->Out().AsRegister<Register>();
__ movsxw(out, Address(cls, offset));
break;
}
case Primitive::kPrimChar: {
- Register out = locations->Out().As<Register>();
+ Register out = locations->Out().AsRegister<Register>();
__ movzxw(out, Address(cls, offset));
break;
}
case Primitive::kPrimInt:
case Primitive::kPrimNot: {
- Register out = locations->Out().As<Register>();
+ Register out = locations->Out().AsRegister<Register>();
__ movl(out, Address(cls, offset));
break;
}
@@ -3058,13 +3325,13 @@ void InstructionCodeGeneratorX86::VisitStaticFieldGet(HStaticFieldGet* instructi
}
case Primitive::kPrimFloat: {
- XmmRegister out = locations->Out().As<XmmRegister>();
+ XmmRegister out = locations->Out().AsFpuRegister<XmmRegister>();
__ movss(out, Address(cls, offset));
break;
}
case Primitive::kPrimDouble: {
- XmmRegister out = locations->Out().As<XmmRegister>();
+ XmmRegister out = locations->Out().AsFpuRegister<XmmRegister>();
__ movsd(out, Address(cls, offset));
break;
}
@@ -3102,33 +3369,33 @@ void LocationsBuilderX86::VisitStaticFieldSet(HStaticFieldSet* instruction) {
void InstructionCodeGeneratorX86::VisitStaticFieldSet(HStaticFieldSet* instruction) {
LocationSummary* locations = instruction->GetLocations();
- Register cls = locations->InAt(0).As<Register>();
+ Register cls = locations->InAt(0).AsRegister<Register>();
uint32_t offset = instruction->GetFieldOffset().Uint32Value();
Primitive::Type field_type = instruction->GetFieldType();
switch (field_type) {
case Primitive::kPrimBoolean:
case Primitive::kPrimByte: {
- ByteRegister value = locations->InAt(1).As<ByteRegister>();
+ ByteRegister value = locations->InAt(1).AsRegister<ByteRegister>();
__ movb(Address(cls, offset), value);
break;
}
case Primitive::kPrimShort:
case Primitive::kPrimChar: {
- Register value = locations->InAt(1).As<Register>();
+ Register value = locations->InAt(1).AsRegister<Register>();
__ movw(Address(cls, offset), value);
break;
}
case Primitive::kPrimInt:
case Primitive::kPrimNot: {
- Register value = locations->InAt(1).As<Register>();
+ Register value = locations->InAt(1).AsRegister<Register>();
__ movl(Address(cls, offset), value);
if (CodeGenerator::StoreNeedsWriteBarrier(field_type, instruction->InputAt(1))) {
- Register temp = locations->GetTemp(0).As<Register>();
- Register card = locations->GetTemp(1).As<Register>();
+ Register temp = locations->GetTemp(0).AsRegister<Register>();
+ Register card = locations->GetTemp(1).AsRegister<Register>();
codegen_->MarkGCCard(temp, card, cls, value);
}
break;
@@ -3142,13 +3409,13 @@ void InstructionCodeGeneratorX86::VisitStaticFieldSet(HStaticFieldSet* instructi
}
case Primitive::kPrimFloat: {
- XmmRegister value = locations->InAt(1).As<XmmRegister>();
+ XmmRegister value = locations->InAt(1).AsFpuRegister<XmmRegister>();
__ movss(Address(cls, offset), value);
break;
}
case Primitive::kPrimDouble: {
- XmmRegister value = locations->InAt(1).As<XmmRegister>();
+ XmmRegister value = locations->InAt(1).AsFpuRegister<XmmRegister>();
__ movsd(Address(cls, offset), value);
break;
}
@@ -3169,9 +3436,10 @@ void InstructionCodeGeneratorX86::VisitLoadString(HLoadString* load) {
SlowPathCodeX86* slow_path = new (GetGraph()->GetArena()) LoadStringSlowPathX86(load);
codegen_->AddSlowPath(slow_path);
- Register out = load->GetLocations()->Out().As<Register>();
+ Register out = load->GetLocations()->Out().AsRegister<Register>();
codegen_->LoadCurrentMethod(out);
- __ movl(out, Address(out, mirror::ArtMethod::DexCacheStringsOffset().Int32Value()));
+ __ movl(out, Address(out, mirror::ArtMethod::DeclaringClassOffset().Int32Value()));
+ __ movl(out, Address(out, mirror::Class::DexCacheStringsOffset().Int32Value()));
__ movl(out, Address(out, CodeGenerator::GetCacheOffset(load->GetStringIndex())));
__ testl(out, out);
__ j(kEqual, slow_path->GetEntryLabel());
@@ -3186,7 +3454,7 @@ void LocationsBuilderX86::VisitLoadException(HLoadException* load) {
void InstructionCodeGeneratorX86::VisitLoadException(HLoadException* load) {
Address address = Address::Absolute(Thread::ExceptionOffset<kX86WordSize>().Int32Value());
- __ fs()->movl(load->GetLocations()->Out().As<Register>(), address);
+ __ fs()->movl(load->GetLocations()->Out().AsRegister<Register>(), address);
__ fs()->movl(address, Immediate(0));
}
@@ -3214,9 +3482,9 @@ void LocationsBuilderX86::VisitInstanceOf(HInstanceOf* instruction) {
void InstructionCodeGeneratorX86::VisitInstanceOf(HInstanceOf* instruction) {
LocationSummary* locations = instruction->GetLocations();
- Register obj = locations->InAt(0).As<Register>();
+ Register obj = locations->InAt(0).AsRegister<Register>();
Location cls = locations->InAt(1);
- Register out = locations->Out().As<Register>();
+ Register out = locations->Out().AsRegister<Register>();
uint32_t class_offset = mirror::Object::ClassOffset().Int32Value();
Label done, zero;
SlowPathCodeX86* slow_path = nullptr;
@@ -3228,7 +3496,7 @@ void InstructionCodeGeneratorX86::VisitInstanceOf(HInstanceOf* instruction) {
__ movl(out, Address(obj, class_offset));
// Compare the class of `obj` with `cls`.
if (cls.IsRegister()) {
- __ cmpl(out, cls.As<Register>());
+ __ cmpl(out, cls.AsRegister<Register>());
} else {
DCHECK(cls.IsStackSlot()) << cls;
__ cmpl(out, Address(ESP, cls.GetStackIndex()));
@@ -3267,9 +3535,9 @@ void LocationsBuilderX86::VisitCheckCast(HCheckCast* instruction) {
void InstructionCodeGeneratorX86::VisitCheckCast(HCheckCast* instruction) {
LocationSummary* locations = instruction->GetLocations();
- Register obj = locations->InAt(0).As<Register>();
+ Register obj = locations->InAt(0).AsRegister<Register>();
Location cls = locations->InAt(1);
- Register temp = locations->GetTemp(0).As<Register>();
+ Register temp = locations->GetTemp(0).AsRegister<Register>();
uint32_t class_offset = mirror::Object::ClassOffset().Int32Value();
SlowPathCodeX86* slow_path = new (GetGraph()->GetArena()) TypeCheckSlowPathX86(
instruction, locations->InAt(1), locations->GetTemp(0), instruction->GetDexPc());
@@ -3282,7 +3550,7 @@ void InstructionCodeGeneratorX86::VisitCheckCast(HCheckCast* instruction) {
// Compare the class of `obj` with `cls`.
if (cls.IsRegister()) {
- __ cmpl(temp, cls.As<Register>());
+ __ cmpl(temp, cls.AsRegister<Register>());
} else {
DCHECK(cls.IsStackSlot()) << cls;
__ cmpl(temp, Address(ESP, cls.GetStackIndex()));
@@ -3341,30 +3609,33 @@ void InstructionCodeGeneratorX86::HandleBitwiseOperation(HBinaryOperation* instr
if (instruction->GetResultType() == Primitive::kPrimInt) {
if (second.IsRegister()) {
if (instruction->IsAnd()) {
- __ andl(first.As<Register>(), second.As<Register>());
+ __ andl(first.AsRegister<Register>(), second.AsRegister<Register>());
} else if (instruction->IsOr()) {
- __ orl(first.As<Register>(), second.As<Register>());
+ __ orl(first.AsRegister<Register>(), second.AsRegister<Register>());
} else {
DCHECK(instruction->IsXor());
- __ xorl(first.As<Register>(), second.As<Register>());
+ __ xorl(first.AsRegister<Register>(), second.AsRegister<Register>());
}
} else if (second.IsConstant()) {
if (instruction->IsAnd()) {
- __ andl(first.As<Register>(), Immediate(second.GetConstant()->AsIntConstant()->GetValue()));
+ __ andl(first.AsRegister<Register>(),
+ Immediate(second.GetConstant()->AsIntConstant()->GetValue()));
} else if (instruction->IsOr()) {
- __ orl(first.As<Register>(), Immediate(second.GetConstant()->AsIntConstant()->GetValue()));
+ __ orl(first.AsRegister<Register>(),
+ Immediate(second.GetConstant()->AsIntConstant()->GetValue()));
} else {
DCHECK(instruction->IsXor());
- __ xorl(first.As<Register>(), Immediate(second.GetConstant()->AsIntConstant()->GetValue()));
+ __ xorl(first.AsRegister<Register>(),
+ Immediate(second.GetConstant()->AsIntConstant()->GetValue()));
}
} else {
if (instruction->IsAnd()) {
- __ andl(first.As<Register>(), Address(ESP, second.GetStackIndex()));
+ __ andl(first.AsRegister<Register>(), Address(ESP, second.GetStackIndex()));
} else if (instruction->IsOr()) {
- __ orl(first.As<Register>(), Address(ESP, second.GetStackIndex()));
+ __ orl(first.AsRegister<Register>(), Address(ESP, second.GetStackIndex()));
} else {
DCHECK(instruction->IsXor());
- __ xorl(first.As<Register>(), Address(ESP, second.GetStackIndex()));
+ __ xorl(first.AsRegister<Register>(), Address(ESP, second.GetStackIndex()));
}
}
} else {