Code cleanup in preparation for x64 backend.
- Use InvokeDexCallingConventionVisitor for setting
up HParameterValues
- Use kVregSize instead of kX86WordSize when dealing with
virtual registers.
Change-Id: Ia520223010194c70a3ff0ed659077f55cec4e7d8
diff --git a/compiler/optimizing/code_generator.h b/compiler/optimizing/code_generator.h
index d459dd5..5c7cac1 100644
--- a/compiler/optimizing/code_generator.h
+++ b/compiler/optimizing/code_generator.h
@@ -26,6 +26,8 @@
namespace art {
+static size_t constexpr kVRegSize = 4;
+
class DexCompilationUnit;
class CodeAllocator {
@@ -323,10 +325,10 @@
return registers_[index];
}
- uint8_t GetStackOffsetOf(size_t index) const {
+ uint8_t GetStackOffsetOf(size_t index, size_t word_size) const {
// We still reserve the space for parameters passed by registers.
- // Add kWordSize for the method pointer.
- return index * kWordSize + kWordSize;
+ // Add word_size for the method pointer.
+ return index * kVRegSize + word_size;
}
private:
diff --git a/compiler/optimizing/code_generator_arm.cc b/compiler/optimizing/code_generator_arm.cc
index cdd9696..27691ac 100644
--- a/compiler/optimizing/code_generator_arm.cc
+++ b/compiler/optimizing/code_generator_arm.cc
@@ -48,9 +48,11 @@
core_spill_mask_ |= (1 << LR);
__ PushList((1 << LR));
- // Add the current ART method to the frame size, the return PC, and the filler.
- SetFrameSize(RoundUp((
- GetGraph()->GetMaximumNumberOfOutVRegs() + GetGraph()->GetNumberOfVRegs() + 3) * kArmWordSize,
+ SetFrameSize(RoundUp(
+ (GetGraph()->GetMaximumNumberOfOutVRegs() + GetGraph()->GetNumberOfVRegs()) * kVRegSize
+ + kVRegSize // filler
+ + kArmWordSize // Art method
+ + kNumberOfPushedRegistersAtEntry * kArmWordSize,
kStackAlignment));
// The return PC has already been pushed on the stack.
__ AddConstant(SP, -(GetFrameSize() - kNumberOfPushedRegistersAtEntry * kArmWordSize));
@@ -73,85 +75,56 @@
if (reg_number >= number_of_vregs - number_of_in_vregs) {
// Local is a parameter of the method. It is stored in the caller's frame.
return GetFrameSize() + kArmWordSize // ART method
- + (reg_number - number_of_vregs + number_of_in_vregs) * kArmWordSize;
+ + (reg_number - number_of_vregs + number_of_in_vregs) * kVRegSize;
} else {
// Local is a temporary in this method. It is stored in this method's frame.
return GetFrameSize() - (kNumberOfPushedRegistersAtEntry * kArmWordSize)
- - kArmWordSize // filler.
- - (number_of_vregs * kArmWordSize)
- + (reg_number * kArmWordSize);
+ - kVRegSize // filler.
+ - (number_of_vregs * kVRegSize)
+ + (reg_number * kVRegSize);
}
}
-static constexpr Register kParameterCoreRegisters[] = { R1, R2, R3 };
-static constexpr RegisterPair kParameterCorePairRegisters[] = { R1_R2, R2_R3 };
-static constexpr size_t kParameterCoreRegistersLength = arraysize(kParameterCoreRegisters);
-
-class InvokeDexCallingConvention : public CallingConvention<Register> {
- public:
- InvokeDexCallingConvention()
- : CallingConvention(kParameterCoreRegisters, kParameterCoreRegistersLength) {}
-
- RegisterPair GetRegisterPairAt(size_t argument_index) {
- DCHECK_LT(argument_index + 1, GetNumberOfRegisters());
- return kParameterCorePairRegisters[argument_index];
- }
-
- private:
- DISALLOW_COPY_AND_ASSIGN(InvokeDexCallingConvention);
-};
-
-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 ArmCoreLocation(calling_convention.GetRegisterAt(index));
- } else {
- return Location::StackSlot(calling_convention.GetStackOffsetOf(index));
- }
+Location InvokeDexCallingConventionVisitor::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 ArmCoreLocation(calling_convention.GetRegisterAt(index));
+ } else {
+ return Location::StackSlot(calling_convention.GetStackOffsetOf(index, kArmWordSize));
}
-
- case Primitive::kPrimLong: {
- uint32_t index = gp_index_;
- gp_index_ += 2;
- if (index + 1 < calling_convention.GetNumberOfRegisters()) {
- return Location::RegisterLocation(ArmManagedRegister::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();
+
+ case Primitive::kPrimLong: {
+ uint32_t index = gp_index_;
+ gp_index_ += 2;
+ if (index + 1 < calling_convention.GetNumberOfRegisters()) {
+ return Location::RegisterLocation(ArmManagedRegister::FromRegisterPair(
+ calling_convention.GetRegisterPairAt(index)));
+ } else if (index + 1 == calling_convention.GetNumberOfRegisters()) {
+ return Location::QuickParameter(index);
+ } else {
+ return Location::DoubleStackSlot(calling_convention.GetStackOffsetOf(index, kArmWordSize));
+ }
+ }
+
+ case Primitive::kPrimDouble:
+ case Primitive::kPrimFloat:
+ LOG(FATAL) << "Unimplemented parameter type " << type;
+ break;
+
+ case Primitive::kPrimVoid:
+ LOG(FATAL) << "Unexpected parameter type " << type;
+ break;
}
-
- private:
- InvokeDexCallingConvention calling_convention;
- uint32_t gp_index_;
-
- DISALLOW_COPY_AND_ASSIGN(InvokeDexCallingConventionVisitor);
-};
+ return Location();
+}
void CodeGeneratorARM::Move32(Location destination, Location source) {
if (source.Equals(destination)) {
@@ -188,7 +161,7 @@
__ Mov(destination.AsArm().AsRegisterPairLow(),
calling_convention.GetRegisterAt(argument_index));
__ ldr(destination.AsArm().AsRegisterPairHigh(),
- Address(SP, calling_convention.GetStackOffsetOf(argument_index + 1) + GetFrameSize()));
+ Address(SP, calling_convention.GetStackOffsetOf(argument_index + 1, kArmWordSize) + GetFrameSize()));
} else {
DCHECK(source.IsDoubleStackSlot());
if (destination.AsArm().AsRegisterPair() == R1_R2) {
@@ -205,12 +178,12 @@
if (source.IsRegister()) {
__ Mov(calling_convention.GetRegisterAt(argument_index), source.AsArm().AsRegisterPairLow());
__ str(source.AsArm().AsRegisterPairHigh(),
- Address(SP, calling_convention.GetStackOffsetOf(argument_index + 1)));
+ Address(SP, calling_convention.GetStackOffsetOf(argument_index + 1, kArmWordSize)));
} else {
DCHECK(source.IsDoubleStackSlot());
__ ldr(calling_convention.GetRegisterAt(argument_index), Address(SP, source.GetStackIndex()));
__ ldr(R0, Address(SP, source.GetHighStackIndex(kArmWordSize)));
- __ str(R0, Address(SP, calling_convention.GetStackOffsetOf(argument_index + 1)));
+ __ str(R0, Address(SP, calling_convention.GetStackOffsetOf(argument_index + 1, kArmWordSize)));
}
} else {
DCHECK(destination.IsDoubleStackSlot());
@@ -228,7 +201,7 @@
__ str(calling_convention.GetRegisterAt(argument_index),
Address(SP, destination.GetStackIndex()));
__ ldr(R0,
- Address(SP, calling_convention.GetStackOffsetOf(argument_index + 1) + GetFrameSize()));
+ Address(SP, calling_convention.GetStackOffsetOf(argument_index + 1, kArmWordSize) + GetFrameSize()));
__ str(R0, Address(SP, destination.GetHighStackIndex(kArmWordSize)));
} else {
DCHECK(source.IsDoubleStackSlot());
@@ -694,39 +667,13 @@
void LocationsBuilderARM::VisitParameterValue(HParameterValue* instruction) {
LocationSummary* locations = new (GetGraph()->GetArena()) LocationSummary(instruction);
- InvokeDexCallingConvention calling_convention;
- uint32_t argument_index = instruction->GetIndex();
- switch (instruction->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->SetOut(ArmCoreLocation(calling_convention.GetRegisterAt(argument_index)));
- } else {
- locations->SetOut(Location::StackSlot(
- calling_convention.GetStackOffsetOf(argument_index) + codegen_->GetFrameSize()));
- }
- break;
-
- case Primitive::kPrimLong:
- if (argument_index + 1 < calling_convention.GetNumberOfRegisters()) {
- locations->SetOut(Location::RegisterLocation(ArmManagedRegister::FromRegisterPair(
- (calling_convention.GetRegisterPairAt(argument_index)))));
- } else if (argument_index + 1 == calling_convention.GetNumberOfRegisters()) {
- // Spanning a register and a stack slot. Use the quick parameter kind.
- locations->SetOut(Location::QuickParameter(argument_index));
- } else {
- locations->SetOut(Location::DoubleStackSlot(
- calling_convention.GetStackOffsetOf(argument_index) + codegen_->GetFrameSize()));
- }
- break;
-
- default:
- LOG(FATAL) << "Unimplemented parameter type " << instruction->GetType();
+ Location location = parameter_visitor_.GetNextLocation(instruction->GetType());
+ if (location.IsStackSlot()) {
+ location = Location::StackSlot(location.GetStackIndex() + codegen_->GetFrameSize());
+ } else if (location.IsDoubleStackSlot()) {
+ location = Location::DoubleStackSlot(location.GetStackIndex() + codegen_->GetFrameSize());
}
+ locations->SetOut(location);
instruction->SetLocations(locations);
}
diff --git a/compiler/optimizing/code_generator_arm.h b/compiler/optimizing/code_generator_arm.h
index 3fbe631..ed35f94 100644
--- a/compiler/optimizing/code_generator_arm.h
+++ b/compiler/optimizing/code_generator_arm.h
@@ -28,6 +28,37 @@
static constexpr size_t kArmWordSize = 4;
+static constexpr Register kParameterCoreRegisters[] = { R1, R2, R3 };
+static constexpr RegisterPair kParameterCorePairRegisters[] = { R1_R2, R2_R3 };
+static constexpr size_t kParameterCoreRegistersLength = arraysize(kParameterCoreRegisters);
+
+class InvokeDexCallingConvention : public CallingConvention<Register> {
+ public:
+ InvokeDexCallingConvention()
+ : CallingConvention(kParameterCoreRegisters, kParameterCoreRegistersLength) {}
+
+ RegisterPair GetRegisterPairAt(size_t argument_index) {
+ DCHECK_LT(argument_index + 1, GetNumberOfRegisters());
+ return kParameterCorePairRegisters[argument_index];
+ }
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(InvokeDexCallingConvention);
+};
+
+class InvokeDexCallingConventionVisitor {
+ public:
+ InvokeDexCallingConventionVisitor() : gp_index_(0) {}
+
+ Location GetNextLocation(Primitive::Type type);
+
+ private:
+ InvokeDexCallingConvention calling_convention;
+ uint32_t gp_index_;
+
+ DISALLOW_COPY_AND_ASSIGN(InvokeDexCallingConventionVisitor);
+};
+
class LocationsBuilderARM : public HGraphVisitor {
public:
explicit LocationsBuilderARM(HGraph* graph, CodeGeneratorARM* codegen)
@@ -42,6 +73,7 @@
private:
CodeGeneratorARM* const codegen_;
+ InvokeDexCallingConventionVisitor parameter_visitor_;
DISALLOW_COPY_AND_ASSIGN(LocationsBuilderARM);
};
diff --git a/compiler/optimizing/code_generator_x86.cc b/compiler/optimizing/code_generator_x86.cc
index 7b3d31d..1142631 100644
--- a/compiler/optimizing/code_generator_x86.cc
+++ b/compiler/optimizing/code_generator_x86.cc
@@ -49,10 +49,13 @@
static const int kFakeReturnRegister = 8;
core_spill_mask_ |= (1 << kFakeReturnRegister);
- // Add the current ART method to the frame size, the return PC, and the filler.
- SetFrameSize(RoundUp((
- GetGraph()->GetMaximumNumberOfOutVRegs() + GetGraph()->GetNumberOfVRegs() + 3) * kX86WordSize,
+ SetFrameSize(RoundUp(
+ (GetGraph()->GetMaximumNumberOfOutVRegs() + GetGraph()->GetNumberOfVRegs()) * kVRegSize
+ + kVRegSize // filler
+ + kX86WordSize // Art method
+ + kNumberOfPushedRegistersAtEntry * kX86WordSize,
kStackAlignment));
+
// The return PC has already been pushed on the stack.
__ subl(ESP, Immediate(GetFrameSize() - kNumberOfPushedRegistersAtEntry * kX86WordSize));
__ movl(Address(ESP, kCurrentMethodStackOffset), EAX);
@@ -77,34 +80,16 @@
if (reg_number >= number_of_vregs - number_of_in_vregs) {
// Local is a parameter of the method. It is stored in the caller's frame.
return GetFrameSize() + kX86WordSize // ART method
- + (reg_number - number_of_vregs + number_of_in_vregs) * kX86WordSize;
+ + (reg_number - number_of_vregs + number_of_in_vregs) * kVRegSize;
} else {
// Local is a temporary in this method. It is stored in this method's frame.
return GetFrameSize() - (kNumberOfPushedRegistersAtEntry * kX86WordSize)
- - kX86WordSize // filler.
- - (number_of_vregs * kX86WordSize)
- + (reg_number * kX86WordSize);
+ - kVRegSize // filler.
+ - (number_of_vregs * kVRegSize)
+ + (reg_number * kVRegSize);
}
}
-static constexpr Register kParameterCoreRegisters[] = { ECX, EDX, EBX };
-static constexpr RegisterPair kParameterCorePairRegisters[] = { ECX_EDX, EDX_EBX };
-static constexpr size_t kParameterCoreRegistersLength = arraysize(kParameterCoreRegisters);
-
-class InvokeDexCallingConvention : public CallingConvention<Register> {
- public:
- InvokeDexCallingConvention()
- : CallingConvention(kParameterCoreRegisters, kParameterCoreRegistersLength) {}
-
- RegisterPair GetRegisterPairAt(size_t argument_index) {
- DCHECK_LT(argument_index + 1, GetNumberOfRegisters());
- return kParameterCorePairRegisters[argument_index];
- }
-
- private:
- DISALLOW_COPY_AND_ASSIGN(InvokeDexCallingConvention);
-};
-
static constexpr Register kRuntimeParameterCoreRegisters[] = { EAX, ECX, EDX };
static constexpr size_t kRuntimeParameterCoreRegistersLength =
arraysize(kRuntimeParameterCoreRegisters);
@@ -119,57 +104,46 @@
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));
- }
+Location InvokeDexCallingConventionVisitor::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, kX86WordSize));
}
-
- 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();
+
+ 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, kX86WordSize));
+ }
+ }
+
+ case Primitive::kPrimDouble:
+ case Primitive::kPrimFloat:
+ LOG(FATAL) << "Unimplemented parameter type " << type;
+ break;
+
+ case Primitive::kPrimVoid:
+ LOG(FATAL) << "Unexpected parameter type " << type;
+ break;
}
-
- private:
- InvokeDexCallingConvention calling_convention;
- uint32_t gp_index_;
-
- DISALLOW_COPY_AND_ASSIGN(InvokeDexCallingConventionVisitor);
-};
+ return Location();
+}
void CodeGeneratorX86::Move32(Location destination, Location source) {
if (source.Equals(destination)) {
@@ -206,9 +180,8 @@
InvokeDexCallingConvention calling_convention;
__ movl(destination.AsX86().AsRegisterPairLow(),
calling_convention.GetRegisterAt(argument_index));
- __ movl(destination.AsX86().AsRegisterPairHigh(),
- Address(ESP,
- calling_convention.GetStackOffsetOf(argument_index + 1) + GetFrameSize()));
+ __ movl(destination.AsX86().AsRegisterPairHigh(), Address(ESP,
+ calling_convention.GetStackOffsetOf(argument_index + 1, kX86WordSize) + GetFrameSize()));
} else {
DCHECK(source.IsDoubleStackSlot());
__ movl(destination.AsX86().AsRegisterPairLow(), Address(ESP, source.GetStackIndex()));
@@ -220,14 +193,14 @@
uint32_t argument_index = destination.GetQuickParameterIndex();
if (source.IsRegister()) {
__ movl(calling_convention.GetRegisterAt(argument_index), source.AsX86().AsRegisterPairLow());
- __ movl(Address(ESP, calling_convention.GetStackOffsetOf(argument_index + 1)),
+ __ movl(Address(ESP, calling_convention.GetStackOffsetOf(argument_index + 1, kX86WordSize)),
source.AsX86().AsRegisterPairHigh());
} else {
DCHECK(source.IsDoubleStackSlot());
__ movl(calling_convention.GetRegisterAt(argument_index),
Address(ESP, source.GetStackIndex()));
__ movl(EAX, Address(ESP, source.GetHighStackIndex(kX86WordSize)));
- __ movl(Address(ESP, calling_convention.GetStackOffsetOf(argument_index + 1)), EAX);
+ __ movl(Address(ESP, calling_convention.GetStackOffsetOf(argument_index + 1, kX86WordSize)), EAX);
}
} else {
if (source.IsRegister()) {
@@ -239,9 +212,8 @@
uint32_t argument_index = source.GetQuickParameterIndex();
__ movl(Address(ESP, destination.GetStackIndex()),
calling_convention.GetRegisterAt(argument_index));
- __ movl(EAX,
- Address(ESP,
- calling_convention.GetStackOffsetOf(argument_index + 1) + GetFrameSize()));
+ __ movl(EAX, Address(ESP,
+ calling_convention.GetStackOffsetOf(argument_index + 1, kX86WordSize) + GetFrameSize()));
__ movl(Address(ESP, destination.GetHighStackIndex(kX86WordSize)), EAX);
} else {
DCHECK(source.IsDoubleStackSlot());
@@ -688,38 +660,13 @@
void LocationsBuilderX86::VisitParameterValue(HParameterValue* instruction) {
LocationSummary* locations = new (GetGraph()->GetArena()) LocationSummary(instruction);
- InvokeDexCallingConvention calling_convention;
- uint32_t argument_index = instruction->GetIndex();
- switch (instruction->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->SetOut(X86CpuLocation(calling_convention.GetRegisterAt(argument_index)));
- } else {
- locations->SetOut(Location::StackSlot(
- calling_convention.GetStackOffsetOf(argument_index) + codegen_->GetFrameSize()));
- }
- break;
-
- case Primitive::kPrimLong:
- if (argument_index + 1 < calling_convention.GetNumberOfRegisters()) {
- locations->SetOut(Location::RegisterLocation(X86ManagedRegister::FromRegisterPair(
- (calling_convention.GetRegisterPairAt(argument_index)))));
- } else if (argument_index + 1 == calling_convention.GetNumberOfRegisters()) {
- locations->SetOut(Location::QuickParameter(argument_index));
- } else {
- locations->SetOut(Location::DoubleStackSlot(
- calling_convention.GetStackOffsetOf(argument_index) + codegen_->GetFrameSize()));
- }
- break;
-
- default:
- LOG(FATAL) << "Unimplemented parameter type " << instruction->GetType();
+ Location location = parameter_visitor_.GetNextLocation(instruction->GetType());
+ if (location.IsStackSlot()) {
+ location = Location::StackSlot(location.GetStackIndex() + codegen_->GetFrameSize());
+ } else if (location.IsDoubleStackSlot()) {
+ location = Location::DoubleStackSlot(location.GetStackIndex() + codegen_->GetFrameSize());
}
+ locations->SetOut(location);
instruction->SetLocations(locations);
}
diff --git a/compiler/optimizing/code_generator_x86.h b/compiler/optimizing/code_generator_x86.h
index 9108f80..f22890e 100644
--- a/compiler/optimizing/code_generator_x86.h
+++ b/compiler/optimizing/code_generator_x86.h
@@ -28,6 +28,37 @@
class CodeGeneratorX86;
+static constexpr Register kParameterCoreRegisters[] = { ECX, EDX, EBX };
+static constexpr RegisterPair kParameterCorePairRegisters[] = { ECX_EDX, EDX_EBX };
+static constexpr size_t kParameterCoreRegistersLength = arraysize(kParameterCoreRegisters);
+
+class InvokeDexCallingConvention : public CallingConvention<Register> {
+ public:
+ InvokeDexCallingConvention()
+ : CallingConvention(kParameterCoreRegisters, kParameterCoreRegistersLength) {}
+
+ RegisterPair GetRegisterPairAt(size_t argument_index) {
+ DCHECK_LT(argument_index + 1, GetNumberOfRegisters());
+ return kParameterCorePairRegisters[argument_index];
+ }
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(InvokeDexCallingConvention);
+};
+
+class InvokeDexCallingConventionVisitor {
+ public:
+ InvokeDexCallingConventionVisitor() : gp_index_(0) {}
+
+ Location GetNextLocation(Primitive::Type type);
+
+ private:
+ InvokeDexCallingConvention calling_convention;
+ uint32_t gp_index_;
+
+ DISALLOW_COPY_AND_ASSIGN(InvokeDexCallingConventionVisitor);
+};
+
class LocationsBuilderX86 : public HGraphVisitor {
public:
LocationsBuilderX86(HGraph* graph, CodeGeneratorX86* codegen)
@@ -42,6 +73,7 @@
private:
CodeGeneratorX86* const codegen_;
+ InvokeDexCallingConventionVisitor parameter_visitor_;
DISALLOW_COPY_AND_ASSIGN(LocationsBuilderX86);
};