Simplify HInvokeStatic code generation.
HPushArgument is not needed for now (but might be when we start
optimizing). Also, calling convention for 64bits backend will
require to know more about the argument than the argument's
index. Therefore currently let HInvokeStatic setup the arguments,
which is possible because arguments of a calls are virtual registers
and not instructions.
Change-Id: I8753ed6083aa083c5180ab53b436dc8de4f1fe31
diff --git a/compiler/optimizing/code_generator_x86.cc b/compiler/optimizing/code_generator_x86.cc
index 7507ee7..7b3d31d 100644
--- a/compiler/optimizing/code_generator_x86.cc
+++ b/compiler/optimizing/code_generator_x86.cc
@@ -105,6 +105,72 @@
DISALLOW_COPY_AND_ASSIGN(InvokeDexCallingConvention);
};
+static constexpr Register kRuntimeParameterCoreRegisters[] = { EAX, ECX, EDX };
+static constexpr size_t kRuntimeParameterCoreRegistersLength =
+ arraysize(kRuntimeParameterCoreRegisters);
+
+class InvokeRuntimeCallingConvention : public CallingConvention<Register> {
+ public:
+ InvokeRuntimeCallingConvention()
+ : CallingConvention(kRuntimeParameterCoreRegisters,
+ kRuntimeParameterCoreRegistersLength) {}
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(InvokeRuntimeCallingConvention);
+};
+
+class InvokeDexCallingConventionVisitor {
+ public:
+ InvokeDexCallingConventionVisitor() : gp_index_(0) {}
+
+ Location GetNextLocation(Primitive::Type type) {
+ switch (type) {
+ case Primitive::kPrimBoolean:
+ case Primitive::kPrimByte:
+ case Primitive::kPrimChar:
+ case Primitive::kPrimShort:
+ case Primitive::kPrimInt:
+ case Primitive::kPrimNot: {
+ uint32_t index = gp_index_++;
+ if (index < calling_convention.GetNumberOfRegisters()) {
+ return X86CpuLocation(calling_convention.GetRegisterAt(index));
+ } else {
+ return Location::StackSlot(calling_convention.GetStackOffsetOf(index));
+ }
+ }
+
+ case Primitive::kPrimLong: {
+ uint32_t index = gp_index_;
+ gp_index_ += 2;
+ if (index + 1 < calling_convention.GetNumberOfRegisters()) {
+ return Location::RegisterLocation(X86ManagedRegister::FromRegisterPair(
+ calling_convention.GetRegisterPairAt(index)));
+ } else if (index + 1 == calling_convention.GetNumberOfRegisters()) {
+ return Location::QuickParameter(index);
+ } else {
+ return Location::DoubleStackSlot(calling_convention.GetStackOffsetOf(index));
+ }
+ }
+
+ case Primitive::kPrimDouble:
+ case Primitive::kPrimFloat:
+ LOG(FATAL) << "Unimplemented parameter type " << type;
+ break;
+
+ case Primitive::kPrimVoid:
+ LOG(FATAL) << "Unexpected parameter type " << type;
+ break;
+ }
+ return Location();
+ }
+
+ private:
+ InvokeDexCallingConvention calling_convention;
+ uint32_t gp_index_;
+
+ DISALLOW_COPY_AND_ASSIGN(InvokeDexCallingConventionVisitor);
+};
+
void CodeGeneratorX86::Move32(Location destination, Location source) {
if (source.Equals(destination)) {
return;
@@ -413,67 +479,16 @@
__ ret();
}
-static constexpr Register kRuntimeParameterCoreRegisters[] = { EAX, ECX, EDX };
-static constexpr size_t kRuntimeParameterCoreRegistersLength =
- arraysize(kRuntimeParameterCoreRegisters);
-
-class InvokeRuntimeCallingConvention : public CallingConvention<Register> {
- public:
- InvokeRuntimeCallingConvention()
- : CallingConvention(kRuntimeParameterCoreRegisters,
- kRuntimeParameterCoreRegistersLength) {}
-
- private:
- DISALLOW_COPY_AND_ASSIGN(InvokeRuntimeCallingConvention);
-};
-
-void LocationsBuilderX86::VisitPushArgument(HPushArgument* argument) {
- LocationSummary* locations = new (GetGraph()->GetArena()) LocationSummary(argument);
- InvokeDexCallingConvention calling_convention;
- uint32_t argument_index = argument->GetArgumentIndex();
- switch (argument->InputAt(0)->GetType()) {
- case Primitive::kPrimBoolean:
- case Primitive::kPrimByte:
- case Primitive::kPrimChar:
- case Primitive::kPrimShort:
- case Primitive::kPrimInt:
- case Primitive::kPrimNot: {
- if (argument_index < calling_convention.GetNumberOfRegisters()) {
- locations->SetInAt(
- 0, X86CpuLocation(calling_convention.GetRegisterAt(argument->GetArgumentIndex())));
- } else {
- locations->SetInAt(
- 0, Location::StackSlot(calling_convention.GetStackOffsetOf(argument_index)));
- }
- break;
- }
- case Primitive::kPrimLong: {
- if (argument_index + 1 < calling_convention.GetNumberOfRegisters()) {
- Location location = Location::RegisterLocation(X86ManagedRegister::FromRegisterPair(
- calling_convention.GetRegisterPairAt(argument_index)));
- locations->SetInAt(0, location);
- } else if (argument_index + 1 == calling_convention.GetNumberOfRegisters()) {
- locations->SetInAt(0, Location::QuickParameter(argument_index));
- } else {
- locations->SetInAt(
- 0, Location::DoubleStackSlot(calling_convention.GetStackOffsetOf(argument_index)));
- }
- break;
- }
- default:
- LOG(FATAL) << "Unimplemented argument type " << argument->InputAt(0)->GetType();
- }
-
- argument->SetLocations(locations);
-}
-
-void InstructionCodeGeneratorX86::VisitPushArgument(HPushArgument* argument) {
- // Nothing to do.
-}
-
void LocationsBuilderX86::VisitInvokeStatic(HInvokeStatic* invoke) {
LocationSummary* locations = new (GetGraph()->GetArena()) LocationSummary(invoke);
locations->AddTemp(X86CpuLocation(EAX));
+
+ InvokeDexCallingConventionVisitor calling_convention_visitor;
+ for (int i = 0; i < invoke->InputCount(); i++) {
+ HInstruction* input = invoke->InputAt(i);
+ locations->SetInAt(i, calling_convention_visitor.GetNextLocation(input->GetType()));
+ }
+
switch (invoke->GetType()) {
case Primitive::kPrimBoolean:
case Primitive::kPrimByte: