}
}
+void CodeGenerator::CreateCommonInvokeLocationSummary(
+ HInvoke* invoke, InvokeDexCallingConventionVisitor* visitor){
+ ArenaAllocator* allocator = invoke->GetBlock()->GetGraph()->GetArena();
+ LocationSummary* locations = new (allocator) LocationSummary(invoke, LocationSummary::kCall);
+ locations->AddTemp(visitor->GetMethodLocation());
+
+ for (size_t i = 0; i < invoke->GetNumberOfArguments(); i++) {
+ HInstruction* input = invoke->InputAt(i);
+ locations->SetInAt(i, visitor->GetNextLocation(input->GetType()));
+ }
+
+ locations->SetOut(visitor->GetReturnLocation(invoke->GetType()));
+}
+
void CodeGenerator::BlockIfInRegister(Location location, bool is_out) const {
// The DCHECKS below check that a register is not specified twice in
// the summary. The out location can overlap with an input, so we need
class InvokeDexCallingConventionVisitor {
public:
virtual Location GetNextLocation(Primitive::Type type) = 0;
+ virtual Location GetReturnLocation(Primitive::Type type) const = 0;
+ virtual Location GetMethodLocation() const = 0;
protected:
InvokeDexCallingConventionVisitor() {}
virtual ParallelMoveResolver* GetMoveResolver() = 0;
+ static void CreateCommonInvokeLocationSummary(
+ HInvoke* invoke, InvokeDexCallingConventionVisitor* visitor);
+
protected:
CodeGenerator(HGraph* graph,
size_t number_of_core_registers,
return Location();
}
-Location InvokeDexCallingConventionVisitorARM::GetReturnLocation(Primitive::Type type) {
+Location InvokeDexCallingConventionVisitorARM::GetReturnLocation(Primitive::Type type) const {
switch (type) {
case Primitive::kPrimBoolean:
case Primitive::kPrimByte:
UNREACHABLE();
}
+Location InvokeDexCallingConventionVisitorARM::GetMethodLocation() const {
+ return Location::RegisterLocation(kMethodRegisterArgument);
+}
+
void CodeGeneratorARM::Move32(Location destination, Location source) {
if (source.Equals(destination)) {
return;
}
void LocationsBuilderARM::HandleInvoke(HInvoke* invoke) {
- LocationSummary* locations =
- new (GetGraph()->GetArena()) LocationSummary(invoke, LocationSummary::kCall);
- locations->AddTemp(Location::RegisterLocation(kMethodRegisterArgument));
-
InvokeDexCallingConventionVisitorARM calling_convention_visitor;
- for (size_t i = 0; i < invoke->GetNumberOfArguments(); i++) {
- HInstruction* input = invoke->InputAt(i);
- locations->SetInAt(i, calling_convention_visitor.GetNextLocation(input->GetType()));
- }
-
- locations->SetOut(calling_convention_visitor.GetReturnLocation(invoke->GetType()));
+ CodeGenerator::CreateCommonInvokeLocationSummary(invoke, &calling_convention_visitor);
}
void LocationsBuilderARM::VisitInvokeVirtual(HInvokeVirtual* invoke) {
virtual ~InvokeDexCallingConventionVisitorARM() {}
Location GetNextLocation(Primitive::Type type) OVERRIDE;
- Location GetReturnLocation(Primitive::Type type);
+ Location GetReturnLocation(Primitive::Type type) const OVERRIDE;
+ Location GetMethodLocation() const OVERRIDE;
private:
InvokeDexCallingConvention calling_convention;
return next_location;
}
+Location InvokeDexCallingConventionVisitorARM64::GetMethodLocation() const {
+ return LocationFrom(x0);
+}
+
CodeGeneratorARM64::CodeGeneratorARM64(HGraph* graph,
const Arm64InstructionSetFeatures& isa_features,
const CompilerOptions& compiler_options)
}
void LocationsBuilderARM64::HandleInvoke(HInvoke* invoke) {
- LocationSummary* locations =
- new (GetGraph()->GetArena()) LocationSummary(invoke, LocationSummary::kCall);
- locations->AddTemp(LocationFrom(x0));
-
InvokeDexCallingConventionVisitorARM64 calling_convention_visitor;
- for (size_t i = 0; i < invoke->GetNumberOfArguments(); i++) {
- HInstruction* input = invoke->InputAt(i);
- locations->SetInAt(i, calling_convention_visitor.GetNextLocation(input->GetType()));
- }
-
- Primitive::Type return_type = invoke->GetType();
- if (return_type != Primitive::kPrimVoid) {
- locations->SetOut(calling_convention_visitor.GetReturnLocation(return_type));
- }
+ CodeGenerator::CreateCommonInvokeLocationSummary(invoke, &calling_convention_visitor);
}
void LocationsBuilderARM64::VisitInvokeInterface(HInvokeInterface* invoke) {
kParameterFPRegistersLength,
kArm64PointerSize) {}
- Location GetReturnLocation(Primitive::Type return_type) {
+ Location GetReturnLocation(Primitive::Type return_type) const {
return ARM64ReturnLocation(return_type);
}
virtual ~InvokeDexCallingConventionVisitorARM64() {}
Location GetNextLocation(Primitive::Type type) OVERRIDE;
- Location GetReturnLocation(Primitive::Type return_type) {
+ Location GetReturnLocation(Primitive::Type return_type) const OVERRIDE {
return calling_convention.GetReturnLocation(return_type);
}
+ Location GetMethodLocation() const OVERRIDE;
private:
InvokeDexCallingConvention calling_convention;
UNREACHABLE();
}
+Location InvokeDexCallingConventionVisitorX86::GetReturnLocation(Primitive::Type type) const {
+ switch (type) {
+ case Primitive::kPrimBoolean:
+ case Primitive::kPrimByte:
+ case Primitive::kPrimChar:
+ case Primitive::kPrimShort:
+ case Primitive::kPrimInt:
+ case Primitive::kPrimNot:
+ return Location::RegisterLocation(EAX);
+
+ case Primitive::kPrimLong:
+ return Location::RegisterPairLocation(EAX, EDX);
+
+ case Primitive::kPrimVoid:
+ return Location::NoLocation();
+
+ case Primitive::kPrimDouble:
+ case Primitive::kPrimFloat:
+ return Location::FpuRegisterLocation(XMM0);
+ }
+}
+
+Location InvokeDexCallingConventionVisitorX86::GetMethodLocation() const {
+ return Location::RegisterLocation(kMethodRegisterArgument);
+}
+
Location InvokeDexCallingConventionVisitorX86::GetNextLocation(Primitive::Type type) {
switch (type) {
case Primitive::kPrimBoolean:
default:
LOG(FATAL) << "Unknown local type " << store->InputAt(1)->GetType();
}
- store->SetLocations(locations);
}
void InstructionCodeGeneratorX86::VisitStoreLocal(HStoreLocal* store) {
}
void LocationsBuilderX86::HandleInvoke(HInvoke* invoke) {
- LocationSummary* locations =
- new (GetGraph()->GetArena()) LocationSummary(invoke, LocationSummary::kCall);
- locations->AddTemp(Location::RegisterLocation(kMethodRegisterArgument));
-
InvokeDexCallingConventionVisitorX86 calling_convention_visitor;
- for (size_t i = 0; i < invoke->GetNumberOfArguments(); i++) {
- HInstruction* input = invoke->InputAt(i);
- locations->SetInAt(i, calling_convention_visitor.GetNextLocation(input->GetType()));
- }
-
- switch (invoke->GetType()) {
- case Primitive::kPrimBoolean:
- case Primitive::kPrimByte:
- case Primitive::kPrimChar:
- case Primitive::kPrimShort:
- case Primitive::kPrimInt:
- case Primitive::kPrimNot:
- locations->SetOut(Location::RegisterLocation(EAX));
- break;
-
- case Primitive::kPrimLong:
- locations->SetOut(Location::RegisterPairLocation(EAX, EDX));
- break;
-
- case Primitive::kPrimVoid:
- break;
-
- case Primitive::kPrimDouble:
- case Primitive::kPrimFloat:
- locations->SetOut(Location::FpuRegisterLocation(XMM0));
- break;
- }
-
- invoke->SetLocations(locations);
+ CodeGenerator::CreateCommonInvokeLocationSummary(invoke, &calling_convention_visitor);
}
void InstructionCodeGeneratorX86::VisitInvokeVirtual(HInvokeVirtual* invoke) {
LocationSummary* locations = new (GetGraph()->GetArena()) LocationSummary(instruction);
locations->SetInAt(0, Location::RequiresRegister());
locations->SetOut(Location::RequiresRegister(), Location::kNoOutputOverlap);
- instruction->SetLocations(locations);
}
void InstructionCodeGeneratorX86::VisitArrayLength(HArrayLength* instruction) {
virtual ~InvokeDexCallingConventionVisitorX86() {}
Location GetNextLocation(Primitive::Type type) OVERRIDE;
+ Location GetReturnLocation(Primitive::Type type) const OVERRIDE;
+ Location GetMethodLocation() const OVERRIDE;
private:
InvokeDexCallingConvention calling_convention;
codegen_->GenerateFrameExit();
}
+Location InvokeDexCallingConventionVisitorX86_64::GetReturnLocation(Primitive::Type type) const {
+ switch (type) {
+ case Primitive::kPrimBoolean:
+ case Primitive::kPrimByte:
+ case Primitive::kPrimChar:
+ case Primitive::kPrimShort:
+ case Primitive::kPrimInt:
+ case Primitive::kPrimNot:
+ case Primitive::kPrimLong:
+ return Location::RegisterLocation(RAX);
+
+ case Primitive::kPrimVoid:
+ return Location::NoLocation();
+
+ case Primitive::kPrimDouble:
+ case Primitive::kPrimFloat:
+ return Location::FpuRegisterLocation(XMM0);
+ }
+}
+
+Location InvokeDexCallingConventionVisitorX86_64::GetMethodLocation() const {
+ return Location::RegisterLocation(kMethodRegisterArgument);
+}
+
Location InvokeDexCallingConventionVisitorX86_64::GetNextLocation(Primitive::Type type) {
switch (type) {
case Primitive::kPrimBoolean:
}
void LocationsBuilderX86_64::HandleInvoke(HInvoke* invoke) {
- LocationSummary* locations =
- new (GetGraph()->GetArena()) LocationSummary(invoke, LocationSummary::kCall);
- locations->AddTemp(Location::RegisterLocation(kMethodRegisterArgument));
-
InvokeDexCallingConventionVisitorX86_64 calling_convention_visitor;
- for (size_t i = 0; i < invoke->GetNumberOfArguments(); i++) {
- HInstruction* input = invoke->InputAt(i);
- locations->SetInAt(i, calling_convention_visitor.GetNextLocation(input->GetType()));
- }
-
- switch (invoke->GetType()) {
- case Primitive::kPrimBoolean:
- case Primitive::kPrimByte:
- case Primitive::kPrimChar:
- case Primitive::kPrimShort:
- case Primitive::kPrimInt:
- case Primitive::kPrimNot:
- case Primitive::kPrimLong:
- locations->SetOut(Location::RegisterLocation(RAX));
- break;
-
- case Primitive::kPrimVoid:
- break;
-
- case Primitive::kPrimDouble:
- case Primitive::kPrimFloat:
- locations->SetOut(Location::FpuRegisterLocation(XMM0));
- break;
- }
+ CodeGenerator::CreateCommonInvokeLocationSummary(invoke, &calling_convention_visitor);
}
void LocationsBuilderX86_64::VisitInvokeVirtual(HInvokeVirtual* invoke) {
virtual ~InvokeDexCallingConventionVisitorX86_64() {}
Location GetNextLocation(Primitive::Type type) OVERRIDE;
+ Location GetReturnLocation(Primitive::Type type) const OVERRIDE;
+ Location GetMethodLocation() const OVERRIDE;
private:
InvokeDexCallingConvention calling_convention;