summaryrefslogtreecommitdiffstats
path: root/compiler/optimizing
diff options
context:
space:
mode:
authorMark Mendell <mark.p.mendell@intel.com>2015-01-19 14:09:22 -0500
committerMark P Mendell <mark.p.mendell@intel.com>2015-01-30 13:17:23 +0000
commit3e6a3bf797e49b7f449256455c7e522e888687d8 (patch)
tree1e574169ff7743729cdfb1b9cf3b217f198a330d /compiler/optimizing
parent9544368685b4aa65e746332e602491a3e8e5b247 (diff)
downloadart-3e6a3bf797e49b7f449256455c7e522e888687d8.tar.gz
art-3e6a3bf797e49b7f449256455c7e522e888687d8.tar.bz2
art-3e6a3bf797e49b7f449256455c7e522e888687d8.zip
ART: Change x86 long param ABI (Quick/JNI/Opt)
Ensure that we don't pass a long parameter across the last register and the stack: skip the register and allocate it only on the stack. This was requested to simplify the optimizing compiler code generation for x86. Optimizing (Baseline) compiler support for x86 longs: - Remove QuickParameter from Location, as there are no longer any uses of it. Bump oat.h version because we changed an ABI again. I changed IsParamALong() to return false for argument 0 (this argument). I am not sure why it differed from all other tests. I have not tested on ARM. I followed Nicolas's suggestions for setting the value of kSplitPairAcrossRegisterAndStack for different architectures. Change-Id: I2f16b33c1dac58dd4f4f503e9c2309d845f5fb7a Signed-off-by: Mark Mendell <mark.p.mendell@intel.com>
Diffstat (limited to 'compiler/optimizing')
-rw-r--r--compiler/optimizing/code_generator_x86.cc42
-rw-r--r--compiler/optimizing/locations.h28
2 files changed, 1 insertions, 69 deletions
diff --git a/compiler/optimizing/code_generator_x86.cc b/compiler/optimizing/code_generator_x86.cc
index 063550be92..d880eefeda 100644
--- a/compiler/optimizing/code_generator_x86.cc
+++ b/compiler/optimizing/code_generator_x86.cc
@@ -534,9 +534,6 @@ Location InvokeDexCallingConventionVisitor::GetNextLocation(Primitive::Type type
X86ManagedRegister pair = X86ManagedRegister::FromRegisterPair(
calling_convention.GetRegisterPairAt(index));
return Location::RegisterPairLocation(pair.AsRegisterPairLow(), pair.AsRegisterPairHigh());
- } else if (index + 1 == calling_convention.GetNumberOfRegisters()) {
- // 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));
}
@@ -628,16 +625,6 @@ void CodeGeneratorX86::Move64(Location destination, Location source) {
Location::RegisterLocation(destination.AsRegisterPairLow<Register>()));
} else if (source.IsFpuRegister()) {
LOG(FATAL) << "Unimplemented";
- } else if (source.IsQuickParameter()) {
- uint16_t register_index = source.GetQuickParameterRegisterIndex();
- uint16_t stack_index = source.GetQuickParameterStackIndex();
- InvokeDexCallingConvention calling_convention;
- EmitParallelMoves(
- Location::RegisterLocation(calling_convention.GetRegisterAt(register_index)),
- Location::RegisterLocation(destination.AsRegisterPairLow<Register>()),
- Location::StackSlot(
- calling_convention.GetStackOffsetOf(stack_index + 1) + GetFrameSize()),
- Location::RegisterLocation(destination.AsRegisterPairHigh<Register>()));
} else {
// No conflict possible, so just do the moves.
DCHECK(source.IsDoubleStackSlot());
@@ -645,23 +632,6 @@ void CodeGeneratorX86::Move64(Location destination, Location source) {
__ movl(destination.AsRegisterPairHigh<Register>(),
Address(ESP, source.GetHighStackIndex(kX86WordSize)));
}
- } else if (destination.IsQuickParameter()) {
- InvokeDexCallingConvention calling_convention;
- uint16_t register_index = destination.GetQuickParameterRegisterIndex();
- uint16_t stack_index = destination.GetQuickParameterStackIndex();
- if (source.IsRegisterPair()) {
- LOG(FATAL) << "Unimplemented";
- } else if (source.IsFpuRegister()) {
- LOG(FATAL) << "Unimplemented";
- } else {
- DCHECK(source.IsDoubleStackSlot());
- EmitParallelMoves(
- Location::StackSlot(source.GetStackIndex()),
- Location::StackSlot(calling_convention.GetStackOffsetOf(stack_index)),
- Location::StackSlot(source.GetHighStackIndex(kX86WordSize)),
- Location::StackSlot(calling_convention.GetStackOffsetOf(stack_index + 1)));
- __ movl(calling_convention.GetRegisterAt(register_index), Address(ESP, source.GetStackIndex()));
- }
} else if (destination.IsFpuRegister()) {
if (source.IsFpuRegister()) {
__ movaps(destination.AsFpuRegister<XmmRegister>(), source.AsFpuRegister<XmmRegister>());
@@ -677,18 +647,6 @@ void CodeGeneratorX86::Move64(Location destination, Location source) {
__ movl(Address(ESP, destination.GetStackIndex()), source.AsRegisterPairLow<Register>());
__ movl(Address(ESP, destination.GetHighStackIndex(kX86WordSize)),
source.AsRegisterPairHigh<Register>());
- } else if (source.IsQuickParameter()) {
- // No conflict possible, so just do the move.
- InvokeDexCallingConvention calling_convention;
- uint16_t register_index = source.GetQuickParameterRegisterIndex();
- uint16_t stack_index = source.GetQuickParameterStackIndex();
- // Just move the low part. The only time a source is a quick parameter is
- // when moving the parameter to its stack locations. And the (Java) caller
- // of this method has already done that.
- __ movl(Address(ESP, destination.GetStackIndex()),
- calling_convention.GetRegisterAt(register_index));
- DCHECK_EQ(calling_convention.GetStackOffsetOf(stack_index + 1) + GetFrameSize(),
- static_cast<size_t>(destination.GetHighStackIndex(kX86WordSize)));
} else if (source.IsFpuRegister()) {
__ movsd(Address(ESP, destination.GetStackIndex()), source.AsFpuRegister<XmmRegister>());
} else {
diff --git a/compiler/optimizing/locations.h b/compiler/optimizing/locations.h
index 8b06d607f5..8eef98618a 100644
--- a/compiler/optimizing/locations.h
+++ b/compiler/optimizing/locations.h
@@ -62,17 +62,11 @@ class Location : public ValueObject {
// We do not use the value 9 because it conflicts with kLocationConstantMask.
kDoNotUse9 = 9,
- // On 32bits architectures, quick can pass a long where the
- // low bits are in the last parameter register, and the high
- // bits are in a stack slot. The kQuickParameter kind is for
- // handling this special case.
- kQuickParameter = 10,
-
// Unallocated location represents a location that is not fixed and can be
// allocated by a register allocator. Each unallocated location has
// a policy that specifies what kind of location is suitable. Payload
// contains register allocation policy.
- kUnallocated = 11,
+ kUnallocated = 10,
};
Location() : value_(kInvalid) {
@@ -82,7 +76,6 @@ class Location : public ValueObject {
static_assert((kStackSlot & kLocationConstantMask) != kConstant, "TagError");
static_assert((kDoubleStackSlot & kLocationConstantMask) != kConstant, "TagError");
static_assert((kRegister & kLocationConstantMask) != kConstant, "TagError");
- static_assert((kQuickParameter & kLocationConstantMask) != kConstant, "TagError");
static_assert((kFpuRegister & kLocationConstantMask) != kConstant, "TagError");
static_assert((kRegisterPair & kLocationConstantMask) != kConstant, "TagError");
static_assert((kFpuRegisterPair & kLocationConstantMask) != kConstant, "TagError");
@@ -267,24 +260,6 @@ class Location : public ValueObject {
return GetPayload() - kStackIndexBias + word_size;
}
- static Location QuickParameter(uint16_t register_index, uint16_t stack_index) {
- return Location(kQuickParameter, register_index << 16 | stack_index);
- }
-
- uint32_t GetQuickParameterRegisterIndex() const {
- DCHECK(IsQuickParameter());
- return GetPayload() >> 16;
- }
-
- uint32_t GetQuickParameterStackIndex() const {
- DCHECK(IsQuickParameter());
- return GetPayload() & 0xFFFF;
- }
-
- bool IsQuickParameter() const {
- return GetKind() == kQuickParameter;
- }
-
Kind GetKind() const {
return IsConstant() ? kConstant : KindField::Decode(value_);
}
@@ -299,7 +274,6 @@ class Location : public ValueObject {
case kRegister: return "R";
case kStackSlot: return "S";
case kDoubleStackSlot: return "DS";
- case kQuickParameter: return "Q";
case kUnallocated: return "U";
case kConstant: return "C";
case kFpuRegister: return "F";