diff options
| -rw-r--r-- | compiler/optimizing/code_generator.h | 8 | ||||
| -rw-r--r-- | compiler/optimizing/code_generator_arm.cc | 159 | ||||
| -rw-r--r-- | compiler/optimizing/code_generator_arm.h | 32 | ||||
| -rw-r--r-- | compiler/optimizing/code_generator_x86.cc | 165 | ||||
| -rw-r--r-- | compiler/optimizing/code_generator_x86.h | 32 |
5 files changed, 178 insertions, 218 deletions
diff --git a/compiler/optimizing/code_generator.h b/compiler/optimizing/code_generator.h index d459dd5f44..5c7cac1e5c 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 @@ class CallingConvention { 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 cdd9696fcd..27691ac080 100644 --- a/compiler/optimizing/code_generator_arm.cc +++ b/compiler/optimizing/code_generator_arm.cc @@ -48,9 +48,11 @@ void CodeGeneratorARM::GenerateFrameEntry() { 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 @@ int32_t CodeGeneratorARM::GetStackSlot(HLocal* local) const { 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::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; } - return Location(); - } - private: - InvokeDexCallingConvention calling_convention; - uint32_t gp_index_; + case Primitive::kPrimDouble: + case Primitive::kPrimFloat: + LOG(FATAL) << "Unimplemented parameter type " << type; + break; - DISALLOW_COPY_AND_ASSIGN(InvokeDexCallingConventionVisitor); -}; + case Primitive::kPrimVoid: + LOG(FATAL) << "Unexpected parameter type " << type; + break; + } + return Location(); +} void CodeGeneratorARM::Move32(Location destination, Location source) { if (source.Equals(destination)) { @@ -188,7 +161,7 @@ void CodeGeneratorARM::Move64(Location destination, Location source) { __ 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 @@ void CodeGeneratorARM::Move64(Location destination, Location source) { 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 @@ void CodeGeneratorARM::Move64(Location destination, Location source) { __ 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 InstructionCodeGeneratorARM::VisitNewInstance(HNewInstance* instruction) { 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 3fbe63119f..ed35f94e2b 100644 --- a/compiler/optimizing/code_generator_arm.h +++ b/compiler/optimizing/code_generator_arm.h @@ -28,6 +28,37 @@ class CodeGeneratorARM; 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 @@ class LocationsBuilderARM : public HGraphVisitor { 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 7b3d31ddff..114263161d 100644 --- a/compiler/optimizing/code_generator_x86.cc +++ b/compiler/optimizing/code_generator_x86.cc @@ -49,10 +49,13 @@ void CodeGeneratorX86::GenerateFrameEntry() { 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 @@ int32_t CodeGeneratorX86::GetStackSlot(HLocal* local) const { 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 @@ class InvokeRuntimeCallingConvention : public CallingConvention<Register> { 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::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; } - return Location(); - } - private: - InvokeDexCallingConvention calling_convention; - uint32_t gp_index_; + case Primitive::kPrimDouble: + case Primitive::kPrimFloat: + LOG(FATAL) << "Unimplemented parameter type " << type; + break; - DISALLOW_COPY_AND_ASSIGN(InvokeDexCallingConventionVisitor); -}; + case Primitive::kPrimVoid: + LOG(FATAL) << "Unexpected parameter type " << type; + break; + } + return Location(); +} void CodeGeneratorX86::Move32(Location destination, Location source) { if (source.Equals(destination)) { @@ -206,9 +180,8 @@ void CodeGeneratorX86::Move64(Location destination, Location source) { 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 @@ void CodeGeneratorX86::Move64(Location destination, Location source) { 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 @@ void CodeGeneratorX86::Move64(Location destination, Location source) { 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 InstructionCodeGeneratorX86::VisitNewInstance(HNewInstance* instruction) { 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 9108f80d79..f22890e708 100644 --- a/compiler/optimizing/code_generator_x86.h +++ b/compiler/optimizing/code_generator_x86.h @@ -28,6 +28,37 @@ static constexpr size_t kX86WordSize = 4; 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 @@ class LocationsBuilderX86 : public HGraphVisitor { private: CodeGeneratorX86* const codegen_; + InvokeDexCallingConventionVisitor parameter_visitor_; DISALLOW_COPY_AND_ASSIGN(LocationsBuilderX86); }; |