summaryrefslogtreecommitdiffstats
path: root/compiler/optimizing/code_generator_x86.cc
diff options
context:
space:
mode:
authorNicolas Geoffray <ngeoffray@google.com>2014-04-16 17:38:32 +0100
committerNicolas Geoffray <ngeoffray@google.com>2014-04-17 13:23:24 +0000
commitdb928fcc975b431d8a78700c11bd7da21090384a (patch)
tree24092c6da3cd3651fc0eaee89d0093ac05afeaed /compiler/optimizing/code_generator_x86.cc
parente8b2e6e70decca7ce324350c9c03c9a432ed64d6 (diff)
downloadart-db928fcc975b431d8a78700c11bd7da21090384a.zip
art-db928fcc975b431d8a78700c11bd7da21090384a.tar.gz
art-db928fcc975b431d8a78700c11bd7da21090384a.tar.bz2
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
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: