summaryrefslogtreecommitdiffstats
path: root/compiler/optimizing/code_generator_x86.cc
diff options
context:
space:
mode:
Diffstat (limited to 'compiler/optimizing/code_generator_x86.cc')
-rw-r--r--compiler/optimizing/code_generator_x86.cc131
1 files changed, 73 insertions, 58 deletions
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 @@ class InvokeDexCallingConvention : public CallingConvention<Register> {
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 @@ void InstructionCodeGeneratorX86::VisitReturn(HReturn* ret) {
__ 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: