summaryrefslogtreecommitdiff
path: root/compiler/optimizing/code_generator_arm.cc
diff options
context:
space:
mode:
authorNicolas Geoffray <ngeoffray@google.com>2014-10-31 14:24:05 +0000
committerGerrit Code Review <noreply-gerritcodereview@google.com>2014-10-31 14:24:06 +0000
commita9014f977ae90373f5bad4cf812c2bda810b10f8 (patch)
tree40f4bc76cb5e7cf9c95fced70b1ad5c2c2d39f4e /compiler/optimizing/code_generator_arm.cc
parent8b557af85871e5086589afd2b3a17089d0f67df8 (diff)
parentb5f62b3dc5ac2731ba8ad53cdf3d9bdb14fbf86b (diff)
Merge "Support for CONST_STRING in optimizing compiler."
Diffstat (limited to 'compiler/optimizing/code_generator_arm.cc')
-rw-r--r--compiler/optimizing/code_generator_arm.cc51
1 files changed, 51 insertions, 0 deletions
diff --git a/compiler/optimizing/code_generator_arm.cc b/compiler/optimizing/code_generator_arm.cc
index 9ed19695a3..c812f6b416 100644
--- a/compiler/optimizing/code_generator_arm.cc
+++ b/compiler/optimizing/code_generator_arm.cc
@@ -196,6 +196,37 @@ class ClinitCheckSlowPathARM : public SlowPathCodeARM {
DISALLOW_COPY_AND_ASSIGN(ClinitCheckSlowPathARM);
};
+class LoadStringSlowPathARM : public SlowPathCodeARM {
+ public:
+ explicit LoadStringSlowPathARM(HLoadString* instruction) : instruction_(instruction) {}
+
+ virtual void EmitNativeCode(CodeGenerator* codegen) OVERRIDE {
+ LocationSummary* locations = instruction_->GetLocations();
+ DCHECK(!locations->GetLiveRegisters()->ContainsCoreRegister(locations->Out().reg()));
+
+ CodeGeneratorARM* arm_codegen = down_cast<CodeGeneratorARM*>(codegen);
+ __ Bind(GetEntryLabel());
+ codegen->SaveLiveRegisters(locations);
+
+ InvokeRuntimeCallingConvention calling_convention;
+ arm_codegen->LoadCurrentMethod(calling_convention.GetRegisterAt(0));
+ __ LoadImmediate(calling_convention.GetRegisterAt(1), instruction_->GetStringIndex());
+ arm_codegen->InvokeRuntime(
+ QUICK_ENTRY_POINT(pResolveString), instruction_, instruction_->GetDexPc());
+ arm_codegen->Move32(locations->Out(), Location::RegisterLocation(R0));
+
+ codegen->RestoreLiveRegisters(locations);
+ __ b(GetExitLabel());
+ }
+
+ private:
+ HLoadString* const instruction_;
+
+ DISALLOW_COPY_AND_ASSIGN(LoadStringSlowPathARM);
+};
+
+#undef __
+
#undef __
#define __ reinterpret_cast<ArmAssembler*>(GetAssembler())->
@@ -2270,5 +2301,25 @@ void InstructionCodeGeneratorARM::VisitStaticFieldSet(HStaticFieldSet* instructi
}
}
+void LocationsBuilderARM::VisitLoadString(HLoadString* load) {
+ LocationSummary* locations =
+ new (GetGraph()->GetArena()) LocationSummary(load, LocationSummary::kCallOnSlowPath);
+ locations->SetOut(Location::RequiresRegister());
+}
+
+void InstructionCodeGeneratorARM::VisitLoadString(HLoadString* load) {
+ SlowPathCodeARM* slow_path = new (GetGraph()->GetArena()) LoadStringSlowPathARM(load);
+ codegen_->AddSlowPath(slow_path);
+
+ Register out = load->GetLocations()->Out().As<Register>();
+ codegen_->LoadCurrentMethod(out);
+ __ LoadFromOffset(
+ kLoadWord, out, out, mirror::ArtMethod::DexCacheStringsOffset().Int32Value());
+ __ LoadFromOffset(kLoadWord, out, out, CodeGenerator::GetCacheOffset(load->GetStringIndex()));
+ __ cmp(out, ShifterOperand(0));
+ __ b(slow_path->GetEntryLabel(), EQ);
+ __ Bind(slow_path->GetExitLabel());
+}
+
} // namespace arm
} // namespace art