summaryrefslogtreecommitdiff
path: root/compiler/optimizing
diff options
context:
space:
mode:
Diffstat (limited to 'compiler/optimizing')
-rw-r--r--compiler/optimizing/code_generator_arm.cc124
-rw-r--r--compiler/optimizing/code_generator_arm.h9
-rw-r--r--compiler/optimizing/intrinsics_arm.cc34
3 files changed, 51 insertions, 116 deletions
diff --git a/compiler/optimizing/code_generator_arm.cc b/compiler/optimizing/code_generator_arm.cc
index 4ea17a9271..d8866a92c1 100644
--- a/compiler/optimizing/code_generator_arm.cc
+++ b/compiler/optimizing/code_generator_arm.cc
@@ -74,8 +74,10 @@ class NullCheckSlowPathARM : public SlowPathCode {
// Live registers will be restored in the catch block if caught.
SaveLiveRegisters(codegen, instruction_->GetLocations());
}
- arm_codegen->InvokeRuntime(
- QUICK_ENTRY_POINT(pThrowNullPointer), instruction_, instruction_->GetDexPc(), this);
+ arm_codegen->InvokeRuntime(kQuickThrowNullPointer,
+ instruction_,
+ instruction_->GetDexPc(),
+ this);
CheckEntrypointTypes<kQuickThrowNullPointer, void, void>();
}
@@ -98,8 +100,7 @@ class DivZeroCheckSlowPathARM : public SlowPathCode {
// Live registers will be restored in the catch block if caught.
SaveLiveRegisters(codegen, instruction_->GetLocations());
}
- arm_codegen->InvokeRuntime(
- QUICK_ENTRY_POINT(pThrowDivZero), instruction_, instruction_->GetDexPc(), this);
+ arm_codegen->InvokeRuntime(kQuickThrowDivZero, instruction_, instruction_->GetDexPc(), this);
CheckEntrypointTypes<kQuickThrowDivZero, void, void>();
}
@@ -119,8 +120,7 @@ class SuspendCheckSlowPathARM : public SlowPathCode {
void EmitNativeCode(CodeGenerator* codegen) OVERRIDE {
CodeGeneratorARM* arm_codegen = down_cast<CodeGeneratorARM*>(codegen);
__ Bind(GetEntryLabel());
- arm_codegen->InvokeRuntime(
- QUICK_ENTRY_POINT(pTestSuspend), instruction_, instruction_->GetDexPc(), this);
+ arm_codegen->InvokeRuntime(kQuickTestSuspend, instruction_, instruction_->GetDexPc(), this);
CheckEntrypointTypes<kQuickTestSuspend, void, void>();
if (successor_ == nullptr) {
__ b(GetReturnLabel());
@@ -174,10 +174,10 @@ class BoundsCheckSlowPathARM : public SlowPathCode {
locations->InAt(1),
Location::RegisterLocation(calling_convention.GetRegisterAt(1)),
Primitive::kPrimInt);
- uint32_t entry_point_offset = instruction_->AsBoundsCheck()->IsStringCharAt()
- ? QUICK_ENTRY_POINT(pThrowStringBounds)
- : QUICK_ENTRY_POINT(pThrowArrayBounds);
- arm_codegen->InvokeRuntime(entry_point_offset, instruction_, instruction_->GetDexPc(), this);
+ QuickEntrypointEnum entrypoint = instruction_->AsBoundsCheck()->IsStringCharAt()
+ ? kQuickThrowStringBounds
+ : kQuickThrowArrayBounds;
+ arm_codegen->InvokeRuntime(entrypoint, instruction_, instruction_->GetDexPc(), this);
CheckEntrypointTypes<kQuickThrowStringBounds, void, int32_t, int32_t>();
CheckEntrypointTypes<kQuickThrowArrayBounds, void, int32_t, int32_t>();
}
@@ -209,10 +209,9 @@ class LoadClassSlowPathARM : public SlowPathCode {
InvokeRuntimeCallingConvention calling_convention;
__ LoadImmediate(calling_convention.GetRegisterAt(0), cls_->GetTypeIndex());
- int32_t entry_point_offset = do_clinit_
- ? QUICK_ENTRY_POINT(pInitializeStaticStorage)
- : QUICK_ENTRY_POINT(pInitializeType);
- arm_codegen->InvokeRuntime(entry_point_offset, at_, dex_pc_, this);
+ QuickEntrypointEnum entrypoint = do_clinit_ ? kQuickInitializeStaticStorage
+ : kQuickInitializeType;
+ arm_codegen->InvokeRuntime(entrypoint, at_, dex_pc_, this);
if (do_clinit_) {
CheckEntrypointTypes<kQuickInitializeStaticStorage, void*, uint32_t>();
} else {
@@ -263,8 +262,7 @@ class LoadStringSlowPathARM : public SlowPathCode {
InvokeRuntimeCallingConvention calling_convention;
const uint32_t string_index = instruction_->AsLoadString()->GetStringIndex();
__ LoadImmediate(calling_convention.GetRegisterAt(0), string_index);
- arm_codegen->InvokeRuntime(
- QUICK_ENTRY_POINT(pResolveString), instruction_, instruction_->GetDexPc(), this);
+ arm_codegen->InvokeRuntime(kQuickResolveString, instruction_, instruction_->GetDexPc(), this);
CheckEntrypointTypes<kQuickResolveString, void*, uint32_t>();
arm_codegen->Move32(locations->Out(), Location::RegisterLocation(R0));
@@ -309,7 +307,7 @@ class TypeCheckSlowPathARM : public SlowPathCode {
Primitive::kPrimNot);
if (instruction_->IsInstanceOf()) {
- arm_codegen->InvokeRuntime(QUICK_ENTRY_POINT(pInstanceofNonTrivial),
+ arm_codegen->InvokeRuntime(kQuickInstanceofNonTrivial,
instruction_,
instruction_->GetDexPc(),
this);
@@ -318,10 +316,7 @@ class TypeCheckSlowPathARM : public SlowPathCode {
arm_codegen->Move32(locations->Out(), Location::RegisterLocation(R0));
} else {
DCHECK(instruction_->IsCheckCast());
- arm_codegen->InvokeRuntime(QUICK_ENTRY_POINT(pCheckCast),
- instruction_,
- instruction_->GetDexPc(),
- this);
+ arm_codegen->InvokeRuntime(kQuickCheckCast, instruction_, instruction_->GetDexPc(), this);
CheckEntrypointTypes<kQuickCheckCast, void, const mirror::Class*, const mirror::Class*>();
}
@@ -350,10 +345,7 @@ class DeoptimizationSlowPathARM : public SlowPathCode {
CodeGeneratorARM* arm_codegen = down_cast<CodeGeneratorARM*>(codegen);
__ Bind(GetEntryLabel());
SaveLiveRegisters(codegen, instruction_->GetLocations());
- arm_codegen->InvokeRuntime(QUICK_ENTRY_POINT(pDeoptimize),
- instruction_,
- instruction_->GetDexPc(),
- this);
+ arm_codegen->InvokeRuntime(kQuickDeoptimize, instruction_, instruction_->GetDexPc(), this);
CheckEntrypointTypes<kQuickDeoptimize, void, void>();
}
@@ -392,10 +384,7 @@ class ArraySetSlowPathARM : public SlowPathCode {
codegen->GetMoveResolver()->EmitNativeCode(&parallel_move);
CodeGeneratorARM* arm_codegen = down_cast<CodeGeneratorARM*>(codegen);
- arm_codegen->InvokeRuntime(QUICK_ENTRY_POINT(pAputObject),
- instruction_,
- instruction_->GetDexPc(),
- this);
+ arm_codegen->InvokeRuntime(kQuickAputObject, instruction_, instruction_->GetDexPc(), this);
CheckEntrypointTypes<kQuickAputObject, void, mirror::Array*, int32_t, mirror::Object*>();
RestoreLiveRegisters(codegen, locations);
__ b(GetExitLabel());
@@ -613,10 +602,7 @@ class ReadBarrierForHeapReferenceSlowPathARM : public SlowPathCode {
codegen->GetMoveResolver()->EmitNativeCode(&parallel_move);
__ LoadImmediate(calling_convention.GetRegisterAt(2), offset_);
}
- arm_codegen->InvokeRuntime(QUICK_ENTRY_POINT(pReadBarrierSlow),
- instruction_,
- instruction_->GetDexPc(),
- this);
+ arm_codegen->InvokeRuntime(kQuickReadBarrierSlow, instruction_, instruction_->GetDexPc(), this);
CheckEntrypointTypes<
kQuickReadBarrierSlow, mirror::Object*, mirror::Object*, mirror::Object*, uint32_t>();
arm_codegen->Move32(out_, Location::RegisterLocation(R0));
@@ -680,7 +666,7 @@ class ReadBarrierForRootSlowPathARM : public SlowPathCode {
InvokeRuntimeCallingConvention calling_convention;
CodeGeneratorARM* arm_codegen = down_cast<CodeGeneratorARM*>(codegen);
arm_codegen->Move32(Location::RegisterLocation(calling_convention.GetRegisterAt(0)), root_);
- arm_codegen->InvokeRuntime(QUICK_ENTRY_POINT(pReadBarrierForRootSlow),
+ arm_codegen->InvokeRuntime(kQuickReadBarrierForRootSlow,
instruction_,
instruction_->GetDexPc(),
this);
@@ -1221,19 +1207,8 @@ void CodeGeneratorARM::InvokeRuntime(QuickEntrypointEnum entrypoint,
HInstruction* instruction,
uint32_t dex_pc,
SlowPathCode* slow_path) {
- InvokeRuntime(GetThreadOffset<kArmPointerSize>(entrypoint).Int32Value(),
- instruction,
- dex_pc,
- slow_path);
-}
-
-void CodeGeneratorARM::InvokeRuntime(int32_t entry_point_offset,
- HInstruction* instruction,
- uint32_t dex_pc,
- SlowPathCode* slow_path) {
ValidateInvokeRuntime(instruction, slow_path);
- __ LoadFromOffset(kLoadWord, LR, TR, entry_point_offset);
- __ blx(LR);
+ GenerateInvokeRuntime(GetThreadOffset<kArmPointerSize>(entrypoint).Int32Value());
RecordPcInfo(instruction, dex_pc, slow_path);
}
@@ -1241,6 +1216,10 @@ void CodeGeneratorARM::InvokeRuntimeWithoutRecordingPcInfo(int32_t entry_point_o
HInstruction* instruction,
SlowPathCode* slow_path) {
ValidateInvokeRuntimeWithoutRecordingPcInfo(instruction, slow_path);
+ GenerateInvokeRuntime(entry_point_offset);
+}
+
+void CodeGeneratorARM::GenerateInvokeRuntime(int32_t entry_point_offset) {
__ LoadFromOffset(kLoadWord, LR, TR, entry_point_offset);
__ blx(LR);
}
@@ -2374,19 +2353,13 @@ void InstructionCodeGeneratorARM::VisitTypeConversion(HTypeConversion* conversio
case Primitive::kPrimFloat:
// Processing a Dex `float-to-long' instruction.
- codegen_->InvokeRuntime(QUICK_ENTRY_POINT(pF2l),
- conversion,
- conversion->GetDexPc(),
- nullptr);
+ codegen_->InvokeRuntime(kQuickF2l, conversion, conversion->GetDexPc());
CheckEntrypointTypes<kQuickF2l, int64_t, float>();
break;
case Primitive::kPrimDouble:
// Processing a Dex `double-to-long' instruction.
- codegen_->InvokeRuntime(QUICK_ENTRY_POINT(pD2l),
- conversion,
- conversion->GetDexPc(),
- nullptr);
+ codegen_->InvokeRuntime(kQuickD2l, conversion, conversion->GetDexPc());
CheckEntrypointTypes<kQuickD2l, int64_t, double>();
break;
@@ -2433,10 +2406,7 @@ void InstructionCodeGeneratorARM::VisitTypeConversion(HTypeConversion* conversio
case Primitive::kPrimLong:
// Processing a Dex `long-to-float' instruction.
- codegen_->InvokeRuntime(QUICK_ENTRY_POINT(pL2f),
- conversion,
- conversion->GetDexPc(),
- nullptr);
+ codegen_->InvokeRuntime(kQuickL2f, conversion, conversion->GetDexPc());
CheckEntrypointTypes<kQuickL2f, float, int64_t>();
break;
@@ -2968,7 +2938,7 @@ void InstructionCodeGeneratorARM::VisitDiv(HDiv* div) {
DCHECK_EQ(calling_convention.GetRegisterAt(1), second.AsRegister<Register>());
DCHECK_EQ(R0, out.AsRegister<Register>());
- codegen_->InvokeRuntime(QUICK_ENTRY_POINT(pIdivmod), div, div->GetDexPc(), nullptr);
+ codegen_->InvokeRuntime(kQuickIdivmod, div, div->GetDexPc());
CheckEntrypointTypes<kQuickIdivmod, int32_t, int32_t, int32_t>();
}
break;
@@ -2983,7 +2953,7 @@ void InstructionCodeGeneratorARM::VisitDiv(HDiv* div) {
DCHECK_EQ(R0, out.AsRegisterPairLow<Register>());
DCHECK_EQ(R1, out.AsRegisterPairHigh<Register>());
- codegen_->InvokeRuntime(QUICK_ENTRY_POINT(pLdiv), div, div->GetDexPc(), nullptr);
+ codegen_->InvokeRuntime(kQuickLdiv, div, div->GetDexPc());
CheckEntrypointTypes<kQuickLdiv, int64_t, int64_t, int64_t>();
break;
}
@@ -3112,26 +3082,26 @@ void InstructionCodeGeneratorARM::VisitRem(HRem* rem) {
DCHECK_EQ(calling_convention.GetRegisterAt(1), second.AsRegister<Register>());
DCHECK_EQ(R1, out.AsRegister<Register>());
- codegen_->InvokeRuntime(QUICK_ENTRY_POINT(pIdivmod), rem, rem->GetDexPc(), nullptr);
+ codegen_->InvokeRuntime(kQuickIdivmod, rem, rem->GetDexPc());
CheckEntrypointTypes<kQuickIdivmod, int32_t, int32_t, int32_t>();
}
break;
}
case Primitive::kPrimLong: {
- codegen_->InvokeRuntime(QUICK_ENTRY_POINT(pLmod), rem, rem->GetDexPc(), nullptr);
+ codegen_->InvokeRuntime(kQuickLmod, rem, rem->GetDexPc());
CheckEntrypointTypes<kQuickLmod, int64_t, int64_t, int64_t>();
break;
}
case Primitive::kPrimFloat: {
- codegen_->InvokeRuntime(QUICK_ENTRY_POINT(pFmodf), rem, rem->GetDexPc(), nullptr);
+ codegen_->InvokeRuntime(kQuickFmodf, rem, rem->GetDexPc());
CheckEntrypointTypes<kQuickFmodf, float, float, float>();
break;
}
case Primitive::kPrimDouble: {
- codegen_->InvokeRuntime(QUICK_ENTRY_POINT(pFmod), rem, rem->GetDexPc(), nullptr);
+ codegen_->InvokeRuntime(kQuickFmod, rem, rem->GetDexPc());
CheckEntrypointTypes<kQuickFmod, double, double, double>();
break;
}
@@ -3571,10 +3541,7 @@ void InstructionCodeGeneratorARM::VisitNewInstance(HNewInstance* instruction) {
__ blx(LR);
codegen_->RecordPcInfo(instruction, instruction->GetDexPc());
} else {
- codegen_->InvokeRuntime(instruction->GetEntrypoint(),
- instruction,
- instruction->GetDexPc(),
- nullptr);
+ codegen_->InvokeRuntime(instruction->GetEntrypoint(), instruction, instruction->GetDexPc());
CheckEntrypointTypes<kQuickAllocObjectWithAccessCheck, void*, uint32_t, ArtMethod*>();
}
}
@@ -3594,10 +3561,7 @@ void InstructionCodeGeneratorARM::VisitNewArray(HNewArray* instruction) {
__ LoadImmediate(calling_convention.GetRegisterAt(0), instruction->GetTypeIndex());
// Note: if heap poisoning is enabled, the entry point takes cares
// of poisoning the reference.
- codegen_->InvokeRuntime(instruction->GetEntrypoint(),
- instruction,
- instruction->GetDexPc(),
- nullptr);
+ codegen_->InvokeRuntime(instruction->GetEntrypoint(), instruction, instruction->GetDexPc());
CheckEntrypointTypes<kQuickAllocArrayWithAccessCheck, void*, uint32_t, int32_t, ArtMethod*>();
}
@@ -5432,10 +5396,7 @@ void InstructionCodeGeneratorARM::VisitLoadClass(HLoadClass* cls) {
LocationSummary* locations = cls->GetLocations();
if (cls->NeedsAccessCheck()) {
codegen_->MoveConstant(locations->GetTemp(0), cls->GetTypeIndex());
- codegen_->InvokeRuntime(QUICK_ENTRY_POINT(pInitializeTypeAndVerifyAccess),
- cls,
- cls->GetDexPc(),
- nullptr);
+ codegen_->InvokeRuntime(kQuickInitializeTypeAndVerifyAccess, cls, cls->GetDexPc());
CheckEntrypointTypes<kQuickInitializeTypeAndVerifyAccess, void*, uint32_t>();
return;
}
@@ -5694,8 +5655,7 @@ void LocationsBuilderARM::VisitThrow(HThrow* instruction) {
}
void InstructionCodeGeneratorARM::VisitThrow(HThrow* instruction) {
- codegen_->InvokeRuntime(
- QUICK_ENTRY_POINT(pDeliverException), instruction, instruction->GetDexPc(), nullptr);
+ codegen_->InvokeRuntime(kQuickDeliverException, instruction, instruction->GetDexPc());
CheckEntrypointTypes<kQuickDeliverException, void, mirror::Object*>();
}
@@ -6095,11 +6055,9 @@ void LocationsBuilderARM::VisitMonitorOperation(HMonitorOperation* instruction)
}
void InstructionCodeGeneratorARM::VisitMonitorOperation(HMonitorOperation* instruction) {
- codegen_->InvokeRuntime(instruction->IsEnter()
- ? QUICK_ENTRY_POINT(pLockObject) : QUICK_ENTRY_POINT(pUnlockObject),
- instruction,
- instruction->GetDexPc(),
- nullptr);
+ codegen_->InvokeRuntime(instruction->IsEnter() ? kQuickLockObject : kQuickUnlockObject,
+ instruction,
+ instruction->GetDexPc());
if (instruction->IsEnter()) {
CheckEntrypointTypes<kQuickLockObject, void, mirror::Object*>();
} else {
diff --git a/compiler/optimizing/code_generator_arm.h b/compiler/optimizing/code_generator_arm.h
index 5d9b2dce1c..a07dd6b5ef 100644
--- a/compiler/optimizing/code_generator_arm.h
+++ b/compiler/optimizing/code_generator_arm.h
@@ -390,12 +390,7 @@ class CodeGeneratorARM : public CodeGenerator {
void InvokeRuntime(QuickEntrypointEnum entrypoint,
HInstruction* instruction,
uint32_t dex_pc,
- SlowPathCode* slow_path) OVERRIDE;
-
- void InvokeRuntime(int32_t offset,
- HInstruction* instruction,
- uint32_t dex_pc,
- SlowPathCode* slow_path);
+ SlowPathCode* slow_path = nullptr) OVERRIDE;
// Generate code to invoke a runtime entry point, but do not record
// PC-related information in a stack map.
@@ -403,6 +398,8 @@ class CodeGeneratorARM : public CodeGenerator {
HInstruction* instruction,
SlowPathCode* slow_path);
+ void GenerateInvokeRuntime(int32_t entry_point_offset);
+
// Emit a write barrier.
void MarkGCCard(Register temp, Register card, Register object, Register value, bool can_be_null);
diff --git a/compiler/optimizing/intrinsics_arm.cc b/compiler/optimizing/intrinsics_arm.cc
index df7cb85a4c..a1fc7c3b84 100644
--- a/compiler/optimizing/intrinsics_arm.cc
+++ b/compiler/optimizing/intrinsics_arm.cc
@@ -1291,10 +1291,8 @@ static void GenerateVisitStringIndexOf(HInvoke* invoke,
__ LoadImmediate(tmp_reg, 0);
}
- __ LoadFromOffset(kLoadWord, LR, TR,
- QUICK_ENTRYPOINT_OFFSET(kArmPointerSize, pIndexOf).Int32Value());
+ codegen->InvokeRuntime(kQuickIndexOf, invoke, invoke->GetDexPc(), slow_path);
CheckEntrypointTypes<kQuickIndexOf, int32_t, void*, uint32_t, uint32_t>();
- __ blx(LR);
if (slow_path != nullptr) {
__ Bind(slow_path->GetExitLabel());
@@ -1361,13 +1359,8 @@ void IntrinsicCodeGeneratorARM::VisitStringNewStringFromBytes(HInvoke* invoke) {
codegen_->AddSlowPath(slow_path);
__ b(slow_path->GetEntryLabel(), EQ);
- __ LoadFromOffset(kLoadWord,
- LR,
- TR,
- QUICK_ENTRYPOINT_OFFSET(kArmPointerSize, pAllocStringFromBytes).Int32Value());
+ codegen_->InvokeRuntime(kQuickAllocStringFromBytes, invoke, invoke->GetDexPc(), slow_path);
CheckEntrypointTypes<kQuickAllocStringFromBytes, void*, void*, int32_t, int32_t, int32_t>();
- __ blx(LR);
- codegen_->RecordPcInfo(invoke, invoke->GetDexPc());
__ Bind(slow_path->GetExitLabel());
}
@@ -1383,21 +1376,14 @@ void IntrinsicLocationsBuilderARM::VisitStringNewStringFromChars(HInvoke* invoke
}
void IntrinsicCodeGeneratorARM::VisitStringNewStringFromChars(HInvoke* invoke) {
- ArmAssembler* assembler = GetAssembler();
-
// No need to emit code checking whether `locations->InAt(2)` is a null
// pointer, as callers of the native method
//
// java.lang.StringFactory.newStringFromChars(int offset, int charCount, char[] data)
//
// all include a null check on `data` before calling that method.
- __ LoadFromOffset(kLoadWord,
- LR,
- TR,
- QUICK_ENTRYPOINT_OFFSET(kArmPointerSize, pAllocStringFromChars).Int32Value());
+ codegen_->InvokeRuntime(kQuickAllocStringFromChars, invoke, invoke->GetDexPc());
CheckEntrypointTypes<kQuickAllocStringFromChars, void*, int32_t, int32_t, void*>();
- __ blx(LR);
- codegen_->RecordPcInfo(invoke, invoke->GetDexPc());
}
void IntrinsicLocationsBuilderARM::VisitStringNewStringFromString(HInvoke* invoke) {
@@ -1419,11 +1405,9 @@ void IntrinsicCodeGeneratorARM::VisitStringNewStringFromString(HInvoke* invoke)
codegen_->AddSlowPath(slow_path);
__ b(slow_path->GetEntryLabel(), EQ);
- __ LoadFromOffset(kLoadWord,
- LR, TR, QUICK_ENTRYPOINT_OFFSET(kArmPointerSize, pAllocStringFromString).Int32Value());
+ codegen_->InvokeRuntime(kQuickAllocStringFromString, invoke, invoke->GetDexPc(), slow_path);
CheckEntrypointTypes<kQuickAllocStringFromString, void*, void*>();
- __ blx(LR);
- codegen_->RecordPcInfo(invoke, invoke->GetDexPc());
+
__ Bind(slow_path->GetExitLabel());
}
@@ -1999,13 +1983,11 @@ static void GenFPToFPCall(HInvoke* invoke,
DCHECK(!locations->GetLiveRegisters()->ContainsCoreRegister(calling_convention.GetRegisterAt(0)));
DCHECK(!locations->GetLiveRegisters()->ContainsCoreRegister(calling_convention.GetRegisterAt(1)));
- __ LoadFromOffset(kLoadWord, LR, TR, GetThreadOffset<kArmPointerSize>(entry).Int32Value());
// Native code uses the soft float ABI.
__ vmovrrd(calling_convention.GetRegisterAt(0),
calling_convention.GetRegisterAt(1),
FromLowSToD(locations->InAt(0).AsFpuRegisterPairLow<SRegister>()));
- __ blx(LR);
- codegen->RecordPcInfo(invoke, invoke->GetDexPc());
+ codegen->InvokeRuntime(entry, invoke, invoke->GetDexPc());
__ vmovdrr(FromLowSToD(locations->Out().AsFpuRegisterPairLow<SRegister>()),
calling_convention.GetRegisterAt(0),
calling_convention.GetRegisterAt(1));
@@ -2025,7 +2007,6 @@ static void GenFPFPToFPCall(HInvoke* invoke,
DCHECK(!locations->GetLiveRegisters()->ContainsCoreRegister(calling_convention.GetRegisterAt(2)));
DCHECK(!locations->GetLiveRegisters()->ContainsCoreRegister(calling_convention.GetRegisterAt(3)));
- __ LoadFromOffset(kLoadWord, LR, TR, GetThreadOffset<kArmPointerSize>(entry).Int32Value());
// Native code uses the soft float ABI.
__ vmovrrd(calling_convention.GetRegisterAt(0),
calling_convention.GetRegisterAt(1),
@@ -2033,8 +2014,7 @@ static void GenFPFPToFPCall(HInvoke* invoke,
__ vmovrrd(calling_convention.GetRegisterAt(2),
calling_convention.GetRegisterAt(3),
FromLowSToD(locations->InAt(1).AsFpuRegisterPairLow<SRegister>()));
- __ blx(LR);
- codegen->RecordPcInfo(invoke, invoke->GetDexPc());
+ codegen->InvokeRuntime(entry, invoke, invoke->GetDexPc());
__ vmovdrr(FromLowSToD(locations->Out().AsFpuRegisterPairLow<SRegister>()),
calling_convention.GetRegisterAt(0),
calling_convention.GetRegisterAt(1));