summaryrefslogtreecommitdiffstats
path: root/compiler/optimizing
diff options
context:
space:
mode:
Diffstat (limited to 'compiler/optimizing')
-rw-r--r--compiler/optimizing/builder.cc10
-rw-r--r--compiler/optimizing/code_generator.cc22
-rw-r--r--compiler/optimizing/code_generator.h5
-rw-r--r--compiler/optimizing/code_generator_arm.cc505
-rw-r--r--compiler/optimizing/code_generator_x86.cc543
-rw-r--r--compiler/optimizing/code_generator_x86_64.cc526
-rw-r--r--compiler/optimizing/gvn.cc98
-rw-r--r--compiler/optimizing/gvn.h72
-rw-r--r--compiler/optimizing/locations.h9
-rw-r--r--compiler/optimizing/register_allocator.cc90
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();
+ }
}
}