summaryrefslogtreecommitdiffstats
path: root/compiler/optimizing
diff options
context:
space:
mode:
authorMark P Mendell <mark.p.mendell@intel.com>2015-01-27 15:45:27 +0000
committerMark Mendell <mark.p.mendell@intel.com>2015-01-27 17:00:21 -0500
commit966c3ae95d3c699ee9fbdbccc1acdaaf02325faf (patch)
tree7a9bd5dbfb8b02f8bb7e3387876be0c1f7844063 /compiler/optimizing
parent85ed6bdd890c08f50c205d7f0604b5a35603b13e (diff)
downloadandroid_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.cc68
-rw-r--r--compiler/optimizing/code_generator_x86.h11
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);
};