summaryrefslogtreecommitdiff
path: root/compiler
diff options
context:
space:
mode:
author Vladimir Marko <vmarko@google.com> 2016-12-07 17:15:08 +0000
committer Gerrit Code Review <noreply-gerritcodereview@google.com> 2016-12-07 17:15:08 +0000
commitb08265b2d61cd3923dd6fc01d6c82f73d5230e82 (patch)
treecebb0dd2570ed90265dc376d89c17768700fd90d /compiler
parentb4ee681c21564ee9afe0202e1006cfa21019e88b (diff)
parent1b8464d17c2266763714ae18be7c4dc26e28bf61 (diff)
Merge "MIPS32: Pass more arguments in registers."
Diffstat (limited to 'compiler')
-rw-r--r--compiler/jni/jni_cfi_test_expected.inc4
-rw-r--r--compiler/jni/quick/mips/calling_convention_mips.cc49
-rw-r--r--compiler/optimizing/code_generator_mips.cc9
-rw-r--r--compiler/optimizing/code_generator_mips.h6
-rw-r--r--compiler/optimizing/emit_swap_mips_test.cc36
-rw-r--r--compiler/utils/mips/assembler_mips.cc6
6 files changed, 65 insertions, 45 deletions
diff --git a/compiler/jni/jni_cfi_test_expected.inc b/compiler/jni/jni_cfi_test_expected.inc
index a205800dfa..2710ae9b53 100644
--- a/compiler/jni/jni_cfi_test_expected.inc
+++ b/compiler/jni/jni_cfi_test_expected.inc
@@ -327,7 +327,7 @@ static constexpr uint8_t expected_asm_kMips[] = {
0xC0, 0xFF, 0xBD, 0x27, 0x3C, 0x00, 0xBF, 0xAF, 0x38, 0x00, 0xBE, 0xAF,
0x34, 0x00, 0xB7, 0xAF, 0x30, 0x00, 0xB6, 0xAF, 0x2C, 0x00, 0xB5, 0xAF,
0x28, 0x00, 0xB4, 0xAF, 0x24, 0x00, 0xB3, 0xAF, 0x20, 0x00, 0xB2, 0xAF,
- 0x00, 0x00, 0xA4, 0xAF, 0x44, 0x00, 0xA5, 0xAF, 0x48, 0x00, 0xAC, 0xE7,
+ 0x00, 0x00, 0xA4, 0xAF, 0x44, 0x00, 0xA5, 0xAF, 0x48, 0x00, 0xA8, 0xE7,
0x4C, 0x00, 0xA6, 0xAF, 0x50, 0x00, 0xA7, 0xAF, 0xE0, 0xFF, 0xBD, 0x27,
0x20, 0x00, 0xBD, 0x27, 0x20, 0x00, 0xB2, 0x8F, 0x24, 0x00, 0xB3, 0x8F,
0x28, 0x00, 0xB4, 0x8F, 0x2C, 0x00, 0xB5, 0x8F, 0x30, 0x00, 0xB6, 0x8F,
@@ -361,7 +361,7 @@ static constexpr uint8_t expected_cfi_kMips[] = {
// 0x00000024: .cfi_offset: r18 at cfa-32
// 0x00000024: sw r4, +0(r29)
// 0x00000028: sw r5, +68(r29)
-// 0x0000002c: swc1 f12, +72(r29)
+// 0x0000002c: swc1 f8, +72(r29)
// 0x00000030: sw r6, +76(r29)
// 0x00000034: sw r7, +80(r29)
// 0x00000038: addiu r29, r29, -32
diff --git a/compiler/jni/quick/mips/calling_convention_mips.cc b/compiler/jni/quick/mips/calling_convention_mips.cc
index e6948ec198..0e0716e911 100644
--- a/compiler/jni/quick/mips/calling_convention_mips.cc
+++ b/compiler/jni/quick/mips/calling_convention_mips.cc
@@ -23,6 +23,10 @@
namespace art {
namespace mips {
+//
+// JNI calling convention constants.
+//
+
// Up to how many float-like (float, double) args can be enregistered in floating-point registers.
// The rest of the args must go in integer registers or on the stack.
constexpr size_t kMaxFloatOrDoubleRegisterArguments = 2u;
@@ -30,9 +34,17 @@ constexpr size_t kMaxFloatOrDoubleRegisterArguments = 2u;
// enregistered. The rest of the args must go on the stack.
constexpr size_t kMaxIntLikeRegisterArguments = 4u;
-static const Register kCoreArgumentRegisters[] = { A0, A1, A2, A3 };
-static const FRegister kFArgumentRegisters[] = { F12, F14 };
-static const DRegister kDArgumentRegisters[] = { D6, D7 };
+static const Register kJniCoreArgumentRegisters[] = { A0, A1, A2, A3 };
+static const FRegister kJniFArgumentRegisters[] = { F12, F14 };
+static const DRegister kJniDArgumentRegisters[] = { D6, D7 };
+
+//
+// Managed calling convention constants.
+//
+
+static const Register kManagedCoreArgumentRegisters[] = { A0, A1, A2, A3, T0, T1 };
+static const FRegister kManagedFArgumentRegisters[] = { F8, F10, F12, F14, F16, F18 };
+static const DRegister kManagedDArgumentRegisters[] = { D4, D5, D6, D7, D8, D9 };
static constexpr ManagedRegister kCalleeSaveRegisters[] = {
// Core registers.
@@ -133,30 +145,30 @@ const ManagedRegisterEntrySpills& MipsManagedRuntimeCallingConvention::EntrySpil
for (ResetIterator(FrameOffset(0)); HasNext(); Next()) {
if (IsCurrentParamAFloatOrDouble()) {
if (IsCurrentParamADouble()) {
- if (fpr_index < arraysize(kDArgumentRegisters)) {
+ if (fpr_index < arraysize(kManagedDArgumentRegisters)) {
entry_spills_.push_back(
- MipsManagedRegister::FromDRegister(kDArgumentRegisters[fpr_index++]));
+ MipsManagedRegister::FromDRegister(kManagedDArgumentRegisters[fpr_index++]));
} else {
entry_spills_.push_back(ManagedRegister::NoRegister(), 8);
}
} else {
- if (fpr_index < arraysize(kFArgumentRegisters)) {
+ if (fpr_index < arraysize(kManagedFArgumentRegisters)) {
entry_spills_.push_back(
- MipsManagedRegister::FromFRegister(kFArgumentRegisters[fpr_index++]));
+ MipsManagedRegister::FromFRegister(kManagedFArgumentRegisters[fpr_index++]));
} else {
entry_spills_.push_back(ManagedRegister::NoRegister(), 4);
}
}
} else {
if (IsCurrentParamALong() && !IsCurrentParamAReference()) {
- if (gpr_index == 1) {
- // Don't use a1-a2 as a register pair, move to a2-a3 instead.
+ if (gpr_index == 1 || gpr_index == 3) {
+ // Don't use A1-A2(A3-T0) as a register pair, move to A2-A3(T0-T1) instead.
gpr_index++;
}
- if (gpr_index < arraysize(kCoreArgumentRegisters) - 1) {
+ if (gpr_index < arraysize(kManagedCoreArgumentRegisters) - 1) {
entry_spills_.push_back(
- MipsManagedRegister::FromCoreRegister(kCoreArgumentRegisters[gpr_index++]));
- } else if (gpr_index == arraysize(kCoreArgumentRegisters) - 1) {
+ MipsManagedRegister::FromCoreRegister(kManagedCoreArgumentRegisters[gpr_index++]));
+ } else if (gpr_index == arraysize(kManagedCoreArgumentRegisters) - 1) {
gpr_index++;
entry_spills_.push_back(ManagedRegister::NoRegister(), 4);
} else {
@@ -164,9 +176,9 @@ const ManagedRegisterEntrySpills& MipsManagedRuntimeCallingConvention::EntrySpil
}
}
- if (gpr_index < arraysize(kCoreArgumentRegisters)) {
+ if (gpr_index < arraysize(kManagedCoreArgumentRegisters)) {
entry_spills_.push_back(
- MipsManagedRegister::FromCoreRegister(kCoreArgumentRegisters[gpr_index++]));
+ MipsManagedRegister::FromCoreRegister(kManagedCoreArgumentRegisters[gpr_index++]));
} else {
entry_spills_.push_back(ManagedRegister::NoRegister(), 4);
}
@@ -175,6 +187,7 @@ const ManagedRegisterEntrySpills& MipsManagedRuntimeCallingConvention::EntrySpil
}
return entry_spills_;
}
+
// JNI calling convention
MipsJniCallingConvention::MipsJniCallingConvention(bool is_static,
@@ -285,7 +298,7 @@ MipsJniCallingConvention::MipsJniCallingConvention(bool is_static,
// | FLOAT | INT | DOUBLE |
// | F12 | A1 | A2 | A3 |
// (c) first two arguments are floating-point (float, double)
- // | FLAOT | (PAD) | DOUBLE | INT |
+ // | FLOAT | (PAD) | DOUBLE | INT |
// | F12 | | F14 | SP+16 |
// (d) first two arguments are floating-point (double, float)
// | DOUBLE | FLOAT | INT |
@@ -404,9 +417,9 @@ ManagedRegister MipsJniCallingConvention::CurrentParamRegister() {
if (use_fp_arg_registers_ && (itr_args_ < kMaxFloatOrDoubleRegisterArguments)) {
if (IsCurrentParamAFloatOrDouble()) {
if (IsCurrentParamADouble()) {
- return MipsManagedRegister::FromDRegister(kDArgumentRegisters[itr_args_]);
+ return MipsManagedRegister::FromDRegister(kJniDArgumentRegisters[itr_args_]);
} else {
- return MipsManagedRegister::FromFRegister(kFArgumentRegisters[itr_args_]);
+ return MipsManagedRegister::FromFRegister(kJniFArgumentRegisters[itr_args_]);
}
}
}
@@ -420,7 +433,7 @@ ManagedRegister MipsJniCallingConvention::CurrentParamRegister() {
return MipsManagedRegister::FromRegisterPair(A2_A3);
}
} else {
- return MipsManagedRegister::FromCoreRegister(kCoreArgumentRegisters[itr_slots_]);
+ return MipsManagedRegister::FromCoreRegister(kJniCoreArgumentRegisters[itr_slots_]);
}
}
diff --git a/compiler/optimizing/code_generator_mips.cc b/compiler/optimizing/code_generator_mips.cc
index 61dabfabaa..ff48f6642d 100644
--- a/compiler/optimizing/code_generator_mips.cc
+++ b/compiler/optimizing/code_generator_mips.cc
@@ -99,8 +99,9 @@ Location InvokeDexCallingConventionVisitorMIPS::GetNextLocation(Primitive::Type
uint32_t gp_index = gp_index_;
gp_index_ += 2;
if (gp_index + 1 < calling_convention.GetNumberOfRegisters()) {
- if (calling_convention.GetRegisterAt(gp_index) == A1) {
- gp_index_++; // Skip A1, and use A2_A3 instead.
+ Register reg = calling_convention.GetRegisterAt(gp_index);
+ if (reg == A1 || reg == A3) {
+ gp_index_++; // Skip A1(A3), and use A2_A3(T0_T1) instead.
gp_index++;
}
Register low_even = calling_convention.GetRegisterAt(gp_index);
@@ -5095,9 +5096,9 @@ void LocationsBuilderMIPS::HandleInvoke(HInvoke* invoke) {
void LocationsBuilderMIPS::VisitInvokeInterface(HInvokeInterface* invoke) {
HandleInvoke(invoke);
- // The register T0 is required to be used for the hidden argument in
+ // The register T7 is required to be used for the hidden argument in
// art_quick_imt_conflict_trampoline, so add the hidden argument.
- invoke->GetLocations()->AddTemp(Location::RegisterLocation(T0));
+ invoke->GetLocations()->AddTemp(Location::RegisterLocation(T7));
}
void InstructionCodeGeneratorMIPS::VisitInvokeInterface(HInvokeInterface* invoke) {
diff --git a/compiler/optimizing/code_generator_mips.h b/compiler/optimizing/code_generator_mips.h
index 2273e52b06..f03f29c5d4 100644
--- a/compiler/optimizing/code_generator_mips.h
+++ b/compiler/optimizing/code_generator_mips.h
@@ -32,11 +32,11 @@ namespace mips {
// InvokeDexCallingConvention registers
static constexpr Register kParameterCoreRegisters[] =
- { A1, A2, A3 };
+ { A1, A2, A3, T0, T1 };
static constexpr size_t kParameterCoreRegistersLength = arraysize(kParameterCoreRegisters);
static constexpr FRegister kParameterFpuRegisters[] =
- { F12, F14 };
+ { F8, F10, F12, F14, F16, F18 };
static constexpr size_t kParameterFpuRegistersLength = arraysize(kParameterFpuRegisters);
@@ -48,7 +48,7 @@ static constexpr size_t kRuntimeParameterCoreRegistersLength =
arraysize(kRuntimeParameterCoreRegisters);
static constexpr FRegister kRuntimeParameterFpuRegisters[] =
- { F12, F14};
+ { F12, F14 };
static constexpr size_t kRuntimeParameterFpuRegistersLength =
arraysize(kRuntimeParameterFpuRegisters);
diff --git a/compiler/optimizing/emit_swap_mips_test.cc b/compiler/optimizing/emit_swap_mips_test.cc
index 9dc53e6811..0d4e1c5c97 100644
--- a/compiler/optimizing/emit_swap_mips_test.cc
+++ b/compiler/optimizing/emit_swap_mips_test.cc
@@ -154,54 +154,54 @@ TEST_F(EmitSwapMipsTest, TwoRegisterPairs) {
TEST_F(EmitSwapMipsTest, TwoFpuRegistersFloat) {
moves_->AddMove(
Location::FpuRegisterLocation(4),
- Location::FpuRegisterLocation(6),
+ Location::FpuRegisterLocation(2),
Primitive::kPrimFloat,
nullptr);
moves_->AddMove(
- Location::FpuRegisterLocation(6),
+ Location::FpuRegisterLocation(2),
Location::FpuRegisterLocation(4),
Primitive::kPrimFloat,
nullptr);
const char* expected =
- "mov.s $f8, $f6\n"
- "mov.s $f6, $f4\n"
- "mov.s $f4, $f8\n";
+ "mov.s $f6, $f2\n"
+ "mov.s $f2, $f4\n"
+ "mov.s $f4, $f6\n";
DriverWrapper(moves_, expected, "TwoFpuRegistersFloat");
}
TEST_F(EmitSwapMipsTest, TwoFpuRegistersDouble) {
moves_->AddMove(
Location::FpuRegisterLocation(4),
- Location::FpuRegisterLocation(6),
+ Location::FpuRegisterLocation(2),
Primitive::kPrimDouble,
nullptr);
moves_->AddMove(
- Location::FpuRegisterLocation(6),
+ Location::FpuRegisterLocation(2),
Location::FpuRegisterLocation(4),
Primitive::kPrimDouble,
nullptr);
const char* expected =
- "mov.d $f8, $f6\n"
- "mov.d $f6, $f4\n"
- "mov.d $f4, $f8\n";
+ "mov.d $f6, $f2\n"
+ "mov.d $f2, $f4\n"
+ "mov.d $f4, $f6\n";
DriverWrapper(moves_, expected, "TwoFpuRegistersDouble");
}
TEST_F(EmitSwapMipsTest, RegisterAndFpuRegister) {
moves_->AddMove(
Location::RegisterLocation(4),
- Location::FpuRegisterLocation(6),
+ Location::FpuRegisterLocation(2),
Primitive::kPrimFloat,
nullptr);
moves_->AddMove(
- Location::FpuRegisterLocation(6),
+ Location::FpuRegisterLocation(2),
Location::RegisterLocation(4),
Primitive::kPrimFloat,
nullptr);
const char* expected =
"or $t8, $a0, $zero\n"
- "mfc1 $a0, $f6\n"
- "mtc1 $t8, $f6\n";
+ "mfc1 $a0, $f2\n"
+ "mtc1 $t8, $f2\n";
DriverWrapper(moves_, expected, "RegisterAndFpuRegister");
}
@@ -327,9 +327,9 @@ TEST_F(EmitSwapMipsTest, FpuRegisterAndStackSlot) {
Primitive::kPrimFloat,
nullptr);
const char* expected =
- "mov.s $f8, $f4\n"
+ "mov.s $f6, $f4\n"
"lwc1 $f4, 48($sp)\n"
- "swc1 $f8, 48($sp)\n";
+ "swc1 $f6, 48($sp)\n";
DriverWrapper(moves_, expected, "FpuRegisterAndStackSlot");
}
@@ -345,9 +345,9 @@ TEST_F(EmitSwapMipsTest, FpuRegisterAndDoubleStackSlot) {
Primitive::kPrimDouble,
nullptr);
const char* expected =
- "mov.d $f8, $f4\n"
+ "mov.d $f6, $f4\n"
"ldc1 $f4, 48($sp)\n"
- "sdc1 $f8, 48($sp)\n";
+ "sdc1 $f6, 48($sp)\n";
DriverWrapper(moves_, expected, "FpuRegisterAndDoubleStackSlot");
}
diff --git a/compiler/utils/mips/assembler_mips.cc b/compiler/utils/mips/assembler_mips.cc
index b29974c238..3dcad6a6b9 100644
--- a/compiler/utils/mips/assembler_mips.cc
+++ b/compiler/utils/mips/assembler_mips.cc
@@ -3252,6 +3252,9 @@ void MipsAssembler::EmitLoad(ManagedRegister m_dst, Register src_register, int32
CHECK_EQ(kMipsDoublewordSize, size) << dst;
LoadDFromOffset(dst.AsFRegister(), src_register, src_offset);
}
+ } else if (dst.IsDRegister()) {
+ CHECK_EQ(kMipsDoublewordSize, size) << dst;
+ LoadDFromOffset(dst.AsOverlappingDRegisterLow(), src_register, src_offset);
}
}
@@ -3396,6 +3399,9 @@ void MipsAssembler::Store(FrameOffset dest, ManagedRegister msrc, size_t size) {
CHECK_EQ(kMipsDoublewordSize, size);
StoreDToOffset(src.AsFRegister(), SP, dest.Int32Value());
}
+ } else if (src.IsDRegister()) {
+ CHECK_EQ(kMipsDoublewordSize, size);
+ StoreDToOffset(src.AsOverlappingDRegisterLow(), SP, dest.Int32Value());
}
}