summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNicolas Geoffray <ngeoffray@google.com>2015-01-13 11:42:13 +0000
committerNicolas Geoffray <ngeoffray@google.com>2015-01-13 18:11:24 +0000
commit69c15d340e7e76821bbc5d4494d4cef383774dee (patch)
treeafea69c321ffa55e0af63a83be62eedd2b378d2f
parent603104b5b5c3759b0bc2733bda2f972686a775a3 (diff)
downloadandroid_art-69c15d340e7e76821bbc5d4494d4cef383774dee.tar.gz
android_art-69c15d340e7e76821bbc5d4494d4cef383774dee.tar.bz2
android_art-69c15d340e7e76821bbc5d4494d4cef383774dee.zip
Skip r1 on arm if first parameter is a long.
Change-Id: I16d927ee0a0b55031ade4c92c0095fd74e18ed5b
-rw-r--r--compiler/dex/quick/arm/target_arm.cc4
-rw-r--r--compiler/jni/quick/arm/calling_convention_arm.cc7
-rw-r--r--compiler/optimizing/code_generator_arm.cc17
-rw-r--r--compiler/optimizing/code_generator_arm.h6
-rw-r--r--runtime/arch/arm/quick_entrypoints_cc_arm.cc7
-rw-r--r--runtime/entrypoints/quick/quick_trampoline_entrypoints.cc10
6 files changed, 42 insertions, 9 deletions
diff --git a/compiler/dex/quick/arm/target_arm.cc b/compiler/dex/quick/arm/target_arm.cc
index b05939156f..52a516cc5a 100644
--- a/compiler/dex/quick/arm/target_arm.cc
+++ b/compiler/dex/quick/arm/target_arm.cc
@@ -929,6 +929,10 @@ RegStorage ArmMir2Lir::InToRegStorageArmMapper::GetNextReg(ShortyArg arg) {
}
} else {
if (cur_core_reg_ < coreArgMappingToPhysicalRegSize) {
+ if (!kArm32QuickCodeUseSoftFloat && arg.IsWide() && cur_core_reg_ == 0) {
+ // Skip r1, and use r2-r3 for the register pair.
+ cur_core_reg_++;
+ }
result = coreArgMappingToPhysicalReg[cur_core_reg_++];
if (arg.IsWide() && cur_core_reg_ < coreArgMappingToPhysicalRegSize) {
result = RegStorage::MakeRegPair(result, coreArgMappingToPhysicalReg[cur_core_reg_++]);
diff --git a/compiler/jni/quick/arm/calling_convention_arm.cc b/compiler/jni/quick/arm/calling_convention_arm.cc
index fd207150f7..669c3bb716 100644
--- a/compiler/jni/quick/arm/calling_convention_arm.cc
+++ b/compiler/jni/quick/arm/calling_convention_arm.cc
@@ -168,6 +168,13 @@ const ManagedRegisterEntrySpills& ArmManagedRuntimeCallingConvention::EntrySpill
} else {
// FIXME: Pointer this returns as both reference and long.
if (IsCurrentParamALong() && !IsCurrentParamAReference()) { // Long.
+ if (gpr_index < arraysize(kHFCoreArgumentRegisters) - 1) {
+ // Skip R1, and use R2_R3 if the long is the first parameter.
+ if (gpr_index == 1) {
+ gpr_index++;
+ }
+ }
+
// If it spans register and memory, we must use the value in memory.
if (gpr_index < arraysize(kHFCoreArgumentRegisters) - 1) {
entry_spills_.push_back(
diff --git a/compiler/optimizing/code_generator_arm.cc b/compiler/optimizing/code_generator_arm.cc
index 1cc2dcc9b8..20b8b6a62d 100644
--- a/compiler/optimizing/code_generator_arm.cc
+++ b/compiler/optimizing/code_generator_arm.cc
@@ -590,9 +590,17 @@ Location InvokeDexCallingConventionVisitor::GetNextLocation(Primitive::Type type
gp_index_ += 2;
stack_index_ += 2;
if (index + 1 < calling_convention.GetNumberOfRegisters()) {
- ArmManagedRegister pair = ArmManagedRegister::FromRegisterPair(
- calling_convention.GetRegisterPairAt(index));
- return Location::RegisterPairLocation(pair.AsRegisterPairLow(), pair.AsRegisterPairHigh());
+ if (calling_convention.GetRegisterAt(index) == R1) {
+ // Skip R1, and use R2_R3 instead.
+ gp_index_++;
+ index++;
+ }
+ }
+ if (index + 1 < calling_convention.GetNumberOfRegisters()) {
+ DCHECK_EQ(calling_convention.GetRegisterAt(index) + 1,
+ calling_convention.GetRegisterAt(index + 1));
+ return Location::RegisterPairLocation(calling_convention.GetRegisterAt(index),
+ calling_convention.GetRegisterAt(index + 1));
} else {
return Location::DoubleStackSlot(calling_convention.GetStackOffsetOf(stack_index));
}
@@ -617,6 +625,9 @@ Location InvokeDexCallingConventionVisitor::GetNextLocation(Primitive::Type type
if (double_index_ + 1 < calling_convention.GetNumberOfFpuRegisters()) {
uint32_t index = double_index_;
double_index_ += 2;
+ DCHECK_EQ(calling_convention.GetFpuRegisterAt(index) + 1,
+ calling_convention.GetFpuRegisterAt(index + 1));
+ DCHECK_EQ(calling_convention.GetFpuRegisterAt(index) & 1, 0);
return Location::FpuRegisterPairLocation(
calling_convention.GetFpuRegisterAt(index),
calling_convention.GetFpuRegisterAt(index + 1));
diff --git a/compiler/optimizing/code_generator_arm.h b/compiler/optimizing/code_generator_arm.h
index c1b4eda3a4..8b29b159ab 100644
--- a/compiler/optimizing/code_generator_arm.h
+++ b/compiler/optimizing/code_generator_arm.h
@@ -33,7 +33,6 @@ class SlowPathCodeARM;
static constexpr size_t kArmWordSize = kArmPointerSize;
static constexpr Register kParameterCoreRegisters[] = { R1, R2, R3 };
-static constexpr RegisterPair kParameterCorePairRegisters[] = { R1_R2, R2_R3 };
static constexpr size_t kParameterCoreRegistersLength = arraysize(kParameterCoreRegisters);
static constexpr SRegister kParameterFpuRegisters[] =
{ S0, S1, S2, S3, S4, S5, S6, S7, S8, S9, S10, S11, S12, S13, S14, S15 };
@@ -47,11 +46,6 @@ class InvokeDexCallingConvention : public CallingConvention<Register, SRegister>
kParameterFpuRegisters,
kParameterFpuRegistersLength) {}
- RegisterPair GetRegisterPairAt(size_t argument_index) {
- DCHECK_LT(argument_index + 1, GetNumberOfRegisters());
- return kParameterCorePairRegisters[argument_index];
- }
-
private:
DISALLOW_COPY_AND_ASSIGN(InvokeDexCallingConvention);
};
diff --git a/runtime/arch/arm/quick_entrypoints_cc_arm.cc b/runtime/arch/arm/quick_entrypoints_cc_arm.cc
index e21e6c1a2e..a3acd7e10a 100644
--- a/runtime/arch/arm/quick_entrypoints_cc_arm.cc
+++ b/runtime/arch/arm/quick_entrypoints_cc_arm.cc
@@ -75,7 +75,14 @@ static void quick_invoke_reg_setup(mirror::ArtMethod* method, uint32_t* args, ui
}
break;
case 'J':
+ if (gpr_index == 1 && !kArm32QuickCodeUseSoftFloat) {
+ // Don't use r1-r2 as a register pair, move to r2-r3 instead.
+ gpr_index++;
+ }
if (gpr_index < arraysize(core_reg_args)) {
+ // Note that we don't need to do this if two registers are not available
+ // when !kArm32QuickCodeUseSoftFloat. We do it anyway to leave this
+ // code simple.
core_reg_args[gpr_index++] = args[arg_index];
}
++arg_index;
diff --git a/runtime/entrypoints/quick/quick_trampoline_entrypoints.cc b/runtime/entrypoints/quick/quick_trampoline_entrypoints.cc
index 4bec70acd6..ac640b4454 100644
--- a/runtime/entrypoints/quick/quick_trampoline_entrypoints.cc
+++ b/runtime/entrypoints/quick/quick_trampoline_entrypoints.cc
@@ -59,6 +59,7 @@ class QuickArgumentVisitor {
// | S0 |
// | | 4x2 bytes padding
// | Method* | <- sp
+ static constexpr bool kAlignPairRegister = !kArm32QuickCodeUseSoftFloat;
static constexpr bool kQuickSoftFloatAbi = kArm32QuickCodeUseSoftFloat;
static constexpr bool kQuickDoubleRegAlignedFloatBackFilled = !kArm32QuickCodeUseSoftFloat;
static constexpr size_t kNumQuickGprArgs = 3;
@@ -93,6 +94,7 @@ class QuickArgumentVisitor {
// | D0 |
// | | padding
// | Method* | <- sp
+ static constexpr bool kAlignPairRegister = false;
static constexpr bool kQuickSoftFloatAbi = false; // This is a hard float ABI.
static constexpr bool kQuickDoubleRegAlignedFloatBackFilled = false;
static constexpr size_t kNumQuickGprArgs = 7; // 7 arguments passed in GPRs.
@@ -121,6 +123,7 @@ class QuickArgumentVisitor {
// | A2 | arg2
// | A1 | arg1
// | A0/Method* | <- sp
+ static constexpr bool kAlignPairRegister = false;
static constexpr bool kQuickSoftFloatAbi = true; // This is a soft float ABI.
static constexpr bool kQuickDoubleRegAlignedFloatBackFilled = false;
static constexpr size_t kNumQuickGprArgs = 3; // 3 arguments passed in GPRs.
@@ -146,6 +149,7 @@ class QuickArgumentVisitor {
// | EDX | arg2
// | ECX | arg1
// | EAX/Method* | <- sp
+ static constexpr bool kAlignPairRegister = false;
static constexpr bool kQuickSoftFloatAbi = true; // This is a soft float ABI.
static constexpr bool kQuickDoubleRegAlignedFloatBackFilled = false;
static constexpr size_t kNumQuickGprArgs = 3; // 3 arguments passed in GPRs.
@@ -184,6 +188,7 @@ class QuickArgumentVisitor {
// | XMM0 | float arg 1
// | Padding |
// | RDI/Method* | <- sp
+ static constexpr bool kAlignPairRegister = false;
static constexpr bool kQuickSoftFloatAbi = false; // This is a hard float ABI.
static constexpr bool kQuickDoubleRegAlignedFloatBackFilled = false;
static constexpr size_t kNumQuickGprArgs = 5; // 5 arguments passed in GPRs.
@@ -370,6 +375,11 @@ class QuickArgumentVisitor {
case Primitive::kPrimDouble:
case Primitive::kPrimLong:
if (kQuickSoftFloatAbi || (cur_type_ == Primitive::kPrimLong)) {
+ if (cur_type_ == Primitive::kPrimLong && kAlignPairRegister && gpr_index_ == 0) {
+ // Currently, this is only for ARM, where the first available parameter register
+ // is R1. So we skip it, and use R2 instead.
+ gpr_index_++;
+ }
is_split_long_or_double_ = (GetBytesPerGprSpillLocation(kRuntimeISA) == 4) &&
((gpr_index_ + 1) == kNumQuickGprArgs);
Visit();