diff options
author | Mark P Mendell <mark.p.mendell@intel.com> | 2015-01-27 15:45:27 +0000 |
---|---|---|
committer | Mark Mendell <mark.p.mendell@intel.com> | 2015-01-27 17:00:21 -0500 |
commit | 966c3ae95d3c699ee9fbdbccc1acdaaf02325faf (patch) | |
tree | 7a9bd5dbfb8b02f8bb7e3387876be0c1f7844063 /compiler/optimizing | |
parent | 85ed6bdd890c08f50c205d7f0604b5a35603b13e (diff) | |
download | android_art-966c3ae95d3c699ee9fbdbccc1acdaaf02325faf.tar.gz android_art-966c3ae95d3c699ee9fbdbccc1acdaaf02325faf.tar.bz2 android_art-966c3ae95d3c699ee9fbdbccc1acdaaf02325faf.zip |
Revert "Revert "ART: Implement X86 hard float (Quick/JNI/Baseline)""
This reverts commit 949c91fb91f40a4a80b2b492913cf8541008975e.
This time, don't clobber EBX before saving it.
Redo some of the macros to make register usage explicit.
Change-Id: I8db8662877cd006816e16a28f42444ab7c36bfef
Diffstat (limited to 'compiler/optimizing')
-rw-r--r-- | compiler/optimizing/code_generator_x86.cc | 68 | ||||
-rw-r--r-- | compiler/optimizing/code_generator_x86.h | 11 |
2 files changed, 45 insertions, 34 deletions
diff --git a/compiler/optimizing/code_generator_x86.cc b/compiler/optimizing/code_generator_x86.cc index c0fdcaa8aa..66f1d5e58d 100644 --- a/compiler/optimizing/code_generator_x86.cc +++ b/compiler/optimizing/code_generator_x86.cc @@ -36,8 +36,9 @@ static constexpr int kCurrentMethodStackOffset = 0; static constexpr Register kRuntimeParameterCoreRegisters[] = { EAX, ECX, EDX, EBX }; static constexpr size_t kRuntimeParameterCoreRegistersLength = arraysize(kRuntimeParameterCoreRegisters); -static constexpr XmmRegister kRuntimeParameterFpuRegisters[] = { }; -static constexpr size_t kRuntimeParameterFpuRegistersLength = 0; +static constexpr XmmRegister kRuntimeParameterFpuRegisters[] = { XMM0, XMM1, XMM2, XMM3 }; +static constexpr size_t kRuntimeParameterFpuRegistersLength = + arraysize(kRuntimeParameterFpuRegisters); static constexpr int kC2ConditionMask = 0x400; @@ -504,30 +505,49 @@ Location InvokeDexCallingConventionVisitor::GetNextLocation(Primitive::Type type case Primitive::kPrimChar: case Primitive::kPrimShort: case Primitive::kPrimInt: - case Primitive::kPrimFloat: case Primitive::kPrimNot: { uint32_t index = gp_index_++; + stack_index_++; if (index < calling_convention.GetNumberOfRegisters()) { return Location::RegisterLocation(calling_convention.GetRegisterAt(index)); } else { - return Location::StackSlot(calling_convention.GetStackOffsetOf(index)); + return Location::StackSlot(calling_convention.GetStackOffsetOf(stack_index_ - 1)); } } - case Primitive::kPrimLong: - case Primitive::kPrimDouble: { + case Primitive::kPrimLong: { uint32_t index = gp_index_; gp_index_ += 2; + stack_index_ += 2; if (index + 1 < calling_convention.GetNumberOfRegisters()) { X86ManagedRegister pair = X86ManagedRegister::FromRegisterPair( calling_convention.GetRegisterPairAt(index)); return Location::RegisterPairLocation(pair.AsRegisterPairLow(), pair.AsRegisterPairHigh()); } else if (index + 1 == calling_convention.GetNumberOfRegisters()) { - // On X86, the register index and stack index of a quick parameter is the same, since - // we are passing floating pointer values in core registers. - return Location::QuickParameter(index, index); + // stack_index_ is the right offset for the memory. + return Location::QuickParameter(index, stack_index_ - 2); + } else { + return Location::DoubleStackSlot(calling_convention.GetStackOffsetOf(stack_index_ - 2)); + } + } + + case Primitive::kPrimFloat: { + uint32_t index = fp_index_++; + stack_index_++; + if (index < calling_convention.GetNumberOfFpuRegisters()) { + return Location::FpuRegisterLocation(calling_convention.GetFpuRegisterAt(index)); + } else { + return Location::StackSlot(calling_convention.GetStackOffsetOf(stack_index_ - 1)); + } + } + + case Primitive::kPrimDouble: { + uint32_t index = fp_index_++; + stack_index_ += 2; + if (index < calling_convention.GetNumberOfFpuRegisters()) { + return Location::FpuRegisterLocation(calling_convention.GetFpuRegisterAt(index)); } else { - return Location::DoubleStackSlot(calling_convention.GetStackOffsetOf(index)); + return Location::DoubleStackSlot(calling_convention.GetStackOffsetOf(stack_index_ - 2)); } } @@ -1186,7 +1206,7 @@ void InstructionCodeGeneratorX86::VisitInvokeVirtual(HInvokeVirtual* invoke) { void LocationsBuilderX86::VisitInvokeInterface(HInvokeInterface* invoke) { HandleInvoke(invoke); // Add the hidden argument. - invoke->GetLocations()->AddTemp(Location::FpuRegisterLocation(XMM0)); + invoke->GetLocations()->AddTemp(Location::FpuRegisterLocation(XMM7)); } void InstructionCodeGeneratorX86::VisitInvokeInterface(HInvokeInterface* invoke) { @@ -1388,31 +1408,17 @@ void LocationsBuilderX86::VisitTypeConversion(HTypeConversion* conversion) { locations->SetOut(Location::RegisterPairLocation(EAX, EDX)); break; - case Primitive::kPrimFloat: { - // Processing a Dex `float-to-long' instruction. - InvokeRuntimeCallingConvention calling_convention; - // Note that on x86 floating-point parameters are passed - // through core registers (here, EAX). - locations->SetInAt(0, Location::RegisterLocation( - calling_convention.GetRegisterAt(0))); - // The runtime helper puts the result in EAX, EDX. - locations->SetOut(Location::RegisterPairLocation(EAX, EDX)); - break; - } - + case Primitive::kPrimFloat: case Primitive::kPrimDouble: { - // Processing a Dex `double-to-long' instruction. + // Processing a Dex `float-to-long' or 'double-to-long' instruction. InvokeRuntimeCallingConvention calling_convention; - // Note that on x86 floating-point parameters are passed - // through core registers (here, EAX and ECX). - locations->SetInAt(0, Location::RegisterPairLocation( - calling_convention.GetRegisterAt(0), - calling_convention.GetRegisterAt(1))); + XmmRegister parameter = calling_convention.GetFpuRegisterAt(0); + locations->SetInAt(0, Location::FpuRegisterLocation(parameter)); + // The runtime helper puts the result in EAX, EDX. locations->SetOut(Location::RegisterPairLocation(EAX, EDX)); - break; } - break; + break; default: LOG(FATAL) << "Unexpected type conversion from " << input_type diff --git a/compiler/optimizing/code_generator_x86.h b/compiler/optimizing/code_generator_x86.h index 73b647c1c4..55d71e39c4 100644 --- a/compiler/optimizing/code_generator_x86.h +++ b/compiler/optimizing/code_generator_x86.h @@ -36,8 +36,8 @@ class SlowPathCodeX86; static constexpr Register kParameterCoreRegisters[] = { ECX, EDX, EBX }; static constexpr RegisterPair kParameterCorePairRegisters[] = { ECX_EDX, EDX_EBX }; static constexpr size_t kParameterCoreRegistersLength = arraysize(kParameterCoreRegisters); -static constexpr XmmRegister kParameterFpuRegisters[] = { }; -static constexpr size_t kParameterFpuRegistersLength = 0; +static constexpr XmmRegister kParameterFpuRegisters[] = { XMM0, XMM1, XMM2, XMM3 }; +static constexpr size_t kParameterFpuRegistersLength = arraysize(kParameterFpuRegisters); class InvokeDexCallingConvention : public CallingConvention<Register, XmmRegister> { public: @@ -58,13 +58,18 @@ class InvokeDexCallingConvention : public CallingConvention<Register, XmmRegiste class InvokeDexCallingConventionVisitor { public: - InvokeDexCallingConventionVisitor() : gp_index_(0) {} + InvokeDexCallingConventionVisitor() : gp_index_(0), fp_index_(0), stack_index_(0) {} Location GetNextLocation(Primitive::Type type); private: InvokeDexCallingConvention calling_convention; + // The current index for cpu registers. uint32_t gp_index_; + // The current index for fpu registers. + uint32_t fp_index_; + // The current stack index. + uint32_t stack_index_; DISALLOW_COPY_AND_ASSIGN(InvokeDexCallingConventionVisitor); }; |