summaryrefslogtreecommitdiff
path: root/compiler/optimizing/code_generator_mips.cc
diff options
context:
space:
mode:
authorAlexey Frunze <Alexey.Frunze@imgtec.com>2016-07-29 22:04:46 -0700
committerAlexey Frunze <Alexey.Frunze@imgtec.com>2016-08-30 16:50:28 -0700
commit57eb0f58419e0e6773f69cf6e0c78e5fed0464cd (patch)
tree5104bb1c1ad04f9f6a04fcac5d497d54ed0c97ab /compiler/optimizing/code_generator_mips.cc
parentd7eabc2cc1a88c1f7f927da61246ae65aab0626c (diff)
MIPS32: Fill branch delay slots
Test: booted MIPS32 in QEMU Test: test-art-host-gtest Test: test-art-target-gtest Test: test-art-target-run-test-optimizing on CI20 Change-Id: I727e80753395ab99fff004cb5d2e0a06409150d7
Diffstat (limited to 'compiler/optimizing/code_generator_mips.cc')
-rw-r--r--compiler/optimizing/code_generator_mips.cc39
1 files changed, 29 insertions, 10 deletions
diff --git a/compiler/optimizing/code_generator_mips.cc b/compiler/optimizing/code_generator_mips.cc
index 8a2f90d541..e0de03bf8f 100644
--- a/compiler/optimizing/code_generator_mips.cc
+++ b/compiler/optimizing/code_generator_mips.cc
@@ -792,12 +792,24 @@ void CodeGeneratorMIPS::GenerateFrameExit() {
// TODO: __ cfi().Restore(DWARFReg(reg));
}
- __ DecreaseFrameSize(GetFrameSize());
+ size_t frame_size = GetFrameSize();
+ // Adjust the stack pointer in the delay slot if doing so doesn't break CFI.
+ bool exchange = IsInt<16>(static_cast<int32_t>(frame_size));
+ bool reordering = __ SetReorder(false);
+ if (exchange) {
+ __ Jr(RA);
+ __ DecreaseFrameSize(frame_size); // Single instruction in delay slot.
+ } else {
+ __ DecreaseFrameSize(frame_size);
+ __ Jr(RA);
+ __ Nop(); // In delay slot.
+ }
+ __ SetReorder(reordering);
+ } else {
+ __ Jr(RA);
+ __ NopIfNoReordering();
}
- __ Jr(RA);
- __ Nop();
-
__ cfi().RestoreState();
__ cfi().DefCFAOffset(GetFrameSize());
}
@@ -1251,6 +1263,7 @@ void CodeGeneratorMIPS::InvokeRuntime(int32_t entry_point_offset,
uint32_t dex_pc,
SlowPathCode* slow_path,
bool is_direct_entrypoint) {
+ bool reordering = __ SetReorder(false);
__ LoadFromOffset(kLoadWord, T9, TR, entry_point_offset);
__ Jalr(T9);
if (is_direct_entrypoint) {
@@ -1262,6 +1275,7 @@ void CodeGeneratorMIPS::InvokeRuntime(int32_t entry_point_offset,
} else {
__ Nop(); // In delay slot.
}
+ __ SetReorder(reordering);
RecordPcInfo(instruction, dex_pc, slow_path);
}
@@ -3953,7 +3967,7 @@ void InstructionCodeGeneratorMIPS::VisitInvokeInterface(HInvokeInterface* invoke
__ LoadFromOffset(kLoadWord, T9, temp, entry_point.Int32Value());
// T9();
__ Jalr(T9);
- __ Nop();
+ __ NopIfNoReordering();
DCHECK(!codegen_->IsLeafMethod());
codegen_->RecordPcInfo(invoke, invoke->GetDexPc());
}
@@ -4254,7 +4268,7 @@ void CodeGeneratorMIPS::GenerateStaticOrDirectCall(HInvokeStaticOrDirect* invoke
// T9 prepared above for better instruction scheduling.
// T9()
__ Jalr(T9);
- __ Nop();
+ __ NopIfNoReordering();
break;
case HInvokeStaticOrDirect::CodePtrLocation::kCallPCRelative:
// TODO: Implement this type.
@@ -4270,7 +4284,7 @@ void CodeGeneratorMIPS::GenerateStaticOrDirectCall(HInvokeStaticOrDirect* invoke
kMipsPointerSize).Int32Value());
// T9()
__ Jalr(T9);
- __ Nop();
+ __ NopIfNoReordering();
break;
}
DCHECK(!IsLeafMethod());
@@ -4312,7 +4326,7 @@ void CodeGeneratorMIPS::GenerateVirtualCall(HInvokeVirtual* invoke, Location tem
__ LoadFromOffset(kLoadWord, T9, temp, entry_point.Int32Value());
// T9();
__ Jalr(T9);
- __ Nop();
+ __ NopIfNoReordering();
}
void InstructionCodeGeneratorMIPS::VisitInvokeVirtual(HInvokeVirtual* invoke) {
@@ -4421,6 +4435,7 @@ void InstructionCodeGeneratorMIPS::VisitLoadClass(HLoadClass* cls) {
DCHECK(!kEmitCompilerReadBarrier);
CodeGeneratorMIPS::PcRelativePatchInfo* info =
codegen_->NewPcRelativeTypePatch(cls->GetDexFile(), cls->GetTypeIndex());
+ bool reordering = __ SetReorder(false);
if (isR6) {
__ Bind(&info->high_label);
__ Bind(&info->pc_rel_label);
@@ -4436,6 +4451,7 @@ void InstructionCodeGeneratorMIPS::VisitLoadClass(HLoadClass* cls) {
// Add a 32-bit offset to PC.
__ Addu(out, out, base_or_current_method_reg);
}
+ __ SetReorder(reordering);
break;
}
case HLoadClass::LoadKind::kBootImageAddress: {
@@ -4579,6 +4595,7 @@ void InstructionCodeGeneratorMIPS::VisitLoadString(HLoadString* load) {
DCHECK(!kEmitCompilerReadBarrier);
CodeGeneratorMIPS::PcRelativePatchInfo* info =
codegen_->NewPcRelativeStringPatch(load->GetDexFile(), load->GetStringIndex());
+ bool reordering = __ SetReorder(false);
if (isR6) {
__ Bind(&info->high_label);
__ Bind(&info->pc_rel_label);
@@ -4594,6 +4611,7 @@ void InstructionCodeGeneratorMIPS::VisitLoadString(HLoadString* load) {
// Add a 32-bit offset to PC.
__ Addu(out, out, base_or_current_method_reg);
}
+ __ SetReorder(reordering);
return; // No dex cache slow path.
}
case HLoadString::LoadKind::kBootImageAddress: {
@@ -4851,7 +4869,7 @@ void InstructionCodeGeneratorMIPS::VisitNewInstance(HNewInstance* instruction) {
__ LoadFromOffset(kLoadWord, temp, TR, QUICK_ENTRY_POINT(pNewEmptyString));
__ LoadFromOffset(kLoadWord, T9, temp, code_offset.Int32Value());
__ Jalr(T9);
- __ Nop();
+ __ NopIfNoReordering();
codegen_->RecordPcInfo(instruction, instruction->GetDexPc());
} else {
codegen_->InvokeRuntime(
@@ -5751,7 +5769,7 @@ void InstructionCodeGeneratorMIPS::VisitMipsDexCacheArraysBase(HMipsDexCacheArra
Register reg = base->GetLocations()->Out().AsRegister<Register>();
CodeGeneratorMIPS::PcRelativePatchInfo* info =
codegen_->NewPcRelativeDexCacheArrayPatch(base->GetDexFile(), base->GetElementOffset());
-
+ bool reordering = __ SetReorder(false);
if (codegen_->GetInstructionSetFeatures().IsR6()) {
__ Bind(&info->high_label);
__ Bind(&info->pc_rel_label);
@@ -5769,6 +5787,7 @@ void InstructionCodeGeneratorMIPS::VisitMipsDexCacheArraysBase(HMipsDexCacheArra
__ Addu(reg, reg, RA);
// TODO: Can we share this code with that of VisitMipsComputeBaseMethodAddress()?
}
+ __ SetReorder(reordering);
}
void LocationsBuilderMIPS::VisitInvokeUnresolved(HInvokeUnresolved* invoke) {