diff options
Diffstat (limited to 'compiler/optimizing')
-rw-r--r-- | compiler/optimizing/builder.cc | 10 | ||||
-rw-r--r-- | compiler/optimizing/code_generator.cc | 22 | ||||
-rw-r--r-- | compiler/optimizing/code_generator.h | 5 | ||||
-rw-r--r-- | compiler/optimizing/code_generator_arm.cc | 505 | ||||
-rw-r--r-- | compiler/optimizing/code_generator_x86.cc | 543 | ||||
-rw-r--r-- | compiler/optimizing/code_generator_x86_64.cc | 526 | ||||
-rw-r--r-- | compiler/optimizing/gvn.cc | 98 | ||||
-rw-r--r-- | compiler/optimizing/gvn.h | 72 | ||||
-rw-r--r-- | compiler/optimizing/locations.h | 9 | ||||
-rw-r--r-- | compiler/optimizing/register_allocator.cc | 90 |
10 files changed, 1107 insertions, 773 deletions
diff --git a/compiler/optimizing/builder.cc b/compiler/optimizing/builder.cc index 1be6e00938..777a117a3b 100644 --- a/compiler/optimizing/builder.cc +++ b/compiler/optimizing/builder.cc @@ -1043,6 +1043,16 @@ bool HGraphBuilder::AnalyzeDexInstruction(const Instruction& instruction, uint32 break; } + case Instruction::LONG_TO_FLOAT: { + Conversion_12x(instruction, Primitive::kPrimLong, Primitive::kPrimFloat); + break; + } + + case Instruction::LONG_TO_DOUBLE: { + Conversion_12x(instruction, Primitive::kPrimLong, Primitive::kPrimDouble); + break; + } + case Instruction::INT_TO_BYTE: { Conversion_12x(instruction, Primitive::kPrimInt, Primitive::kPrimByte); break; diff --git a/compiler/optimizing/code_generator.cc b/compiler/optimizing/code_generator.cc index 0b593275c7..6cacd4fa23 100644 --- a/compiler/optimizing/code_generator.cc +++ b/compiler/optimizing/code_generator.cc @@ -228,7 +228,8 @@ void CodeGenerator::AllocateRegistersLocally(HInstruction* instruction) const { DCHECK(!blocked_fpu_registers_[loc.reg()]); blocked_fpu_registers_[loc.reg()] = true; } else { - DCHECK_EQ(loc.GetPolicy(), Location::kRequiresRegister); + DCHECK(loc.GetPolicy() == Location::kRequiresRegister + || loc.GetPolicy() == Location::kRequiresFpuRegister); } } @@ -259,10 +260,21 @@ void CodeGenerator::AllocateRegistersLocally(HInstruction* instruction) const { for (size_t i = 0, e = locations->GetTempCount(); i < e; ++i) { Location loc = locations->GetTemp(i); if (loc.IsUnallocated()) { - DCHECK_EQ(loc.GetPolicy(), Location::kRequiresRegister); - // TODO: Adjust handling of temps. We currently consider temps to use - // core registers. They may also use floating point registers at some point. - loc = AllocateFreeRegister(Primitive::kPrimInt); + switch (loc.GetPolicy()) { + case Location::kRequiresRegister: + // Allocate a core register (large enough to fit a 32-bit integer). + loc = AllocateFreeRegister(Primitive::kPrimInt); + break; + + case Location::kRequiresFpuRegister: + // Allocate a core register (large enough to fit a 64-bit double). + loc = AllocateFreeRegister(Primitive::kPrimDouble); + break; + + default: + LOG(FATAL) << "Unexpected policy for temporary location " + << loc.GetPolicy(); + } locations->SetTempAt(i, loc); } } diff --git a/compiler/optimizing/code_generator.h b/compiler/optimizing/code_generator.h index f906eb8c05..321a31f596 100644 --- a/compiler/optimizing/code_generator.h +++ b/compiler/optimizing/code_generator.h @@ -30,6 +30,11 @@ namespace art { static size_t constexpr kVRegSize = 4; static size_t constexpr kUninitializedFrameSize = 0; +// Binary encoding of 2^32 for type double. +static int64_t constexpr k2Pow32EncodingForDouble = INT64_C(0x41F0000000000000); +// Binary encoding of 2^31 for type double. +static int64_t constexpr k2Pow31EncodingForDouble = INT64_C(0x41E0000000000000); + class Assembler; class CodeGenerator; class DexCompilationUnit; diff --git a/compiler/optimizing/code_generator_arm.cc b/compiler/optimizing/code_generator_arm.cc index df65ff054e..7d6d827386 100644 --- a/compiler/optimizing/code_generator_arm.cc +++ b/compiler/optimizing/code_generator_arm.cc @@ -495,7 +495,8 @@ InstructionCodeGeneratorARM::InstructionCodeGeneratorARM(HGraph* graph, CodeGene codegen_(codegen) {} void CodeGeneratorARM::GenerateFrameEntry() { - bool skip_overflow_check = IsLeafMethod() && !FrameNeedsStackCheck(GetFrameSize(), InstructionSet::kArm); + bool skip_overflow_check = + IsLeafMethod() && !FrameNeedsStackCheck(GetFrameSize(), InstructionSet::kArm); if (!skip_overflow_check) { if (kExplicitStackOverflowCheck) { SlowPathCodeARM* slow_path = new (GetGraph()->GetArena()) StackOverflowCheckSlowPathARM(); @@ -655,26 +656,26 @@ void CodeGeneratorARM::Move32(Location destination, Location source) { } if (destination.IsRegister()) { if (source.IsRegister()) { - __ Mov(destination.As<Register>(), source.As<Register>()); + __ Mov(destination.AsRegister<Register>(), source.AsRegister<Register>()); } else if (source.IsFpuRegister()) { - __ vmovrs(destination.As<Register>(), source.As<SRegister>()); + __ vmovrs(destination.AsRegister<Register>(), source.AsFpuRegister<SRegister>()); } else { - __ LoadFromOffset(kLoadWord, destination.As<Register>(), SP, source.GetStackIndex()); + __ LoadFromOffset(kLoadWord, destination.AsRegister<Register>(), SP, source.GetStackIndex()); } } else if (destination.IsFpuRegister()) { if (source.IsRegister()) { - __ vmovsr(destination.As<SRegister>(), source.As<Register>()); + __ vmovsr(destination.AsFpuRegister<SRegister>(), source.AsRegister<Register>()); } else if (source.IsFpuRegister()) { - __ vmovs(destination.As<SRegister>(), source.As<SRegister>()); + __ vmovs(destination.AsFpuRegister<SRegister>(), source.AsFpuRegister<SRegister>()); } else { - __ LoadSFromOffset(destination.As<SRegister>(), SP, source.GetStackIndex()); + __ LoadSFromOffset(destination.AsFpuRegister<SRegister>(), SP, source.GetStackIndex()); } } else { DCHECK(destination.IsStackSlot()) << destination; if (source.IsRegister()) { - __ StoreToOffset(kStoreWord, source.As<Register>(), SP, destination.GetStackIndex()); + __ StoreToOffset(kStoreWord, source.AsRegister<Register>(), SP, destination.GetStackIndex()); } else if (source.IsFpuRegister()) { - __ StoreSToOffset(source.As<SRegister>(), SP, destination.GetStackIndex()); + __ StoreSToOffset(source.AsFpuRegister<SRegister>(), SP, destination.GetStackIndex()); } else { DCHECK(source.IsStackSlot()) << source; __ LoadFromOffset(kLoadWord, IP, SP, source.GetStackIndex()); @@ -689,19 +690,25 @@ void CodeGeneratorARM::Move64(Location destination, Location source) { } if (destination.IsRegisterPair()) { if (source.IsRegisterPair()) { - __ Mov(destination.AsRegisterPairLow<Register>(), source.AsRegisterPairLow<Register>()); - __ Mov(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()) { UNIMPLEMENTED(FATAL); } else if (source.IsQuickParameter()) { uint16_t register_index = source.GetQuickParameterRegisterIndex(); uint16_t stack_index = source.GetQuickParameterStackIndex(); InvokeDexCallingConvention calling_convention; - __ Mov(destination.AsRegisterPairLow<Register>(), - calling_convention.GetRegisterAt(register_index)); - __ LoadFromOffset(kLoadWord, destination.AsRegisterPairHigh<Register>(), - SP, 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()); if (destination.AsRegisterPairLow<Register>() == R1) { DCHECK_EQ(destination.AsRegisterPairHigh<Register>(), R2); @@ -725,22 +732,21 @@ void CodeGeneratorARM::Move64(Location destination, Location source) { uint16_t register_index = destination.GetQuickParameterRegisterIndex(); uint16_t stack_index = destination.GetQuickParameterStackIndex(); if (source.IsRegisterPair()) { - __ Mov(calling_convention.GetRegisterAt(register_index), - source.AsRegisterPairLow<Register>()); - __ StoreToOffset(kStoreWord, source.AsRegisterPairHigh<Register>(), - SP, calling_convention.GetStackOffsetOf(stack_index + 1)); + UNIMPLEMENTED(FATAL); } else if (source.IsFpuRegister()) { UNIMPLEMENTED(FATAL); } else { DCHECK(source.IsDoubleStackSlot()); - __ LoadFromOffset( - kLoadWord, calling_convention.GetRegisterAt(register_index), SP, source.GetStackIndex()); - __ LoadFromOffset(kLoadWord, R0, SP, source.GetHighStackIndex(kArmWordSize)); - __ StoreToOffset(kStoreWord, R0, SP, calling_convention.GetStackOffsetOf(stack_index + 1)); + EmitParallelMoves( + Location::StackSlot(source.GetStackIndex()), + Location::RegisterLocation(calling_convention.GetRegisterAt(register_index)), + Location::StackSlot(source.GetHighStackIndex(kArmWordSize)), + Location::StackSlot(calling_convention.GetStackOffsetOf(stack_index + 1))); } } else { DCHECK(destination.IsDoubleStackSlot()); if (source.IsRegisterPair()) { + // No conflict possible, so just do the moves. if (source.AsRegisterPairLow<Register>() == R1) { DCHECK_EQ(source.AsRegisterPairHigh<Register>(), R2); __ StoreToOffset(kStoreWord, R1, SP, destination.GetStackIndex()); @@ -753,21 +759,24 @@ void CodeGeneratorARM::Move64(Location destination, Location source) { 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. __ StoreToOffset(kStoreWord, calling_convention.GetRegisterAt(register_index), - SP, destination.GetStackIndex()); - __ LoadFromOffset(kLoadWord, R0, - SP, calling_convention.GetStackOffsetOf(stack_index + 1) + GetFrameSize()); - __ StoreToOffset(kStoreWord, R0, SP, destination.GetHighStackIndex(kArmWordSize)); + SP, destination.GetStackIndex()); + DCHECK_EQ(calling_convention.GetStackOffsetOf(stack_index + 1) + GetFrameSize(), + static_cast<size_t>(destination.GetHighStackIndex(kArmWordSize))); } else if (source.IsFpuRegisterPair()) { __ StoreDToOffset(FromLowSToD(source.AsFpuRegisterPairLow<SRegister>()), SP, destination.GetStackIndex()); } else { DCHECK(source.IsDoubleStackSlot()); - __ LoadFromOffset(kLoadWord, IP, SP, source.GetStackIndex()); - __ StoreToOffset(kStoreWord, IP, SP, destination.GetStackIndex()); - __ LoadFromOffset(kLoadWord, IP, SP, source.GetHighStackIndex(kArmWordSize)); - __ StoreToOffset(kStoreWord, IP, SP, destination.GetHighStackIndex(kArmWordSize)); + EmitParallelMoves( + Location::StackSlot(source.GetStackIndex()), + Location::StackSlot(destination.GetStackIndex()), + Location::StackSlot(source.GetHighStackIndex(kArmWordSize)), + Location::StackSlot(destination.GetHighStackIndex(kArmWordSize))); } } } @@ -783,7 +792,7 @@ void CodeGeneratorARM::Move(HInstruction* instruction, Location location, HInstr if (const_to_move->IsIntConstant()) { int32_t value = const_to_move->AsIntConstant()->GetValue(); if (location.IsRegister()) { - __ LoadImmediate(location.As<Register>(), value); + __ LoadImmediate(location.AsRegister<Register>(), value); } else { DCHECK(location.IsStackSlot()); __ LoadImmediate(IP, value); @@ -933,7 +942,7 @@ void InstructionCodeGeneratorARM::VisitIf(HIf* if_instr) { if (!cond->IsCondition() || cond->AsCondition()->NeedsMaterialization()) { // Condition has been materialized, compare the output to 0 DCHECK(if_instr->GetLocations()->InAt(0).IsRegister()); - __ cmp(if_instr->GetLocations()->InAt(0).As<Register>(), + __ cmp(if_instr->GetLocations()->InAt(0).AsRegister<Register>(), ShifterOperand(0)); __ b(codegen_->GetLabelOf(if_instr->IfTrueSuccessor()), NE); } else { @@ -941,19 +950,19 @@ void InstructionCodeGeneratorARM::VisitIf(HIf* if_instr) { // comparison and its condition as the branch condition. LocationSummary* locations = cond->GetLocations(); if (locations->InAt(1).IsRegister()) { - __ cmp(locations->InAt(0).As<Register>(), - ShifterOperand(locations->InAt(1).As<Register>())); + __ cmp(locations->InAt(0).AsRegister<Register>(), + ShifterOperand(locations->InAt(1).AsRegister<Register>())); } else { DCHECK(locations->InAt(1).IsConstant()); int32_t value = locations->InAt(1).GetConstant()->AsIntConstant()->GetValue(); ShifterOperand operand; if (ShifterOperand::CanHoldArm(value, &operand)) { - __ cmp(locations->InAt(0).As<Register>(), ShifterOperand(value)); + __ cmp(locations->InAt(0).AsRegister<Register>(), ShifterOperand(value)); } else { Register temp = IP; __ LoadImmediate(temp, value); - __ cmp(locations->InAt(0).As<Register>(), ShifterOperand(temp)); + __ cmp(locations->InAt(0).AsRegister<Register>(), ShifterOperand(temp)); } } __ b(codegen_->GetLabelOf(if_instr->IfTrueSuccessor()), @@ -982,24 +991,24 @@ void InstructionCodeGeneratorARM::VisitCondition(HCondition* comp) { LocationSummary* locations = comp->GetLocations(); if (locations->InAt(1).IsRegister()) { - __ cmp(locations->InAt(0).As<Register>(), - ShifterOperand(locations->InAt(1).As<Register>())); + __ cmp(locations->InAt(0).AsRegister<Register>(), + ShifterOperand(locations->InAt(1).AsRegister<Register>())); } else { DCHECK(locations->InAt(1).IsConstant()); int32_t value = locations->InAt(1).GetConstant()->AsIntConstant()->GetValue(); ShifterOperand operand; if (ShifterOperand::CanHoldArm(value, &operand)) { - __ cmp(locations->InAt(0).As<Register>(), ShifterOperand(value)); + __ cmp(locations->InAt(0).AsRegister<Register>(), ShifterOperand(value)); } else { Register temp = IP; __ LoadImmediate(temp, value); - __ cmp(locations->InAt(0).As<Register>(), ShifterOperand(temp)); + __ cmp(locations->InAt(0).AsRegister<Register>(), ShifterOperand(temp)); } } __ it(ARMCondition(comp->GetCondition()), kItElse); - __ mov(locations->Out().As<Register>(), ShifterOperand(1), + __ mov(locations->Out().AsRegister<Register>(), ShifterOperand(1), ARMCondition(comp->GetCondition())); - __ mov(locations->Out().As<Register>(), ShifterOperand(0), + __ mov(locations->Out().AsRegister<Register>(), ShifterOperand(0), ARMOppositeCondition(comp->GetCondition())); } @@ -1169,7 +1178,7 @@ void CodeGeneratorARM::LoadCurrentMethod(Register reg) { } void InstructionCodeGeneratorARM::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 @@ -1216,7 +1225,7 @@ void LocationsBuilderARM::VisitInvokeVirtual(HInvokeVirtual* invoke) { } void InstructionCodeGeneratorARM::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(); @@ -1227,7 +1236,7 @@ void InstructionCodeGeneratorARM::VisitInvokeVirtual(HInvokeVirtual* invoke) { __ LoadFromOffset(kLoadWord, temp, SP, receiver.GetStackIndex()); __ LoadFromOffset(kLoadWord, temp, temp, class_offset); } else { - __ LoadFromOffset(kLoadWord, temp, receiver.As<Register>(), class_offset); + __ LoadFromOffset(kLoadWord, temp, receiver.AsRegister<Register>(), class_offset); } // temp = temp->GetMethodAt(method_offset); uint32_t entry_point = mirror::ArtMethod::EntryPointFromQuickCompiledCodeOffset( @@ -1249,7 +1258,7 @@ void LocationsBuilderARM::VisitInvokeInterface(HInvokeInterface* invoke) { void InstructionCodeGeneratorARM::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(); @@ -1257,14 +1266,15 @@ void InstructionCodeGeneratorARM::VisitInvokeInterface(HInvokeInterface* invoke) uint32_t class_offset = mirror::Object::ClassOffset().Int32Value(); // Set the hidden argument. - __ LoadImmediate(invoke->GetLocations()->GetTemp(1).As<Register>(), invoke->GetDexMethodIndex()); + __ LoadImmediate(invoke->GetLocations()->GetTemp(1).AsRegister<Register>(), + invoke->GetDexMethodIndex()); // temp = object->GetClass(); if (receiver.IsStackSlot()) { __ LoadFromOffset(kLoadWord, temp, SP, receiver.GetStackIndex()); __ LoadFromOffset(kLoadWord, temp, temp, class_offset); } else { - __ LoadFromOffset(kLoadWord, temp, receiver.As<Register>(), class_offset); + __ LoadFromOffset(kLoadWord, temp, receiver.AsRegister<Register>(), class_offset); } // temp = temp->GetImtEntryAt(method_offset); uint32_t entry_point = mirror::ArtMethod::EntryPointFromQuickCompiledCodeOffset( @@ -1308,7 +1318,7 @@ void InstructionCodeGeneratorARM::VisitNeg(HNeg* neg) { switch (neg->GetResultType()) { case Primitive::kPrimInt: DCHECK(in.IsRegister()); - __ rsb(out.As<Register>(), in.As<Register>(), ShifterOperand(0)); + __ rsb(out.AsRegister<Register>(), in.AsRegister<Register>(), ShifterOperand(0)); break; case Primitive::kPrimLong: @@ -1334,7 +1344,7 @@ void InstructionCodeGeneratorARM::VisitNeg(HNeg* neg) { case Primitive::kPrimFloat: DCHECK(in.IsFpuRegister()); - __ vnegs(out.As<SRegister>(), in.As<SRegister>()); + __ vnegs(out.AsFpuRegister<SRegister>(), in.AsFpuRegister<SRegister>()); break; case Primitive::kPrimDouble: @@ -1458,6 +1468,15 @@ void LocationsBuilderARM::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::RequiresRegister()); + locations->AddTemp(Location::RequiresRegister()); + 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"; @@ -1481,6 +1500,14 @@ void LocationsBuilderARM::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::RequiresRegister()); + locations->AddTemp(Location::RequiresRegister()); + locations->AddTemp(Location::RequiresFpuRegister()); + break; + case Primitive::kPrimFloat: LOG(FATAL) << "Type conversion from " << input_type << " to " << result_type << " not yet implemented"; @@ -1511,7 +1538,7 @@ void InstructionCodeGeneratorARM::VisitTypeConversion(HTypeConversion* conversio case Primitive::kPrimInt: case Primitive::kPrimChar: // Processing a Dex `int-to-byte' instruction. - __ sbfx(out.As<Register>(), in.As<Register>(), 0, 8); + __ sbfx(out.AsRegister<Register>(), in.AsRegister<Register>(), 0, 8); break; default: @@ -1526,7 +1553,7 @@ void InstructionCodeGeneratorARM::VisitTypeConversion(HTypeConversion* conversio case Primitive::kPrimInt: case Primitive::kPrimChar: // Processing a Dex `int-to-short' instruction. - __ sbfx(out.As<Register>(), in.As<Register>(), 0, 16); + __ sbfx(out.AsRegister<Register>(), in.AsRegister<Register>(), 0, 16); break; default: @@ -1541,14 +1568,14 @@ void InstructionCodeGeneratorARM::VisitTypeConversion(HTypeConversion* conversio // Processing a Dex `long-to-int' instruction. DCHECK(out.IsRegister()); if (in.IsRegisterPair()) { - __ Mov(out.As<Register>(), in.AsRegisterPairLow<Register>()); + __ Mov(out.AsRegister<Register>(), in.AsRegisterPairLow<Register>()); } else if (in.IsDoubleStackSlot()) { - __ LoadFromOffset(kLoadWord, out.As<Register>(), SP, in.GetStackIndex()); + __ LoadFromOffset(kLoadWord, out.AsRegister<Register>(), SP, in.GetStackIndex()); } else { DCHECK(in.IsConstant()); DCHECK(in.GetConstant()->IsLongConstant()); int64_t value = in.GetConstant()->AsLongConstant()->GetValue(); - __ LoadImmediate(out.As<Register>(), static_cast<int32_t>(value)); + __ LoadImmediate(out.AsRegister<Register>(), static_cast<int32_t>(value)); } break; @@ -1573,7 +1600,7 @@ void InstructionCodeGeneratorARM::VisitTypeConversion(HTypeConversion* conversio // Processing a Dex `int-to-long' instruction. DCHECK(out.IsRegisterPair()); DCHECK(in.IsRegister()); - __ Mov(out.AsRegisterPairLow<Register>(), in.As<Register>()); + __ Mov(out.AsRegisterPairLow<Register>(), in.AsRegister<Register>()); // Sign extension. __ Asr(out.AsRegisterPairHigh<Register>(), out.AsRegisterPairLow<Register>(), @@ -1599,7 +1626,7 @@ void InstructionCodeGeneratorARM::VisitTypeConversion(HTypeConversion* conversio case Primitive::kPrimInt: case Primitive::kPrimChar: // Processing a Dex `int-to-char' instruction. - __ ubfx(out.As<Register>(), in.As<Register>(), 0, 16); + __ ubfx(out.AsRegister<Register>(), in.AsRegister<Register>(), 0, 16); break; default: @@ -1615,12 +1642,53 @@ void InstructionCodeGeneratorARM::VisitTypeConversion(HTypeConversion* conversio case Primitive::kPrimInt: case Primitive::kPrimChar: { // Processing a Dex `int-to-float' instruction. - __ vmovsr(out.As<SRegister>(), in.As<Register>()); - __ vcvtsi(out.As<SRegister>(), out.As<SRegister>()); + __ vmovsr(out.AsFpuRegister<SRegister>(), in.AsRegister<Register>()); + __ vcvtsi(out.AsFpuRegister<SRegister>(), out.AsFpuRegister<SRegister>()); + break; + } + + case Primitive::kPrimLong: { + // Processing a Dex `long-to-float' instruction. + Register low = in.AsRegisterPairLow<Register>(); + Register high = in.AsRegisterPairHigh<Register>(); + SRegister output = out.AsFpuRegister<SRegister>(); + Register constant_low = locations->GetTemp(0).AsRegister<Register>(); + Register constant_high = locations->GetTemp(1).AsRegister<Register>(); + SRegister temp1_s = locations->GetTemp(2).AsFpuRegisterPairLow<SRegister>(); + DRegister temp1_d = FromLowSToD(temp1_s); + SRegister temp2_s = locations->GetTemp(3).AsFpuRegisterPairLow<SRegister>(); + DRegister temp2_d = FromLowSToD(temp2_s); + + // 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. + + // temp1_d = int-to-double(high) + __ vmovsr(temp1_s, high); + __ vcvtdi(temp1_d, temp1_s); + // Using vmovd to load the `k2Pow32EncodingForDouble` constant + // as an immediate value into `temp2_d` does not work, as + // this instruction only transfers 8 significant bits of its + // immediate operand. Instead, use two 32-bit core + // registers to load `k2Pow32EncodingForDouble` into + // `temp2_d`. + __ LoadImmediate(constant_low, Low32Bits(k2Pow32EncodingForDouble)); + __ LoadImmediate(constant_high, High32Bits(k2Pow32EncodingForDouble)); + __ vmovdrr(temp2_d, constant_low, constant_high); + // temp1_d = temp1_d * 2^32 + __ vmuld(temp1_d, temp1_d, temp2_d); + // temp2_d = unsigned-to-double(low) + __ vmovsr(temp2_s, low); + __ vcvtdu(temp2_d, temp2_s); + // temp1_d = temp1_d + temp2_d + __ vaddd(temp1_d, temp1_d, temp2_d); + // output = double-to-float(temp1_d); + __ vcvtsd(output, temp1_d); break; } - case Primitive::kPrimLong: case Primitive::kPrimDouble: LOG(FATAL) << "Type conversion from " << input_type << " to " << result_type << " not yet implemented"; @@ -1639,13 +1707,44 @@ void InstructionCodeGeneratorARM::VisitTypeConversion(HTypeConversion* conversio case Primitive::kPrimInt: case Primitive::kPrimChar: { // Processing a Dex `int-to-double' instruction. - __ vmovsr(out.AsFpuRegisterPairLow<SRegister>(), in.As<Register>()); + __ vmovsr(out.AsFpuRegisterPairLow<SRegister>(), in.AsRegister<Register>()); __ vcvtdi(FromLowSToD(out.AsFpuRegisterPairLow<SRegister>()), out.AsFpuRegisterPairLow<SRegister>()); break; } - case Primitive::kPrimLong: + case Primitive::kPrimLong: { + // Processing a Dex `long-to-double' instruction. + Register low = in.AsRegisterPairLow<Register>(); + Register high = in.AsRegisterPairHigh<Register>(); + SRegister out_s = out.AsFpuRegisterPairLow<SRegister>(); + DRegister out_d = FromLowSToD(out_s); + Register constant_low = locations->GetTemp(0).AsRegister<Register>(); + Register constant_high = locations->GetTemp(1).AsRegister<Register>(); + SRegister temp_s = locations->GetTemp(2).AsFpuRegisterPairLow<SRegister>(); + DRegister temp_d = FromLowSToD(temp_s); + + // out_d = int-to-double(high) + __ vmovsr(out_s, high); + __ vcvtdi(out_d, out_s); + // Using vmovd to load the `k2Pow32EncodingForDouble` constant + // as an immediate value into `temp_d` does not work, as + // this instruction only transfers 8 significant bits of its + // immediate operand. Instead, use two 32-bit core + // registers to load `k2Pow32EncodingForDouble` into `temp_d`. + __ LoadImmediate(constant_low, Low32Bits(k2Pow32EncodingForDouble)); + __ LoadImmediate(constant_high, High32Bits(k2Pow32EncodingForDouble)); + __ vmovdrr(temp_d, constant_low, constant_high); + // out_d = out_d * 2^32 + __ vmuld(out_d, out_d, temp_d); + // temp_d = unsigned-to-double(low) + __ vmovsr(temp_s, low); + __ vcvtdu(temp_d, temp_s); + // out_d = out_d + temp_d + __ vaddd(out_d, out_d, temp_d); + break; + } + case Primitive::kPrimFloat: LOG(FATAL) << "Type conversion from " << input_type << " to " << result_type << " not yet implemented"; @@ -1697,10 +1796,12 @@ void InstructionCodeGeneratorARM::VisitAdd(HAdd* add) { switch (add->GetResultType()) { case Primitive::kPrimInt: if (second.IsRegister()) { - __ add(out.As<Register>(), first.As<Register>(), ShifterOperand(second.As<Register>())); + __ add(out.AsRegister<Register>(), + first.AsRegister<Register>(), + ShifterOperand(second.AsRegister<Register>())); } else { - __ AddConstant(out.As<Register>(), - first.As<Register>(), + __ AddConstant(out.AsRegister<Register>(), + first.AsRegister<Register>(), second.GetConstant()->AsIntConstant()->GetValue()); } break; @@ -1715,7 +1816,9 @@ void InstructionCodeGeneratorARM::VisitAdd(HAdd* add) { break; case Primitive::kPrimFloat: - __ vadds(out.As<SRegister>(), first.As<SRegister>(), second.As<SRegister>()); + __ vadds(out.AsFpuRegister<SRegister>(), + first.AsFpuRegister<SRegister>(), + second.AsFpuRegister<SRegister>()); break; case Primitive::kPrimDouble: @@ -1761,10 +1864,12 @@ void InstructionCodeGeneratorARM::VisitSub(HSub* sub) { switch (sub->GetResultType()) { case Primitive::kPrimInt: { if (second.IsRegister()) { - __ sub(out.As<Register>(), first.As<Register>(), ShifterOperand(second.As<Register>())); + __ sub(out.AsRegister<Register>(), + first.AsRegister<Register>(), + ShifterOperand(second.AsRegister<Register>())); } else { - __ AddConstant(out.As<Register>(), - first.As<Register>(), + __ AddConstant(out.AsRegister<Register>(), + first.AsRegister<Register>(), -second.GetConstant()->AsIntConstant()->GetValue()); } break; @@ -1781,7 +1886,9 @@ void InstructionCodeGeneratorARM::VisitSub(HSub* sub) { } case Primitive::kPrimFloat: { - __ vsubs(out.As<SRegister>(), first.As<SRegister>(), second.As<SRegister>()); + __ vsubs(out.AsFpuRegister<SRegister>(), + first.AsFpuRegister<SRegister>(), + second.AsFpuRegister<SRegister>()); break; } @@ -1830,7 +1937,9 @@ void InstructionCodeGeneratorARM::VisitMul(HMul* mul) { Location second = locations->InAt(1); switch (mul->GetResultType()) { case Primitive::kPrimInt: { - __ mul(out.As<Register>(), first.As<Register>(), second.As<Register>()); + __ mul(out.AsRegister<Register>(), + first.AsRegister<Register>(), + second.AsRegister<Register>()); break; } case Primitive::kPrimLong: { @@ -1865,7 +1974,9 @@ void InstructionCodeGeneratorARM::VisitMul(HMul* mul) { } case Primitive::kPrimFloat: { - __ vmuls(out.As<SRegister>(), first.As<SRegister>(), second.As<SRegister>()); + __ vmuls(out.AsFpuRegister<SRegister>(), + first.AsFpuRegister<SRegister>(), + second.AsFpuRegister<SRegister>()); break; } @@ -1925,7 +2036,9 @@ void InstructionCodeGeneratorARM::VisitDiv(HDiv* div) { switch (div->GetResultType()) { case Primitive::kPrimInt: { - __ sdiv(out.As<Register>(), first.As<Register>(), second.As<Register>()); + __ sdiv(out.AsRegister<Register>(), + first.AsRegister<Register>(), + second.AsRegister<Register>()); break; } @@ -1943,7 +2056,9 @@ void InstructionCodeGeneratorARM::VisitDiv(HDiv* div) { } case Primitive::kPrimFloat: { - __ vdivs(out.As<SRegister>(), first.As<SRegister>(), second.As<SRegister>()); + __ vdivs(out.AsFpuRegister<SRegister>(), + first.AsFpuRegister<SRegister>(), + second.AsFpuRegister<SRegister>()); break; } @@ -2002,16 +2117,16 @@ void InstructionCodeGeneratorARM::VisitRem(HRem* rem) { switch (rem->GetResultType()) { case Primitive::kPrimInt: { - Register reg1 = first.As<Register>(); - Register reg2 = second.As<Register>(); - Register temp = locations->GetTemp(0).As<Register>(); + Register reg1 = first.AsRegister<Register>(); + Register reg2 = second.AsRegister<Register>(); + Register temp = locations->GetTemp(0).AsRegister<Register>(); // temp = reg1 / reg2 (integer division) // temp = temp * reg2 // dest = reg1 - temp __ sdiv(temp, reg1, reg2); __ mul(temp, temp, reg2); - __ sub(out.As<Register>(), reg1, ShifterOperand(temp)); + __ sub(out.AsRegister<Register>(), reg1, ShifterOperand(temp)); break; } @@ -2058,7 +2173,7 @@ void InstructionCodeGeneratorARM::VisitDivZeroCheck(HDivZeroCheck* instruction) switch (instruction->GetType()) { case Primitive::kPrimInt: { if (value.IsRegister()) { - __ cmp(value.As<Register>(), ShifterOperand(0)); + __ cmp(value.AsRegister<Register>(), ShifterOperand(0)); __ b(slow_path->GetEntryLabel(), EQ); } else { DCHECK(value.IsConstant()) << value; @@ -2127,11 +2242,11 @@ void InstructionCodeGeneratorARM::HandleShift(HBinaryOperation* op) { Primitive::Type type = op->GetResultType(); switch (type) { case Primitive::kPrimInt: { - Register out_reg = out.As<Register>(); - Register first_reg = first.As<Register>(); + Register out_reg = out.AsRegister<Register>(); + Register first_reg = first.AsRegister<Register>(); // Arm doesn't mask the shift count so we need to do it ourselves. if (second.IsRegister()) { - Register second_reg = second.As<Register>(); + Register second_reg = second.AsRegister<Register>(); __ and_(second_reg, second_reg, ShifterOperand(kMaxIntShiftValue)); if (op->IsShl()) { __ Lsl(out_reg, first_reg, second_reg); @@ -2160,7 +2275,7 @@ void InstructionCodeGeneratorARM::HandleShift(HBinaryOperation* op) { InvokeRuntimeCallingConvention calling_convention; DCHECK_EQ(calling_convention.GetRegisterAt(0), first.AsRegisterPairLow<Register>()); DCHECK_EQ(calling_convention.GetRegisterAt(1), first.AsRegisterPairHigh<Register>()); - DCHECK_EQ(calling_convention.GetRegisterAt(2), second.As<Register>()); + DCHECK_EQ(calling_convention.GetRegisterAt(2), second.AsRegister<Register>()); DCHECK_EQ(R0, out.AsRegisterPairLow<Register>()); DCHECK_EQ(R2, out.AsRegisterPairHigh<Register>()); @@ -2270,11 +2385,11 @@ void InstructionCodeGeneratorARM::VisitNot(HNot* not_) { Location in = locations->InAt(0); switch (not_->InputAt(0)->GetType()) { case Primitive::kPrimBoolean: - __ eor(out.As<Register>(), in.As<Register>(), ShifterOperand(1)); + __ eor(out.AsRegister<Register>(), in.AsRegister<Register>(), ShifterOperand(1)); break; case Primitive::kPrimInt: - __ mvn(out.As<Register>(), ShifterOperand(in.As<Register>())); + __ mvn(out.AsRegister<Register>(), ShifterOperand(in.AsRegister<Register>())); break; case Primitive::kPrimLong: @@ -2313,12 +2428,13 @@ void LocationsBuilderARM::VisitCompare(HCompare* compare) { void InstructionCodeGeneratorARM::VisitCompare(HCompare* compare) { LocationSummary* locations = compare->GetLocations(); - Register out = locations->Out().As<Register>(); + 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()) { + Primitive::Type type = compare->InputAt(0)->GetType(); + switch (type) { case Primitive::kPrimLong: { __ cmp(left.AsRegisterPairHigh<Register>(), ShifterOperand(right.AsRegisterPairHigh<Register>())); // Signed compare. @@ -2330,21 +2446,21 @@ void InstructionCodeGeneratorARM::VisitCompare(HCompare* compare) { ShifterOperand(right.AsRegisterPairLow<Register>())); // Unsigned compare. break; } - case Primitive::kPrimFloat: { - __ LoadImmediate(out, 0); - __ vcmps(left.As<SRegister>(), right.As<SRegister>()); - __ b(compare->IsGtBias() ? &greater : &less, VS); // VS for unordered - break; - } + case Primitive::kPrimFloat: case Primitive::kPrimDouble: { __ LoadImmediate(out, 0); - __ vcmpd(FromLowSToD(left.AsFpuRegisterPairLow<SRegister>()), - FromLowSToD(right.AsFpuRegisterPairLow<SRegister>())); - __ b(compare->IsGtBias() ? &greater : &less, VS); + if (type == Primitive::kPrimFloat) { + __ vcmps(left.AsFpuRegister<SRegister>(), right.AsFpuRegister<SRegister>()); + } else { + __ vcmpd(FromLowSToD(left.AsFpuRegisterPairLow<SRegister>()), + FromLowSToD(right.AsFpuRegisterPairLow<SRegister>())); + } + __ vmstat(); // transfer FP status register to ARM APSR. + __ b(compare->IsGtBias() ? &greater : &less, VS); // VS for unordered. break; } default: - LOG(FATAL) << "Unexpected compare type " << compare->InputAt(0)->GetType(); + LOG(FATAL) << "Unexpected compare type " << type; } __ b(&done, EQ); __ b(&less, CC); // CC is for both: unsigned compare for longs and 'less than' for floats. @@ -2389,32 +2505,32 @@ void LocationsBuilderARM::VisitInstanceFieldSet(HInstanceFieldSet* instruction) void InstructionCodeGeneratorARM::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: { - Register value = locations->InAt(1).As<Register>(); + Register value = locations->InAt(1).AsRegister<Register>(); __ StoreToOffset(kStoreByte, value, obj, offset); break; } case Primitive::kPrimShort: case Primitive::kPrimChar: { - Register value = locations->InAt(1).As<Register>(); + Register value = locations->InAt(1).AsRegister<Register>(); __ StoreToOffset(kStoreHalfword, value, obj, offset); break; } case Primitive::kPrimInt: case Primitive::kPrimNot: { - Register value = locations->InAt(1).As<Register>(); + Register value = locations->InAt(1).AsRegister<Register>(); __ StoreToOffset(kStoreWord, value, obj, offset); if (CodeGenerator::StoreNeedsWriteBarrier(field_type, instruction->GetValue())) { - 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; @@ -2427,7 +2543,7 @@ void InstructionCodeGeneratorARM::VisitInstanceFieldSet(HInstanceFieldSet* instr } case Primitive::kPrimFloat: { - SRegister value = locations->InAt(1).As<SRegister>(); + SRegister value = locations->InAt(1).AsFpuRegister<SRegister>(); __ StoreSToOffset(value, obj, offset); break; } @@ -2453,37 +2569,37 @@ void LocationsBuilderARM::VisitInstanceFieldGet(HInstanceFieldGet* instruction) void InstructionCodeGeneratorARM::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>(); __ LoadFromOffset(kLoadUnsignedByte, out, obj, offset); break; } case Primitive::kPrimByte: { - Register out = locations->Out().As<Register>(); + Register out = locations->Out().AsRegister<Register>(); __ LoadFromOffset(kLoadSignedByte, out, obj, offset); break; } case Primitive::kPrimShort: { - Register out = locations->Out().As<Register>(); + Register out = locations->Out().AsRegister<Register>(); __ LoadFromOffset(kLoadSignedHalfword, out, obj, offset); break; } case Primitive::kPrimChar: { - Register out = locations->Out().As<Register>(); + Register out = locations->Out().AsRegister<Register>(); __ LoadFromOffset(kLoadUnsignedHalfword, out, obj, offset); break; } case Primitive::kPrimInt: case Primitive::kPrimNot: { - Register out = locations->Out().As<Register>(); + Register out = locations->Out().AsRegister<Register>(); __ LoadFromOffset(kLoadWord, out, obj, offset); break; } @@ -2496,7 +2612,7 @@ void InstructionCodeGeneratorARM::VisitInstanceFieldGet(HInstanceFieldGet* instr } case Primitive::kPrimFloat: { - SRegister out = locations->Out().As<SRegister>(); + SRegister out = locations->Out().AsFpuRegister<SRegister>(); __ LoadSFromOffset(out, obj, offset); break; } @@ -2530,7 +2646,7 @@ void InstructionCodeGeneratorARM::VisitNullCheck(HNullCheck* instruction) { Location obj = locations->InAt(0); if (obj.IsRegister()) { - __ cmp(obj.As<Register>(), ShifterOperand(0)); + __ cmp(obj.AsRegister<Register>(), ShifterOperand(0)); __ b(slow_path->GetEntryLabel(), EQ); } else { DCHECK(obj.IsConstant()) << obj; @@ -2549,18 +2665,19 @@ void LocationsBuilderARM::VisitArrayGet(HArrayGet* instruction) { void InstructionCodeGeneratorARM::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()) { - size_t offset = (index.GetConstant()->AsIntConstant()->GetValue() << TIMES_1) + data_offset; + size_t offset = + (index.GetConstant()->AsIntConstant()->GetValue() << TIMES_1) + data_offset; __ LoadFromOffset(kLoadUnsignedByte, out, obj, offset); } else { - __ add(IP, obj, ShifterOperand(index.As<Register>())); + __ add(IP, obj, ShifterOperand(index.AsRegister<Register>())); __ LoadFromOffset(kLoadUnsignedByte, out, IP, data_offset); } break; @@ -2568,12 +2685,13 @@ void InstructionCodeGeneratorARM::VisitArrayGet(HArrayGet* instruction) { 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()) { - size_t offset = (index.GetConstant()->AsIntConstant()->GetValue() << TIMES_1) + data_offset; + size_t offset = + (index.GetConstant()->AsIntConstant()->GetValue() << TIMES_1) + data_offset; __ LoadFromOffset(kLoadSignedByte, out, obj, offset); } else { - __ add(IP, obj, ShifterOperand(index.As<Register>())); + __ add(IP, obj, ShifterOperand(index.AsRegister<Register>())); __ LoadFromOffset(kLoadSignedByte, out, IP, data_offset); } break; @@ -2581,12 +2699,13 @@ void InstructionCodeGeneratorARM::VisitArrayGet(HArrayGet* instruction) { 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()) { - size_t offset = (index.GetConstant()->AsIntConstant()->GetValue() << TIMES_2) + data_offset; + size_t offset = + (index.GetConstant()->AsIntConstant()->GetValue() << TIMES_2) + data_offset; __ LoadFromOffset(kLoadSignedHalfword, out, obj, offset); } else { - __ add(IP, obj, ShifterOperand(index.As<Register>(), LSL, TIMES_2)); + __ add(IP, obj, ShifterOperand(index.AsRegister<Register>(), LSL, TIMES_2)); __ LoadFromOffset(kLoadSignedHalfword, out, IP, data_offset); } break; @@ -2594,12 +2713,13 @@ void InstructionCodeGeneratorARM::VisitArrayGet(HArrayGet* instruction) { 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()) { - size_t offset = (index.GetConstant()->AsIntConstant()->GetValue() << TIMES_2) + data_offset; + size_t offset = + (index.GetConstant()->AsIntConstant()->GetValue() << TIMES_2) + data_offset; __ LoadFromOffset(kLoadUnsignedHalfword, out, obj, offset); } else { - __ add(IP, obj, ShifterOperand(index.As<Register>(), LSL, TIMES_2)); + __ add(IP, obj, ShifterOperand(index.AsRegister<Register>(), LSL, TIMES_2)); __ LoadFromOffset(kLoadUnsignedHalfword, out, IP, data_offset); } break; @@ -2609,12 +2729,13 @@ void InstructionCodeGeneratorARM::VisitArrayGet(HArrayGet* instruction) { case Primitive::kPrimNot: { DCHECK_EQ(sizeof(mirror::HeapReference<mirror::Object>), sizeof(int32_t)); 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()) { - size_t offset = (index.GetConstant()->AsIntConstant()->GetValue() << TIMES_4) + data_offset; + size_t offset = + (index.GetConstant()->AsIntConstant()->GetValue() << TIMES_4) + data_offset; __ LoadFromOffset(kLoadWord, out, obj, offset); } else { - __ add(IP, obj, ShifterOperand(index.As<Register>(), LSL, TIMES_4)); + __ add(IP, obj, ShifterOperand(index.AsRegister<Register>(), LSL, TIMES_4)); __ LoadFromOffset(kLoadWord, out, IP, data_offset); } break; @@ -2624,10 +2745,11 @@ void InstructionCodeGeneratorARM::VisitArrayGet(HArrayGet* instruction) { uint32_t data_offset = mirror::Array::DataOffset(sizeof(int64_t)).Uint32Value(); Location out = locations->Out(); if (index.IsConstant()) { - size_t offset = (index.GetConstant()->AsIntConstant()->GetValue() << TIMES_8) + data_offset; + size_t offset = + (index.GetConstant()->AsIntConstant()->GetValue() << TIMES_8) + data_offset; __ LoadFromOffset(kLoadWordPair, out.AsRegisterPairLow<Register>(), obj, offset); } else { - __ add(IP, obj, ShifterOperand(index.As<Register>(), LSL, TIMES_8)); + __ add(IP, obj, ShifterOperand(index.AsRegister<Register>(), LSL, TIMES_8)); __ LoadFromOffset(kLoadWordPair, out.AsRegisterPairLow<Register>(), IP, data_offset); } break; @@ -2672,7 +2794,7 @@ void LocationsBuilderARM::VisitArraySet(HArraySet* instruction) { void InstructionCodeGeneratorARM::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); Primitive::Type value_type = instruction->GetComponentType(); bool needs_runtime_call = locations->WillCall(); @@ -2683,12 +2805,13 @@ void InstructionCodeGeneratorARM::VisitArraySet(HArraySet* instruction) { case Primitive::kPrimBoolean: case Primitive::kPrimByte: { uint32_t data_offset = mirror::Array::DataOffset(sizeof(uint8_t)).Uint32Value(); - Register value = locations->InAt(2).As<Register>(); + Register value = locations->InAt(2).AsRegister<Register>(); if (index.IsConstant()) { - size_t offset = (index.GetConstant()->AsIntConstant()->GetValue() << TIMES_1) + data_offset; + size_t offset = + (index.GetConstant()->AsIntConstant()->GetValue() << TIMES_1) + data_offset; __ StoreToOffset(kStoreByte, value, obj, offset); } else { - __ add(IP, obj, ShifterOperand(index.As<Register>())); + __ add(IP, obj, ShifterOperand(index.AsRegister<Register>())); __ StoreToOffset(kStoreByte, value, IP, data_offset); } break; @@ -2697,12 +2820,13 @@ void InstructionCodeGeneratorARM::VisitArraySet(HArraySet* instruction) { case Primitive::kPrimShort: case Primitive::kPrimChar: { uint32_t data_offset = mirror::Array::DataOffset(sizeof(uint16_t)).Uint32Value(); - Register value = locations->InAt(2).As<Register>(); + Register value = locations->InAt(2).AsRegister<Register>(); if (index.IsConstant()) { - size_t offset = (index.GetConstant()->AsIntConstant()->GetValue() << TIMES_2) + data_offset; + size_t offset = + (index.GetConstant()->AsIntConstant()->GetValue() << TIMES_2) + data_offset; __ StoreToOffset(kStoreHalfword, value, obj, offset); } else { - __ add(IP, obj, ShifterOperand(index.As<Register>(), LSL, TIMES_2)); + __ add(IP, obj, ShifterOperand(index.AsRegister<Register>(), LSL, TIMES_2)); __ StoreToOffset(kStoreHalfword, value, IP, data_offset); } break; @@ -2712,24 +2836,27 @@ void InstructionCodeGeneratorARM::VisitArraySet(HArraySet* instruction) { case Primitive::kPrimNot: { if (!needs_runtime_call) { uint32_t data_offset = mirror::Array::DataOffset(sizeof(int32_t)).Uint32Value(); - Register value = locations->InAt(2).As<Register>(); + Register value = locations->InAt(2).AsRegister<Register>(); 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; __ StoreToOffset(kStoreWord, value, obj, offset); } else { DCHECK(index.IsRegister()) << index; - __ add(IP, obj, ShifterOperand(index.As<Register>(), LSL, TIMES_4)); + __ add(IP, obj, ShifterOperand(index.AsRegister<Register>(), LSL, TIMES_4)); __ StoreToOffset(kStoreWord, value, IP, data_offset); } if (needs_write_barrier) { DCHECK_EQ(value_type, Primitive::kPrimNot); - 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); } } else { DCHECK_EQ(value_type, Primitive::kPrimNot); - codegen_->InvokeRuntime(QUICK_ENTRY_POINT(pAputObject), instruction, instruction->GetDexPc()); + codegen_->InvokeRuntime(QUICK_ENTRY_POINT(pAputObject), + instruction, + instruction->GetDexPc()); } break; } @@ -2738,10 +2865,11 @@ void InstructionCodeGeneratorARM::VisitArraySet(HArraySet* instruction) { uint32_t data_offset = mirror::Array::DataOffset(sizeof(int64_t)).Uint32Value(); Location value = locations->InAt(2); if (index.IsConstant()) { - size_t offset = (index.GetConstant()->AsIntConstant()->GetValue() << TIMES_8) + data_offset; + size_t offset = + (index.GetConstant()->AsIntConstant()->GetValue() << TIMES_8) + data_offset; __ StoreToOffset(kStoreWordPair, value.AsRegisterPairLow<Register>(), obj, offset); } else { - __ add(IP, obj, ShifterOperand(index.As<Register>(), LSL, TIMES_8)); + __ add(IP, obj, ShifterOperand(index.AsRegister<Register>(), LSL, TIMES_8)); __ StoreToOffset(kStoreWordPair, value.AsRegisterPairLow<Register>(), IP, data_offset); } break; @@ -2767,8 +2895,8 @@ void LocationsBuilderARM::VisitArrayLength(HArrayLength* instruction) { void InstructionCodeGeneratorARM::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>(); __ LoadFromOffset(kLoadWord, out, obj, offset); } @@ -2788,8 +2916,8 @@ void InstructionCodeGeneratorARM::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>(); __ cmp(index, ShifterOperand(length)); __ b(slow_path->GetEntryLabel(), CS); @@ -2870,15 +2998,15 @@ void ParallelMoveResolverARM::EmitMove(size_t index) { if (source.IsRegister()) { if (destination.IsRegister()) { - __ Mov(destination.As<Register>(), source.As<Register>()); + __ Mov(destination.AsRegister<Register>(), source.AsRegister<Register>()); } else { DCHECK(destination.IsStackSlot()); - __ StoreToOffset(kStoreWord, source.As<Register>(), + __ StoreToOffset(kStoreWord, source.AsRegister<Register>(), SP, destination.GetStackIndex()); } } else if (source.IsStackSlot()) { if (destination.IsRegister()) { - __ LoadFromOffset(kLoadWord, destination.As<Register>(), + __ LoadFromOffset(kLoadWord, destination.AsRegister<Register>(), SP, source.GetStackIndex()); } else { DCHECK(destination.IsStackSlot()); @@ -2890,7 +3018,7 @@ void ParallelMoveResolverARM::EmitMove(size_t index) { DCHECK(source.GetConstant()->IsIntConstant()); int32_t value = source.GetConstant()->AsIntConstant()->GetValue(); if (destination.IsRegister()) { - __ LoadImmediate(destination.As<Register>(), value); + __ LoadImmediate(destination.AsRegister<Register>(), value); } else { DCHECK(destination.IsStackSlot()); __ LoadImmediate(IP, value); @@ -2922,15 +3050,15 @@ void ParallelMoveResolverARM::EmitSwap(size_t index) { Location destination = move->GetDestination(); if (source.IsRegister() && destination.IsRegister()) { - DCHECK_NE(source.As<Register>(), IP); - DCHECK_NE(destination.As<Register>(), IP); - __ Mov(IP, source.As<Register>()); - __ Mov(source.As<Register>(), destination.As<Register>()); - __ Mov(destination.As<Register>(), IP); + DCHECK_NE(source.AsRegister<Register>(), IP); + DCHECK_NE(destination.AsRegister<Register>(), IP); + __ Mov(IP, source.AsRegister<Register>()); + __ Mov(source.AsRegister<Register>(), destination.AsRegister<Register>()); + __ Mov(destination.AsRegister<Register>(), IP); } 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(source.GetStackIndex(), destination.GetStackIndex()); } else { @@ -2956,7 +3084,7 @@ void LocationsBuilderARM::VisitLoadClass(HLoadClass* cls) { } void InstructionCodeGeneratorARM::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()); @@ -2996,7 +3124,8 @@ void InstructionCodeGeneratorARM::VisitClinitCheck(HClinitCheck* check) { SlowPathCodeARM* slow_path = new (GetGraph()->GetArena()) LoadClassSlowPathARM( 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 InstructionCodeGeneratorARM::GenerateClassInitializationCheck( @@ -3019,37 +3148,37 @@ void LocationsBuilderARM::VisitStaticFieldGet(HStaticFieldGet* instruction) { void InstructionCodeGeneratorARM::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>(); __ LoadFromOffset(kLoadUnsignedByte, out, cls, offset); break; } case Primitive::kPrimByte: { - Register out = locations->Out().As<Register>(); + Register out = locations->Out().AsRegister<Register>(); __ LoadFromOffset(kLoadSignedByte, out, cls, offset); break; } case Primitive::kPrimShort: { - Register out = locations->Out().As<Register>(); + Register out = locations->Out().AsRegister<Register>(); __ LoadFromOffset(kLoadSignedHalfword, out, cls, offset); break; } case Primitive::kPrimChar: { - Register out = locations->Out().As<Register>(); + Register out = locations->Out().AsRegister<Register>(); __ LoadFromOffset(kLoadUnsignedHalfword, out, cls, offset); break; } case Primitive::kPrimInt: case Primitive::kPrimNot: { - Register out = locations->Out().As<Register>(); + Register out = locations->Out().AsRegister<Register>(); __ LoadFromOffset(kLoadWord, out, cls, offset); break; } @@ -3062,7 +3191,7 @@ void InstructionCodeGeneratorARM::VisitStaticFieldGet(HStaticFieldGet* instructi } case Primitive::kPrimFloat: { - SRegister out = locations->Out().As<SRegister>(); + SRegister out = locations->Out().AsFpuRegister<SRegister>(); __ LoadSFromOffset(out, cls, offset); break; } @@ -3095,32 +3224,32 @@ void LocationsBuilderARM::VisitStaticFieldSet(HStaticFieldSet* instruction) { void InstructionCodeGeneratorARM::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: { - Register value = locations->InAt(1).As<Register>(); + Register value = locations->InAt(1).AsRegister<Register>(); __ StoreToOffset(kStoreByte, value, cls, offset); break; } case Primitive::kPrimShort: case Primitive::kPrimChar: { - Register value = locations->InAt(1).As<Register>(); + Register value = locations->InAt(1).AsRegister<Register>(); __ StoreToOffset(kStoreHalfword, value, cls, offset); break; } case Primitive::kPrimInt: case Primitive::kPrimNot: { - Register value = locations->InAt(1).As<Register>(); + Register value = locations->InAt(1).AsRegister<Register>(); __ StoreToOffset(kStoreWord, value, cls, offset); if (CodeGenerator::StoreNeedsWriteBarrier(field_type, instruction->GetValue())) { - 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; @@ -3133,7 +3262,7 @@ void InstructionCodeGeneratorARM::VisitStaticFieldSet(HStaticFieldSet* instructi } case Primitive::kPrimFloat: { - SRegister value = locations->InAt(1).As<SRegister>(); + SRegister value = locations->InAt(1).AsFpuRegister<SRegister>(); __ StoreSToOffset(value, cls, offset); break; } @@ -3160,7 +3289,7 @@ void InstructionCodeGeneratorARM::VisitLoadString(HLoadString* load) { SlowPathCodeARM* slow_path = new (GetGraph()->GetArena()) LoadStringSlowPathARM(load); codegen_->AddSlowPath(slow_path); - Register out = load->GetLocations()->Out().As<Register>(); + Register out = load->GetLocations()->Out().AsRegister<Register>(); codegen_->LoadCurrentMethod(out); __ LoadFromOffset(kLoadWord, out, out, mirror::ArtMethod::DeclaringClassOffset().Int32Value()); __ LoadFromOffset(kLoadWord, out, out, mirror::Class::DexCacheStringsOffset().Int32Value()); @@ -3177,7 +3306,7 @@ void LocationsBuilderARM::VisitLoadException(HLoadException* load) { } void InstructionCodeGeneratorARM::VisitLoadException(HLoadException* load) { - Register out = load->GetLocations()->Out().As<Register>(); + Register out = load->GetLocations()->Out().AsRegister<Register>(); int32_t offset = Thread::ExceptionOffset<kArmWordSize>().Int32Value(); __ LoadFromOffset(kLoadWord, out, TR, offset); __ LoadImmediate(IP, 0); @@ -3208,9 +3337,9 @@ void LocationsBuilderARM::VisitInstanceOf(HInstanceOf* instruction) { void InstructionCodeGeneratorARM::VisitInstanceOf(HInstanceOf* instruction) { LocationSummary* locations = instruction->GetLocations(); - Register obj = locations->InAt(0).As<Register>(); - Register cls = locations->InAt(1).As<Register>(); - Register out = locations->Out().As<Register>(); + Register obj = locations->InAt(0).AsRegister<Register>(); + Register cls = locations->InAt(1).AsRegister<Register>(); + Register out = locations->Out().AsRegister<Register>(); uint32_t class_offset = mirror::Object::ClassOffset().Int32Value(); Label done, zero; SlowPathCodeARM* slow_path = nullptr; @@ -3255,9 +3384,9 @@ void LocationsBuilderARM::VisitCheckCast(HCheckCast* instruction) { void InstructionCodeGeneratorARM::VisitCheckCast(HCheckCast* instruction) { LocationSummary* locations = instruction->GetLocations(); - Register obj = locations->InAt(0).As<Register>(); - Register cls = locations->InAt(1).As<Register>(); - Register temp = locations->GetTemp(0).As<Register>(); + Register obj = locations->InAt(0).AsRegister<Register>(); + Register cls = locations->InAt(1).AsRegister<Register>(); + Register temp = locations->GetTemp(0).AsRegister<Register>(); uint32_t class_offset = mirror::Object::ClassOffset().Int32Value(); SlowPathCodeARM* slow_path = new (GetGraph()->GetArena()) TypeCheckSlowPathARM( @@ -3319,9 +3448,9 @@ void InstructionCodeGeneratorARM::HandleBitwiseOperation(HBinaryOperation* instr LocationSummary* locations = instruction->GetLocations(); if (instruction->GetResultType() == Primitive::kPrimInt) { - Register first = locations->InAt(0).As<Register>(); - Register second = locations->InAt(1).As<Register>(); - Register out = locations->Out().As<Register>(); + Register first = locations->InAt(0).AsRegister<Register>(); + Register second = locations->InAt(1).AsRegister<Register>(); + Register out = locations->Out().AsRegister<Register>(); if (instruction->IsAnd()) { __ and_(out, first, ShifterOperand(second)); } else if (instruction->IsOr()) { diff --git a/compiler/optimizing/code_generator_x86.cc b/compiler/optimizing/code_generator_x86.cc index 537e5e10d7..b21abadda3 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 @@ -1169,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(); @@ -1180,7 +1196,7 @@ 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)); @@ -1200,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(); @@ -1209,14 +1225,14 @@ 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)); @@ -1239,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: @@ -1259,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: @@ -1275,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(); @@ -1406,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"; @@ -1429,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"; @@ -1460,13 +1503,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; @@ -1483,13 +1526,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; @@ -1504,14 +1547,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; @@ -1536,7 +1579,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; @@ -1560,13 +1603,13 @@ void InstructionCodeGeneratorX86::VisitTypeConversion(HTypeConversion* conversio 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; @@ -1578,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"; @@ -1600,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"; @@ -1660,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; } @@ -1683,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; } @@ -1736,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; } @@ -1758,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; } @@ -1818,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; } @@ -1836,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); @@ -1868,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; } @@ -1893,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! @@ -1997,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; } @@ -2097,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)); @@ -2112,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()); @@ -2165,9 +2269,9 @@ void InstructionCodeGeneratorX86::HandleShift(HBinaryOperation* op) { switch (op->GetResultType()) { case Primitive::kPrimInt: { - Register first_reg = first.As<Register>(); + Register first_reg = first.AsRegister<Register>(); if (second.IsRegister()) { - Register second_reg = second.As<Register>(); + Register second_reg = second.AsRegister<Register>(); DCHECK_EQ(ECX, second_reg); if (op->IsShl()) { __ shll(first_reg, second_reg); @@ -2189,7 +2293,7 @@ void InstructionCodeGeneratorX86::HandleShift(HBinaryOperation* op) { break; } case Primitive::kPrimLong: { - Register second_reg = second.As<Register>(); + Register second_reg = second.AsRegister<Register>(); DCHECK_EQ(ECX, second_reg); if (op->IsShl()) { GenerateShlLong(first, second_reg); @@ -2335,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: @@ -2377,7 +2481,7 @@ void LocationsBuilderX86::VisitCompare(HCompare* compare) { void InstructionCodeGeneratorX86::VisitCompare(HCompare* compare) { LocationSummary* locations = compare->GetLocations(); - Register out = locations->Out().As<Register>(); + Register out = locations->Out().AsRegister<Register>(); Location left = locations->InAt(0); Location right = locations->InAt(1); @@ -2402,12 +2506,12 @@ void InstructionCodeGeneratorX86::VisitCompare(HCompare* compare) { break; } case Primitive::kPrimFloat: { - __ ucomiss(left.As<XmmRegister>(), right.As<XmmRegister>()); + __ ucomiss(left.AsFpuRegister<XmmRegister>(), right.AsFpuRegister<XmmRegister>()); __ j(kUnordered, compare->IsGtBias() ? &greater : &less); break; } case Primitive::kPrimDouble: { - __ ucomisd(left.As<XmmRegister>(), right.As<XmmRegister>()); + __ ucomisd(left.AsFpuRegister<XmmRegister>(), right.AsFpuRegister<XmmRegister>()); __ j(kUnordered, compare->IsGtBias() ? &greater : &less); break; } @@ -2470,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; @@ -2510,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; } @@ -2548,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; } @@ -2591,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; } @@ -2625,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 { @@ -2647,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; } @@ -2702,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; } @@ -2721,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; } @@ -2783,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(); @@ -2798,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())); } } @@ -2821,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())); } } @@ -2843,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), @@ -2854,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); @@ -2892,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))); } } @@ -2928,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)); } @@ -2949,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()); @@ -3027,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(), @@ -3044,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); } @@ -3086,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 { @@ -3116,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()); @@ -3155,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( @@ -3176,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; } @@ -3219,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; } @@ -3263,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; @@ -3303,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; } @@ -3330,7 +3436,7 @@ 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::DeclaringClassOffset().Int32Value())); __ movl(out, Address(out, mirror::Class::DexCacheStringsOffset().Int32Value())); @@ -3348,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)); } @@ -3376,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; @@ -3390,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())); @@ -3429,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()); @@ -3444,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())); @@ -3503,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 { diff --git a/compiler/optimizing/code_generator_x86_64.cc b/compiler/optimizing/code_generator_x86_64.cc index a39b238d5a..5d3e809abb 100644 --- a/compiler/optimizing/code_generator_x86_64.cc +++ b/compiler/optimizing/code_generator_x86_64.cc @@ -539,37 +539,37 @@ void CodeGeneratorX86_64::Move(Location destination, Location source) { } if (destination.IsRegister()) { if (source.IsRegister()) { - __ movq(destination.As<CpuRegister>(), source.As<CpuRegister>()); + __ movq(destination.AsRegister<CpuRegister>(), source.AsRegister<CpuRegister>()); } else if (source.IsFpuRegister()) { - __ movd(destination.As<CpuRegister>(), source.As<XmmRegister>()); + __ movd(destination.AsRegister<CpuRegister>(), source.AsFpuRegister<XmmRegister>()); } else if (source.IsStackSlot()) { - __ movl(destination.As<CpuRegister>(), + __ movl(destination.AsRegister<CpuRegister>(), Address(CpuRegister(RSP), source.GetStackIndex())); } else { DCHECK(source.IsDoubleStackSlot()); - __ movq(destination.As<CpuRegister>(), + __ movq(destination.AsRegister<CpuRegister>(), Address(CpuRegister(RSP), source.GetStackIndex())); } } else if (destination.IsFpuRegister()) { if (source.IsRegister()) { - __ movd(destination.As<XmmRegister>(), source.As<CpuRegister>()); + __ movd(destination.AsFpuRegister<XmmRegister>(), source.AsRegister<CpuRegister>()); } else if (source.IsFpuRegister()) { - __ movaps(destination.As<XmmRegister>(), source.As<XmmRegister>()); + __ movaps(destination.AsFpuRegister<XmmRegister>(), source.AsFpuRegister<XmmRegister>()); } else if (source.IsStackSlot()) { - __ movss(destination.As<XmmRegister>(), + __ movss(destination.AsFpuRegister<XmmRegister>(), Address(CpuRegister(RSP), source.GetStackIndex())); } else { DCHECK(source.IsDoubleStackSlot()); - __ movsd(destination.As<XmmRegister>(), + __ movsd(destination.AsFpuRegister<XmmRegister>(), Address(CpuRegister(RSP), source.GetStackIndex())); } } else if (destination.IsStackSlot()) { if (source.IsRegister()) { __ movl(Address(CpuRegister(RSP), destination.GetStackIndex()), - source.As<CpuRegister>()); + source.AsRegister<CpuRegister>()); } else if (source.IsFpuRegister()) { __ movss(Address(CpuRegister(RSP), destination.GetStackIndex()), - source.As<XmmRegister>()); + source.AsFpuRegister<XmmRegister>()); } else { DCHECK(source.IsStackSlot()); __ movl(CpuRegister(TMP), Address(CpuRegister(RSP), source.GetStackIndex())); @@ -579,10 +579,10 @@ void CodeGeneratorX86_64::Move(Location destination, Location source) { DCHECK(destination.IsDoubleStackSlot()); if (source.IsRegister()) { __ movq(Address(CpuRegister(RSP), destination.GetStackIndex()), - source.As<CpuRegister>()); + source.AsRegister<CpuRegister>()); } else if (source.IsFpuRegister()) { __ movsd(Address(CpuRegister(RSP), destination.GetStackIndex()), - source.As<XmmRegister>()); + source.AsFpuRegister<XmmRegister>()); } else { DCHECK(source.IsDoubleStackSlot()); __ movq(CpuRegister(TMP), Address(CpuRegister(RSP), source.GetStackIndex())); @@ -604,7 +604,7 @@ void CodeGeneratorX86_64::Move(HInstruction* instruction, if (const_to_move->IsIntConstant()) { Immediate imm(const_to_move->AsIntConstant()->GetValue()); if (location.IsRegister()) { - __ movl(location.As<CpuRegister>(), imm); + __ movl(location.AsRegister<CpuRegister>(), imm); } else if (location.IsStackSlot()) { __ movl(Address(CpuRegister(RSP), location.GetStackIndex()), imm); } else { @@ -614,7 +614,7 @@ void CodeGeneratorX86_64::Move(HInstruction* instruction, } else if (const_to_move->IsLongConstant()) { int64_t value = const_to_move->AsLongConstant()->GetValue(); if (location.IsRegister()) { - __ movq(location.As<CpuRegister>(), Immediate(value)); + __ movq(location.AsRegister<CpuRegister>(), Immediate(value)); } else if (location.IsDoubleStackSlot()) { __ movq(CpuRegister(TMP), Immediate(value)); __ movq(Address(CpuRegister(RSP), location.GetStackIndex()), CpuRegister(TMP)); @@ -637,7 +637,8 @@ void CodeGeneratorX86_64::Move(HInstruction* instruction, case Primitive::kPrimLong: case Primitive::kPrimDouble: - Move(location, Location::DoubleStackSlot(GetStackSlot(instruction->AsLoadLocal()->GetLocal()))); + Move(location, + Location::DoubleStackSlot(GetStackSlot(instruction->AsLoadLocal()->GetLocal()))); break; default: @@ -741,7 +742,7 @@ void InstructionCodeGeneratorX86_64::VisitIf(HIf* if_instr) { // Materialized condition, compare against 0. Location lhs = if_instr->GetLocations()->InAt(0); if (lhs.IsRegister()) { - __ cmpl(lhs.As<CpuRegister>(), Immediate(0)); + __ cmpl(lhs.AsRegister<CpuRegister>(), Immediate(0)); } else { __ cmpl(Address(CpuRegister(RSP), lhs.GetStackIndex()), Immediate(0)); @@ -755,12 +756,12 @@ void InstructionCodeGeneratorX86_64::VisitIf(HIf* if_instr) { Location lhs = cond->GetLocations()->InAt(0); Location rhs = cond->GetLocations()->InAt(1); if (rhs.IsRegister()) { - __ cmpl(lhs.As<CpuRegister>(), rhs.As<CpuRegister>()); + __ cmpl(lhs.AsRegister<CpuRegister>(), rhs.AsRegister<CpuRegister>()); } else if (rhs.IsConstant()) { - __ cmpl(lhs.As<CpuRegister>(), + __ cmpl(lhs.AsRegister<CpuRegister>(), Immediate(rhs.GetConstant()->AsIntConstant()->GetValue())); } else { - __ cmpl(lhs.As<CpuRegister>(), + __ cmpl(lhs.AsRegister<CpuRegister>(), Address(CpuRegister(RSP), rhs.GetStackIndex())); } __ j(X86_64Condition(cond->AsCondition()->GetCondition()), @@ -831,17 +832,17 @@ void LocationsBuilderX86_64::VisitCondition(HCondition* comp) { void InstructionCodeGeneratorX86_64::VisitCondition(HCondition* comp) { if (comp->NeedsMaterialization()) { LocationSummary* locations = comp->GetLocations(); - CpuRegister reg = locations->Out().As<CpuRegister>(); + CpuRegister reg = locations->Out().AsRegister<CpuRegister>(); // Clear register: setcc only sets the low byte. __ xorq(reg, reg); if (locations->InAt(1).IsRegister()) { - __ cmpl(locations->InAt(0).As<CpuRegister>(), - locations->InAt(1).As<CpuRegister>()); + __ cmpl(locations->InAt(0).AsRegister<CpuRegister>(), + locations->InAt(1).AsRegister<CpuRegister>()); } else if (locations->InAt(1).IsConstant()) { - __ cmpl(locations->InAt(0).As<CpuRegister>(), + __ cmpl(locations->InAt(0).AsRegister<CpuRegister>(), Immediate(locations->InAt(1).GetConstant()->AsIntConstant()->GetValue())); } else { - __ cmpl(locations->InAt(0).As<CpuRegister>(), + __ cmpl(locations->InAt(0).AsRegister<CpuRegister>(), Address(CpuRegister(RSP), locations->InAt(1).GetStackIndex())); } __ setcc(X86_64Condition(comp->GetCondition()), reg); @@ -920,7 +921,7 @@ void LocationsBuilderX86_64::VisitCompare(HCompare* compare) { void InstructionCodeGeneratorX86_64::VisitCompare(HCompare* compare) { LocationSummary* locations = compare->GetLocations(); - CpuRegister out = locations->Out().As<CpuRegister>(); + CpuRegister out = locations->Out().AsRegister<CpuRegister>(); Location left = locations->InAt(0); Location right = locations->InAt(1); @@ -928,16 +929,16 @@ void InstructionCodeGeneratorX86_64::VisitCompare(HCompare* compare) { Primitive::Type type = compare->InputAt(0)->GetType(); switch (type) { case Primitive::kPrimLong: { - __ cmpq(left.As<CpuRegister>(), right.As<CpuRegister>()); + __ cmpq(left.AsRegister<CpuRegister>(), right.AsRegister<CpuRegister>()); break; } case Primitive::kPrimFloat: { - __ ucomiss(left.As<XmmRegister>(), right.As<XmmRegister>()); + __ ucomiss(left.AsFpuRegister<XmmRegister>(), right.AsFpuRegister<XmmRegister>()); __ j(kUnordered, compare->IsGtBias() ? &greater : &less); break; } case Primitive::kPrimDouble: { - __ ucomisd(left.As<XmmRegister>(), right.As<XmmRegister>()); + __ ucomisd(left.AsFpuRegister<XmmRegister>(), right.AsFpuRegister<XmmRegister>()); __ j(kUnordered, compare->IsGtBias() ? &greater : &less); break; } @@ -1047,12 +1048,12 @@ void InstructionCodeGeneratorX86_64::VisitReturn(HReturn* ret) { case Primitive::kPrimInt: case Primitive::kPrimNot: case Primitive::kPrimLong: - DCHECK_EQ(ret->GetLocations()->InAt(0).As<CpuRegister>().AsRegister(), RAX); + DCHECK_EQ(ret->GetLocations()->InAt(0).AsRegister<CpuRegister>().AsRegister(), RAX); break; case Primitive::kPrimFloat: case Primitive::kPrimDouble: - DCHECK_EQ(ret->GetLocations()->InAt(0).As<XmmRegister>().AsFloatRegister(), + DCHECK_EQ(ret->GetLocations()->InAt(0).AsFpuRegister<XmmRegister>().AsFloatRegister(), XMM0); break; @@ -1125,7 +1126,7 @@ void LocationsBuilderX86_64::VisitInvokeStatic(HInvokeStatic* invoke) { } void InstructionCodeGeneratorX86_64::VisitInvokeStatic(HInvokeStatic* invoke) { - CpuRegister temp = invoke->GetLocations()->GetTemp(0).As<CpuRegister>(); + CpuRegister temp = invoke->GetLocations()->GetTemp(0).AsRegister<CpuRegister>(); // TODO: Implement all kinds of calls: // 1) boot -> boot // 2) app -> boot @@ -1184,7 +1185,7 @@ void LocationsBuilderX86_64::VisitInvokeVirtual(HInvokeVirtual* invoke) { } void InstructionCodeGeneratorX86_64::VisitInvokeVirtual(HInvokeVirtual* invoke) { - CpuRegister temp = invoke->GetLocations()->GetTemp(0).As<CpuRegister>(); + CpuRegister temp = invoke->GetLocations()->GetTemp(0).AsRegister<CpuRegister>(); size_t method_offset = mirror::Class::EmbeddedVTableOffset().SizeValue() + invoke->GetVTableIndex() * sizeof(mirror::Class::VTableEntry); LocationSummary* locations = invoke->GetLocations(); @@ -1195,7 +1196,7 @@ void InstructionCodeGeneratorX86_64::VisitInvokeVirtual(HInvokeVirtual* invoke) __ movl(temp, Address(CpuRegister(RSP), receiver.GetStackIndex())); __ movl(temp, Address(temp, class_offset)); } else { - __ movl(temp, Address(receiver.As<CpuRegister>(), class_offset)); + __ movl(temp, Address(receiver.AsRegister<CpuRegister>(), class_offset)); } // temp = temp->GetMethodAt(method_offset); __ movl(temp, Address(temp, method_offset)); @@ -1215,7 +1216,7 @@ void LocationsBuilderX86_64::VisitInvokeInterface(HInvokeInterface* invoke) { void InstructionCodeGeneratorX86_64::VisitInvokeInterface(HInvokeInterface* invoke) { // TODO: b/18116999, our IMTs can miss an IncompatibleClassChangeError. - CpuRegister temp = invoke->GetLocations()->GetTemp(0).As<CpuRegister>(); + CpuRegister temp = invoke->GetLocations()->GetTemp(0).AsRegister<CpuRegister>(); uint32_t method_offset = mirror::Class::EmbeddedImTableOffset().Uint32Value() + (invoke->GetImtIndex() % mirror::Class::kImtSize) * sizeof(mirror::Class::ImTableEntry); LocationSummary* locations = invoke->GetLocations(); @@ -1223,7 +1224,7 @@ void InstructionCodeGeneratorX86_64::VisitInvokeInterface(HInvokeInterface* invo size_t class_offset = mirror::Object::ClassOffset().SizeValue(); // Set the hidden argument. - __ movq(invoke->GetLocations()->GetTemp(1).As<CpuRegister>(), + __ movq(invoke->GetLocations()->GetTemp(1).AsRegister<CpuRegister>(), Immediate(invoke->GetDexMethodIndex())); // temp = object->GetClass(); @@ -1231,7 +1232,7 @@ void InstructionCodeGeneratorX86_64::VisitInvokeInterface(HInvokeInterface* invo __ movl(temp, Address(CpuRegister(RSP), receiver.GetStackIndex())); __ movl(temp, Address(temp, class_offset)); } else { - __ movl(temp, Address(receiver.As<CpuRegister>(), class_offset)); + __ movl(temp, Address(receiver.AsRegister<CpuRegister>(), class_offset)); } // temp = temp->GetImtEntryAt(method_offset); __ movl(temp, Address(temp, method_offset)); @@ -1256,9 +1257,9 @@ void LocationsBuilderX86_64::VisitNeg(HNeg* neg) { case Primitive::kPrimFloat: 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::RequiresRegister()); + locations->AddTemp(Location::RequiresFpuRegister()); break; default: @@ -1274,49 +1275,40 @@ void InstructionCodeGeneratorX86_64::VisitNeg(HNeg* neg) { case Primitive::kPrimInt: DCHECK(in.IsRegister()); DCHECK(in.Equals(out)); - __ negl(out.As<CpuRegister>()); + __ negl(out.AsRegister<CpuRegister>()); break; case Primitive::kPrimLong: DCHECK(in.IsRegister()); DCHECK(in.Equals(out)); - __ negq(out.As<CpuRegister>()); + __ negq(out.AsRegister<CpuRegister>()); break; - case Primitive::kPrimFloat: - DCHECK(in.IsFpuRegister()); - DCHECK(out.IsFpuRegister()); - DCHECK(!in.Equals(out)); - // TODO: Instead of computing negation as a subtraction from - // zero, implement it with an exclusive or with value 0x80000000 - // (mask for bit 31, representing the sign of a single-precision - // floating-point number), fetched from a constant pool: - // - // xorps out, [RIP:...] // value at RIP is 0x80 00 00 00 - - // 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)); + CpuRegister constant = locations->GetTemp(0).AsRegister<CpuRegister>(); + 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). + __ movq(constant, Immediate(INT64_C(0x80000000))); + __ movd(mask, constant); + __ xorps(out.AsFpuRegister<XmmRegister>(), mask); break; + } - case Primitive::kPrimDouble: - DCHECK(in.IsFpuRegister()); - DCHECK(out.IsFpuRegister()); - DCHECK(!in.Equals(out)); - // TODO: Instead of computing negation as a subtraction from - // zero, implement it with an exclusive or with value + case Primitive::kPrimDouble: { + DCHECK(in.Equals(out)); + CpuRegister constant = locations->GetTemp(0).AsRegister<CpuRegister>(); + XmmRegister mask = locations->GetTemp(1).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), fetched from a - // constant pool: - // - // xorpd out, [RIP:...] // value at RIP is 0x80 00 00 00 00 00 00 00 - - // out = 0 - __ xorpd(out.As<XmmRegister>(), out.As<XmmRegister>()); - // out = out - in - __ subsd(out.As<XmmRegister>(), in.As<XmmRegister>()); + // a double-precision floating-point number). + __ movq(constant, Immediate(INT64_C(0x8000000000000000))); + __ movd(mask, constant); + __ xorpd(out.AsFpuRegister<XmmRegister>(), mask); break; + } default: LOG(FATAL) << "Unexpected neg type " << neg->GetResultType(); @@ -1435,6 +1427,11 @@ void LocationsBuilderX86_64::VisitTypeConversion(HTypeConversion* conversion) { break; case Primitive::kPrimLong: + // Processing a Dex `long-to-float' instruction. + locations->SetInAt(0, Location::RequiresRegister()); + locations->SetOut(Location::RequiresFpuRegister()); + break; + case Primitive::kPrimDouble: LOG(FATAL) << "Type conversion from " << input_type << " to " << result_type << " not yet implemented"; @@ -1458,6 +1455,11 @@ void LocationsBuilderX86_64::VisitTypeConversion(HTypeConversion* conversion) { break; case Primitive::kPrimLong: + // Processing a Dex `long-to-double' instruction. + locations->SetInAt(0, Location::RequiresRegister()); + locations->SetOut(Location::RequiresFpuRegister()); + break; + case Primitive::kPrimFloat: LOG(FATAL) << "Type conversion from " << input_type << " to " << result_type << " not yet implemented"; @@ -1489,13 +1491,13 @@ void InstructionCodeGeneratorX86_64::VisitTypeConversion(HTypeConversion* conver case Primitive::kPrimChar: // Processing a Dex `int-to-byte' instruction. if (in.IsRegister()) { - __ movsxb(out.As<CpuRegister>(), in.As<CpuRegister>()); + __ movsxb(out.AsRegister<CpuRegister>(), in.AsRegister<CpuRegister>()); } else if (in.IsStackSlot()) { - __ movsxb(out.As<CpuRegister>(), + __ movsxb(out.AsRegister<CpuRegister>(), Address(CpuRegister(RSP), in.GetStackIndex())); } else { DCHECK(in.GetConstant()->IsIntConstant()); - __ movl(out.As<CpuRegister>(), + __ movl(out.AsRegister<CpuRegister>(), Immediate(static_cast<int8_t>(in.GetConstant()->AsIntConstant()->GetValue()))); } break; @@ -1513,13 +1515,13 @@ void InstructionCodeGeneratorX86_64::VisitTypeConversion(HTypeConversion* conver case Primitive::kPrimChar: // Processing a Dex `int-to-short' instruction. if (in.IsRegister()) { - __ movsxw(out.As<CpuRegister>(), in.As<CpuRegister>()); + __ movsxw(out.AsRegister<CpuRegister>(), in.AsRegister<CpuRegister>()); } else if (in.IsStackSlot()) { - __ movsxw(out.As<CpuRegister>(), + __ movsxw(out.AsRegister<CpuRegister>(), Address(CpuRegister(RSP), in.GetStackIndex())); } else { DCHECK(in.GetConstant()->IsIntConstant()); - __ movl(out.As<CpuRegister>(), + __ movl(out.AsRegister<CpuRegister>(), Immediate(static_cast<int16_t>(in.GetConstant()->AsIntConstant()->GetValue()))); } break; @@ -1535,15 +1537,15 @@ void InstructionCodeGeneratorX86_64::VisitTypeConversion(HTypeConversion* conver case Primitive::kPrimLong: // Processing a Dex `long-to-int' instruction. if (in.IsRegister()) { - __ movl(out.As<CpuRegister>(), in.As<CpuRegister>()); + __ movl(out.AsRegister<CpuRegister>(), in.AsRegister<CpuRegister>()); } else if (in.IsDoubleStackSlot()) { - __ movl(out.As<CpuRegister>(), + __ movl(out.AsRegister<CpuRegister>(), Address(CpuRegister(RSP), in.GetStackIndex())); } else { DCHECK(in.IsConstant()); DCHECK(in.GetConstant()->IsLongConstant()); int64_t value = in.GetConstant()->AsLongConstant()->GetValue(); - __ movl(out.As<CpuRegister>(), Immediate(static_cast<int32_t>(value))); + __ movl(out.AsRegister<CpuRegister>(), Immediate(static_cast<int32_t>(value))); } break; @@ -1568,7 +1570,7 @@ void InstructionCodeGeneratorX86_64::VisitTypeConversion(HTypeConversion* conver case Primitive::kPrimChar: // Processing a Dex `int-to-long' instruction. DCHECK(in.IsRegister()); - __ movsxd(out.As<CpuRegister>(), in.As<CpuRegister>()); + __ movsxd(out.AsRegister<CpuRegister>(), in.AsRegister<CpuRegister>()); break; case Primitive::kPrimFloat: @@ -1591,13 +1593,13 @@ void InstructionCodeGeneratorX86_64::VisitTypeConversion(HTypeConversion* conver case Primitive::kPrimChar: // Processing a Dex `int-to-char' instruction. if (in.IsRegister()) { - __ movzxw(out.As<CpuRegister>(), in.As<CpuRegister>()); + __ movzxw(out.AsRegister<CpuRegister>(), in.AsRegister<CpuRegister>()); } else if (in.IsStackSlot()) { - __ movzxw(out.As<CpuRegister>(), + __ movzxw(out.AsRegister<CpuRegister>(), Address(CpuRegister(RSP), in.GetStackIndex())); } else { DCHECK(in.GetConstant()->IsIntConstant()); - __ movl(out.As<CpuRegister>(), + __ movl(out.AsRegister<CpuRegister>(), Immediate(static_cast<uint16_t>(in.GetConstant()->AsIntConstant()->GetValue()))); } break; @@ -1610,15 +1612,19 @@ void InstructionCodeGeneratorX86_64::VisitTypeConversion(HTypeConversion* conver 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<CpuRegister>()); + // Processing a Dex `int-to-float' instruction. + __ cvtsi2ss(out.AsFpuRegister<XmmRegister>(), in.AsRegister<CpuRegister>(), false); break; case Primitive::kPrimLong: + // Processing a Dex `long-to-float' instruction. + __ cvtsi2ss(out.AsFpuRegister<XmmRegister>(), in.AsRegister<CpuRegister>(), true); + break; + case Primitive::kPrimDouble: LOG(FATAL) << "Type conversion from " << input_type << " to " << result_type << " not yet implemented"; @@ -1632,15 +1638,19 @@ void InstructionCodeGeneratorX86_64::VisitTypeConversion(HTypeConversion* conver 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<CpuRegister>()); + // Processing a Dex `int-to-double' instruction. + __ cvtsi2sd(out.AsFpuRegister<XmmRegister>(), in.AsRegister<CpuRegister>(), false); break; case Primitive::kPrimLong: + // Processing a Dex `long-to-double' instruction. + __ cvtsi2sd(out.AsFpuRegister<XmmRegister>(), in.AsRegister<CpuRegister>(), true); + break; + case Primitive::kPrimFloat: LOG(FATAL) << "Type conversion from " << input_type << " to " << result_type << " not yet implemented"; @@ -1698,28 +1708,28 @@ void InstructionCodeGeneratorX86_64::VisitAdd(HAdd* add) { switch (add->GetResultType()) { case Primitive::kPrimInt: { if (second.IsRegister()) { - __ addl(first.As<CpuRegister>(), second.As<CpuRegister>()); + __ addl(first.AsRegister<CpuRegister>(), second.AsRegister<CpuRegister>()); } else if (second.IsConstant()) { Immediate imm(second.GetConstant()->AsIntConstant()->GetValue()); - __ addl(first.As<CpuRegister>(), imm); + __ addl(first.AsRegister<CpuRegister>(), imm); } else { - __ addl(first.As<CpuRegister>(), Address(CpuRegister(RSP), second.GetStackIndex())); + __ addl(first.AsRegister<CpuRegister>(), Address(CpuRegister(RSP), second.GetStackIndex())); } break; } case Primitive::kPrimLong: { - __ addq(first.As<CpuRegister>(), second.As<CpuRegister>()); + __ addq(first.AsRegister<CpuRegister>(), second.AsRegister<CpuRegister>()); break; } case Primitive::kPrimFloat: { - __ addss(first.As<XmmRegister>(), second.As<XmmRegister>()); + __ addss(first.AsFpuRegister<XmmRegister>(), second.AsFpuRegister<XmmRegister>()); break; } case Primitive::kPrimDouble: { - __ addsd(first.As<XmmRegister>(), second.As<XmmRegister>()); + __ addsd(first.AsFpuRegister<XmmRegister>(), second.AsFpuRegister<XmmRegister>()); break; } @@ -1764,27 +1774,27 @@ void InstructionCodeGeneratorX86_64::VisitSub(HSub* sub) { switch (sub->GetResultType()) { case Primitive::kPrimInt: { if (second.IsRegister()) { - __ subl(first.As<CpuRegister>(), second.As<CpuRegister>()); + __ subl(first.AsRegister<CpuRegister>(), second.AsRegister<CpuRegister>()); } else if (second.IsConstant()) { Immediate imm(second.GetConstant()->AsIntConstant()->GetValue()); - __ subl(first.As<CpuRegister>(), imm); + __ subl(first.AsRegister<CpuRegister>(), imm); } else { - __ subl(first.As<CpuRegister>(), Address(CpuRegister(RSP), second.GetStackIndex())); + __ subl(first.AsRegister<CpuRegister>(), Address(CpuRegister(RSP), second.GetStackIndex())); } break; } case Primitive::kPrimLong: { - __ subq(first.As<CpuRegister>(), second.As<CpuRegister>()); + __ subq(first.AsRegister<CpuRegister>(), second.AsRegister<CpuRegister>()); break; } 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; } @@ -1830,28 +1840,29 @@ void InstructionCodeGeneratorX86_64::VisitMul(HMul* mul) { switch (mul->GetResultType()) { case Primitive::kPrimInt: { if (second.IsRegister()) { - __ imull(first.As<CpuRegister>(), second.As<CpuRegister>()); + __ imull(first.AsRegister<CpuRegister>(), second.AsRegister<CpuRegister>()); } else if (second.IsConstant()) { Immediate imm(second.GetConstant()->AsIntConstant()->GetValue()); - __ imull(first.As<CpuRegister>(), imm); + __ imull(first.AsRegister<CpuRegister>(), imm); } else { DCHECK(second.IsStackSlot()); - __ imull(first.As<CpuRegister>(), Address(CpuRegister(RSP), second.GetStackIndex())); + __ imull(first.AsRegister<CpuRegister>(), + Address(CpuRegister(RSP), second.GetStackIndex())); } break; } case Primitive::kPrimLong: { - __ imulq(first.As<CpuRegister>(), second.As<CpuRegister>()); + __ imulq(first.AsRegister<CpuRegister>(), second.AsRegister<CpuRegister>()); break; } 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; } @@ -1868,10 +1879,10 @@ void InstructionCodeGeneratorX86_64::GenerateDivRemIntegral(HBinaryOperation* in bool is_div = instruction->IsDiv(); LocationSummary* locations = instruction->GetLocations(); - CpuRegister out_reg = locations->Out().As<CpuRegister>(); - CpuRegister second_reg = locations->InAt(1).As<CpuRegister>(); + CpuRegister out_reg = locations->Out().AsRegister<CpuRegister>(); + CpuRegister second_reg = locations->InAt(1).AsRegister<CpuRegister>(); - DCHECK_EQ(RAX, locations->InAt(0).As<CpuRegister>().AsRegister()); + DCHECK_EQ(RAX, locations->InAt(0).AsRegister<CpuRegister>().AsRegister()); DCHECK_EQ(is_div ? RAX : RDX, out_reg.AsRegister()); SlowPathCodeX86_64* slow_path = @@ -1943,12 +1954,12 @@ void InstructionCodeGeneratorX86_64::VisitDiv(HDiv* div) { } case Primitive::kPrimFloat: { - __ divss(first.As<XmmRegister>(), second.As<XmmRegister>()); + __ divss(first.AsFpuRegister<XmmRegister>(), second.AsFpuRegister<XmmRegister>()); break; } case Primitive::kPrimDouble: { - __ divsd(first.As<XmmRegister>(), second.As<XmmRegister>()); + __ divsd(first.AsFpuRegister<XmmRegister>(), second.AsFpuRegister<XmmRegister>()); break; } @@ -2021,7 +2032,7 @@ void InstructionCodeGeneratorX86_64::VisitDivZeroCheck(HDivZeroCheck* instructio switch (instruction->GetType()) { case Primitive::kPrimInt: { if (value.IsRegister()) { - __ testl(value.As<CpuRegister>(), value.As<CpuRegister>()); + __ testl(value.AsRegister<CpuRegister>(), value.AsRegister<CpuRegister>()); __ j(kEqual, slow_path->GetEntryLabel()); } else if (value.IsStackSlot()) { __ cmpl(Address(CpuRegister(RSP), value.GetStackIndex()), Immediate(0)); @@ -2036,7 +2047,7 @@ void InstructionCodeGeneratorX86_64::VisitDivZeroCheck(HDivZeroCheck* instructio } case Primitive::kPrimLong: { if (value.IsRegister()) { - __ testq(value.As<CpuRegister>(), value.As<CpuRegister>()); + __ testq(value.AsRegister<CpuRegister>(), value.AsRegister<CpuRegister>()); __ j(kEqual, slow_path->GetEntryLabel()); } else if (value.IsDoubleStackSlot()) { __ cmpq(Address(CpuRegister(RSP), value.GetStackIndex()), Immediate(0)); @@ -2078,13 +2089,13 @@ void InstructionCodeGeneratorX86_64::HandleShift(HBinaryOperation* op) { DCHECK(op->IsShl() || op->IsShr() || op->IsUShr()); LocationSummary* locations = op->GetLocations(); - CpuRegister first_reg = locations->InAt(0).As<CpuRegister>(); + CpuRegister first_reg = locations->InAt(0).AsRegister<CpuRegister>(); Location second = locations->InAt(1); switch (op->GetResultType()) { case Primitive::kPrimInt: { if (second.IsRegister()) { - CpuRegister second_reg = second.As<CpuRegister>(); + CpuRegister second_reg = second.AsRegister<CpuRegister>(); if (op->IsShl()) { __ shll(first_reg, second_reg); } else if (op->IsShr()) { @@ -2106,7 +2117,7 @@ void InstructionCodeGeneratorX86_64::HandleShift(HBinaryOperation* op) { } case Primitive::kPrimLong: { if (second.IsRegister()) { - CpuRegister second_reg = second.As<CpuRegister>(); + CpuRegister second_reg = second.AsRegister<CpuRegister>(); if (op->IsShl()) { __ shlq(first_reg, second_reg); } else if (op->IsShr()) { @@ -2224,20 +2235,20 @@ void LocationsBuilderX86_64::VisitNot(HNot* not_) { void InstructionCodeGeneratorX86_64::VisitNot(HNot* not_) { LocationSummary* locations = not_->GetLocations(); - DCHECK_EQ(locations->InAt(0).As<CpuRegister>().AsRegister(), - locations->Out().As<CpuRegister>().AsRegister()); + DCHECK_EQ(locations->InAt(0).AsRegister<CpuRegister>().AsRegister(), + locations->Out().AsRegister<CpuRegister>().AsRegister()); Location out = locations->Out(); switch (not_->InputAt(0)->GetType()) { case Primitive::kPrimBoolean: - __ xorq(out.As<CpuRegister>(), Immediate(1)); + __ xorq(out.AsRegister<CpuRegister>(), Immediate(1)); break; case Primitive::kPrimInt: - __ notl(out.As<CpuRegister>()); + __ notl(out.AsRegister<CpuRegister>()); break; case Primitive::kPrimLong: - __ notq(out.As<CpuRegister>()); + __ notq(out.AsRegister<CpuRegister>()); break; default: @@ -2276,51 +2287,51 @@ void LocationsBuilderX86_64::VisitInstanceFieldSet(HInstanceFieldSet* instructio void InstructionCodeGeneratorX86_64::VisitInstanceFieldSet(HInstanceFieldSet* instruction) { LocationSummary* locations = instruction->GetLocations(); - CpuRegister obj = locations->InAt(0).As<CpuRegister>(); + CpuRegister obj = locations->InAt(0).AsRegister<CpuRegister>(); size_t offset = instruction->GetFieldOffset().SizeValue(); Primitive::Type field_type = instruction->GetFieldType(); switch (field_type) { case Primitive::kPrimBoolean: case Primitive::kPrimByte: { - CpuRegister value = locations->InAt(1).As<CpuRegister>(); + CpuRegister value = locations->InAt(1).AsRegister<CpuRegister>(); __ movb(Address(obj, offset), value); break; } case Primitive::kPrimShort: case Primitive::kPrimChar: { - CpuRegister value = locations->InAt(1).As<CpuRegister>(); + CpuRegister value = locations->InAt(1).AsRegister<CpuRegister>(); __ movw(Address(obj, offset), value); break; } case Primitive::kPrimInt: case Primitive::kPrimNot: { - CpuRegister value = locations->InAt(1).As<CpuRegister>(); + CpuRegister value = locations->InAt(1).AsRegister<CpuRegister>(); __ movl(Address(obj, offset), value); if (CodeGenerator::StoreNeedsWriteBarrier(field_type, instruction->GetValue())) { - CpuRegister temp = locations->GetTemp(0).As<CpuRegister>(); - CpuRegister card = locations->GetTemp(1).As<CpuRegister>(); + CpuRegister temp = locations->GetTemp(0).AsRegister<CpuRegister>(); + CpuRegister card = locations->GetTemp(1).AsRegister<CpuRegister>(); codegen_->MarkGCCard(temp, card, obj, value); } break; } case Primitive::kPrimLong: { - CpuRegister value = locations->InAt(1).As<CpuRegister>(); + CpuRegister value = locations->InAt(1).AsRegister<CpuRegister>(); __ movq(Address(obj, offset), value); break; } 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; } @@ -2340,55 +2351,55 @@ void LocationsBuilderX86_64::VisitInstanceFieldGet(HInstanceFieldGet* instructio void InstructionCodeGeneratorX86_64::VisitInstanceFieldGet(HInstanceFieldGet* instruction) { LocationSummary* locations = instruction->GetLocations(); - CpuRegister obj = locations->InAt(0).As<CpuRegister>(); + CpuRegister obj = locations->InAt(0).AsRegister<CpuRegister>(); size_t offset = instruction->GetFieldOffset().SizeValue(); switch (instruction->GetType()) { case Primitive::kPrimBoolean: { - CpuRegister out = locations->Out().As<CpuRegister>(); + CpuRegister out = locations->Out().AsRegister<CpuRegister>(); __ movzxb(out, Address(obj, offset)); break; } case Primitive::kPrimByte: { - CpuRegister out = locations->Out().As<CpuRegister>(); + CpuRegister out = locations->Out().AsRegister<CpuRegister>(); __ movsxb(out, Address(obj, offset)); break; } case Primitive::kPrimShort: { - CpuRegister out = locations->Out().As<CpuRegister>(); + CpuRegister out = locations->Out().AsRegister<CpuRegister>(); __ movsxw(out, Address(obj, offset)); break; } case Primitive::kPrimChar: { - CpuRegister out = locations->Out().As<CpuRegister>(); + CpuRegister out = locations->Out().AsRegister<CpuRegister>(); __ movzxw(out, Address(obj, offset)); break; } case Primitive::kPrimInt: case Primitive::kPrimNot: { - CpuRegister out = locations->Out().As<CpuRegister>(); + CpuRegister out = locations->Out().AsRegister<CpuRegister>(); __ movl(out, Address(obj, offset)); break; } case Primitive::kPrimLong: { - CpuRegister out = locations->Out().As<CpuRegister>(); + CpuRegister out = locations->Out().AsRegister<CpuRegister>(); __ movq(out, Address(obj, offset)); break; } 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; } @@ -2416,7 +2427,7 @@ void InstructionCodeGeneratorX86_64::VisitNullCheck(HNullCheck* instruction) { Location obj = locations->InAt(0); if (obj.IsRegister()) { - __ cmpl(obj.As<CpuRegister>(), Immediate(0)); + __ cmpl(obj.AsRegister<CpuRegister>(), Immediate(0)); } else if (obj.IsStackSlot()) { __ cmpl(Address(CpuRegister(RSP), obj.GetStackIndex()), Immediate(0)); } else { @@ -2439,54 +2450,54 @@ void LocationsBuilderX86_64::VisitArrayGet(HArrayGet* instruction) { void InstructionCodeGeneratorX86_64::VisitArrayGet(HArrayGet* instruction) { LocationSummary* locations = instruction->GetLocations(); - CpuRegister obj = locations->InAt(0).As<CpuRegister>(); + CpuRegister obj = locations->InAt(0).AsRegister<CpuRegister>(); Location index = locations->InAt(1); switch (instruction->GetType()) { case Primitive::kPrimBoolean: { uint32_t data_offset = mirror::Array::DataOffset(sizeof(uint8_t)).Uint32Value(); - CpuRegister out = locations->Out().As<CpuRegister>(); + CpuRegister out = locations->Out().AsRegister<CpuRegister>(); if (index.IsConstant()) { __ movzxb(out, Address(obj, (index.GetConstant()->AsIntConstant()->GetValue() << TIMES_1) + data_offset)); } else { - __ movzxb(out, Address(obj, index.As<CpuRegister>(), TIMES_1, data_offset)); + __ movzxb(out, Address(obj, index.AsRegister<CpuRegister>(), TIMES_1, data_offset)); } break; } case Primitive::kPrimByte: { uint32_t data_offset = mirror::Array::DataOffset(sizeof(int8_t)).Uint32Value(); - CpuRegister out = locations->Out().As<CpuRegister>(); + CpuRegister out = locations->Out().AsRegister<CpuRegister>(); if (index.IsConstant()) { __ movsxb(out, Address(obj, (index.GetConstant()->AsIntConstant()->GetValue() << TIMES_1) + data_offset)); } else { - __ movsxb(out, Address(obj, index.As<CpuRegister>(), TIMES_1, data_offset)); + __ movsxb(out, Address(obj, index.AsRegister<CpuRegister>(), TIMES_1, data_offset)); } break; } case Primitive::kPrimShort: { uint32_t data_offset = mirror::Array::DataOffset(sizeof(int16_t)).Uint32Value(); - CpuRegister out = locations->Out().As<CpuRegister>(); + CpuRegister out = locations->Out().AsRegister<CpuRegister>(); if (index.IsConstant()) { __ movsxw(out, Address(obj, (index.GetConstant()->AsIntConstant()->GetValue() << TIMES_2) + data_offset)); } else { - __ movsxw(out, Address(obj, index.As<CpuRegister>(), TIMES_2, data_offset)); + __ movsxw(out, Address(obj, index.AsRegister<CpuRegister>(), TIMES_2, data_offset)); } break; } case Primitive::kPrimChar: { uint32_t data_offset = mirror::Array::DataOffset(sizeof(uint16_t)).Uint32Value(); - CpuRegister out = locations->Out().As<CpuRegister>(); + CpuRegister out = locations->Out().AsRegister<CpuRegister>(); if (index.IsConstant()) { __ movzxw(out, Address(obj, (index.GetConstant()->AsIntConstant()->GetValue() << TIMES_2) + data_offset)); } else { - __ movzxw(out, Address(obj, index.As<CpuRegister>(), TIMES_2, data_offset)); + __ movzxw(out, Address(obj, index.AsRegister<CpuRegister>(), TIMES_2, data_offset)); } break; } @@ -2495,48 +2506,48 @@ void InstructionCodeGeneratorX86_64::VisitArrayGet(HArrayGet* instruction) { case Primitive::kPrimNot: { DCHECK_EQ(sizeof(mirror::HeapReference<mirror::Object>), sizeof(int32_t)); uint32_t data_offset = mirror::Array::DataOffset(sizeof(int32_t)).Uint32Value(); - CpuRegister out = locations->Out().As<CpuRegister>(); + CpuRegister out = locations->Out().AsRegister<CpuRegister>(); if (index.IsConstant()) { __ movl(out, Address(obj, (index.GetConstant()->AsIntConstant()->GetValue() << TIMES_4) + data_offset)); } else { - __ movl(out, Address(obj, index.As<CpuRegister>(), TIMES_4, data_offset)); + __ movl(out, Address(obj, index.AsRegister<CpuRegister>(), TIMES_4, data_offset)); } break; } case Primitive::kPrimLong: { uint32_t data_offset = mirror::Array::DataOffset(sizeof(int64_t)).Uint32Value(); - CpuRegister out = locations->Out().As<CpuRegister>(); + CpuRegister out = locations->Out().AsRegister<CpuRegister>(); if (index.IsConstant()) { __ movq(out, Address(obj, (index.GetConstant()->AsIntConstant()->GetValue() << TIMES_8) + data_offset)); } else { - __ movq(out, Address(obj, index.As<CpuRegister>(), TIMES_8, data_offset)); + __ movq(out, Address(obj, index.AsRegister<CpuRegister>(), TIMES_8, data_offset)); } break; } case Primitive::kPrimFloat: { uint32_t data_offset = mirror::Array::DataOffset(sizeof(float)).Uint32Value(); - XmmRegister out = locations->Out().As<XmmRegister>(); + XmmRegister out = locations->Out().AsFpuRegister<XmmRegister>(); if (index.IsConstant()) { __ movss(out, Address(obj, (index.GetConstant()->AsIntConstant()->GetValue() << TIMES_4) + data_offset)); } else { - __ movss(out, Address(obj, index.As<CpuRegister>(), TIMES_4, data_offset)); + __ movss(out, Address(obj, index.AsRegister<CpuRegister>(), TIMES_4, data_offset)); } break; } case Primitive::kPrimDouble: { uint32_t data_offset = mirror::Array::DataOffset(sizeof(double)).Uint32Value(); - XmmRegister out = locations->Out().As<XmmRegister>(); + XmmRegister out = locations->Out().AsFpuRegister<XmmRegister>(); if (index.IsConstant()) { __ movsd(out, Address(obj, (index.GetConstant()->AsIntConstant()->GetValue() << TIMES_8) + data_offset)); } else { - __ movsd(out, Address(obj, index.As<CpuRegister>(), TIMES_8, data_offset)); + __ movsd(out, Address(obj, index.AsRegister<CpuRegister>(), TIMES_8, data_offset)); } break; } @@ -2584,7 +2595,7 @@ void LocationsBuilderX86_64::VisitArraySet(HArraySet* instruction) { void InstructionCodeGeneratorX86_64::VisitArraySet(HArraySet* instruction) { LocationSummary* locations = instruction->GetLocations(); - CpuRegister obj = locations->InAt(0).As<CpuRegister>(); + CpuRegister obj = locations->InAt(0).AsRegister<CpuRegister>(); Location index = locations->InAt(1); Location value = locations->InAt(2); Primitive::Type value_type = instruction->GetComponentType(); @@ -2599,16 +2610,17 @@ void InstructionCodeGeneratorX86_64::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<CpuRegister>()); + __ movb(Address(obj, offset), value.AsRegister<CpuRegister>()); } else { - __ movb(Address(obj, offset), Immediate(value.GetConstant()->AsIntConstant()->GetValue())); + __ movb(Address(obj, offset), + Immediate(value.GetConstant()->AsIntConstant()->GetValue())); } } else { if (value.IsRegister()) { - __ movb(Address(obj, index.As<CpuRegister>(), TIMES_1, data_offset), - value.As<CpuRegister>()); + __ movb(Address(obj, index.AsRegister<CpuRegister>(), TIMES_1, data_offset), + value.AsRegister<CpuRegister>()); } else { - __ movb(Address(obj, index.As<CpuRegister>(), TIMES_1, data_offset), + __ movb(Address(obj, index.AsRegister<CpuRegister>(), TIMES_1, data_offset), Immediate(value.GetConstant()->AsIntConstant()->GetValue())); } } @@ -2621,19 +2633,20 @@ void InstructionCodeGeneratorX86_64::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<CpuRegister>()); + __ movw(Address(obj, offset), value.AsRegister<CpuRegister>()); } else { DCHECK(value.IsConstant()) << value; - __ movw(Address(obj, offset), Immediate(value.GetConstant()->AsIntConstant()->GetValue())); + __ movw(Address(obj, offset), + Immediate(value.GetConstant()->AsIntConstant()->GetValue())); } } else { DCHECK(index.IsRegister()) << index; if (value.IsRegister()) { - __ movw(Address(obj, index.As<CpuRegister>(), TIMES_2, data_offset), - value.As<CpuRegister>()); + __ movw(Address(obj, index.AsRegister<CpuRegister>(), TIMES_2, data_offset), + value.AsRegister<CpuRegister>()); } else { DCHECK(value.IsConstant()) << value; - __ movw(Address(obj, index.As<CpuRegister>(), TIMES_2, data_offset), + __ movw(Address(obj, index.AsRegister<CpuRegister>(), TIMES_2, data_offset), Immediate(value.GetConstant()->AsIntConstant()->GetValue())); } } @@ -2648,7 +2661,7 @@ void InstructionCodeGeneratorX86_64::VisitArraySet(HArraySet* instruction) { size_t offset = (index.GetConstant()->AsIntConstant()->GetValue() << TIMES_4) + data_offset; if (value.IsRegister()) { - __ movl(Address(obj, offset), value.As<CpuRegister>()); + __ movl(Address(obj, offset), value.AsRegister<CpuRegister>()); } else { DCHECK(value.IsConstant()) << value; __ movl(Address(obj, offset), @@ -2657,24 +2670,25 @@ void InstructionCodeGeneratorX86_64::VisitArraySet(HArraySet* instruction) { } else { DCHECK(index.IsRegister()) << index; if (value.IsRegister()) { - __ movl(Address(obj, index.As<CpuRegister>(), TIMES_4, data_offset), - value.As<CpuRegister>()); + __ movl(Address(obj, index.AsRegister<CpuRegister>(), TIMES_4, data_offset), + value.AsRegister<CpuRegister>()); } else { DCHECK(value.IsConstant()) << value; - __ movl(Address(obj, index.As<CpuRegister>(), TIMES_4, data_offset), + __ movl(Address(obj, index.AsRegister<CpuRegister>(), TIMES_4, data_offset), Immediate(value.GetConstant()->AsIntConstant()->GetValue())); } } if (needs_write_barrier) { DCHECK_EQ(value_type, Primitive::kPrimNot); - CpuRegister temp = locations->GetTemp(0).As<CpuRegister>(); - CpuRegister card = locations->GetTemp(1).As<CpuRegister>(); - codegen_->MarkGCCard(temp, card, obj, value.As<CpuRegister>()); + CpuRegister temp = locations->GetTemp(0).AsRegister<CpuRegister>(); + CpuRegister card = locations->GetTemp(1).AsRegister<CpuRegister>(); + codegen_->MarkGCCard(temp, card, obj, value.AsRegister<CpuRegister>()); } } else { DCHECK_EQ(value_type, Primitive::kPrimNot); - __ gs()->call(Address::Absolute(QUICK_ENTRYPOINT_OFFSET(kX86_64WordSize, pAputObject), true)); + __ gs()->call(Address::Absolute(QUICK_ENTRYPOINT_OFFSET(kX86_64WordSize, pAputObject), + true)); DCHECK(!codegen_->IsLeafMethod()); codegen_->RecordPcInfo(instruction, instruction->GetDexPc()); } @@ -2686,11 +2700,11 @@ void InstructionCodeGeneratorX86_64::VisitArraySet(HArraySet* instruction) { if (index.IsConstant()) { size_t offset = (index.GetConstant()->AsIntConstant()->GetValue() << TIMES_8) + data_offset; DCHECK(value.IsRegister()); - __ movq(Address(obj, offset), value.As<CpuRegister>()); + __ movq(Address(obj, offset), value.AsRegister<CpuRegister>()); } else { DCHECK(value.IsRegister()); - __ movq(Address(obj, index.As<CpuRegister>(), TIMES_8, data_offset), - value.As<CpuRegister>()); + __ movq(Address(obj, index.AsRegister<CpuRegister>(), TIMES_8, data_offset), + value.AsRegister<CpuRegister>()); } break; } @@ -2700,11 +2714,11 @@ void InstructionCodeGeneratorX86_64::VisitArraySet(HArraySet* instruction) { if (index.IsConstant()) { size_t offset = (index.GetConstant()->AsIntConstant()->GetValue() << TIMES_4) + data_offset; DCHECK(value.IsFpuRegister()); - __ movss(Address(obj, offset), value.As<XmmRegister>()); + __ movss(Address(obj, offset), value.AsFpuRegister<XmmRegister>()); } else { DCHECK(value.IsFpuRegister()); - __ movss(Address(obj, index.As<CpuRegister>(), TIMES_4, data_offset), - value.As<XmmRegister>()); + __ movss(Address(obj, index.AsRegister<CpuRegister>(), TIMES_4, data_offset), + value.AsFpuRegister<XmmRegister>()); } break; } @@ -2714,11 +2728,11 @@ void InstructionCodeGeneratorX86_64::VisitArraySet(HArraySet* instruction) { if (index.IsConstant()) { size_t offset = (index.GetConstant()->AsIntConstant()->GetValue() << TIMES_8) + data_offset; DCHECK(value.IsFpuRegister()); - __ movsd(Address(obj, offset), value.As<XmmRegister>()); + __ movsd(Address(obj, offset), value.AsFpuRegister<XmmRegister>()); } else { DCHECK(value.IsFpuRegister()); - __ movsd(Address(obj, index.As<CpuRegister>(), TIMES_8, data_offset), - value.As<XmmRegister>()); + __ movsd(Address(obj, index.AsRegister<CpuRegister>(), TIMES_8, data_offset), + value.AsFpuRegister<XmmRegister>()); } break; } @@ -2739,8 +2753,8 @@ void LocationsBuilderX86_64::VisitArrayLength(HArrayLength* instruction) { void InstructionCodeGeneratorX86_64::VisitArrayLength(HArrayLength* instruction) { LocationSummary* locations = instruction->GetLocations(); uint32_t offset = mirror::Array::LengthOffset().Uint32Value(); - CpuRegister obj = locations->InAt(0).As<CpuRegister>(); - CpuRegister out = locations->Out().As<CpuRegister>(); + CpuRegister obj = locations->InAt(0).AsRegister<CpuRegister>(); + CpuRegister out = locations->Out().AsRegister<CpuRegister>(); __ movl(out, Address(obj, offset)); } @@ -2760,8 +2774,8 @@ void InstructionCodeGeneratorX86_64::VisitBoundsCheck(HBoundsCheck* instruction) instruction, locations->InAt(0), locations->InAt(1)); codegen_->AddSlowPath(slow_path); - CpuRegister index = locations->InAt(0).As<CpuRegister>(); - CpuRegister length = locations->InAt(1).As<CpuRegister>(); + CpuRegister index = locations->InAt(0).AsRegister<CpuRegister>(); + CpuRegister length = locations->InAt(1).AsRegister<CpuRegister>(); __ cmpl(index, length); __ j(kAboveEqual, slow_path->GetEntryLabel()); @@ -2845,21 +2859,21 @@ void ParallelMoveResolverX86_64::EmitMove(size_t index) { if (source.IsRegister()) { if (destination.IsRegister()) { - __ movq(destination.As<CpuRegister>(), source.As<CpuRegister>()); + __ movq(destination.AsRegister<CpuRegister>(), source.AsRegister<CpuRegister>()); } else if (destination.IsStackSlot()) { __ movl(Address(CpuRegister(RSP), destination.GetStackIndex()), - source.As<CpuRegister>()); + source.AsRegister<CpuRegister>()); } else { DCHECK(destination.IsDoubleStackSlot()); __ movq(Address(CpuRegister(RSP), destination.GetStackIndex()), - source.As<CpuRegister>()); + source.AsRegister<CpuRegister>()); } } else if (source.IsStackSlot()) { if (destination.IsRegister()) { - __ movl(destination.As<CpuRegister>(), + __ movl(destination.AsRegister<CpuRegister>(), Address(CpuRegister(RSP), source.GetStackIndex())); } else if (destination.IsFpuRegister()) { - __ movss(destination.As<XmmRegister>(), + __ movss(destination.AsFpuRegister<XmmRegister>(), Address(CpuRegister(RSP), source.GetStackIndex())); } else { DCHECK(destination.IsStackSlot()); @@ -2868,10 +2882,11 @@ void ParallelMoveResolverX86_64::EmitMove(size_t index) { } } else if (source.IsDoubleStackSlot()) { if (destination.IsRegister()) { - __ movq(destination.As<CpuRegister>(), + __ movq(destination.AsRegister<CpuRegister>(), Address(CpuRegister(RSP), source.GetStackIndex())); } else if (destination.IsFpuRegister()) { - __ movsd(destination.As<XmmRegister>(), Address(CpuRegister(RSP), source.GetStackIndex())); + __ movsd(destination.AsFpuRegister<XmmRegister>(), + Address(CpuRegister(RSP), source.GetStackIndex())); } else { DCHECK(destination.IsDoubleStackSlot()) << destination; __ movq(CpuRegister(TMP), Address(CpuRegister(RSP), source.GetStackIndex())); @@ -2882,7 +2897,7 @@ void ParallelMoveResolverX86_64::EmitMove(size_t index) { if (constant->IsIntConstant()) { Immediate imm(constant->AsIntConstant()->GetValue()); if (destination.IsRegister()) { - __ movl(destination.As<CpuRegister>(), imm); + __ movl(destination.AsRegister<CpuRegister>(), imm); } else { DCHECK(destination.IsStackSlot()) << destination; __ movl(Address(CpuRegister(RSP), destination.GetStackIndex()), imm); @@ -2890,7 +2905,7 @@ void ParallelMoveResolverX86_64::EmitMove(size_t index) { } else if (constant->IsLongConstant()) { int64_t value = constant->AsLongConstant()->GetValue(); if (destination.IsRegister()) { - __ movq(destination.As<CpuRegister>(), Immediate(value)); + __ movq(destination.AsRegister<CpuRegister>(), Immediate(value)); } else { DCHECK(destination.IsDoubleStackSlot()) << destination; __ movq(CpuRegister(TMP), Immediate(value)); @@ -2900,7 +2915,7 @@ void ParallelMoveResolverX86_64::EmitMove(size_t index) { Immediate imm(bit_cast<float, int32_t>(constant->AsFloatConstant()->GetValue())); if (destination.IsFpuRegister()) { __ movl(CpuRegister(TMP), imm); - __ movd(destination.As<XmmRegister>(), CpuRegister(TMP)); + __ movd(destination.AsFpuRegister<XmmRegister>(), CpuRegister(TMP)); } else { DCHECK(destination.IsStackSlot()) << destination; __ movl(Address(CpuRegister(RSP), destination.GetStackIndex()), imm); @@ -2910,7 +2925,7 @@ void ParallelMoveResolverX86_64::EmitMove(size_t index) { Immediate imm(bit_cast<double, int64_t>(constant->AsDoubleConstant()->GetValue())); if (destination.IsFpuRegister()) { __ movq(CpuRegister(TMP), imm); - __ movd(destination.As<XmmRegister>(), CpuRegister(TMP)); + __ movd(destination.AsFpuRegister<XmmRegister>(), CpuRegister(TMP)); } else { DCHECK(destination.IsDoubleStackSlot()) << destination; __ movq(CpuRegister(TMP), imm); @@ -2919,14 +2934,14 @@ void ParallelMoveResolverX86_64::EmitMove(size_t index) { } } else if (source.IsFpuRegister()) { if (destination.IsFpuRegister()) { - __ movaps(destination.As<XmmRegister>(), source.As<XmmRegister>()); + __ movaps(destination.AsFpuRegister<XmmRegister>(), source.AsFpuRegister<XmmRegister>()); } else if (destination.IsStackSlot()) { __ movss(Address(CpuRegister(RSP), destination.GetStackIndex()), - source.As<XmmRegister>()); + source.AsFpuRegister<XmmRegister>()); } else { DCHECK(destination.IsDoubleStackSlot()) << destination; __ movsd(Address(CpuRegister(RSP), destination.GetStackIndex()), - source.As<XmmRegister>()); + source.AsFpuRegister<XmmRegister>()); } } } @@ -2987,31 +3002,31 @@ void ParallelMoveResolverX86_64::EmitSwap(size_t index) { Location destination = move->GetDestination(); if (source.IsRegister() && destination.IsRegister()) { - __ xchgq(destination.As<CpuRegister>(), source.As<CpuRegister>()); + __ xchgq(destination.AsRegister<CpuRegister>(), source.AsRegister<CpuRegister>()); } else if (source.IsRegister() && destination.IsStackSlot()) { - Exchange32(source.As<CpuRegister>(), destination.GetStackIndex()); + Exchange32(source.AsRegister<CpuRegister>(), destination.GetStackIndex()); } else if (source.IsStackSlot() && destination.IsRegister()) { - Exchange32(destination.As<CpuRegister>(), source.GetStackIndex()); + Exchange32(destination.AsRegister<CpuRegister>(), source.GetStackIndex()); } else if (source.IsStackSlot() && destination.IsStackSlot()) { Exchange32(destination.GetStackIndex(), source.GetStackIndex()); } else if (source.IsRegister() && destination.IsDoubleStackSlot()) { - Exchange64(source.As<CpuRegister>(), destination.GetStackIndex()); + Exchange64(source.AsRegister<CpuRegister>(), destination.GetStackIndex()); } else if (source.IsDoubleStackSlot() && destination.IsRegister()) { - Exchange64(destination.As<CpuRegister>(), source.GetStackIndex()); + Exchange64(destination.AsRegister<CpuRegister>(), source.GetStackIndex()); } else if (source.IsDoubleStackSlot() && destination.IsDoubleStackSlot()) { Exchange64(destination.GetStackIndex(), source.GetStackIndex()); } else if (source.IsFpuRegister() && destination.IsFpuRegister()) { - __ movd(CpuRegister(TMP), source.As<XmmRegister>()); - __ movaps(source.As<XmmRegister>(), destination.As<XmmRegister>()); - __ movd(destination.As<XmmRegister>(), CpuRegister(TMP)); + __ movd(CpuRegister(TMP), source.AsFpuRegister<XmmRegister>()); + __ movaps(source.AsFpuRegister<XmmRegister>(), destination.AsFpuRegister<XmmRegister>()); + __ movd(destination.AsFpuRegister<XmmRegister>(), CpuRegister(TMP)); } else if (source.IsFpuRegister() && destination.IsStackSlot()) { - Exchange32(source.As<XmmRegister>(), destination.GetStackIndex()); + Exchange32(source.AsFpuRegister<XmmRegister>(), destination.GetStackIndex()); } else if (source.IsStackSlot() && destination.IsFpuRegister()) { - Exchange32(destination.As<XmmRegister>(), source.GetStackIndex()); + Exchange32(destination.AsFpuRegister<XmmRegister>(), source.GetStackIndex()); } else if (source.IsFpuRegister() && destination.IsDoubleStackSlot()) { - Exchange64(source.As<XmmRegister>(), destination.GetStackIndex()); + Exchange64(source.AsFpuRegister<XmmRegister>(), destination.GetStackIndex()); } else if (source.IsDoubleStackSlot() && destination.IsFpuRegister()) { - Exchange64(destination.As<XmmRegister>(), source.GetStackIndex()); + Exchange64(destination.AsFpuRegister<XmmRegister>(), source.GetStackIndex()); } else { LOG(FATAL) << "Unimplemented swap between " << source << " and " << destination; } @@ -3046,7 +3061,7 @@ void LocationsBuilderX86_64::VisitLoadClass(HLoadClass* cls) { } void InstructionCodeGeneratorX86_64::VisitLoadClass(HLoadClass* cls) { - CpuRegister out = cls->GetLocations()->Out().As<CpuRegister>(); + CpuRegister out = cls->GetLocations()->Out().AsRegister<CpuRegister>(); if (cls->IsReferrersClass()) { DCHECK(!cls->CanCallRuntime()); DCHECK(!cls->MustGenerateClinitCheck()); @@ -3084,7 +3099,8 @@ void InstructionCodeGeneratorX86_64::VisitClinitCheck(HClinitCheck* check) { SlowPathCodeX86_64* slow_path = new (GetGraph()->GetArena()) LoadClassSlowPathX86_64( check->GetLoadClass(), check, check->GetDexPc(), true); codegen_->AddSlowPath(slow_path); - GenerateClassInitializationCheck(slow_path, check->GetLocations()->InAt(0).As<CpuRegister>()); + GenerateClassInitializationCheck(slow_path, + check->GetLocations()->InAt(0).AsRegister<CpuRegister>()); } void LocationsBuilderX86_64::VisitStaticFieldGet(HStaticFieldGet* instruction) { @@ -3096,55 +3112,55 @@ void LocationsBuilderX86_64::VisitStaticFieldGet(HStaticFieldGet* instruction) { void InstructionCodeGeneratorX86_64::VisitStaticFieldGet(HStaticFieldGet* instruction) { LocationSummary* locations = instruction->GetLocations(); - CpuRegister cls = locations->InAt(0).As<CpuRegister>(); + CpuRegister cls = locations->InAt(0).AsRegister<CpuRegister>(); size_t offset = instruction->GetFieldOffset().SizeValue(); switch (instruction->GetType()) { case Primitive::kPrimBoolean: { - CpuRegister out = locations->Out().As<CpuRegister>(); + CpuRegister out = locations->Out().AsRegister<CpuRegister>(); __ movzxb(out, Address(cls, offset)); break; } case Primitive::kPrimByte: { - CpuRegister out = locations->Out().As<CpuRegister>(); + CpuRegister out = locations->Out().AsRegister<CpuRegister>(); __ movsxb(out, Address(cls, offset)); break; } case Primitive::kPrimShort: { - CpuRegister out = locations->Out().As<CpuRegister>(); + CpuRegister out = locations->Out().AsRegister<CpuRegister>(); __ movsxw(out, Address(cls, offset)); break; } case Primitive::kPrimChar: { - CpuRegister out = locations->Out().As<CpuRegister>(); + CpuRegister out = locations->Out().AsRegister<CpuRegister>(); __ movzxw(out, Address(cls, offset)); break; } case Primitive::kPrimInt: case Primitive::kPrimNot: { - CpuRegister out = locations->Out().As<CpuRegister>(); + CpuRegister out = locations->Out().AsRegister<CpuRegister>(); __ movl(out, Address(cls, offset)); break; } case Primitive::kPrimLong: { - CpuRegister out = locations->Out().As<CpuRegister>(); + CpuRegister out = locations->Out().AsRegister<CpuRegister>(); __ movq(out, Address(cls, offset)); break; } 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; } @@ -3172,51 +3188,51 @@ void LocationsBuilderX86_64::VisitStaticFieldSet(HStaticFieldSet* instruction) { void InstructionCodeGeneratorX86_64::VisitStaticFieldSet(HStaticFieldSet* instruction) { LocationSummary* locations = instruction->GetLocations(); - CpuRegister cls = locations->InAt(0).As<CpuRegister>(); + CpuRegister cls = locations->InAt(0).AsRegister<CpuRegister>(); size_t offset = instruction->GetFieldOffset().SizeValue(); Primitive::Type field_type = instruction->GetFieldType(); switch (field_type) { case Primitive::kPrimBoolean: case Primitive::kPrimByte: { - CpuRegister value = locations->InAt(1).As<CpuRegister>(); + CpuRegister value = locations->InAt(1).AsRegister<CpuRegister>(); __ movb(Address(cls, offset), value); break; } case Primitive::kPrimShort: case Primitive::kPrimChar: { - CpuRegister value = locations->InAt(1).As<CpuRegister>(); + CpuRegister value = locations->InAt(1).AsRegister<CpuRegister>(); __ movw(Address(cls, offset), value); break; } case Primitive::kPrimInt: case Primitive::kPrimNot: { - CpuRegister value = locations->InAt(1).As<CpuRegister>(); + CpuRegister value = locations->InAt(1).AsRegister<CpuRegister>(); __ movl(Address(cls, offset), value); if (CodeGenerator::StoreNeedsWriteBarrier(field_type, instruction->GetValue())) { - CpuRegister temp = locations->GetTemp(0).As<CpuRegister>(); - CpuRegister card = locations->GetTemp(1).As<CpuRegister>(); + CpuRegister temp = locations->GetTemp(0).AsRegister<CpuRegister>(); + CpuRegister card = locations->GetTemp(1).AsRegister<CpuRegister>(); codegen_->MarkGCCard(temp, card, cls, value); } break; } case Primitive::kPrimLong: { - CpuRegister value = locations->InAt(1).As<CpuRegister>(); + CpuRegister value = locations->InAt(1).AsRegister<CpuRegister>(); __ movq(Address(cls, offset), value); break; } 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; } @@ -3237,7 +3253,7 @@ void InstructionCodeGeneratorX86_64::VisitLoadString(HLoadString* load) { SlowPathCodeX86_64* slow_path = new (GetGraph()->GetArena()) LoadStringSlowPathX86_64(load); codegen_->AddSlowPath(slow_path); - CpuRegister out = load->GetLocations()->Out().As<CpuRegister>(); + CpuRegister out = load->GetLocations()->Out().AsRegister<CpuRegister>(); codegen_->LoadCurrentMethod(CpuRegister(out)); __ movl(out, Address(out, mirror::ArtMethod::DeclaringClassOffset().Int32Value())); __ movl(out, Address(out, mirror::Class::DexCacheStringsOffset().Int32Value())); @@ -3256,7 +3272,7 @@ void LocationsBuilderX86_64::VisitLoadException(HLoadException* load) { void InstructionCodeGeneratorX86_64::VisitLoadException(HLoadException* load) { Address address = Address::Absolute( Thread::ExceptionOffset<kX86_64WordSize>().Int32Value(), true); - __ gs()->movl(load->GetLocations()->Out().As<CpuRegister>(), address); + __ gs()->movl(load->GetLocations()->Out().AsRegister<CpuRegister>(), address); __ gs()->movl(address, Immediate(0)); } @@ -3285,9 +3301,9 @@ void LocationsBuilderX86_64::VisitInstanceOf(HInstanceOf* instruction) { void InstructionCodeGeneratorX86_64::VisitInstanceOf(HInstanceOf* instruction) { LocationSummary* locations = instruction->GetLocations(); - CpuRegister obj = locations->InAt(0).As<CpuRegister>(); + CpuRegister obj = locations->InAt(0).AsRegister<CpuRegister>(); Location cls = locations->InAt(1); - CpuRegister out = locations->Out().As<CpuRegister>(); + CpuRegister out = locations->Out().AsRegister<CpuRegister>(); uint32_t class_offset = mirror::Object::ClassOffset().Int32Value(); Label done, zero; SlowPathCodeX86_64* slow_path = nullptr; @@ -3299,7 +3315,7 @@ void InstructionCodeGeneratorX86_64::VisitInstanceOf(HInstanceOf* instruction) { // Compare the class of `obj` with `cls`. __ movl(out, Address(obj, class_offset)); if (cls.IsRegister()) { - __ cmpl(out, cls.As<CpuRegister>()); + __ cmpl(out, cls.AsRegister<CpuRegister>()); } else { DCHECK(cls.IsStackSlot()) << cls; __ cmpl(out, Address(CpuRegister(RSP), cls.GetStackIndex())); @@ -3337,9 +3353,9 @@ void LocationsBuilderX86_64::VisitCheckCast(HCheckCast* instruction) { void InstructionCodeGeneratorX86_64::VisitCheckCast(HCheckCast* instruction) { LocationSummary* locations = instruction->GetLocations(); - CpuRegister obj = locations->InAt(0).As<CpuRegister>(); + CpuRegister obj = locations->InAt(0).AsRegister<CpuRegister>(); Location cls = locations->InAt(1); - CpuRegister temp = locations->GetTemp(0).As<CpuRegister>(); + CpuRegister temp = locations->GetTemp(0).AsRegister<CpuRegister>(); uint32_t class_offset = mirror::Object::ClassOffset().Int32Value(); SlowPathCodeX86_64* slow_path = new (GetGraph()->GetArena()) TypeCheckSlowPathX86_64( instruction, locations->InAt(1), locations->GetTemp(0), instruction->GetDexPc()); @@ -3351,7 +3367,7 @@ void InstructionCodeGeneratorX86_64::VisitCheckCast(HCheckCast* instruction) { // Compare the class of `obj` with `cls`. __ movl(temp, Address(obj, class_offset)); if (cls.IsRegister()) { - __ cmpl(temp, cls.As<CpuRegister>()); + __ cmpl(temp, cls.AsRegister<CpuRegister>()); } else { DCHECK(cls.IsStackSlot()) << cls; __ cmpl(temp, Address(CpuRegister(RSP), cls.GetStackIndex())); @@ -3416,43 +3432,43 @@ void InstructionCodeGeneratorX86_64::HandleBitwiseOperation(HBinaryOperation* in if (instruction->GetResultType() == Primitive::kPrimInt) { if (second.IsRegister()) { if (instruction->IsAnd()) { - __ andl(first.As<CpuRegister>(), second.As<CpuRegister>()); + __ andl(first.AsRegister<CpuRegister>(), second.AsRegister<CpuRegister>()); } else if (instruction->IsOr()) { - __ orl(first.As<CpuRegister>(), second.As<CpuRegister>()); + __ orl(first.AsRegister<CpuRegister>(), second.AsRegister<CpuRegister>()); } else { DCHECK(instruction->IsXor()); - __ xorl(first.As<CpuRegister>(), second.As<CpuRegister>()); + __ xorl(first.AsRegister<CpuRegister>(), second.AsRegister<CpuRegister>()); } } else if (second.IsConstant()) { Immediate imm(second.GetConstant()->AsIntConstant()->GetValue()); if (instruction->IsAnd()) { - __ andl(first.As<CpuRegister>(), imm); + __ andl(first.AsRegister<CpuRegister>(), imm); } else if (instruction->IsOr()) { - __ orl(first.As<CpuRegister>(), imm); + __ orl(first.AsRegister<CpuRegister>(), imm); } else { DCHECK(instruction->IsXor()); - __ xorl(first.As<CpuRegister>(), imm); + __ xorl(first.AsRegister<CpuRegister>(), imm); } } else { Address address(CpuRegister(RSP), second.GetStackIndex()); if (instruction->IsAnd()) { - __ andl(first.As<CpuRegister>(), address); + __ andl(first.AsRegister<CpuRegister>(), address); } else if (instruction->IsOr()) { - __ orl(first.As<CpuRegister>(), address); + __ orl(first.AsRegister<CpuRegister>(), address); } else { DCHECK(instruction->IsXor()); - __ xorl(first.As<CpuRegister>(), address); + __ xorl(first.AsRegister<CpuRegister>(), address); } } } else { DCHECK_EQ(instruction->GetResultType(), Primitive::kPrimLong); if (instruction->IsAnd()) { - __ andq(first.As<CpuRegister>(), second.As<CpuRegister>()); + __ andq(first.AsRegister<CpuRegister>(), second.AsRegister<CpuRegister>()); } else if (instruction->IsOr()) { - __ orq(first.As<CpuRegister>(), second.As<CpuRegister>()); + __ orq(first.AsRegister<CpuRegister>(), second.AsRegister<CpuRegister>()); } else { DCHECK(instruction->IsXor()); - __ xorq(first.As<CpuRegister>(), second.As<CpuRegister>()); + __ xorq(first.AsRegister<CpuRegister>(), second.AsRegister<CpuRegister>()); } } } diff --git a/compiler/optimizing/gvn.cc b/compiler/optimizing/gvn.cc index 25168b5b0c..6e5f1bd203 100644 --- a/compiler/optimizing/gvn.cc +++ b/compiler/optimizing/gvn.cc @@ -91,29 +91,38 @@ SideEffects GlobalValueNumberer::GetBlockEffects(HBasicBlock* block) const { return block_effects_.Get(block->GetBlockId()); } -static bool IsLoopExit(HBasicBlock* block, HBasicBlock* successor) { - HLoopInformation* block_info = block->GetLoopInformation(); - HLoopInformation* other_info = successor->GetLoopInformation(); - return block_info != other_info && (other_info == nullptr || block_info->IsIn(*other_info)); -} - void GlobalValueNumberer::VisitBasicBlock(HBasicBlock* block) { - if (kIsDebugBuild) { - // Check that all non back-edge processors have been visited. - for (size_t i = 0, e = block->GetPredecessors().Size(); i < e; ++i) { - HBasicBlock* predecessor = block->GetPredecessors().Get(i); - DCHECK(visited_.Get(predecessor->GetBlockId()) - || (block->GetLoopInformation() != nullptr - && (block->GetLoopInformation()->GetBackEdges().Get(0) == predecessor))); + ValueSet* set = nullptr; + const GrowableArray<HBasicBlock*>& predecessors = block->GetPredecessors(); + if (predecessors.Size() == 0 || predecessors.Get(0)->IsEntryBlock()) { + // The entry block should only accumulate constant instructions, and + // the builder puts constants only in the entry block. + // Therefore, there is no need to propagate the value set to the next block. + set = new (allocator_) ValueSet(allocator_); + } else { + HBasicBlock* dominator = block->GetDominator(); + set = sets_.Get(dominator->GetBlockId())->Copy(); + if (dominator->GetSuccessors().Size() != 1 || dominator->GetSuccessors().Get(0) != block) { + // We have to copy if the dominator has other successors, or `block` is not a successor + // of the dominator. + set = set->Copy(); + } + if (!set->IsEmpty()) { + if (block->IsLoopHeader()) { + DCHECK_EQ(block->GetDominator(), block->GetLoopInformation()->GetPreHeader()); + set->Kill(GetLoopEffects(block)); + } else if (predecessors.Size() > 1) { + for (size_t i = 0, e = predecessors.Size(); i < e; ++i) { + set->IntersectionWith(sets_.Get(predecessors.Get(i)->GetBlockId())); + if (set->IsEmpty()) { + break; + } + } + } } - visited_.Put(block->GetBlockId(), true); } - ValueSet* set = sets_.Get(block->GetBlockId()); - - if (block->IsLoopHeader()) { - set->Kill(GetLoopEffects(block)); - } + sets_.Put(block->GetBlockId(), set); HInstruction* current = block->GetFirstInstruction(); while (current != nullptr) { @@ -131,57 +140,6 @@ void GlobalValueNumberer::VisitBasicBlock(HBasicBlock* block) { } current = next; } - - if (block == graph_->GetEntryBlock()) { - // The entry block should only accumulate constant instructions, and - // the builder puts constants only in the entry block. - // Therefore, there is no need to propagate the value set to the next block. - DCHECK_EQ(block->GetDominatedBlocks().Size(), 1u); - HBasicBlock* dominated = block->GetDominatedBlocks().Get(0); - sets_.Put(dominated->GetBlockId(), new (allocator_) ValueSet(allocator_)); - return; - } - - // Copy the value set to dominated blocks. We can re-use - // the current set for the last dominated block because we are done visiting - // this block. - for (size_t i = 0, e = block->GetDominatedBlocks().Size(); i < e; ++i) { - HBasicBlock* dominated = block->GetDominatedBlocks().Get(i); - sets_.Put(dominated->GetBlockId(), i == e - 1 ? set : set->Copy()); - } - - // Kill instructions in the value set of each successor. If the successor - // is a loop exit, then we use the side effects of the loop. If not, we use - // the side effects of this block. - for (size_t i = 0, e = block->GetSuccessors().Size(); i < e; ++i) { - HBasicBlock* successor = block->GetSuccessors().Get(i); - if (successor->IsLoopHeader() - && successor->GetLoopInformation()->GetBackEdges().Get(0) == block) { - // In case of a back edge, we already have visited the loop header. - // We should not update its value set, because the last dominated block - // of the loop header uses the same value set. - DCHECK(visited_.Get(successor->GetBlockId())); - continue; - } - DCHECK(!visited_.Get(successor->GetBlockId())); - ValueSet* successor_set = sets_.Get(successor->GetBlockId()); - // The dominator sets the set, and we are guaranteed to have visited it already. - DCHECK(successor_set != nullptr); - - // If this block dominates this successor there is nothing to do. - // Also if the set is empty, there is nothing to kill. - if (successor->GetDominator() != block && !successor_set->IsEmpty()) { - if (block->IsInLoop() && IsLoopExit(block, successor)) { - // All instructions killed in the loop must be killed for a loop exit. - SideEffects effects = GetLoopEffects(block->GetLoopInformation()->GetHeader()); - sets_.Get(successor->GetBlockId())->Kill(effects); - } else { - // Following block (that might be in the same loop). - // Just kill instructions based on this block's side effects. - sets_.Get(successor->GetBlockId())->Kill(GetBlockEffects(block)); - } - } - } } } // namespace art diff --git a/compiler/optimizing/gvn.h b/compiler/optimizing/gvn.h index 8e739cb6d3..81f2c3fa87 100644 --- a/compiler/optimizing/gvn.h +++ b/compiler/optimizing/gvn.h @@ -96,6 +96,26 @@ class ValueSet : public ArenaObject<kArenaAllocMisc> { return nullptr; } + // Returns whether `instruction` is in the set. + HInstruction* IdentityLookup(HInstruction* instruction) const { + size_t hash_code = instruction->ComputeHashCode(); + size_t index = hash_code % kDefaultNumberOfEntries; + HInstruction* existing = table_[index]; + if (existing != nullptr && existing == instruction) { + return existing; + } + + for (ValueSetNode* node = collisions_; node != nullptr; node = node->GetNext()) { + if (node->GetHashCode() == hash_code) { + existing = node->GetInstruction(); + if (existing == instruction) { + return existing; + } + } + } + return nullptr; + } + // Removes all instructions in the set that are affected by the given side effects. void Kill(SideEffects side_effects) { for (size_t i = 0; i < kDefaultNumberOfEntries; ++i) { @@ -106,9 +126,9 @@ class ValueSet : public ArenaObject<kArenaAllocMisc> { } } - ValueSetNode* current = collisions_; - ValueSetNode* previous = nullptr; - while (current != nullptr) { + for (ValueSetNode* current = collisions_, *previous = nullptr; + current != nullptr; + current = current->GetNext()) { HInstruction* instruction = current->GetInstruction(); if (instruction->GetSideEffects().DependsOn(side_effects)) { if (previous == nullptr) { @@ -120,7 +140,6 @@ class ValueSet : public ArenaObject<kArenaAllocMisc> { } else { previous = current; } - current = current->GetNext(); } } @@ -143,6 +162,44 @@ class ValueSet : public ArenaObject<kArenaAllocMisc> { return copy; } + void Clear() { + number_of_entries_ = 0; + collisions_ = nullptr; + for (size_t i = 0; i < kDefaultNumberOfEntries; ++i) { + table_[i] = nullptr; + } + } + + // Update this `ValueSet` by intersecting with instructions in `other`. + void IntersectionWith(ValueSet* other) { + if (IsEmpty()) { + return; + } else if (other->IsEmpty()) { + Clear(); + } else { + for (size_t i = 0; i < kDefaultNumberOfEntries; ++i) { + if (table_[i] != nullptr && other->IdentityLookup(table_[i]) == nullptr) { + --number_of_entries_; + table_[i] = nullptr; + } + } + for (ValueSetNode* current = collisions_, *previous = nullptr; + current != nullptr; + current = current->GetNext()) { + if (other->IdentityLookup(current->GetInstruction()) == nullptr) { + if (previous == nullptr) { + collisions_ = current->GetNext(); + } else { + previous->SetNext(current->GetNext()); + } + --number_of_entries_; + } else { + previous = current; + } + } + } + } + bool IsEmpty() const { return number_of_entries_ == 0; } size_t GetNumberOfEntries() const { return number_of_entries_; } @@ -173,13 +230,11 @@ class GlobalValueNumberer : public ValueObject { allocator_(allocator), block_effects_(allocator, graph->GetBlocks().Size()), loop_effects_(allocator, graph->GetBlocks().Size()), - sets_(allocator, graph->GetBlocks().Size()), - visited_(allocator, graph->GetBlocks().Size()) { + sets_(allocator, graph->GetBlocks().Size()) { size_t number_of_blocks = graph->GetBlocks().Size(); block_effects_.SetSize(number_of_blocks); loop_effects_.SetSize(number_of_blocks); sets_.SetSize(number_of_blocks); - visited_.SetSize(number_of_blocks); for (size_t i = 0; i < number_of_blocks; ++i) { block_effects_.Put(i, SideEffects::None()); @@ -219,9 +274,6 @@ class GlobalValueNumberer : public ValueObject { // in the path from the dominator to the block. GrowableArray<ValueSet*> sets_; - // Mark visisted blocks. Only used for debugging. - GrowableArray<bool> visited_; - ART_FRIEND_TEST(GVNTest, LoopSideEffects); DISALLOW_COPY_AND_ASSIGN(GlobalValueNumberer); }; diff --git a/compiler/optimizing/locations.h b/compiler/optimizing/locations.h index e1c8e8ed6e..1ff26d914c 100644 --- a/compiler/optimizing/locations.h +++ b/compiler/optimizing/locations.h @@ -161,7 +161,14 @@ class Location : public ValueObject { } template <typename T> - T As() const { + T AsRegister() const { + DCHECK(IsRegister()); + return static_cast<T>(reg()); + } + + template <typename T> + T AsFpuRegister() const { + DCHECK(IsFpuRegister()); return static_cast<T>(reg()); } diff --git a/compiler/optimizing/register_allocator.cc b/compiler/optimizing/register_allocator.cc index 6d03ad827f..b074c9aa8e 100644 --- a/compiler/optimizing/register_allocator.cc +++ b/compiler/optimizing/register_allocator.cc @@ -70,7 +70,8 @@ bool RegisterAllocator::CanAllocateRegistersFor(const HGraph& graph, it.Advance()) { HInstruction* current = it.Current(); if (current->GetType() == Primitive::kPrimLong && instruction_set != kX86_64) return false; - if ((current->GetType() == Primitive::kPrimFloat || current->GetType() == Primitive::kPrimDouble) + if ((current->GetType() == Primitive::kPrimFloat + || current->GetType() == Primitive::kPrimDouble) && instruction_set != kX86_64) { return false; } @@ -189,11 +190,29 @@ void RegisterAllocator::ProcessInstruction(HInstruction* instruction) { BlockRegister(temp, position, position + 1); } else { DCHECK(temp.IsUnallocated()); - DCHECK(temp.GetPolicy() == Location::kRequiresRegister); - LiveInterval* interval = LiveInterval::MakeTempInterval(allocator_, Primitive::kPrimInt); - temp_intervals_.Add(interval); - interval->AddRange(position, position + 1); - unhandled_core_intervals_.Add(interval); + switch (temp.GetPolicy()) { + case Location::kRequiresRegister: { + LiveInterval* interval = + LiveInterval::MakeTempInterval(allocator_, Primitive::kPrimInt); + temp_intervals_.Add(interval); + interval->AddRange(position, position + 1); + unhandled_core_intervals_.Add(interval); + break; + } + + case Location::kRequiresFpuRegister: { + LiveInterval* interval = + LiveInterval::MakeTempInterval(allocator_, Primitive::kPrimDouble); + temp_intervals_.Add(interval); + interval->AddRange(position, position + 1); + unhandled_fp_intervals_.Add(interval); + break; + } + + default: + LOG(FATAL) << "Unexpected policy for temporary location " + << temp.GetPolicy(); + } } } @@ -215,14 +234,7 @@ void RegisterAllocator::ProcessInstruction(HInstruction* instruction) { // By adding the following interval in the algorithm, we can compute this // maximum before updating locations. LiveInterval* interval = LiveInterval::MakeSlowPathInterval(allocator_, instruction); - // The start of the interval must be after the position of the safepoint, so that - // we can just check the number of active registers at that position. Note that this - // will include the current interval in the computation of - // `maximum_number_of_live_registers`, so we need a better strategy if this becomes - // a problem. - // TODO: We could put the logic in AddSorted, to ensure the safepoint range is - // after all other intervals starting at that same position. - interval->AddRange(position + 1, position + 2); + interval->AddRange(position, position + 1); AddSorted(&unhandled_core_intervals_, interval); AddSorted(&unhandled_fp_intervals_, interval); } @@ -484,16 +496,6 @@ void RegisterAllocator::LinearScan() { DCHECK(!current->IsFixed() && !current->HasSpillSlot()); DCHECK(unhandled_->IsEmpty() || unhandled_->Peek()->GetStart() >= current->GetStart()); - if (current->IsSlowPathSafepoint()) { - // Synthesized interval to record the maximum number of live registers - // at safepoints. No need to allocate a register for it. - // We know that current actives are all live at the safepoint (modulo - // the one created by the safepoint). - maximum_number_of_live_registers_ = - std::max(maximum_number_of_live_registers_, active_.Size()); - continue; - } - size_t position = current->GetStart(); // Remember the inactive_ size here since the ones moved to inactive_ from @@ -534,6 +536,15 @@ void RegisterAllocator::LinearScan() { } } + if (current->IsSlowPathSafepoint()) { + // Synthesized interval to record the maximum number of live registers + // at safepoints. No need to allocate a register for it. + maximum_number_of_live_registers_ = + std::max(maximum_number_of_live_registers_, active_.Size()); + DCHECK(unhandled_->IsEmpty() || unhandled_->Peek()->GetStart() > current->GetStart()); + continue; + } + // (4) Try to find an available register. bool success = TryAllocateFreeReg(current); @@ -775,6 +786,12 @@ void RegisterAllocator::AddSorted(GrowableArray<LiveInterval*>* array, LiveInter if (current->StartsAfter(interval)) { insert_at = i; break; + } else if ((current->GetStart() == interval->GetStart()) && current->IsSlowPathSafepoint()) { + // Ensure the slow path interval is the last to be processed at its location: we want the + // interval to know all live registers at this location. + DCHECK(i == 1 || array->Get(i - 2)->StartsAfter(current)); + insert_at = i; + break; } } array->InsertAt(insert_at, interval); @@ -1092,6 +1109,7 @@ void RegisterAllocator::ConnectSiblings(LiveInterval* interval) { case Location::kRegister: { locations->AddLiveRegister(source); DCHECK_LE(locations->GetNumberOfLiveRegisters(), maximum_number_of_live_registers_); + if (current->GetType() == Primitive::kPrimNot) { locations->SetRegisterBit(source.reg()); } @@ -1266,9 +1284,27 @@ void RegisterAllocator::Resolve() { current = at; } LocationSummary* locations = at->GetLocations(); - DCHECK(temp->GetType() == Primitive::kPrimInt); - locations->SetTempAt( - temp_index++, Location::RegisterLocation(temp->GetRegister())); + switch (temp->GetType()) { + case Primitive::kPrimInt: + locations->SetTempAt( + temp_index++, Location::RegisterLocation(temp->GetRegister())); + break; + + case Primitive::kPrimDouble: + // TODO: Support the case of ARM, where a double value + // requires an FPU register pair (note that the ARM back end + // does not yet use this register allocator when a method uses + // floats or doubles). + DCHECK(codegen_->GetInstructionSet() != kArm + && codegen_->GetInstructionSet() != kThumb2); + locations->SetTempAt( + temp_index++, Location::FpuRegisterLocation(temp->GetRegister())); + break; + + default: + LOG(FATAL) << "Unexpected type for temporary location " + << temp->GetType(); + } } } |