diff options
| -rw-r--r-- | compiler/linker/mips/relative_patcher_mips.cc | 37 | ||||
| -rw-r--r-- | compiler/linker/mips/relative_patcher_mips32r6_test.cc | 7 | ||||
| -rw-r--r-- | compiler/linker/mips/relative_patcher_mips_test.cc | 11 | ||||
| -rw-r--r-- | compiler/optimizing/code_generator_mips.cc | 102 | ||||
| -rw-r--r-- | compiler/optimizing/code_generator_mips.h | 2 | ||||
| -rw-r--r-- | compiler/optimizing/code_generator_mips64.cc | 8 | ||||
| -rw-r--r-- | compiler/optimizing/dex_cache_array_fixups_mips.cc | 7 | ||||
| -rw-r--r-- | test/552-checker-sharpening/src/Main.java | 46 |
8 files changed, 99 insertions, 121 deletions
diff --git a/compiler/linker/mips/relative_patcher_mips.cc b/compiler/linker/mips/relative_patcher_mips.cc index c09950cd5d..fe5f9a948a 100644 --- a/compiler/linker/mips/relative_patcher_mips.cc +++ b/compiler/linker/mips/relative_patcher_mips.cc @@ -49,9 +49,12 @@ void MipsRelativePatcher::PatchPcRelativeReference(std::vector<uint8_t>* code, uint32_t target_offset) { uint32_t anchor_literal_offset = patch.PcInsnOffset(); uint32_t literal_offset = patch.LiteralOffset(); + uint32_t literal_low_offset; bool dex_cache_array = (patch.GetType() == LinkerPatch::Type::kDexCacheArray); - // Basic sanity checks. + // Perform basic sanity checks and initialize `literal_low_offset` to point + // to the instruction containing the 16 least significant bits of the + // relative address. if (is_r6) { DCHECK_GE(code->size(), 8u); DCHECK_LE(literal_offset, code->size() - 8u); @@ -61,10 +64,10 @@ void MipsRelativePatcher::PatchPcRelativeReference(std::vector<uint8_t>* code, DCHECK_EQ((*code)[literal_offset + 1], 0x12); DCHECK_EQ(((*code)[literal_offset + 2] & 0x1F), 0x1E); DCHECK_EQ(((*code)[literal_offset + 3] & 0xFC), 0xEC); - // ADDIU reg, reg, offset_low + // instr reg(s), offset_low DCHECK_EQ((*code)[literal_offset + 4], 0x78); DCHECK_EQ((*code)[literal_offset + 5], 0x56); - DCHECK_EQ(((*code)[literal_offset + 7] & 0xFC), 0x24); + literal_low_offset = literal_offset + 4; } else { DCHECK_GE(code->size(), 16u); DCHECK_LE(literal_offset, code->size() - 12u); @@ -84,36 +87,34 @@ void MipsRelativePatcher::PatchPcRelativeReference(std::vector<uint8_t>* code, DCHECK_EQ((*code)[literal_offset + 1], 0x12); DCHECK_EQ(((*code)[literal_offset + 2] & 0xE0), 0x00); DCHECK_EQ((*code)[literal_offset + 3], 0x3C); - // ORI reg, reg, offset_low - DCHECK_EQ((*code)[literal_offset + 4], 0x78); - DCHECK_EQ((*code)[literal_offset + 5], 0x56); - DCHECK_EQ(((*code)[literal_offset + 7] & 0xFC), 0x34); // ADDU reg, reg, reg2 - DCHECK_EQ((*code)[literal_offset + 8], 0x21); - DCHECK_EQ(((*code)[literal_offset + 9] & 0x07), 0x00); + DCHECK_EQ((*code)[literal_offset + 4], 0x21); + DCHECK_EQ(((*code)[literal_offset + 5] & 0x07), 0x00); if (dex_cache_array) { // reg2 is either RA or from HMipsComputeBaseMethodAddress. - DCHECK_EQ(((*code)[literal_offset + 10] & 0x1F), 0x1F); + DCHECK_EQ(((*code)[literal_offset + 6] & 0x1F), 0x1F); } - DCHECK_EQ(((*code)[literal_offset + 11] & 0xFC), 0x00); + DCHECK_EQ(((*code)[literal_offset + 7] & 0xFC), 0x00); + // instr reg(s), offset_low + DCHECK_EQ((*code)[literal_offset + 8], 0x78); + DCHECK_EQ((*code)[literal_offset + 9], 0x56); + literal_low_offset = literal_offset + 8; } // Apply patch. uint32_t anchor_offset = patch_offset - literal_offset + anchor_literal_offset; uint32_t diff = target_offset - anchor_offset; - if (dex_cache_array) { + if (dex_cache_array && !is_r6) { diff += kDexCacheArrayLwOffset; } - if (is_r6) { - diff += (diff & 0x8000) << 1; // Account for sign extension in ADDIU. - } + diff += (diff & 0x8000) << 1; // Account for sign extension in "instr reg(s), offset_low". // LUI reg, offset_high / AUIPC reg, offset_high (*code)[literal_offset + 0] = static_cast<uint8_t>(diff >> 16); (*code)[literal_offset + 1] = static_cast<uint8_t>(diff >> 24); - // ORI reg, reg, offset_low / ADDIU reg, reg, offset_low - (*code)[literal_offset + 4] = static_cast<uint8_t>(diff >> 0); - (*code)[literal_offset + 5] = static_cast<uint8_t>(diff >> 8); + // instr reg(s), offset_low + (*code)[literal_low_offset + 0] = static_cast<uint8_t>(diff >> 0); + (*code)[literal_low_offset + 1] = static_cast<uint8_t>(diff >> 8); } } // namespace linker diff --git a/compiler/linker/mips/relative_patcher_mips32r6_test.cc b/compiler/linker/mips/relative_patcher_mips32r6_test.cc index 4f9a3a050a..474eb73e08 100644 --- a/compiler/linker/mips/relative_patcher_mips32r6_test.cc +++ b/compiler/linker/mips/relative_patcher_mips32r6_test.cc @@ -20,10 +20,6 @@ namespace art { namespace linker { -// We'll maximize the range of a single load instruction for dex cache array accesses -// by aligning offset -32768 with the offset of the first used element. -static constexpr uint32_t kDexCacheArrayLwOffset = 0x8000; - class Mips32r6RelativePatcherTest : public RelativePatcherTest { public: Mips32r6RelativePatcherTest() : RelativePatcherTest(kMips, "mips32r6") {} @@ -64,9 +60,6 @@ void Mips32r6RelativePatcherTest::CheckPcRelativePatch(const ArrayRef<const Link ASSERT_TRUE(result.first); uint32_t diff = target_offset - (result.second + kAnchorOffset); - if (patches[0].GetType() == LinkerPatch::Type::kDexCacheArray) { - diff += kDexCacheArrayLwOffset; - } diff += (diff & 0x8000) << 1; // Account for sign extension in addiu. const uint8_t expected_code[] = { diff --git a/compiler/linker/mips/relative_patcher_mips_test.cc b/compiler/linker/mips/relative_patcher_mips_test.cc index faeb92a315..b0d1294cf4 100644 --- a/compiler/linker/mips/relative_patcher_mips_test.cc +++ b/compiler/linker/mips/relative_patcher_mips_test.cc @@ -47,12 +47,12 @@ class MipsRelativePatcherTest : public RelativePatcherTest { const uint8_t MipsRelativePatcherTest::kUnpatchedPcRelativeRawCode[] = { 0x00, 0x00, 0x10, 0x04, // nal - 0x34, 0x12, 0x12, 0x3C, // lui s2, high(diff); placeholder = 0x1234 - 0x78, 0x56, 0x52, 0x36, // ori s2, s2, low(diff); placeholder = 0x5678 - 0x21, 0x90, 0x5F, 0x02, // addu s2, s2, ra + 0x34, 0x12, 0x12, 0x3C, // lui s2, high(diff); placeholder = 0x1234 + 0x21, 0x90, 0x5F, 0x02, // addu s2, s2, ra + 0x78, 0x56, 0x52, 0x26, // addiu s2, s2, low(diff); placeholder = 0x5678 }; const uint32_t MipsRelativePatcherTest::kLiteralOffset = 4; // At lui (where patching starts). -const uint32_t MipsRelativePatcherTest::kAnchorOffset = 8; // At ori (where PC+0 points). +const uint32_t MipsRelativePatcherTest::kAnchorOffset = 8; // At addu (where PC+0 points). const ArrayRef<const uint8_t> MipsRelativePatcherTest::kUnpatchedPcRelativeCode( kUnpatchedPcRelativeRawCode); @@ -68,12 +68,13 @@ void MipsRelativePatcherTest::CheckPcRelativePatch(const ArrayRef<const LinkerPa if (patches[0].GetType() == LinkerPatch::Type::kDexCacheArray) { diff += kDexCacheArrayLwOffset; } + diff += (diff & 0x8000) << 1; // Account for sign extension in addiu. const uint8_t expected_code[] = { 0x00, 0x00, 0x10, 0x04, static_cast<uint8_t>(diff >> 16), static_cast<uint8_t>(diff >> 24), 0x12, 0x3C, - static_cast<uint8_t>(diff), static_cast<uint8_t>(diff >> 8), 0x52, 0x36, 0x21, 0x90, 0x5F, 0x02, + static_cast<uint8_t>(diff), static_cast<uint8_t>(diff >> 8), 0x52, 0x26, }; EXPECT_TRUE(CheckLinkedMethod(MethodRef(1u), ArrayRef<const uint8_t>(expected_code))); } diff --git a/compiler/optimizing/code_generator_mips.cc b/compiler/optimizing/code_generator_mips.cc index 76be74e921..a095970a1e 100644 --- a/compiler/optimizing/code_generator_mips.cc +++ b/compiler/optimizing/code_generator_mips.cc @@ -258,8 +258,10 @@ class LoadClassSlowPathMIPS : public SlowPathCodeMIPS { DCHECK_NE(out.AsRegister<Register>(), AT); CodeGeneratorMIPS::PcRelativePatchInfo* info = mips_codegen->NewTypeBssEntryPatch(cls_->GetDexFile(), type_index); - mips_codegen->EmitPcRelativeAddressPlaceholder(info, TMP, base); - __ StoreToOffset(kStoreWord, out.AsRegister<Register>(), TMP, 0); + bool reordering = __ SetReorder(false); + mips_codegen->EmitPcRelativeAddressPlaceholderHigh(info, TMP, base); + __ StoreToOffset(kStoreWord, out.AsRegister<Register>(), TMP, /* placeholder */ 0x5678); + __ SetReorder(reordering); } __ B(GetExitLabel()); } @@ -313,8 +315,10 @@ class LoadStringSlowPathMIPS : public SlowPathCodeMIPS { DCHECK_NE(out, AT); CodeGeneratorMIPS::PcRelativePatchInfo* info = mips_codegen->NewPcRelativeStringPatch(load->GetDexFile(), string_index); - mips_codegen->EmitPcRelativeAddressPlaceholder(info, TMP, base); - __ StoreToOffset(kStoreWord, out, TMP, 0); + bool reordering = __ SetReorder(false); + mips_codegen->EmitPcRelativeAddressPlaceholderHigh(info, TMP, base); + __ StoreToOffset(kStoreWord, out, TMP, /* placeholder */ 0x5678); + __ SetReorder(reordering); __ B(GetExitLabel()); } @@ -1127,16 +1131,15 @@ Literal* CodeGeneratorMIPS::DeduplicateBootImageAddressLiteral(uint32_t address) return DeduplicateUint32Literal(dchecked_integral_cast<uint32_t>(address), map); } -void CodeGeneratorMIPS::EmitPcRelativeAddressPlaceholder( - PcRelativePatchInfo* info, Register out, Register base) { - bool reordering = __ SetReorder(false); +void CodeGeneratorMIPS::EmitPcRelativeAddressPlaceholderHigh(PcRelativePatchInfo* info, + Register out, + Register base) { if (GetInstructionSetFeatures().IsR6()) { DCHECK_EQ(base, ZERO); __ Bind(&info->high_label); __ Bind(&info->pc_rel_label); - // Add a 32-bit offset to PC. + // Add the high half of a 32-bit offset to PC. __ Auipc(out, /* placeholder */ 0x1234); - __ Addiu(out, out, /* placeholder */ 0x5678); } else { // If base is ZERO, emit NAL to obtain the actual base. if (base == ZERO) { @@ -1150,11 +1153,11 @@ void CodeGeneratorMIPS::EmitPcRelativeAddressPlaceholder( if (base == ZERO) { __ Bind(&info->pc_rel_label); } - __ Ori(out, out, /* placeholder */ 0x5678); - // Add a 32-bit offset to PC. + // Add the high half of a 32-bit offset to PC. __ Addu(out, out, (base == ZERO) ? RA : base); } - __ SetReorder(reordering); + // The immediately following instruction will add the sign-extended low half of the 32-bit + // offset to `out` (e.g. lw, jialc, addiu). } void CodeGeneratorMIPS::MarkGCCard(Register object, @@ -5159,7 +5162,8 @@ void LocationsBuilderMIPS::VisitInvokeStaticOrDirect(HInvokeStaticOrDirect* invo // art::PrepareForRegisterAllocation. DCHECK(!invoke->IsStaticWithExplicitClinitCheck()); - bool has_extra_input = invoke->HasPcRelativeDexCache(); + bool is_r6 = codegen_->GetInstructionSetFeatures().IsR6(); + bool has_extra_input = invoke->HasPcRelativeDexCache() && !is_r6; IntrinsicLocationsBuilderMIPS intrinsic(codegen_); if (intrinsic.TryDispatch(invoke)) { @@ -5200,12 +5204,13 @@ HLoadString::LoadKind CodeGeneratorMIPS::GetSupportedLoadStringKind( if (kEmitCompilerReadBarrier) { UNIMPLEMENTED(FATAL) << "for read barrier"; } - // We disable PC-relative load when there is an irreducible loop, as the optimization + // We disable PC-relative load on pre-R6 when there is an irreducible loop, as the optimization // is incompatible with it. // TODO: Create as many MipsDexCacheArraysBase instructions as needed for methods // with irreducible loops. bool has_irreducible_loops = GetGraph()->HasIrreducibleLoops(); - bool fallback_load = has_irreducible_loops; + bool is_r6 = GetInstructionSetFeatures().IsR6(); + bool fallback_load = has_irreducible_loops && !is_r6; switch (desired_string_load_kind) { case HLoadString::LoadKind::kBootImageLinkTimeAddress: DCHECK(!GetCompilerOptions().GetCompilePic()); @@ -5238,10 +5243,11 @@ HLoadClass::LoadKind CodeGeneratorMIPS::GetSupportedLoadClassKind( if (kEmitCompilerReadBarrier) { UNIMPLEMENTED(FATAL) << "for read barrier"; } - // We disable pc-relative load when there is an irreducible loop, as the optimization + // We disable PC-relative load on pre-R6 when there is an irreducible loop, as the optimization // is incompatible with it. bool has_irreducible_loops = GetGraph()->HasIrreducibleLoops(); - bool fallback_load = has_irreducible_loops; + bool is_r6 = GetInstructionSetFeatures().IsR6(); + bool fallback_load = has_irreducible_loops && !is_r6; switch (desired_class_load_kind) { case HLoadClass::LoadKind::kReferrersClass: fallback_load = false; @@ -5259,6 +5265,7 @@ HLoadClass::LoadKind CodeGeneratorMIPS::GetSupportedLoadClassKind( break; case HLoadClass::LoadKind::kJitTableAddress: DCHECK(Runtime::Current()->UseJitCompilation()); + // TODO: implement. fallback_load = true; break; case HLoadClass::LoadKind::kDexCacheViaMethod: @@ -5273,6 +5280,7 @@ HLoadClass::LoadKind CodeGeneratorMIPS::GetSupportedLoadClassKind( Register CodeGeneratorMIPS::GetInvokeStaticOrDirectExtraParameter(HInvokeStaticOrDirect* invoke, Register temp) { + CHECK(!GetInstructionSetFeatures().IsR6()); CHECK_EQ(invoke->InputCount(), invoke->GetNumberOfArguments() + 1u); Location location = invoke->GetLocations()->InAt(invoke->GetSpecialInputIndex()); if (!invoke->GetLocations()->Intrinsified()) { @@ -5301,13 +5309,13 @@ HInvokeStaticOrDirect::DispatchInfo CodeGeneratorMIPS::GetSupportedInvokeStaticO const HInvokeStaticOrDirect::DispatchInfo& desired_dispatch_info, HInvokeStaticOrDirect* invoke ATTRIBUTE_UNUSED) { HInvokeStaticOrDirect::DispatchInfo dispatch_info = desired_dispatch_info; - // We disable PC-relative load when there is an irreducible loop, as the optimization + // We disable PC-relative load on pre-R6 when there is an irreducible loop, as the optimization // is incompatible with it. bool has_irreducible_loops = GetGraph()->HasIrreducibleLoops(); - bool fallback_load = true; + bool is_r6 = GetInstructionSetFeatures().IsR6(); + bool fallback_load = has_irreducible_loops && !is_r6; switch (dispatch_info.method_load_kind) { case HInvokeStaticOrDirect::MethodLoadKind::kDexCachePcRelative: - fallback_load = has_irreducible_loops; break; default: fallback_load = false; @@ -5325,7 +5333,8 @@ void CodeGeneratorMIPS::GenerateStaticOrDirectCall(HInvokeStaticOrDirect* invoke Location callee_method = temp; // For all kinds except kRecursive, callee will be in temp. HInvokeStaticOrDirect::MethodLoadKind method_load_kind = invoke->GetMethodLoadKind(); HInvokeStaticOrDirect::CodePtrLocation code_ptr_location = invoke->GetCodePtrLocation(); - Register base_reg = invoke->HasPcRelativeDexCache() + bool is_r6 = GetInstructionSetFeatures().IsR6(); + Register base_reg = (invoke->HasPcRelativeDexCache() && !is_r6) ? GetInvokeStaticOrDirectExtraParameter(invoke, temp.AsRegister<Register>()) : ZERO; @@ -5346,14 +5355,23 @@ void CodeGeneratorMIPS::GenerateStaticOrDirectCall(HInvokeStaticOrDirect* invoke case HInvokeStaticOrDirect::MethodLoadKind::kDirectAddress: __ LoadConst32(temp.AsRegister<Register>(), invoke->GetMethodAddress()); break; - case HInvokeStaticOrDirect::MethodLoadKind::kDexCachePcRelative: { - HMipsDexCacheArraysBase* base = - invoke->InputAt(invoke->GetSpecialInputIndex())->AsMipsDexCacheArraysBase(); - int32_t offset = - invoke->GetDexCacheArrayOffset() - base->GetElementOffset() - kDexCacheArrayLwOffset; - __ LoadFromOffset(kLoadWord, temp.AsRegister<Register>(), base_reg, offset); + case HInvokeStaticOrDirect::MethodLoadKind::kDexCachePcRelative: + if (is_r6) { + uint32_t offset = invoke->GetDexCacheArrayOffset(); + CodeGeneratorMIPS::PcRelativePatchInfo* info = + NewPcRelativeDexCacheArrayPatch(invoke->GetDexFileForPcRelativeDexCache(), offset); + bool reordering = __ SetReorder(false); + EmitPcRelativeAddressPlaceholderHigh(info, TMP, ZERO); + __ Lw(temp.AsRegister<Register>(), TMP, /* placeholder */ 0x5678); + __ SetReorder(reordering); + } else { + HMipsDexCacheArraysBase* base = + invoke->InputAt(invoke->GetSpecialInputIndex())->AsMipsDexCacheArraysBase(); + int32_t offset = + invoke->GetDexCacheArrayOffset() - base->GetElementOffset() - kDexCacheArrayLwOffset; + __ LoadFromOffset(kLoadWord, temp.AsRegister<Register>(), base_reg, offset); + } break; - } case HInvokeStaticOrDirect::MethodLoadKind::kDexCacheViaMethod: { Location current_method = invoke->GetLocations()->InAt(invoke->GetSpecialInputIndex()); Register reg = temp.AsRegister<Register>(); @@ -5546,7 +5564,10 @@ void InstructionCodeGeneratorMIPS::VisitLoadClass(HLoadClass* cls) NO_THREAD_SAF DCHECK(codegen_->GetCompilerOptions().IsBootImage()); CodeGeneratorMIPS::PcRelativePatchInfo* info = codegen_->NewPcRelativeTypePatch(cls->GetDexFile(), cls->GetTypeIndex()); - codegen_->EmitPcRelativeAddressPlaceholder(info, out, base_or_current_method_reg); + bool reordering = __ SetReorder(false); + codegen_->EmitPcRelativeAddressPlaceholderHigh(info, out, base_or_current_method_reg); + __ Addiu(out, out, /* placeholder */ 0x5678); + __ SetReorder(reordering); break; } case HLoadClass::LoadKind::kBootImageAddress: { @@ -5562,8 +5583,10 @@ void InstructionCodeGeneratorMIPS::VisitLoadClass(HLoadClass* cls) NO_THREAD_SAF case HLoadClass::LoadKind::kBssEntry: { CodeGeneratorMIPS::PcRelativePatchInfo* info = codegen_->NewTypeBssEntryPatch(cls->GetDexFile(), cls->GetTypeIndex()); - codegen_->EmitPcRelativeAddressPlaceholder(info, out, base_or_current_method_reg); - __ LoadFromOffset(kLoadWord, out, out, 0); + bool reordering = __ SetReorder(false); + codegen_->EmitPcRelativeAddressPlaceholderHigh(info, out, base_or_current_method_reg); + __ LoadFromOffset(kLoadWord, out, out, /* placeholder */ 0x5678); + __ SetReorder(reordering); generate_null_check = true; break; } @@ -5678,7 +5701,10 @@ void InstructionCodeGeneratorMIPS::VisitLoadString(HLoadString* load) NO_THREAD_ DCHECK(codegen_->GetCompilerOptions().IsBootImage()); CodeGeneratorMIPS::PcRelativePatchInfo* info = codegen_->NewPcRelativeStringPatch(load->GetDexFile(), load->GetStringIndex()); - codegen_->EmitPcRelativeAddressPlaceholder(info, out, base_or_current_method_reg); + bool reordering = __ SetReorder(false); + codegen_->EmitPcRelativeAddressPlaceholderHigh(info, out, base_or_current_method_reg); + __ Addiu(out, out, /* placeholder */ 0x5678); + __ SetReorder(reordering); return; // No dex cache slow path. } case HLoadString::LoadKind::kBootImageAddress: { @@ -5694,8 +5720,10 @@ void InstructionCodeGeneratorMIPS::VisitLoadString(HLoadString* load) NO_THREAD_ DCHECK(!codegen_->GetCompilerOptions().IsBootImage()); CodeGeneratorMIPS::PcRelativePatchInfo* info = codegen_->NewPcRelativeStringPatch(load->GetDexFile(), load->GetStringIndex()); - codegen_->EmitPcRelativeAddressPlaceholder(info, out, base_or_current_method_reg); - __ LoadFromOffset(kLoadWord, out, out, 0); + bool reordering = __ SetReorder(false); + codegen_->EmitPcRelativeAddressPlaceholderHigh(info, out, base_or_current_method_reg); + __ LoadFromOffset(kLoadWord, out, out, /* placeholder */ 0x5678); + __ SetReorder(reordering); SlowPathCodeMIPS* slow_path = new (GetGraph()->GetArena()) LoadStringSlowPathMIPS(load); codegen_->AddSlowPath(slow_path); __ Beqz(out, slow_path->GetEntryLabel()); @@ -6894,8 +6922,12 @@ void InstructionCodeGeneratorMIPS::VisitMipsDexCacheArraysBase(HMipsDexCacheArra Register reg = base->GetLocations()->Out().AsRegister<Register>(); CodeGeneratorMIPS::PcRelativePatchInfo* info = codegen_->NewPcRelativeDexCacheArrayPatch(base->GetDexFile(), base->GetElementOffset()); + CHECK(!codegen_->GetInstructionSetFeatures().IsR6()); + bool reordering = __ SetReorder(false); // TODO: Reuse MipsComputeBaseMethodAddress on R2 instead of passing ZERO to force emitting NAL. - codegen_->EmitPcRelativeAddressPlaceholder(info, reg, ZERO); + codegen_->EmitPcRelativeAddressPlaceholderHigh(info, reg, ZERO); + __ Addiu(reg, reg, /* placeholder */ 0x5678); + __ SetReorder(reordering); } void LocationsBuilderMIPS::VisitInvokeUnresolved(HInvokeUnresolved* invoke) { diff --git a/compiler/optimizing/code_generator_mips.h b/compiler/optimizing/code_generator_mips.h index c8fd325999..e92eeef88f 100644 --- a/compiler/optimizing/code_generator_mips.h +++ b/compiler/optimizing/code_generator_mips.h @@ -463,7 +463,7 @@ class CodeGeneratorMIPS : public CodeGenerator { Literal* DeduplicateBootImageTypeLiteral(const DexFile& dex_file, dex::TypeIndex type_index); Literal* DeduplicateBootImageAddressLiteral(uint32_t address); - void EmitPcRelativeAddressPlaceholder(PcRelativePatchInfo* info, Register out, Register base); + void EmitPcRelativeAddressPlaceholderHigh(PcRelativePatchInfo* info, Register out, Register base); private: Register GetInvokeStaticOrDirectExtraParameter(HInvokeStaticOrDirect* invoke, Register temp); diff --git a/compiler/optimizing/code_generator_mips64.cc b/compiler/optimizing/code_generator_mips64.cc index 192b4a5050..e96e3d75e1 100644 --- a/compiler/optimizing/code_generator_mips64.cc +++ b/compiler/optimizing/code_generator_mips64.cc @@ -3117,14 +3117,6 @@ void InstructionCodeGeneratorMIPS64::GenerateGcRootFieldLoad( Location root, GpuRegister obj, uint32_t offset) { - // When handling PC-relative loads, the caller calls - // EmitPcRelativeAddressPlaceholderHigh() and then GenerateGcRootFieldLoad(). - // The relative patcher expects the two methods to emit the following patchable - // sequence of instructions in this case: - // auipc reg1, 0x1234 // 0x1234 is a placeholder for offset_high. - // lwu reg2, 0x5678(reg1) // 0x5678 is a placeholder for offset_low. - // TODO: Adjust GenerateGcRootFieldLoad() and its caller when this method is - // extended (e.g. for read barriers) so as not to break the relative patcher. GpuRegister root_reg = root.AsRegister<GpuRegister>(); if (kEmitCompilerReadBarrier) { UNIMPLEMENTED(FATAL) << "for read barrier"; diff --git a/compiler/optimizing/dex_cache_array_fixups_mips.cc b/compiler/optimizing/dex_cache_array_fixups_mips.cc index 04a4294c48..7734f9197d 100644 --- a/compiler/optimizing/dex_cache_array_fixups_mips.cc +++ b/compiler/optimizing/dex_cache_array_fixups_mips.cc @@ -47,7 +47,7 @@ class DexCacheArrayFixupsVisitor : public HGraphVisitor { // Computing the dex cache base for PC-relative accesses will clobber RA with // the NAL instruction on R2. Take a note of this before generating the method // entry. - if (!dex_cache_array_bases_.empty() && !codegen_->GetInstructionSetFeatures().IsR6()) { + if (!dex_cache_array_bases_.empty()) { codegen_->ClobberRA(); } } @@ -92,6 +92,11 @@ class DexCacheArrayFixupsVisitor : public HGraphVisitor { }; void DexCacheArrayFixups::Run() { + CodeGeneratorMIPS* mips_codegen = down_cast<CodeGeneratorMIPS*>(codegen_); + if (mips_codegen->GetInstructionSetFeatures().IsR6()) { + // Do nothing for R6 because it has PC-relative addressing. + return; + } if (graph_->HasIrreducibleLoops()) { // Do not run this optimization, as irreducible loops do not work with an instruction // that can be live-in at the irreducible loop header. diff --git a/test/552-checker-sharpening/src/Main.java b/test/552-checker-sharpening/src/Main.java index a46a23c95c..bf0cbe66c1 100644 --- a/test/552-checker-sharpening/src/Main.java +++ b/test/552-checker-sharpening/src/Main.java @@ -52,7 +52,6 @@ public class Main { /// CHECK: InvokeStaticOrDirect method_load_kind:dex_cache_pc_relative /// CHECK-START-MIPS: int Main.testSimple(int) sharpening (after) - /// CHECK-NOT: MipsDexCacheArraysBase /// CHECK: InvokeStaticOrDirect method_load_kind:dex_cache_pc_relative /// CHECK-START-MIPS64: int Main.testSimple(int) sharpening (after) @@ -69,10 +68,6 @@ public class Main { /// CHECK: ArmDexCacheArraysBase /// CHECK-NOT: ArmDexCacheArraysBase - /// CHECK-START-MIPS: int Main.testSimple(int) dex_cache_array_fixups_mips (after) - /// CHECK: MipsDexCacheArraysBase - /// CHECK-NOT: MipsDexCacheArraysBase - /// CHECK-START-X86: int Main.testSimple(int) pc_relative_fixups_x86 (after) /// CHECK: X86ComputeBaseMethodAddress /// CHECK-NOT: X86ComputeBaseMethodAddress @@ -95,7 +90,6 @@ public class Main { /// CHECK: InvokeStaticOrDirect method_load_kind:dex_cache_pc_relative /// CHECK-START-MIPS: int Main.testDiamond(boolean, int) sharpening (after) - /// CHECK-NOT: MipsDexCacheArraysBase /// CHECK: InvokeStaticOrDirect method_load_kind:dex_cache_pc_relative /// CHECK: InvokeStaticOrDirect method_load_kind:dex_cache_pc_relative @@ -120,14 +114,6 @@ public class Main { /// CHECK: ArmDexCacheArraysBase /// CHECK-NEXT: If - /// CHECK-START-MIPS: int Main.testDiamond(boolean, int) dex_cache_array_fixups_mips (after) - /// CHECK: MipsDexCacheArraysBase - /// CHECK-NOT: MipsDexCacheArraysBase - - /// CHECK-START-MIPS: int Main.testDiamond(boolean, int) dex_cache_array_fixups_mips (after) - /// CHECK: MipsDexCacheArraysBase - /// CHECK-NEXT: If - /// CHECK-START-X86: int Main.testDiamond(boolean, int) pc_relative_fixups_x86 (after) /// CHECK: X86ComputeBaseMethodAddress /// CHECK-NOT: X86ComputeBaseMethodAddress @@ -182,24 +168,6 @@ public class Main { /// CHECK: begin_block /// CHECK: InvokeStaticOrDirect method_load_kind:dex_cache_pc_relative - /// CHECK-START-MIPS: int Main.testLoop(int[], int) dex_cache_array_fixups_mips (before) - /// CHECK-NOT: MipsDexCacheArraysBase - - /// CHECK-START-MIPS: int Main.testLoop(int[], int) dex_cache_array_fixups_mips (after) - /// CHECK: MipsDexCacheArraysBase - /// CHECK-NOT: MipsDexCacheArraysBase - - /// CHECK-START-MIPS: int Main.testLoop(int[], int) dex_cache_array_fixups_mips (after) - /// CHECK: InvokeStaticOrDirect - /// CHECK-NOT: InvokeStaticOrDirect - - /// CHECK-START-MIPS: int Main.testLoop(int[], int) dex_cache_array_fixups_mips (after) - /// CHECK: ArrayLength - /// CHECK-NEXT: MipsDexCacheArraysBase - /// CHECK-NEXT: Goto - /// CHECK: begin_block - /// CHECK: InvokeStaticOrDirect method_load_kind:dex_cache_pc_relative - public static int testLoop(int[] array, int x) { // PC-relative bases used by ARM, MIPS and X86 should be pulled before the loop. for (int i : array) { @@ -228,16 +196,6 @@ public class Main { /// CHECK-NEXT: ArmDexCacheArraysBase /// CHECK-NEXT: Goto - /// CHECK-START-MIPS: int Main.testLoopWithDiamond(int[], boolean, int) dex_cache_array_fixups_mips (before) - /// CHECK-NOT: MipsDexCacheArraysBase - - /// CHECK-START-MIPS: int Main.testLoopWithDiamond(int[], boolean, int) dex_cache_array_fixups_mips (after) - /// CHECK: If - /// CHECK: begin_block - /// CHECK: ArrayLength - /// CHECK-NEXT: MipsDexCacheArraysBase - /// CHECK-NEXT: Goto - public static int testLoopWithDiamond(int[] array, boolean negate, int x) { // PC-relative bases used by ARM, MIPS and X86 should be pulled before the loop // but not outside the if. @@ -387,10 +345,6 @@ public class Main { /// CHECK-START-MIPS: java.lang.Class Main.$noinline$getOtherClass() sharpening (after) /// CHECK: LoadClass load_kind:BssEntry class_name:Other - /// CHECK-START-MIPS: java.lang.Class Main.$noinline$getOtherClass() dex_cache_array_fixups_mips (after) - /// CHECK-DAG: MipsDexCacheArraysBase - /// CHECK-DAG: LoadClass load_kind:BssEntry class_name:Other - /// CHECK-START-MIPS64: java.lang.Class Main.$noinline$getOtherClass() sharpening (after) /// CHECK: LoadClass load_kind:BssEntry class_name:Other |