diff options
Diffstat (limited to 'compiler')
-rw-r--r-- | compiler/jni/jni_cfi_test_expected.inc | 4 | ||||
-rw-r--r-- | compiler/jni/quick/mips/calling_convention_mips.cc | 49 | ||||
-rw-r--r-- | compiler/optimizing/code_generator_mips.cc | 9 | ||||
-rw-r--r-- | compiler/optimizing/code_generator_mips.h | 6 | ||||
-rw-r--r-- | compiler/optimizing/emit_swap_mips_test.cc | 36 | ||||
-rw-r--r-- | compiler/utils/mips/assembler_mips.cc | 6 |
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()); } } |