Merge "ART: Rework quick entrypoint code in Mir2Lir, cleanup"
diff --git a/compiler/dex/compiler_enums.h b/compiler/dex/compiler_enums.h
index 69adb35..346fbb8 100644
--- a/compiler/dex/compiler_enums.h
+++ b/compiler/dex/compiler_enums.h
@@ -425,10 +425,6 @@
std::ostream& operator<<(std::ostream& os, const X86ConditionCode& kind);
-enum ThrowKind {
- kThrowNoSuchMethod,
-};
-
enum DividePattern {
DivideNone,
Divide3,
diff --git a/compiler/dex/quick/arm/codegen_arm.h b/compiler/dex/quick/arm/codegen_arm.h
index fa252a1..9652192 100644
--- a/compiler/dex/quick/arm/codegen_arm.h
+++ b/compiler/dex/quick/arm/codegen_arm.h
@@ -31,22 +31,17 @@
RegLocation rl_dest, int lit);
bool EasyMultiply(RegLocation rl_src, RegLocation rl_dest, int lit) OVERRIDE;
LIR* CheckSuspendUsingLoad() OVERRIDE;
- RegStorage LoadHelper(ThreadOffset<4> offset) OVERRIDE;
- RegStorage LoadHelper(ThreadOffset<8> offset) OVERRIDE;
+ RegStorage LoadHelper(QuickEntrypointEnum trampoline) OVERRIDE;
LIR* LoadBaseDisp(RegStorage r_base, int displacement, RegStorage r_dest,
OpSize size, VolatileKind is_volatile) OVERRIDE;
LIR* LoadBaseIndexed(RegStorage r_base, RegStorage r_index, RegStorage r_dest, int scale,
OpSize size) OVERRIDE;
- LIR* LoadBaseIndexedDisp(RegStorage r_base, RegStorage r_index, int scale, int displacement,
- RegStorage r_dest, OpSize size) OVERRIDE;
LIR* LoadConstantNoClobber(RegStorage r_dest, int value);
LIR* LoadConstantWide(RegStorage r_dest, int64_t value);
LIR* StoreBaseDisp(RegStorage r_base, int displacement, RegStorage r_src,
OpSize size, VolatileKind is_volatile) OVERRIDE;
LIR* StoreBaseIndexed(RegStorage r_base, RegStorage r_index, RegStorage r_src, int scale,
OpSize size) OVERRIDE;
- LIR* StoreBaseIndexedDisp(RegStorage r_base, RegStorage r_index, int scale, int displacement,
- RegStorage r_src, OpSize size) OVERRIDE;
void MarkGCCard(RegStorage val_reg, RegStorage tgt_addr_reg);
// Required for target - register utilities.
@@ -168,7 +163,6 @@
void OpRegCopy(RegStorage r_dest, RegStorage r_src);
LIR* OpRegCopyNoInsert(RegStorage r_dest, RegStorage r_src);
LIR* OpRegImm(OpKind op, RegStorage r_dest_src1, int value);
- LIR* OpRegMem(OpKind op, RegStorage r_dest, RegStorage r_base, int offset);
LIR* OpRegReg(OpKind op, RegStorage r_dest_src1, RegStorage r_src2);
LIR* OpMovRegMem(RegStorage r_dest, RegStorage r_base, int offset, MoveType move_type);
LIR* OpMovMemReg(RegStorage r_base, int offset, RegStorage r_src, MoveType move_type);
@@ -176,14 +170,9 @@
LIR* OpRegRegImm(OpKind op, RegStorage r_dest, RegStorage r_src1, int value);
LIR* OpRegRegReg(OpKind op, RegStorage r_dest, RegStorage r_src1, RegStorage r_src2);
LIR* OpTestSuspend(LIR* target);
- LIR* OpThreadMem(OpKind op, ThreadOffset<4> thread_offset) OVERRIDE;
- LIR* OpThreadMem(OpKind op, ThreadOffset<8> thread_offset) OVERRIDE;
LIR* OpVldm(RegStorage r_base, int count);
LIR* OpVstm(RegStorage r_base, int count);
- void OpLea(RegStorage r_base, RegStorage reg1, RegStorage reg2, int scale, int offset);
void OpRegCopyWide(RegStorage dest, RegStorage src);
- void OpTlsCmp(ThreadOffset<4> offset, int val) OVERRIDE;
- void OpTlsCmp(ThreadOffset<8> offset, int val) OVERRIDE;
LIR* LoadBaseDispBody(RegStorage r_base, int displacement, RegStorage r_dest, OpSize size);
LIR* StoreBaseDispBody(RegStorage r_base, int displacement, RegStorage r_src, OpSize size);
@@ -208,6 +197,8 @@
return false; // Wide FPRs are formed by pairing.
}
+ LIR* InvokeTrampoline(OpKind op, RegStorage r_tgt, QuickEntrypointEnum trampoline) OVERRIDE;
+
private:
void GenFusedLongCmpImmBranch(BasicBlock* bb, RegLocation rl_src1, int64_t val,
ConditionCode ccode);
diff --git a/compiler/dex/quick/arm/fp_arm.cc b/compiler/dex/quick/arm/fp_arm.cc
index dcb8857..2ad11da 100644
--- a/compiler/dex/quick/arm/fp_arm.cc
+++ b/compiler/dex/quick/arm/fp_arm.cc
@@ -49,8 +49,7 @@
case Instruction::REM_FLOAT_2ADDR:
case Instruction::REM_FLOAT:
FlushAllRegs(); // Send everything to home location
- CallRuntimeHelperRegLocationRegLocation(QUICK_ENTRYPOINT_OFFSET(4, pFmodf), rl_src1, rl_src2,
- false);
+ CallRuntimeHelperRegLocationRegLocation(kQuickFmodf, rl_src1, rl_src2, false);
rl_result = GetReturn(kFPReg);
StoreValue(rl_dest, rl_result);
return;
@@ -92,8 +91,7 @@
case Instruction::REM_DOUBLE_2ADDR:
case Instruction::REM_DOUBLE:
FlushAllRegs(); // Send everything to home location
- CallRuntimeHelperRegLocationRegLocation(QUICK_ENTRYPOINT_OFFSET(4, pFmod), rl_src1, rl_src2,
- false);
+ CallRuntimeHelperRegLocationRegLocation(kQuickFmod, rl_src1, rl_src2, false);
rl_result = GetReturnWide(kFPReg);
StoreValueWide(rl_dest, rl_result);
return;
@@ -160,7 +158,7 @@
return;
}
case Instruction::FLOAT_TO_LONG:
- GenConversionCall(QUICK_ENTRYPOINT_OFFSET(4, pF2l), rl_dest, rl_src);
+ GenConversionCall(kQuickF2l, rl_dest, rl_src);
return;
case Instruction::LONG_TO_FLOAT: {
rl_src = LoadValueWide(rl_src, kFPReg);
@@ -190,7 +188,7 @@
return;
}
case Instruction::DOUBLE_TO_LONG:
- GenConversionCall(QUICK_ENTRYPOINT_OFFSET(4, pD2l), rl_dest, rl_src);
+ GenConversionCall(kQuickD2l, rl_dest, rl_src);
return;
default:
LOG(FATAL) << "Unexpected opcode: " << opcode;
diff --git a/compiler/dex/quick/arm/int_arm.cc b/compiler/dex/quick/arm/int_arm.cc
index a85b740..dd14ed9 100644
--- a/compiler/dex/quick/arm/int_arm.cc
+++ b/compiler/dex/quick/arm/int_arm.cc
@@ -784,18 +784,6 @@
return true;
}
-void ArmMir2Lir::OpLea(RegStorage r_base, RegStorage reg1, RegStorage reg2, int scale, int offset) {
- LOG(FATAL) << "Unexpected use of OpLea for Arm";
-}
-
-void ArmMir2Lir::OpTlsCmp(ThreadOffset<4> offset, int val) {
- LOG(FATAL) << "Unexpected use of OpTlsCmp for Arm";
-}
-
-void ArmMir2Lir::OpTlsCmp(ThreadOffset<8> offset, int val) {
- UNIMPLEMENTED(FATAL) << "Should not be called.";
-}
-
// Generate a CAS with memory_order_seq_cst semantics.
bool ArmMir2Lir::GenInlinedCas(CallInfo* info, bool is_long, bool is_object) {
DCHECK_EQ(cu_->instruction_set, kThumb2);
@@ -1097,9 +1085,8 @@
*/
RegLocation rl_result;
if (BadOverlap(rl_src1, rl_dest) || (BadOverlap(rl_src2, rl_dest))) {
- ThreadOffset<4> func_offset = QUICK_ENTRYPOINT_OFFSET(4, pLmul);
FlushAllRegs();
- CallRuntimeHelperRegLocationRegLocation(func_offset, rl_src1, rl_src2, false);
+ CallRuntimeHelperRegLocationRegLocation(kQuickLmul, rl_src1, rl_src2, false);
rl_result = GetReturnWide(kCoreReg);
StoreValueWide(rl_dest, rl_result);
return;
diff --git a/compiler/dex/quick/arm/target_arm.cc b/compiler/dex/quick/arm/target_arm.cc
index 8cc7596..0509ad3 100644
--- a/compiler/dex/quick/arm/target_arm.cc
+++ b/compiler/dex/quick/arm/target_arm.cc
@@ -720,16 +720,11 @@
FreeTemp(rs_r3);
}
-RegStorage ArmMir2Lir::LoadHelper(ThreadOffset<4> offset) {
- LoadWordDisp(rs_rARM_SELF, offset.Int32Value(), rs_rARM_LR);
+RegStorage ArmMir2Lir::LoadHelper(QuickEntrypointEnum trampoline) {
+ LoadWordDisp(rs_rARM_SELF, GetThreadOffset<4>(trampoline).Int32Value(), rs_rARM_LR);
return rs_rARM_LR;
}
-RegStorage ArmMir2Lir::LoadHelper(ThreadOffset<8> offset) {
- UNIMPLEMENTED(FATAL) << "Should not be called.";
- return RegStorage::InvalidReg();
-}
-
LIR* ArmMir2Lir::CheckSuspendUsingLoad() {
RegStorage tmp = rs_r0;
Load32Disp(rs_rARM_SELF, Thread::ThreadSuspendTriggerOffset<4>().Int32Value(), tmp);
diff --git a/compiler/dex/quick/arm/utility_arm.cc b/compiler/dex/quick/arm/utility_arm.cc
index 9bb9dda..cf21da7 100644
--- a/compiler/dex/quick/arm/utility_arm.cc
+++ b/compiler/dex/quick/arm/utility_arm.cc
@@ -1160,36 +1160,13 @@
return res;
}
-LIR* ArmMir2Lir::OpThreadMem(OpKind op, ThreadOffset<4> thread_offset) {
- LOG(FATAL) << "Unexpected use of OpThreadMem for Arm";
- return NULL;
-}
-
-LIR* ArmMir2Lir::OpThreadMem(OpKind op, ThreadOffset<8> thread_offset) {
- UNIMPLEMENTED(FATAL) << "Should not be called.";
- return nullptr;
-}
-
LIR* ArmMir2Lir::OpMem(OpKind op, RegStorage r_base, int disp) {
LOG(FATAL) << "Unexpected use of OpMem for Arm";
return NULL;
}
-LIR* ArmMir2Lir::StoreBaseIndexedDisp(RegStorage r_base, RegStorage r_index, int scale,
- int displacement, RegStorage r_src, OpSize size) {
- LOG(FATAL) << "Unexpected use of StoreBaseIndexedDisp for Arm";
- return NULL;
-}
-
-LIR* ArmMir2Lir::OpRegMem(OpKind op, RegStorage r_dest, RegStorage r_base, int offset) {
- LOG(FATAL) << "Unexpected use of OpRegMem for Arm";
- return NULL;
-}
-
-LIR* ArmMir2Lir::LoadBaseIndexedDisp(RegStorage r_base, RegStorage r_index, int scale,
- int displacement, RegStorage r_dest, OpSize size) {
- LOG(FATAL) << "Unexpected use of LoadBaseIndexedDisp for Arm";
- return NULL;
+LIR* ArmMir2Lir::InvokeTrampoline(OpKind op, RegStorage r_tgt, QuickEntrypointEnum trampoline) {
+ return OpReg(op, r_tgt);
}
} // namespace art
diff --git a/compiler/dex/quick/arm64/codegen_arm64.h b/compiler/dex/quick/arm64/codegen_arm64.h
index 8d15326..ac36519 100644
--- a/compiler/dex/quick/arm64/codegen_arm64.h
+++ b/compiler/dex/quick/arm64/codegen_arm64.h
@@ -73,8 +73,7 @@
RegLocation rl_src, RegLocation rl_dest, int64_t lit);
bool EasyMultiply(RegLocation rl_src, RegLocation rl_dest, int lit) OVERRIDE;
LIR* CheckSuspendUsingLoad() OVERRIDE;
- RegStorage LoadHelper(ThreadOffset<4> offset) OVERRIDE;
- RegStorage LoadHelper(ThreadOffset<8> offset) OVERRIDE;
+ RegStorage LoadHelper(QuickEntrypointEnum trampoline) OVERRIDE;
LIR* LoadBaseDisp(RegStorage r_base, int displacement, RegStorage r_dest,
OpSize size, VolatileKind is_volatile) OVERRIDE;
LIR* LoadRefDisp(RegStorage r_base, int displacement, RegStorage r_dest,
@@ -84,8 +83,6 @@
OpSize size) OVERRIDE;
LIR* LoadRefIndexed(RegStorage r_base, RegStorage r_index, RegStorage r_dest, int scale)
OVERRIDE;
- LIR* LoadBaseIndexedDisp(RegStorage r_base, RegStorage r_index, int scale, int displacement,
- RegStorage r_dest, OpSize size) OVERRIDE;
LIR* LoadConstantNoClobber(RegStorage r_dest, int value);
LIR* LoadConstantWide(RegStorage r_dest, int64_t value);
LIR* StoreBaseDisp(RegStorage r_base, int displacement, RegStorage r_src,
@@ -96,8 +93,6 @@
OpSize size) OVERRIDE;
LIR* StoreRefIndexed(RegStorage r_base, RegStorage r_index, RegStorage r_src, int scale)
OVERRIDE;
- LIR* StoreBaseIndexedDisp(RegStorage r_base, RegStorage r_index, int scale, int displacement,
- RegStorage r_src, OpSize size) OVERRIDE;
void MarkGCCard(RegStorage val_reg, RegStorage tgt_addr_reg) OVERRIDE;
LIR* OpCmpMemImmBranch(ConditionCode cond, RegStorage temp_reg, RegStorage base_reg,
int offset, int check_value, LIR* target, LIR** compare) OVERRIDE;
@@ -246,7 +241,6 @@
LIR* OpRegCopyNoInsert(RegStorage r_dest, RegStorage r_src);
LIR* OpRegImm64(OpKind op, RegStorage r_dest_src1, int64_t value);
LIR* OpRegImm(OpKind op, RegStorage r_dest_src1, int value);
- LIR* OpRegMem(OpKind op, RegStorage r_dest, RegStorage r_base, int offset);
LIR* OpRegReg(OpKind op, RegStorage r_dest_src1, RegStorage r_src2);
LIR* OpMovRegMem(RegStorage r_dest, RegStorage r_base, int offset, MoveType move_type);
LIR* OpMovMemReg(RegStorage r_base, int offset, RegStorage r_src, MoveType move_type);
@@ -255,14 +249,9 @@
LIR* OpRegRegImm(OpKind op, RegStorage r_dest, RegStorage r_src1, int value);
LIR* OpRegRegReg(OpKind op, RegStorage r_dest, RegStorage r_src1, RegStorage r_src2);
LIR* OpTestSuspend(LIR* target);
- LIR* OpThreadMem(OpKind op, ThreadOffset<4> thread_offset) OVERRIDE;
- LIR* OpThreadMem(OpKind op, ThreadOffset<8> thread_offset) OVERRIDE;
LIR* OpVldm(RegStorage r_base, int count);
LIR* OpVstm(RegStorage r_base, int count);
- void OpLea(RegStorage r_base, RegStorage reg1, RegStorage reg2, int scale, int offset);
void OpRegCopyWide(RegStorage dest, RegStorage src);
- void OpTlsCmp(ThreadOffset<4> offset, int val) OVERRIDE;
- void OpTlsCmp(ThreadOffset<8> offset, int val) OVERRIDE;
LIR* LoadBaseDispBody(RegStorage r_base, int displacement, RegStorage r_dest, OpSize size);
LIR* StoreBaseDispBody(RegStorage r_base, int displacement, RegStorage r_src, OpSize size);
@@ -309,6 +298,8 @@
return true; // 64b architecture.
}
+ LIR* InvokeTrampoline(OpKind op, RegStorage r_tgt, QuickEntrypointEnum trampoline) OVERRIDE;
+
private:
/**
* @brief Given register xNN (dNN), returns register wNN (sNN).
diff --git a/compiler/dex/quick/arm64/fp_arm64.cc b/compiler/dex/quick/arm64/fp_arm64.cc
index 175cef1..ed13c04 100644
--- a/compiler/dex/quick/arm64/fp_arm64.cc
+++ b/compiler/dex/quick/arm64/fp_arm64.cc
@@ -45,8 +45,7 @@
case Instruction::REM_FLOAT_2ADDR:
case Instruction::REM_FLOAT:
FlushAllRegs(); // Send everything to home location
- CallRuntimeHelperRegLocationRegLocation(QUICK_ENTRYPOINT_OFFSET(8, pFmodf), rl_src1, rl_src2,
- false);
+ CallRuntimeHelperRegLocationRegLocation(kQuickFmodf, rl_src1, rl_src2, false);
rl_result = GetReturn(kFPReg);
StoreValue(rl_dest, rl_result);
return;
@@ -89,12 +88,11 @@
case Instruction::REM_DOUBLE:
FlushAllRegs(); // Send everything to home location
{
- ThreadOffset<8> helper_offset = QUICK_ENTRYPOINT_OFFSET(8, pFmod);
- RegStorage r_tgt = CallHelperSetup(helper_offset);
+ RegStorage r_tgt = CallHelperSetup(kQuickFmod);
LoadValueDirectWideFixed(rl_src1, rs_d0);
LoadValueDirectWideFixed(rl_src2, rs_d1);
ClobberCallerSave();
- CallHelper(r_tgt, helper_offset, false);
+ CallHelper(r_tgt, kQuickFmod, false);
}
rl_result = GetReturnWide(kFPReg);
StoreValueWide(rl_dest, rl_result);
diff --git a/compiler/dex/quick/arm64/int_arm64.cc b/compiler/dex/quick/arm64/int_arm64.cc
index aed8de8..f9f85f4 100644
--- a/compiler/dex/quick/arm64/int_arm64.cc
+++ b/compiler/dex/quick/arm64/int_arm64.cc
@@ -701,18 +701,6 @@
return true;
}
-void Arm64Mir2Lir::OpLea(RegStorage r_base, RegStorage reg1, RegStorage reg2, int scale, int offset) {
- LOG(FATAL) << "Unexpected use of OpLea for Arm64";
-}
-
-void Arm64Mir2Lir::OpTlsCmp(ThreadOffset<4> offset, int val) {
- UNIMPLEMENTED(FATAL) << "Should not be used.";
-}
-
-void Arm64Mir2Lir::OpTlsCmp(ThreadOffset<8> offset, int val) {
- LOG(FATAL) << "Unexpected use of OpTlsCmp for Arm64";
-}
-
bool Arm64Mir2Lir::GenInlinedCas(CallInfo* info, bool is_long, bool is_object) {
DCHECK_EQ(cu_->instruction_set, kArm64);
// Unused - RegLocation rl_src_unsafe = info->args[0];
diff --git a/compiler/dex/quick/arm64/target_arm64.cc b/compiler/dex/quick/arm64/target_arm64.cc
index f1dc77a..dec81cb 100644
--- a/compiler/dex/quick/arm64/target_arm64.cc
+++ b/compiler/dex/quick/arm64/target_arm64.cc
@@ -758,15 +758,10 @@
FreeTemp(rs_f7);
}
-RegStorage Arm64Mir2Lir::LoadHelper(ThreadOffset<4> offset) {
- UNIMPLEMENTED(FATAL) << "Should not be called.";
- return RegStorage::InvalidReg();
-}
-
-RegStorage Arm64Mir2Lir::LoadHelper(ThreadOffset<8> offset) {
+RegStorage Arm64Mir2Lir::LoadHelper(QuickEntrypointEnum trampoline) {
// TODO(Arm64): use LoadWordDisp instead.
// e.g. LoadWordDisp(rs_rA64_SELF, offset.Int32Value(), rs_rA64_LR);
- LoadBaseDisp(rs_xSELF, offset.Int32Value(), rs_xLR, k64, kNotVolatile);
+ LoadBaseDisp(rs_xSELF, GetThreadOffset<8>(trampoline).Int32Value(), rs_xLR, k64, kNotVolatile);
return rs_xLR;
}
diff --git a/compiler/dex/quick/arm64/utility_arm64.cc b/compiler/dex/quick/arm64/utility_arm64.cc
index fdebb92..f6c140f 100644
--- a/compiler/dex/quick/arm64/utility_arm64.cc
+++ b/compiler/dex/quick/arm64/utility_arm64.cc
@@ -1262,36 +1262,13 @@
return NULL;
}
-LIR* Arm64Mir2Lir::OpThreadMem(OpKind op, ThreadOffset<4> thread_offset) {
- UNIMPLEMENTED(FATAL) << "Should not be used.";
- return nullptr;
-}
-
-LIR* Arm64Mir2Lir::OpThreadMem(OpKind op, ThreadOffset<8> thread_offset) {
- LOG(FATAL) << "Unexpected use of OpThreadMem for Arm64";
- return NULL;
-}
-
LIR* Arm64Mir2Lir::OpMem(OpKind op, RegStorage r_base, int disp) {
LOG(FATAL) << "Unexpected use of OpMem for Arm64";
return NULL;
}
-LIR* Arm64Mir2Lir::StoreBaseIndexedDisp(RegStorage r_base, RegStorage r_index, int scale,
- int displacement, RegStorage r_src, OpSize size) {
- LOG(FATAL) << "Unexpected use of StoreBaseIndexedDisp for Arm64";
- return NULL;
-}
-
-LIR* Arm64Mir2Lir::OpRegMem(OpKind op, RegStorage r_dest, RegStorage r_base, int offset) {
- LOG(FATAL) << "Unexpected use of OpRegMem for Arm64";
- return NULL;
-}
-
-LIR* Arm64Mir2Lir::LoadBaseIndexedDisp(RegStorage r_base, RegStorage r_index, int scale,
- int displacement, RegStorage r_dest, OpSize size) {
- LOG(FATAL) << "Unexpected use of LoadBaseIndexedDisp for Arm64";
- return NULL;
+LIR* Arm64Mir2Lir::InvokeTrampoline(OpKind op, RegStorage r_tgt, QuickEntrypointEnum trampoline) {
+ return OpReg(op, r_tgt);
}
} // namespace art
diff --git a/compiler/dex/quick/gen_common.cc b/compiler/dex/quick/gen_common.cc
index b94e816..f0e4d9c 100644
--- a/compiler/dex/quick/gen_common.cc
+++ b/compiler/dex/quick/gen_common.cc
@@ -73,11 +73,7 @@
m2l_->ResetRegPool();
m2l_->ResetDefTracking();
GenerateTargetLabel(kPseudoThrowTarget);
- if (m2l_->cu_->target64) {
- m2l_->CallRuntimeHelper(QUICK_ENTRYPOINT_OFFSET(8, pThrowDivZero), true);
- } else {
- m2l_->CallRuntimeHelper(QUICK_ENTRYPOINT_OFFSET(4, pThrowDivZero), true);
- }
+ m2l_->CallRuntimeHelper(kQuickThrowDivZero, true);
}
};
@@ -96,13 +92,7 @@
m2l_->ResetRegPool();
m2l_->ResetDefTracking();
GenerateTargetLabel(kPseudoThrowTarget);
- if (m2l_->cu_->target64) {
- m2l_->CallRuntimeHelperRegReg(QUICK_ENTRYPOINT_OFFSET(8, pThrowArrayBounds),
- index_, length_, true);
- } else {
- m2l_->CallRuntimeHelperRegReg(QUICK_ENTRYPOINT_OFFSET(4, pThrowArrayBounds),
- index_, length_, true);
- }
+ m2l_->CallRuntimeHelperRegReg(kQuickThrowArrayBounds, index_, length_, true);
}
private:
@@ -132,13 +122,7 @@
m2l_->OpRegCopy(arg1_32, length_);
m2l_->LoadConstant(arg0_32, index_);
- if (m2l_->cu_->target64) {
- m2l_->CallRuntimeHelperRegReg(QUICK_ENTRYPOINT_OFFSET(8, pThrowArrayBounds),
- arg0_32, arg1_32, true);
- } else {
- m2l_->CallRuntimeHelperRegReg(QUICK_ENTRYPOINT_OFFSET(4, pThrowArrayBounds),
- arg0_32, arg1_32, true);
- }
+ m2l_->CallRuntimeHelperRegReg(kQuickThrowArrayBounds, arg0_32, arg1_32, true);
}
private:
@@ -161,11 +145,7 @@
m2l_->ResetRegPool();
m2l_->ResetDefTracking();
GenerateTargetLabel(kPseudoThrowTarget);
- if (m2l_->cu_->target64) {
- m2l_->CallRuntimeHelper(QUICK_ENTRYPOINT_OFFSET(8, pThrowNullPointer), true);
- } else {
- m2l_->CallRuntimeHelper(QUICK_ENTRYPOINT_OFFSET(4, pThrowNullPointer), true);
- }
+ m2l_->CallRuntimeHelper(kQuickThrowNullPointer, true);
}
};
@@ -360,16 +340,17 @@
StoreValue(rl_dest, rl_result);
}
-template <size_t pointer_size>
-static void GenNewArrayImpl(Mir2Lir* mir_to_lir, CompilationUnit* cu,
- uint32_t type_idx, RegLocation rl_dest,
- RegLocation rl_src) {
- mir_to_lir->FlushAllRegs(); /* Everything to home location */
- ThreadOffset<pointer_size> func_offset(-1);
- const DexFile* dex_file = cu->dex_file;
- CompilerDriver* driver = cu->compiler_driver;
- if (cu->compiler_driver->CanAccessTypeWithoutChecks(cu->method_idx, *dex_file,
- type_idx)) {
+/*
+ * Let helper function take care of everything. Will call
+ * Array::AllocFromCode(type_idx, method, count);
+ * Note: AllocFromCode will handle checks for errNegativeArraySize.
+ */
+void Mir2Lir::GenNewArray(uint32_t type_idx, RegLocation rl_dest,
+ RegLocation rl_src) {
+ FlushAllRegs(); /* Everything to home location */
+ const DexFile* dex_file = cu_->dex_file;
+ CompilerDriver* driver = cu_->compiler_driver;
+ if (cu_->compiler_driver->CanAccessTypeWithoutChecks(cu_->method_idx, *dex_file, type_idx)) {
bool is_type_initialized; // Ignored as an array does not have an initializer.
bool use_direct_type_ptr;
uintptr_t direct_type_ptr;
@@ -379,55 +360,22 @@
&direct_type_ptr, &is_finalizable)) {
// The fast path.
if (!use_direct_type_ptr) {
- mir_to_lir->LoadClassType(type_idx, kArg0);
- func_offset = QUICK_ENTRYPOINT_OFFSET(pointer_size, pAllocArrayResolved);
- mir_to_lir->CallRuntimeHelperRegMethodRegLocation(func_offset,
- mir_to_lir->TargetReg(kArg0, kNotWide),
- rl_src, true);
+ LoadClassType(type_idx, kArg0);
+ CallRuntimeHelperRegMethodRegLocation(kQuickAllocArrayResolved, TargetReg(kArg0, kNotWide),
+ rl_src, true);
} else {
// Use the direct pointer.
- func_offset = QUICK_ENTRYPOINT_OFFSET(pointer_size, pAllocArrayResolved);
- mir_to_lir->CallRuntimeHelperImmMethodRegLocation(func_offset, direct_type_ptr, rl_src,
- true);
+ CallRuntimeHelperImmMethodRegLocation(kQuickAllocArrayResolved, direct_type_ptr, rl_src,
+ true);
}
} else {
// The slow path.
- func_offset = QUICK_ENTRYPOINT_OFFSET(pointer_size, pAllocArray);
- mir_to_lir->CallRuntimeHelperImmMethodRegLocation(func_offset, type_idx, rl_src, true);
+ CallRuntimeHelperImmMethodRegLocation(kQuickAllocArray, type_idx, rl_src, true);
}
- DCHECK_NE(func_offset.Int32Value(), -1);
} else {
- func_offset = QUICK_ENTRYPOINT_OFFSET(pointer_size, pAllocArrayWithAccessCheck);
- mir_to_lir->CallRuntimeHelperImmMethodRegLocation(func_offset, type_idx, rl_src, true);
+ CallRuntimeHelperImmMethodRegLocation(kQuickAllocArrayWithAccessCheck, type_idx, rl_src, true);
}
- RegLocation rl_result = mir_to_lir->GetReturn(kRefReg);
- mir_to_lir->StoreValue(rl_dest, rl_result);
-}
-
-/*
- * Let helper function take care of everything. Will call
- * Array::AllocFromCode(type_idx, method, count);
- * Note: AllocFromCode will handle checks for errNegativeArraySize.
- */
-void Mir2Lir::GenNewArray(uint32_t type_idx, RegLocation rl_dest,
- RegLocation rl_src) {
- if (cu_->target64) {
- GenNewArrayImpl<8>(this, cu_, type_idx, rl_dest, rl_src);
- } else {
- GenNewArrayImpl<4>(this, cu_, type_idx, rl_dest, rl_src);
- }
-}
-
-template <size_t pointer_size>
-static void GenFilledNewArrayCall(Mir2Lir* mir_to_lir, CompilationUnit* cu, int elems, int type_idx) {
- ThreadOffset<pointer_size> func_offset(-1);
- if (cu->compiler_driver->CanAccessTypeWithoutChecks(cu->method_idx, *cu->dex_file,
- type_idx)) {
- func_offset = QUICK_ENTRYPOINT_OFFSET(pointer_size, pCheckAndAllocArray);
- } else {
- func_offset = QUICK_ENTRYPOINT_OFFSET(pointer_size, pCheckAndAllocArrayWithAccessCheck);
- }
- mir_to_lir->CallRuntimeHelperImmMethodImm(func_offset, type_idx, elems, true);
+ StoreValue(rl_dest, GetReturn(kRefReg));
}
/*
@@ -440,11 +388,14 @@
int elems = info->num_arg_words;
int type_idx = info->index;
FlushAllRegs(); /* Everything to home location */
- if (cu_->target64) {
- GenFilledNewArrayCall<8>(this, cu_, elems, type_idx);
+ QuickEntrypointEnum target;
+ if (cu_->compiler_driver->CanAccessTypeWithoutChecks(cu_->method_idx, *cu_->dex_file,
+ type_idx)) {
+ target = kQuickCheckAndAllocArray;
} else {
- GenFilledNewArrayCall<4>(this, cu_, elems, type_idx);
+ target = kQuickCheckAndAllocArrayWithAccessCheck;
}
+ CallRuntimeHelperImmMethodImm(target, type_idx, elems, true);
FreeTemp(TargetReg(kArg2, kNotWide));
FreeTemp(TargetReg(kArg1, kNotWide));
/*
@@ -559,13 +510,7 @@
void Compile() {
LIR* unresolved_target = GenerateTargetLabel();
uninit_->target = unresolved_target;
- if (cu_->target64) {
- m2l_->CallRuntimeHelperImm(QUICK_ENTRYPOINT_OFFSET(8, pInitializeStaticStorage),
- storage_index_, true);
- } else {
- m2l_->CallRuntimeHelperImm(QUICK_ENTRYPOINT_OFFSET(4, pInitializeStaticStorage),
- storage_index_, true);
- }
+ m2l_->CallRuntimeHelperImm(kQuickInitializeStaticStorage, storage_index_, true);
// Copy helper's result into r_base, a no-op on all but MIPS.
m2l_->OpRegCopy(r_base_, m2l_->TargetReg(kRet0, kRef));
@@ -578,17 +523,6 @@
const RegStorage r_base_;
};
-template <size_t pointer_size>
-static void GenSputCall(Mir2Lir* mir_to_lir, bool is_long_or_double, bool is_object,
- const MirSFieldLoweringInfo* field_info, RegLocation rl_src) {
- ThreadOffset<pointer_size> setter_offset =
- is_long_or_double ? QUICK_ENTRYPOINT_OFFSET(pointer_size, pSet64Static)
- : (is_object ? QUICK_ENTRYPOINT_OFFSET(pointer_size, pSetObjStatic)
- : QUICK_ENTRYPOINT_OFFSET(pointer_size, pSet32Static));
- mir_to_lir->CallRuntimeHelperImmRegLocation(setter_offset, field_info->FieldIndex(), rl_src,
- true);
-}
-
void Mir2Lir::GenSput(MIR* mir, RegLocation rl_src, bool is_long_or_double,
bool is_object) {
const MirSFieldLoweringInfo& field_info = mir_graph_->GetSFieldLoweringInfo(mir);
@@ -671,24 +605,13 @@
FreeTemp(r_base);
} else {
FlushAllRegs(); // Everything to home locations
- if (cu_->target64) {
- GenSputCall<8>(this, is_long_or_double, is_object, &field_info, rl_src);
- } else {
- GenSputCall<4>(this, is_long_or_double, is_object, &field_info, rl_src);
- }
+ QuickEntrypointEnum target =
+ is_long_or_double ? kQuickSet64Static
+ : (is_object ? kQuickSetObjStatic : kQuickSet32Static);
+ CallRuntimeHelperImmRegLocation(target, field_info.FieldIndex(), rl_src, true);
}
}
-template <size_t pointer_size>
-static void GenSgetCall(Mir2Lir* mir_to_lir, bool is_long_or_double, bool is_object,
- const MirSFieldLoweringInfo* field_info) {
- ThreadOffset<pointer_size> getter_offset =
- is_long_or_double ? QUICK_ENTRYPOINT_OFFSET(pointer_size, pGet64Static)
- : (is_object ? QUICK_ENTRYPOINT_OFFSET(pointer_size, pGetObjStatic)
- : QUICK_ENTRYPOINT_OFFSET(pointer_size, pGet32Static));
- mir_to_lir->CallRuntimeHelperImm(getter_offset, field_info->FieldIndex(), true);
-}
-
void Mir2Lir::GenSget(MIR* mir, RegLocation rl_dest,
bool is_long_or_double, bool is_object) {
const MirSFieldLoweringInfo& field_info = mir_graph_->GetSFieldLoweringInfo(mir);
@@ -764,11 +687,11 @@
}
} else {
FlushAllRegs(); // Everything to home locations
- if (cu_->target64) {
- GenSgetCall<8>(this, is_long_or_double, is_object, &field_info);
- } else {
- GenSgetCall<4>(this, is_long_or_double, is_object, &field_info);
- }
+ QuickEntrypointEnum target =
+ is_long_or_double ? kQuickGet64Static
+ : (is_object ? kQuickGetObjStatic : kQuickGet32Static);
+ CallRuntimeHelperImm(target, field_info.FieldIndex(), true);
+
// FIXME: pGetXXStatic always return an int or int64 regardless of rl_dest.fp.
if (is_long_or_double) {
RegLocation rl_result = GetReturnWide(kCoreReg);
@@ -791,19 +714,6 @@
slow_paths_.Reset();
}
-template <size_t pointer_size>
-static void GenIgetCall(Mir2Lir* mir_to_lir, bool is_long_or_double, bool is_object,
- const MirIFieldLoweringInfo* field_info, RegLocation rl_obj) {
- ThreadOffset<pointer_size> getter_offset =
- is_long_or_double ? QUICK_ENTRYPOINT_OFFSET(pointer_size, pGet64Instance)
- : (is_object ? QUICK_ENTRYPOINT_OFFSET(pointer_size, pGetObjInstance)
- : QUICK_ENTRYPOINT_OFFSET(pointer_size, pGet32Instance));
- // Second argument of pGetXXInstance is always a reference.
- DCHECK_EQ(static_cast<unsigned int>(rl_obj.wide), 0U);
- mir_to_lir->CallRuntimeHelperImmRegLocation(getter_offset, field_info->FieldIndex(), rl_obj,
- true);
-}
-
void Mir2Lir::GenIGet(MIR* mir, int opt_flags, OpSize size,
RegLocation rl_dest, RegLocation rl_obj, bool is_long_or_double,
bool is_object) {
@@ -832,11 +742,13 @@
StoreValue(rl_dest, rl_result);
}
} else {
- if (cu_->target64) {
- GenIgetCall<8>(this, is_long_or_double, is_object, &field_info, rl_obj);
- } else {
- GenIgetCall<4>(this, is_long_or_double, is_object, &field_info, rl_obj);
- }
+ QuickEntrypointEnum target =
+ is_long_or_double ? kQuickGet64Instance
+ : (is_object ? kQuickGetObjInstance : kQuickGet32Instance);
+ // Second argument of pGetXXInstance is always a reference.
+ DCHECK_EQ(static_cast<unsigned int>(rl_obj.wide), 0U);
+ CallRuntimeHelperImmRegLocation(target, field_info.FieldIndex(), rl_obj, true);
+
// FIXME: pGetXXInstance always return an int or int64 regardless of rl_dest.fp.
if (is_long_or_double) {
RegLocation rl_result = GetReturnWide(kCoreReg);
@@ -848,18 +760,6 @@
}
}
-template <size_t pointer_size>
-static void GenIputCall(Mir2Lir* mir_to_lir, bool is_long_or_double, bool is_object,
- const MirIFieldLoweringInfo* field_info, RegLocation rl_obj,
- RegLocation rl_src) {
- ThreadOffset<pointer_size> setter_offset =
- is_long_or_double ? QUICK_ENTRYPOINT_OFFSET(pointer_size, pSet64Instance)
- : (is_object ? QUICK_ENTRYPOINT_OFFSET(pointer_size, pSetObjInstance)
- : QUICK_ENTRYPOINT_OFFSET(pointer_size, pSet32Instance));
- mir_to_lir->CallRuntimeHelperImmRegLocationRegLocation(setter_offset, field_info->FieldIndex(),
- rl_obj, rl_src, true);
-}
-
void Mir2Lir::GenIPut(MIR* mir, int opt_flags, OpSize size,
RegLocation rl_src, RegLocation rl_obj, bool is_long_or_double,
bool is_object) {
@@ -890,35 +790,24 @@
MarkGCCard(rl_src.reg, rl_obj.reg);
}
} else {
- if (cu_->target64) {
- GenIputCall<8>(this, is_long_or_double, is_object, &field_info, rl_obj, rl_src);
- } else {
- GenIputCall<4>(this, is_long_or_double, is_object, &field_info, rl_obj, rl_src);
- }
+ QuickEntrypointEnum target =
+ is_long_or_double ? kQuickSet64Instance
+ : (is_object ? kQuickSetObjInstance : kQuickSet32Instance);
+ CallRuntimeHelperImmRegLocationRegLocation(target, field_info.FieldIndex(), rl_obj, rl_src,
+ true);
}
}
-template <size_t pointer_size>
-static void GenArrayObjPutCall(Mir2Lir* mir_to_lir, bool needs_range_check, bool needs_null_check,
- RegLocation rl_array, RegLocation rl_index, RegLocation rl_src) {
- ThreadOffset<pointer_size> helper = needs_range_check
- ? (needs_null_check ? QUICK_ENTRYPOINT_OFFSET(pointer_size, pAputObjectWithNullAndBoundCheck)
- : QUICK_ENTRYPOINT_OFFSET(pointer_size, pAputObjectWithBoundCheck))
- : QUICK_ENTRYPOINT_OFFSET(pointer_size, pAputObject);
- mir_to_lir->CallRuntimeHelperRegLocationRegLocationRegLocation(helper, rl_array, rl_index, rl_src,
- true);
-}
-
void Mir2Lir::GenArrayObjPut(int opt_flags, RegLocation rl_array, RegLocation rl_index,
RegLocation rl_src) {
bool needs_range_check = !(opt_flags & MIR_IGNORE_RANGE_CHECK);
bool needs_null_check = !((cu_->disable_opt & (1 << kNullCheckElimination)) &&
(opt_flags & MIR_IGNORE_NULL_CHECK));
- if (cu_->target64) {
- GenArrayObjPutCall<8>(this, needs_range_check, needs_null_check, rl_array, rl_index, rl_src);
- } else {
- GenArrayObjPutCall<4>(this, needs_range_check, needs_null_check, rl_array, rl_index, rl_src);
- }
+ QuickEntrypointEnum target = needs_range_check
+ ? (needs_null_check ? kQuickAputObjectWithNullAndBoundCheck
+ : kQuickAputObjectWithBoundCheck)
+ : kQuickAputObject;
+ CallRuntimeHelperRegLocationRegLocationRegLocation(target, rl_array, rl_index, rl_src, true);
}
void Mir2Lir::GenConstClass(uint32_t type_idx, RegLocation rl_dest) {
@@ -931,13 +820,7 @@
type_idx)) {
// Call out to helper which resolves type and verifies access.
// Resolved type returned in kRet0.
- if (cu_->target64) {
- CallRuntimeHelperImmReg(QUICK_ENTRYPOINT_OFFSET(8, pInitializeTypeAndVerifyAccess),
- type_idx, rl_method.reg, true);
- } else {
- CallRuntimeHelperImmReg(QUICK_ENTRYPOINT_OFFSET(4, pInitializeTypeAndVerifyAccess),
- type_idx, rl_method.reg, true);
- }
+ CallRuntimeHelperImmReg(kQuickInitializeTypeAndVerifyAccess, type_idx, rl_method.reg, true);
RegLocation rl_result = GetReturn(kRefReg);
StoreValue(rl_dest, rl_result);
} else {
@@ -966,15 +849,8 @@
void Compile() {
GenerateTargetLabel();
- if (cu_->target64) {
- m2l_->CallRuntimeHelperImmReg(QUICK_ENTRYPOINT_OFFSET(8, pInitializeType), type_idx_,
- rl_method_.reg, true);
- } else {
- m2l_->CallRuntimeHelperImmReg(QUICK_ENTRYPOINT_OFFSET(4, pInitializeType), type_idx_,
- rl_method_.reg, true);
- }
+ m2l_->CallRuntimeHelperImmReg(kQuickInitializeType, type_idx_, rl_method_.reg, true);
m2l_->OpRegCopy(rl_result_.reg, m2l_->TargetReg(kRet0, kRef));
-
m2l_->OpUnconditionalBranch(cont_);
}
@@ -1035,13 +911,7 @@
void Compile() {
GenerateTargetLabel();
- if (cu_->target64) {
- m2l_->CallRuntimeHelperRegImm(QUICK_ENTRYPOINT_OFFSET(8, pResolveString),
- r_method_, string_idx_, true);
- } else {
- m2l_->CallRuntimeHelperRegImm(QUICK_ENTRYPOINT_OFFSET(4, pResolveString),
- r_method_, string_idx_, true);
- }
+ m2l_->CallRuntimeHelperRegImm(kQuickResolveString, r_method_, string_idx_, true);
m2l_->OpUnconditionalBranch(cont_);
}
@@ -1066,17 +936,17 @@
}
}
-template <size_t pointer_size>
-static void GenNewInstanceImpl(Mir2Lir* mir_to_lir, CompilationUnit* cu, uint32_t type_idx,
- RegLocation rl_dest) {
- mir_to_lir->FlushAllRegs(); /* Everything to home location */
+/*
+ * Let helper function take care of everything. Will
+ * call Class::NewInstanceFromCode(type_idx, method);
+ */
+void Mir2Lir::GenNewInstance(uint32_t type_idx, RegLocation rl_dest) {
+ FlushAllRegs(); /* Everything to home location */
// alloc will always check for resolution, do we also need to verify
// access because the verifier was unable to?
- ThreadOffset<pointer_size> func_offset(-1);
- const DexFile* dex_file = cu->dex_file;
- CompilerDriver* driver = cu->compiler_driver;
- if (driver->CanAccessInstantiableTypeWithoutChecks(
- cu->method_idx, *dex_file, type_idx)) {
+ const DexFile* dex_file = cu_->dex_file;
+ CompilerDriver* driver = cu_->compiler_driver;
+ if (driver->CanAccessInstantiableTypeWithoutChecks(cu_->method_idx, *dex_file, type_idx)) {
bool is_type_initialized;
bool use_direct_type_ptr;
uintptr_t direct_type_ptr;
@@ -1087,60 +957,33 @@
!is_finalizable) {
// The fast path.
if (!use_direct_type_ptr) {
- mir_to_lir->LoadClassType(type_idx, kArg0);
+ LoadClassType(type_idx, kArg0);
if (!is_type_initialized) {
- func_offset = QUICK_ENTRYPOINT_OFFSET(pointer_size, pAllocObjectResolved);
- mir_to_lir->CallRuntimeHelperRegMethod(func_offset, mir_to_lir->TargetReg(kArg0, kRef),
- true);
+ CallRuntimeHelperRegMethod(kQuickAllocObjectResolved, TargetReg(kArg0, kRef), true);
} else {
- func_offset = QUICK_ENTRYPOINT_OFFSET(pointer_size, pAllocObjectInitialized);
- mir_to_lir->CallRuntimeHelperRegMethod(func_offset, mir_to_lir->TargetReg(kArg0, kRef),
- true);
+ CallRuntimeHelperRegMethod(kQuickAllocObjectInitialized, TargetReg(kArg0, kRef), true);
}
} else {
// Use the direct pointer.
if (!is_type_initialized) {
- func_offset = QUICK_ENTRYPOINT_OFFSET(pointer_size, pAllocObjectResolved);
- mir_to_lir->CallRuntimeHelperImmMethod(func_offset, direct_type_ptr, true);
+ CallRuntimeHelperImmMethod(kQuickAllocObjectResolved, direct_type_ptr, true);
} else {
- func_offset = QUICK_ENTRYPOINT_OFFSET(pointer_size, pAllocObjectInitialized);
- mir_to_lir->CallRuntimeHelperImmMethod(func_offset, direct_type_ptr, true);
+ CallRuntimeHelperImmMethod(kQuickAllocObjectInitialized, direct_type_ptr, true);
}
}
} else {
// The slow path.
- DCHECK_EQ(func_offset.Int32Value(), -1);
- func_offset = QUICK_ENTRYPOINT_OFFSET(pointer_size, pAllocObject);
- mir_to_lir->CallRuntimeHelperImmMethod(func_offset, type_idx, true);
+ CallRuntimeHelperImmMethod(kQuickAllocObject, type_idx, true);
}
- DCHECK_NE(func_offset.Int32Value(), -1);
} else {
- func_offset = QUICK_ENTRYPOINT_OFFSET(pointer_size, pAllocObjectWithAccessCheck);
- mir_to_lir->CallRuntimeHelperImmMethod(func_offset, type_idx, true);
+ CallRuntimeHelperImmMethod(kQuickAllocObjectWithAccessCheck, type_idx, true);
}
- RegLocation rl_result = mir_to_lir->GetReturn(kRefReg);
- mir_to_lir->StoreValue(rl_dest, rl_result);
-}
-
-/*
- * Let helper function take care of everything. Will
- * call Class::NewInstanceFromCode(type_idx, method);
- */
-void Mir2Lir::GenNewInstance(uint32_t type_idx, RegLocation rl_dest) {
- if (cu_->target64) {
- GenNewInstanceImpl<8>(this, cu_, type_idx, rl_dest);
- } else {
- GenNewInstanceImpl<4>(this, cu_, type_idx, rl_dest);
- }
+ StoreValue(rl_dest, GetReturn(kRefReg));
}
void Mir2Lir::GenThrow(RegLocation rl_src) {
FlushAllRegs();
- if (cu_->target64) {
- CallRuntimeHelperRegLocation(QUICK_ENTRYPOINT_OFFSET(8, pDeliverException), rl_src, true);
- } else {
- CallRuntimeHelperRegLocation(QUICK_ENTRYPOINT_OFFSET(4, pDeliverException), rl_src, true);
- }
+ CallRuntimeHelperRegLocation(kQuickDeliverException, rl_src, true);
}
// For final classes there are no sub-classes to check and so we can answer the instance-of
@@ -1214,13 +1057,7 @@
if (needs_access_check) {
// Check we have access to type_idx and if not throw IllegalAccessError,
// returns Class* in kArg0
- if (cu_->target64) {
- CallRuntimeHelperImm(QUICK_ENTRYPOINT_OFFSET(8, pInitializeTypeAndVerifyAccess),
- type_idx, true);
- } else {
- CallRuntimeHelperImm(QUICK_ENTRYPOINT_OFFSET(4, pInitializeTypeAndVerifyAccess),
- type_idx, true);
- }
+ CallRuntimeHelperImm(kQuickInitializeTypeAndVerifyAccess, type_idx, true);
OpRegCopy(class_reg, ret_reg); // Align usage with fast path
LoadValueDirectFixed(rl_src, ref_reg); // kArg0 <= ref
} else if (use_declaring_class) {
@@ -1256,16 +1093,9 @@
void Compile() OVERRIDE {
GenerateTargetLabel();
- if (cu_->target64) {
- m2l_->CallRuntimeHelperImm(QUICK_ENTRYPOINT_OFFSET(8, pInitializeType), type_idx_,
- true);
- } else {
- m2l_->CallRuntimeHelperImm(QUICK_ENTRYPOINT_OFFSET(4, pInitializeType), type_idx_,
- true);
- }
+ m2l_->CallRuntimeHelperImm(kQuickInitializeType, type_idx_, true);
m2l_->OpRegCopy(m2l_->TargetReg(kArg2, kRef),
m2l_->TargetReg(kRet0, kRef)); // Align usage with fast path
-
m2l_->OpUnconditionalBranch(cont_);
}
@@ -1299,9 +1129,7 @@
kCoreReg);
} else {
if (cu_->instruction_set == kThumb2) {
- RegStorage r_tgt = cu_->target64 ?
- LoadHelper(QUICK_ENTRYPOINT_OFFSET(8, pInstanceofNonTrivial)) :
- LoadHelper(QUICK_ENTRYPOINT_OFFSET(4, pInstanceofNonTrivial));
+ RegStorage r_tgt = LoadHelper(kQuickInstanceofNonTrivial);
LIR* it = nullptr;
if (!type_known_abstract) {
/* Uses conditional nullification */
@@ -1323,11 +1151,7 @@
}
OpRegCopy(TargetReg(kArg0, kRef), class_reg); // .ne case - arg0 <= class
- if (cu_->target64) {
- CallRuntimeHelper(QUICK_ENTRYPOINT_OFFSET(8, pInstanceofNonTrivial), false);
- } else {
- CallRuntimeHelper(QUICK_ENTRYPOINT_OFFSET(4, pInstanceofNonTrivial), false);
- }
+ CallRuntimeHelper(kQuickInstanceofNonTrivial, false);
}
}
// TODO: only clobber when type isn't final?
@@ -1336,7 +1160,7 @@
LIR* target = NewLIR0(kPseudoTargetLabel);
StoreValue(rl_dest, rl_result);
branch1->target = target;
- if (branchover != NULL) {
+ if (branchover != nullptr) {
branchover->target = target;
}
}
@@ -1386,13 +1210,7 @@
// Check we have access to type_idx and if not throw IllegalAccessError,
// returns Class* in kRet0
// InitializeTypeAndVerifyAccess(idx, method)
- if (cu_->target64) {
- CallRuntimeHelperImm(QUICK_ENTRYPOINT_OFFSET(8, pInitializeTypeAndVerifyAccess),
- type_idx, true);
- } else {
- CallRuntimeHelperImm(QUICK_ENTRYPOINT_OFFSET(4, pInitializeTypeAndVerifyAccess),
- type_idx, true);
- }
+ CallRuntimeHelperImm(kQuickInitializeTypeAndVerifyAccess, type_idx, true);
OpRegCopy(class_reg, TargetReg(kRet0, kRef)); // Align usage with fast path
} else if (use_declaring_class) {
LoadRefDisp(method_reg, mirror::ArtMethod::DeclaringClassOffset().Int32Value(),
@@ -1422,13 +1240,8 @@
// Call out to helper, which will return resolved type in kArg0
// InitializeTypeFromCode(idx, method)
- if (m2l_->cu_->target64) {
- m2l_->CallRuntimeHelperImmReg(QUICK_ENTRYPOINT_OFFSET(8, pInitializeType), type_idx_,
- m2l_->TargetReg(kArg1, kRef), true);
- } else {
- m2l_->CallRuntimeHelperImmReg(QUICK_ENTRYPOINT_OFFSET(4, pInitializeType), type_idx_,
- m2l_->TargetReg(kArg1, kRef), true);
- }
+ m2l_->CallRuntimeHelperImmReg(kQuickInitializeType, type_idx_,
+ m2l_->TargetReg(kArg1, kRef), true);
m2l_->OpRegCopy(class_reg_, m2l_->TargetReg(kRet0, kRef)); // Align usage with fast path
m2l_->OpUnconditionalBranch(cont_);
}
@@ -1459,16 +1272,8 @@
m2l_->LoadRefDisp(m2l_->TargetReg(kArg0, kRef), mirror::Object::ClassOffset().Int32Value(),
m2l_->TargetReg(kArg1, kRef), kNotVolatile);
}
- if (m2l_->cu_->target64) {
- m2l_->CallRuntimeHelperRegReg(QUICK_ENTRYPOINT_OFFSET(8, pCheckCast),
- m2l_->TargetReg(kArg2, kRef), m2l_->TargetReg(kArg1, kRef),
- true);
- } else {
- m2l_->CallRuntimeHelperRegReg(QUICK_ENTRYPOINT_OFFSET(4, pCheckCast),
- m2l_->TargetReg(kArg2, kRef), m2l_->TargetReg(kArg1, kRef),
- true);
- }
-
+ m2l_->CallRuntimeHelperRegReg(kQuickCheckCast, m2l_->TargetReg(kArg2, kRef),
+ m2l_->TargetReg(kArg1, kRef), true);
m2l_->OpUnconditionalBranch(cont_);
}
@@ -1549,39 +1354,28 @@
}
}
-
-template <size_t pointer_size>
-static void GenShiftOpLongCall(Mir2Lir* mir_to_lir, Instruction::Code opcode, RegLocation rl_src1,
- RegLocation rl_shift) {
- ThreadOffset<pointer_size> func_offset(-1);
-
+void Mir2Lir::GenShiftOpLong(Instruction::Code opcode, RegLocation rl_dest,
+ RegLocation rl_src1, RegLocation rl_shift) {
+ QuickEntrypointEnum target;
switch (opcode) {
case Instruction::SHL_LONG:
case Instruction::SHL_LONG_2ADDR:
- func_offset = QUICK_ENTRYPOINT_OFFSET(pointer_size, pShlLong);
+ target = kQuickShlLong;
break;
case Instruction::SHR_LONG:
case Instruction::SHR_LONG_2ADDR:
- func_offset = QUICK_ENTRYPOINT_OFFSET(pointer_size, pShrLong);
+ target = kQuickShrLong;
break;
case Instruction::USHR_LONG:
case Instruction::USHR_LONG_2ADDR:
- func_offset = QUICK_ENTRYPOINT_OFFSET(pointer_size, pUshrLong);
+ target = kQuickUshrLong;
break;
default:
LOG(FATAL) << "Unexpected case";
+ target = kQuickShlLong;
}
- mir_to_lir->FlushAllRegs(); /* Send everything to home location */
- mir_to_lir->CallRuntimeHelperRegLocationRegLocation(func_offset, rl_src1, rl_shift, false);
-}
-
-void Mir2Lir::GenShiftOpLong(Instruction::Code opcode, RegLocation rl_dest,
- RegLocation rl_src1, RegLocation rl_shift) {
- if (cu_->target64) {
- GenShiftOpLongCall<8>(this, opcode, rl_src1, rl_shift);
- } else {
- GenShiftOpLongCall<4>(this, opcode, rl_src1, rl_shift);
- }
+ FlushAllRegs(); /* Send everything to home location */
+ CallRuntimeHelperRegLocationRegLocation(target, rl_src1, rl_shift, false);
RegLocation rl_result = GetReturnWide(kCoreReg);
StoreValueWide(rl_dest, rl_result);
}
@@ -1710,19 +1504,13 @@
if (!done) {
FlushAllRegs(); /* Send everything to home location */
LoadValueDirectFixed(rl_src2, TargetReg(kArg1, kNotWide));
- RegStorage r_tgt = cu_->target64 ?
- CallHelperSetup(QUICK_ENTRYPOINT_OFFSET(8, pIdivmod)) :
- CallHelperSetup(QUICK_ENTRYPOINT_OFFSET(4, pIdivmod));
+ RegStorage r_tgt = CallHelperSetup(kQuickIdivmod);
LoadValueDirectFixed(rl_src1, TargetReg(kArg0, kNotWide));
if (check_zero) {
GenDivZeroCheck(TargetReg(kArg1, kNotWide));
}
// NOTE: callout here is not a safepoint.
- if (cu_->target64) {
- CallHelper(r_tgt, QUICK_ENTRYPOINT_OFFSET(8, pIdivmod), false /* not a safepoint */);
- } else {
- CallHelper(r_tgt, QUICK_ENTRYPOINT_OFFSET(4, pIdivmod), false /* not a safepoint */);
- }
+ CallHelper(r_tgt, kQuickIdivmod, false /* not a safepoint */);
if (op == kOpDiv)
rl_result = GetReturn(kCoreReg);
else
@@ -1981,13 +1769,7 @@
FlushAllRegs(); /* Everything to home location. */
LoadValueDirectFixed(rl_src, TargetReg(kArg0, kNotWide));
Clobber(TargetReg(kArg0, kNotWide));
- if (cu_->target64) {
- CallRuntimeHelperRegImm(QUICK_ENTRYPOINT_OFFSET(8, pIdivmod), TargetReg(kArg0, kNotWide),
- lit, false);
- } else {
- CallRuntimeHelperRegImm(QUICK_ENTRYPOINT_OFFSET(4, pIdivmod), TargetReg(kArg0, kNotWide),
- lit, false);
- }
+ CallRuntimeHelperRegImm(kQuickIdivmod, TargetReg(kArg0, kNotWide), lit, false);
if (is_div)
rl_result = GetReturn(kCoreReg);
else
@@ -2010,42 +1792,41 @@
StoreValue(rl_dest, rl_result);
}
-template <size_t pointer_size>
-static void GenArithOpLongImpl(Mir2Lir* mir_to_lir, CompilationUnit* cu, Instruction::Code opcode,
- RegLocation rl_dest, RegLocation rl_src1, RegLocation rl_src2) {
+void Mir2Lir::GenArithOpLong(Instruction::Code opcode, RegLocation rl_dest,
+ RegLocation rl_src1, RegLocation rl_src2) {
RegLocation rl_result;
OpKind first_op = kOpBkpt;
OpKind second_op = kOpBkpt;
bool call_out = false;
bool check_zero = false;
- ThreadOffset<pointer_size> func_offset(-1);
- int ret_reg = mir_to_lir->TargetReg(kRet0, kNotWide).GetReg();
+ int ret_reg = TargetReg(kRet0, kNotWide).GetReg();
+ QuickEntrypointEnum target;
switch (opcode) {
case Instruction::NOT_LONG:
- if (cu->instruction_set == kArm64 || cu->instruction_set == kX86_64) {
- mir_to_lir->GenNotLong(rl_dest, rl_src2);
+ if (cu_->instruction_set == kArm64 || cu_->instruction_set == kX86_64) {
+ GenNotLong(rl_dest, rl_src2);
return;
}
- rl_src2 = mir_to_lir->LoadValueWide(rl_src2, kCoreReg);
- rl_result = mir_to_lir->EvalLoc(rl_dest, kCoreReg, true);
+ rl_src2 = LoadValueWide(rl_src2, kCoreReg);
+ rl_result = EvalLoc(rl_dest, kCoreReg, true);
// Check for destructive overlap
if (rl_result.reg.GetLowReg() == rl_src2.reg.GetHighReg()) {
- RegStorage t_reg = mir_to_lir->AllocTemp();
- mir_to_lir->OpRegCopy(t_reg, rl_src2.reg.GetHigh());
- mir_to_lir->OpRegReg(kOpMvn, rl_result.reg.GetLow(), rl_src2.reg.GetLow());
- mir_to_lir->OpRegReg(kOpMvn, rl_result.reg.GetHigh(), t_reg);
- mir_to_lir->FreeTemp(t_reg);
+ RegStorage t_reg = AllocTemp();
+ OpRegCopy(t_reg, rl_src2.reg.GetHigh());
+ OpRegReg(kOpMvn, rl_result.reg.GetLow(), rl_src2.reg.GetLow());
+ OpRegReg(kOpMvn, rl_result.reg.GetHigh(), t_reg);
+ FreeTemp(t_reg);
} else {
- mir_to_lir->OpRegReg(kOpMvn, rl_result.reg.GetLow(), rl_src2.reg.GetLow());
- mir_to_lir->OpRegReg(kOpMvn, rl_result.reg.GetHigh(), rl_src2.reg.GetHigh());
+ OpRegReg(kOpMvn, rl_result.reg.GetLow(), rl_src2.reg.GetLow());
+ OpRegReg(kOpMvn, rl_result.reg.GetHigh(), rl_src2.reg.GetHigh());
}
- mir_to_lir->StoreValueWide(rl_dest, rl_result);
+ StoreValueWide(rl_dest, rl_result);
return;
case Instruction::ADD_LONG:
case Instruction::ADD_LONG_2ADDR:
- if (cu->instruction_set != kThumb2) {
- mir_to_lir->GenAddLong(opcode, rl_dest, rl_src1, rl_src2);
+ if (cu_->instruction_set != kThumb2) {
+ GenAddLong(opcode, rl_dest, rl_src1, rl_src2);
return;
}
first_op = kOpAdd;
@@ -2053,8 +1834,8 @@
break;
case Instruction::SUB_LONG:
case Instruction::SUB_LONG_2ADDR:
- if (cu->instruction_set != kThumb2) {
- mir_to_lir->GenSubLong(opcode, rl_dest, rl_src1, rl_src2);
+ if (cu_->instruction_set != kThumb2) {
+ GenSubLong(opcode, rl_dest, rl_src1, rl_src2);
return;
}
first_op = kOpSub;
@@ -2062,53 +1843,53 @@
break;
case Instruction::MUL_LONG:
case Instruction::MUL_LONG_2ADDR:
- if (cu->instruction_set != kMips) {
- mir_to_lir->GenMulLong(opcode, rl_dest, rl_src1, rl_src2);
+ if (cu_->instruction_set != kMips) {
+ GenMulLong(opcode, rl_dest, rl_src1, rl_src2);
return;
} else {
call_out = true;
- ret_reg = mir_to_lir->TargetReg(kRet0, kNotWide).GetReg();
- func_offset = QUICK_ENTRYPOINT_OFFSET(pointer_size, pLmul);
+ TargetReg(kRet0, kNotWide).GetReg();
+ target = kQuickLmul;
}
break;
case Instruction::DIV_LONG:
case Instruction::DIV_LONG_2ADDR:
- if (cu->instruction_set == kArm64 || cu->instruction_set == kX86_64) {
- mir_to_lir->GenDivRemLong(opcode, rl_dest, rl_src1, rl_src2, /*is_div*/ true);
+ if (cu_->instruction_set == kArm64 || cu_->instruction_set == kX86_64) {
+ GenDivRemLong(opcode, rl_dest, rl_src1, rl_src2, /*is_div*/ true);
return;
}
call_out = true;
check_zero = true;
- ret_reg = mir_to_lir->TargetReg(kRet0, kNotWide).GetReg();
- func_offset = QUICK_ENTRYPOINT_OFFSET(pointer_size, pLdiv);
+ ret_reg = TargetReg(kRet0, kNotWide).GetReg();
+ target = kQuickLdiv;
break;
case Instruction::REM_LONG:
case Instruction::REM_LONG_2ADDR:
- if (cu->instruction_set == kArm64 || cu->instruction_set == kX86_64) {
- mir_to_lir->GenDivRemLong(opcode, rl_dest, rl_src1, rl_src2, /*is_div*/ false);
+ if (cu_->instruction_set == kArm64 || cu_->instruction_set == kX86_64) {
+ GenDivRemLong(opcode, rl_dest, rl_src1, rl_src2, /*is_div*/ false);
return;
}
call_out = true;
check_zero = true;
- func_offset = QUICK_ENTRYPOINT_OFFSET(pointer_size, pLmod);
+ target = kQuickLmod;
/* NOTE - for Arm, result is in kArg2/kArg3 instead of kRet0/kRet1 */
- ret_reg = (cu->instruction_set == kThumb2) ? mir_to_lir->TargetReg(kArg2, kNotWide).GetReg() :
- mir_to_lir->TargetReg(kRet0, kNotWide).GetReg();
+ ret_reg = (cu_->instruction_set == kThumb2) ? TargetReg(kArg2, kNotWide).GetReg() :
+ TargetReg(kRet0, kNotWide).GetReg();
break;
case Instruction::AND_LONG_2ADDR:
case Instruction::AND_LONG:
- if (cu->instruction_set == kX86 || cu->instruction_set == kX86_64 ||
- cu->instruction_set == kArm64) {
- return mir_to_lir->GenAndLong(opcode, rl_dest, rl_src1, rl_src2);
+ if (cu_->instruction_set == kX86 || cu_->instruction_set == kX86_64 ||
+ cu_->instruction_set == kArm64) {
+ return GenAndLong(opcode, rl_dest, rl_src1, rl_src2);
}
first_op = kOpAnd;
second_op = kOpAnd;
break;
case Instruction::OR_LONG:
case Instruction::OR_LONG_2ADDR:
- if (cu->instruction_set == kX86 || cu->instruction_set == kX86_64 ||
- cu->instruction_set == kArm64) {
- mir_to_lir->GenOrLong(opcode, rl_dest, rl_src1, rl_src2);
+ if (cu_->instruction_set == kX86 || cu_->instruction_set == kX86_64 ||
+ cu_->instruction_set == kArm64) {
+ GenOrLong(opcode, rl_dest, rl_src1, rl_src2);
return;
}
first_op = kOpOr;
@@ -2116,52 +1897,43 @@
break;
case Instruction::XOR_LONG:
case Instruction::XOR_LONG_2ADDR:
- if (cu->instruction_set == kX86 || cu->instruction_set == kX86_64 ||
- cu->instruction_set == kArm64) {
- mir_to_lir->GenXorLong(opcode, rl_dest, rl_src1, rl_src2);
+ if (cu_->instruction_set == kX86 || cu_->instruction_set == kX86_64 ||
+ cu_->instruction_set == kArm64) {
+ GenXorLong(opcode, rl_dest, rl_src1, rl_src2);
return;
}
first_op = kOpXor;
second_op = kOpXor;
break;
case Instruction::NEG_LONG: {
- mir_to_lir->GenNegLong(rl_dest, rl_src2);
+ GenNegLong(rl_dest, rl_src2);
return;
}
default:
LOG(FATAL) << "Invalid long arith op";
}
if (!call_out) {
- mir_to_lir->GenLong3Addr(first_op, second_op, rl_dest, rl_src1, rl_src2);
+ GenLong3Addr(first_op, second_op, rl_dest, rl_src1, rl_src2);
} else {
- mir_to_lir->FlushAllRegs(); /* Send everything to home location */
+ FlushAllRegs(); /* Send everything to home location */
if (check_zero) {
- RegStorage r_tmp1 = mir_to_lir->TargetReg(kArg0, kWide);
- RegStorage r_tmp2 = mir_to_lir->TargetReg(kArg2, kWide);
- mir_to_lir->LoadValueDirectWideFixed(rl_src2, r_tmp2);
- RegStorage r_tgt = mir_to_lir->CallHelperSetup(func_offset);
- mir_to_lir->GenDivZeroCheckWide(r_tmp2);
- mir_to_lir->LoadValueDirectWideFixed(rl_src1, r_tmp1);
+ RegStorage r_tmp1 = TargetReg(kArg0, kWide);
+ RegStorage r_tmp2 = TargetReg(kArg2, kWide);
+ LoadValueDirectWideFixed(rl_src2, r_tmp2);
+ RegStorage r_tgt = CallHelperSetup(target);
+ GenDivZeroCheckWide(r_tmp2);
+ LoadValueDirectWideFixed(rl_src1, r_tmp1);
// NOTE: callout here is not a safepoint
- mir_to_lir->CallHelper(r_tgt, func_offset, false /* not safepoint */);
+ CallHelper(r_tgt, target, false /* not safepoint */);
} else {
- mir_to_lir->CallRuntimeHelperRegLocationRegLocation(func_offset, rl_src1, rl_src2, false);
+ CallRuntimeHelperRegLocationRegLocation(target, rl_src1, rl_src2, false);
}
// Adjust return regs in to handle case of rem returning kArg2/kArg3
- if (ret_reg == mir_to_lir->TargetReg(kRet0, kNotWide).GetReg())
- rl_result = mir_to_lir->GetReturnWide(kCoreReg);
+ if (ret_reg == TargetReg(kRet0, kNotWide).GetReg())
+ rl_result = GetReturnWide(kCoreReg);
else
- rl_result = mir_to_lir->GetReturnWideAlt();
- mir_to_lir->StoreValueWide(rl_dest, rl_result);
- }
-}
-
-void Mir2Lir::GenArithOpLong(Instruction::Code opcode, RegLocation rl_dest,
- RegLocation rl_src1, RegLocation rl_src2) {
- if (cu_->target64) {
- GenArithOpLongImpl<8>(this, cu_, opcode, rl_dest, rl_src1, rl_src2);
- } else {
- GenArithOpLongImpl<4>(this, cu_, opcode, rl_dest, rl_src1, rl_src2);
+ rl_result = GetReturnWideAlt();
+ StoreValueWide(rl_dest, rl_result);
}
}
@@ -2174,17 +1946,15 @@
}
}
-template <size_t pointer_size>
-void Mir2Lir::GenConversionCall(ThreadOffset<pointer_size> func_offset,
- RegLocation rl_dest, RegLocation rl_src) {
+void Mir2Lir::GenConversionCall(QuickEntrypointEnum trampoline, RegLocation rl_dest,
+ RegLocation rl_src) {
/*
* Don't optimize the register usage since it calls out to support
* functions
*/
- DCHECK_EQ(pointer_size, GetInstructionSetPointerSize(cu_->instruction_set));
FlushAllRegs(); /* Send everything to home location */
- CallRuntimeHelperRegLocation(func_offset, rl_src, false);
+ CallRuntimeHelperRegLocation(trampoline, rl_src, false);
if (rl_dest.wide) {
RegLocation rl_result;
rl_result = GetReturnWide(LocToRegClass(rl_dest));
@@ -2195,10 +1965,6 @@
StoreValue(rl_dest, rl_result);
}
}
-template void Mir2Lir::GenConversionCall(ThreadOffset<4> func_offset,
- RegLocation rl_dest, RegLocation rl_src);
-template void Mir2Lir::GenConversionCall(ThreadOffset<8> func_offset,
- RegLocation rl_dest, RegLocation rl_src);
class SuspendCheckSlowPath : public Mir2Lir::LIRSlowPath {
public:
@@ -2210,11 +1976,7 @@
m2l_->ResetRegPool();
m2l_->ResetDefTracking();
GenerateTargetLabel(kPseudoSuspendTarget);
- if (cu_->target64) {
- m2l_->CallRuntimeHelper(QUICK_ENTRYPOINT_OFFSET(8, pTestSuspend), true);
- } else {
- m2l_->CallRuntimeHelper(QUICK_ENTRYPOINT_OFFSET(4, pTestSuspend), true);
- }
+ m2l_->CallRuntimeHelper(kQuickTestSuspend, true);
if (cont_ != nullptr) {
m2l_->OpUnconditionalBranch(cont_);
}
@@ -2269,21 +2031,13 @@
/* Call out to helper assembly routine that will null check obj and then lock it. */
void Mir2Lir::GenMonitorEnter(int opt_flags, RegLocation rl_src) {
FlushAllRegs();
- if (cu_->target64) {
- CallRuntimeHelperRegLocation(QUICK_ENTRYPOINT_OFFSET(8, pLockObject), rl_src, true);
- } else {
- CallRuntimeHelperRegLocation(QUICK_ENTRYPOINT_OFFSET(4, pLockObject), rl_src, true);
- }
+ CallRuntimeHelperRegLocation(kQuickLockObject, rl_src, true);
}
/* Call out to helper assembly routine that will null check obj and then unlock it. */
void Mir2Lir::GenMonitorExit(int opt_flags, RegLocation rl_src) {
FlushAllRegs();
- if (cu_->target64) {
- CallRuntimeHelperRegLocation(QUICK_ENTRYPOINT_OFFSET(8, pUnlockObject), rl_src, true);
- } else {
- CallRuntimeHelperRegLocation(QUICK_ENTRYPOINT_OFFSET(4, pUnlockObject), rl_src, true);
- }
+ CallRuntimeHelperRegLocation(kQuickUnlockObject, rl_src, true);
}
/* Generic code for generating a wide constant into a VR. */
diff --git a/compiler/dex/quick/gen_invoke.cc b/compiler/dex/quick/gen_invoke.cc
index 2c69593..ea52b39 100755
--- a/compiler/dex/quick/gen_invoke.cc
+++ b/compiler/dex/quick/gen_invoke.cc
@@ -67,13 +67,6 @@
AddSlowPath(new (arena_) IntrinsicSlowPathPath(this, info, branch, resume));
}
-// Macro to help instantiate.
-// TODO: This might be used to only instantiate <4> on pure 32b systems.
-#define INSTANTIATE(sig_part1, ...) \
- template sig_part1(ThreadOffset<4>, __VA_ARGS__); \
- template sig_part1(ThreadOffset<8>, __VA_ARGS__); \
-
-
/*
* To save scheduling time, helper calls are broken into two parts: generation of
* the helper target address, and the actual call to the helper. Because x86
@@ -81,107 +74,73 @@
* load arguments between the two parts.
*/
// template <size_t pointer_size>
-RegStorage Mir2Lir::CallHelperSetup(ThreadOffset<4> helper_offset) {
- // All CallRuntimeHelperXXX call this first. So make a central check here.
- DCHECK_EQ(4U, GetInstructionSetPointerSize(cu_->instruction_set));
-
+RegStorage Mir2Lir::CallHelperSetup(QuickEntrypointEnum trampoline) {
if (cu_->instruction_set == kX86 || cu_->instruction_set == kX86_64) {
return RegStorage::InvalidReg();
} else {
- return LoadHelper(helper_offset);
+ return LoadHelper(trampoline);
}
}
-RegStorage Mir2Lir::CallHelperSetup(ThreadOffset<8> helper_offset) {
- // All CallRuntimeHelperXXX call this first. So make a central check here.
- DCHECK_EQ(8U, GetInstructionSetPointerSize(cu_->instruction_set));
+LIR* Mir2Lir::CallHelper(RegStorage r_tgt, QuickEntrypointEnum trampoline, bool safepoint_pc,
+ bool use_link) {
+ LIR* call_inst = InvokeTrampoline(use_link ? kOpBlx : kOpBx, r_tgt, trampoline);
- if (cu_->instruction_set == kX86 || cu_->instruction_set == kX86_64) {
- return RegStorage::InvalidReg();
- } else {
- return LoadHelper(helper_offset);
- }
-}
-
-/* NOTE: if r_tgt is a temp, it will be freed following use */
-template <size_t pointer_size>
-LIR* Mir2Lir::CallHelper(RegStorage r_tgt, ThreadOffset<pointer_size> helper_offset,
- bool safepoint_pc, bool use_link) {
- LIR* call_inst;
- OpKind op = use_link ? kOpBlx : kOpBx;
- if (cu_->instruction_set == kX86 || cu_->instruction_set == kX86_64) {
- call_inst = OpThreadMem(op, helper_offset);
- } else {
- call_inst = OpReg(op, r_tgt);
+ if (r_tgt.Valid()) {
FreeTemp(r_tgt);
}
+
if (safepoint_pc) {
MarkSafepointPC(call_inst);
}
return call_inst;
}
-template LIR* Mir2Lir::CallHelper(RegStorage r_tgt, ThreadOffset<4> helper_offset,
- bool safepoint_pc, bool use_link);
-template LIR* Mir2Lir::CallHelper(RegStorage r_tgt, ThreadOffset<8> helper_offset,
- bool safepoint_pc, bool use_link);
-template <size_t pointer_size>
-void Mir2Lir::CallRuntimeHelper(ThreadOffset<pointer_size> helper_offset, bool safepoint_pc) {
- RegStorage r_tgt = CallHelperSetup(helper_offset);
+void Mir2Lir::CallRuntimeHelper(QuickEntrypointEnum trampoline, bool safepoint_pc) {
+ RegStorage r_tgt = CallHelperSetup(trampoline);
ClobberCallerSave();
- CallHelper<pointer_size>(r_tgt, helper_offset, safepoint_pc);
+ CallHelper(r_tgt, trampoline, safepoint_pc);
}
-INSTANTIATE(void Mir2Lir::CallRuntimeHelper, bool safepoint_pc)
-template <size_t pointer_size>
-void Mir2Lir::CallRuntimeHelperImm(ThreadOffset<pointer_size> helper_offset, int arg0,
- bool safepoint_pc) {
- RegStorage r_tgt = CallHelperSetup(helper_offset);
+void Mir2Lir::CallRuntimeHelperImm(QuickEntrypointEnum trampoline, int arg0, bool safepoint_pc) {
+ RegStorage r_tgt = CallHelperSetup(trampoline);
LoadConstant(TargetReg(kArg0, kNotWide), arg0);
ClobberCallerSave();
- CallHelper<pointer_size>(r_tgt, helper_offset, safepoint_pc);
+ CallHelper(r_tgt, trampoline, safepoint_pc);
}
-INSTANTIATE(void Mir2Lir::CallRuntimeHelperImm, int arg0, bool safepoint_pc)
-template <size_t pointer_size>
-void Mir2Lir::CallRuntimeHelperReg(ThreadOffset<pointer_size> helper_offset, RegStorage arg0,
+void Mir2Lir::CallRuntimeHelperReg(QuickEntrypointEnum trampoline, RegStorage arg0,
bool safepoint_pc) {
- RegStorage r_tgt = CallHelperSetup(helper_offset);
+ RegStorage r_tgt = CallHelperSetup(trampoline);
OpRegCopy(TargetReg(kArg0, arg0.GetWideKind()), arg0);
ClobberCallerSave();
- CallHelper<pointer_size>(r_tgt, helper_offset, safepoint_pc);
+ CallHelper(r_tgt, trampoline, safepoint_pc);
}
-INSTANTIATE(void Mir2Lir::CallRuntimeHelperReg, RegStorage arg0, bool safepoint_pc)
-template <size_t pointer_size>
-void Mir2Lir::CallRuntimeHelperRegLocation(ThreadOffset<pointer_size> helper_offset,
- RegLocation arg0, bool safepoint_pc) {
- RegStorage r_tgt = CallHelperSetup(helper_offset);
+void Mir2Lir::CallRuntimeHelperRegLocation(QuickEntrypointEnum trampoline, RegLocation arg0,
+ bool safepoint_pc) {
+ RegStorage r_tgt = CallHelperSetup(trampoline);
if (arg0.wide == 0) {
LoadValueDirectFixed(arg0, TargetReg(arg0.fp ? kFArg0 : kArg0, arg0));
} else {
LoadValueDirectWideFixed(arg0, TargetReg(arg0.fp ? kFArg0 : kArg0, kWide));
}
ClobberCallerSave();
- CallHelper<pointer_size>(r_tgt, helper_offset, safepoint_pc);
+ CallHelper(r_tgt, trampoline, safepoint_pc);
}
-INSTANTIATE(void Mir2Lir::CallRuntimeHelperRegLocation, RegLocation arg0, bool safepoint_pc)
-template <size_t pointer_size>
-void Mir2Lir::CallRuntimeHelperImmImm(ThreadOffset<pointer_size> helper_offset, int arg0, int arg1,
+void Mir2Lir::CallRuntimeHelperImmImm(QuickEntrypointEnum trampoline, int arg0, int arg1,
bool safepoint_pc) {
- RegStorage r_tgt = CallHelperSetup(helper_offset);
+ RegStorage r_tgt = CallHelperSetup(trampoline);
LoadConstant(TargetReg(kArg0, kNotWide), arg0);
LoadConstant(TargetReg(kArg1, kNotWide), arg1);
ClobberCallerSave();
- CallHelper<pointer_size>(r_tgt, helper_offset, safepoint_pc);
+ CallHelper(r_tgt, trampoline, safepoint_pc);
}
-INSTANTIATE(void Mir2Lir::CallRuntimeHelperImmImm, int arg0, int arg1, bool safepoint_pc)
-template <size_t pointer_size>
-void Mir2Lir::CallRuntimeHelperImmRegLocation(ThreadOffset<pointer_size> helper_offset, int arg0,
+void Mir2Lir::CallRuntimeHelperImmRegLocation(QuickEntrypointEnum trampoline, int arg0,
RegLocation arg1, bool safepoint_pc) {
- RegStorage r_tgt = CallHelperSetup(helper_offset);
+ RegStorage r_tgt = CallHelperSetup(trampoline);
DCHECK(!arg1.fp);
if (arg1.wide == 0) {
LoadValueDirectFixed(arg1, TargetReg(kArg1, arg1));
@@ -191,61 +150,49 @@
}
LoadConstant(TargetReg(kArg0, kNotWide), arg0);
ClobberCallerSave();
- CallHelper<pointer_size>(r_tgt, helper_offset, safepoint_pc);
+ CallHelper(r_tgt, trampoline, safepoint_pc);
}
-INSTANTIATE(void Mir2Lir::CallRuntimeHelperImmRegLocation, int arg0, RegLocation arg1,
- bool safepoint_pc)
-template <size_t pointer_size>
-void Mir2Lir::CallRuntimeHelperRegLocationImm(ThreadOffset<pointer_size> helper_offset,
- RegLocation arg0, int arg1, bool safepoint_pc) {
- RegStorage r_tgt = CallHelperSetup(helper_offset);
+void Mir2Lir::CallRuntimeHelperRegLocationImm(QuickEntrypointEnum trampoline, RegLocation arg0,
+ int arg1, bool safepoint_pc) {
+ RegStorage r_tgt = CallHelperSetup(trampoline);
DCHECK(!arg0.wide);
LoadValueDirectFixed(arg0, TargetReg(kArg0, arg0));
LoadConstant(TargetReg(kArg1, kNotWide), arg1);
ClobberCallerSave();
- CallHelper<pointer_size>(r_tgt, helper_offset, safepoint_pc);
+ CallHelper(r_tgt, trampoline, safepoint_pc);
}
-INSTANTIATE(void Mir2Lir::CallRuntimeHelperRegLocationImm, RegLocation arg0, int arg1,
- bool safepoint_pc)
-template <size_t pointer_size>
-void Mir2Lir::CallRuntimeHelperImmReg(ThreadOffset<pointer_size> helper_offset, int arg0,
- RegStorage arg1, bool safepoint_pc) {
- RegStorage r_tgt = CallHelperSetup(helper_offset);
+void Mir2Lir::CallRuntimeHelperImmReg(QuickEntrypointEnum trampoline, int arg0, RegStorage arg1,
+ bool safepoint_pc) {
+ RegStorage r_tgt = CallHelperSetup(trampoline);
OpRegCopy(TargetReg(kArg1, arg1.GetWideKind()), arg1);
LoadConstant(TargetReg(kArg0, kNotWide), arg0);
ClobberCallerSave();
- CallHelper<pointer_size>(r_tgt, helper_offset, safepoint_pc);
+ CallHelper(r_tgt, trampoline, safepoint_pc);
}
-INSTANTIATE(void Mir2Lir::CallRuntimeHelperImmReg, int arg0, RegStorage arg1, bool safepoint_pc)
-template <size_t pointer_size>
-void Mir2Lir::CallRuntimeHelperRegImm(ThreadOffset<pointer_size> helper_offset, RegStorage arg0,
- int arg1, bool safepoint_pc) {
- RegStorage r_tgt = CallHelperSetup(helper_offset);
+void Mir2Lir::CallRuntimeHelperRegImm(QuickEntrypointEnum trampoline, RegStorage arg0, int arg1,
+ bool safepoint_pc) {
+ RegStorage r_tgt = CallHelperSetup(trampoline);
OpRegCopy(TargetReg(kArg0, arg0.GetWideKind()), arg0);
LoadConstant(TargetReg(kArg1, kNotWide), arg1);
ClobberCallerSave();
- CallHelper<pointer_size>(r_tgt, helper_offset, safepoint_pc);
+ CallHelper(r_tgt, trampoline, safepoint_pc);
}
-INSTANTIATE(void Mir2Lir::CallRuntimeHelperRegImm, RegStorage arg0, int arg1, bool safepoint_pc)
-template <size_t pointer_size>
-void Mir2Lir::CallRuntimeHelperImmMethod(ThreadOffset<pointer_size> helper_offset, int arg0,
+void Mir2Lir::CallRuntimeHelperImmMethod(QuickEntrypointEnum trampoline, int arg0,
bool safepoint_pc) {
- RegStorage r_tgt = CallHelperSetup(helper_offset);
+ RegStorage r_tgt = CallHelperSetup(trampoline);
LoadCurrMethodDirect(TargetReg(kArg1, kRef));
LoadConstant(TargetReg(kArg0, kNotWide), arg0);
ClobberCallerSave();
- CallHelper<pointer_size>(r_tgt, helper_offset, safepoint_pc);
+ CallHelper(r_tgt, trampoline, safepoint_pc);
}
-INSTANTIATE(void Mir2Lir::CallRuntimeHelperImmMethod, int arg0, bool safepoint_pc)
-template <size_t pointer_size>
-void Mir2Lir::CallRuntimeHelperRegMethod(ThreadOffset<pointer_size> helper_offset, RegStorage arg0,
+void Mir2Lir::CallRuntimeHelperRegMethod(QuickEntrypointEnum trampoline, RegStorage arg0,
bool safepoint_pc) {
- RegStorage r_tgt = CallHelperSetup(helper_offset);
+ RegStorage r_tgt = CallHelperSetup(trampoline);
DCHECK(!IsSameReg(TargetReg(kArg1, arg0.GetWideKind()), arg0));
RegStorage r_tmp = TargetReg(kArg0, arg0.GetWideKind());
if (r_tmp.NotExactlyEquals(arg0)) {
@@ -253,15 +200,12 @@
}
LoadCurrMethodDirect(TargetReg(kArg1, kRef));
ClobberCallerSave();
- CallHelper<pointer_size>(r_tgt, helper_offset, safepoint_pc);
+ CallHelper(r_tgt, trampoline, safepoint_pc);
}
-INSTANTIATE(void Mir2Lir::CallRuntimeHelperRegMethod, RegStorage arg0, bool safepoint_pc)
-template <size_t pointer_size>
-void Mir2Lir::CallRuntimeHelperRegMethodRegLocation(ThreadOffset<pointer_size> helper_offset,
- RegStorage arg0, RegLocation arg2,
- bool safepoint_pc) {
- RegStorage r_tgt = CallHelperSetup(helper_offset);
+void Mir2Lir::CallRuntimeHelperRegMethodRegLocation(QuickEntrypointEnum trampoline, RegStorage arg0,
+ RegLocation arg2, bool safepoint_pc) {
+ RegStorage r_tgt = CallHelperSetup(trampoline);
DCHECK(!IsSameReg(TargetReg(kArg1, arg0.GetWideKind()), arg0));
RegStorage r_tmp = TargetReg(kArg0, arg0.GetWideKind());
if (r_tmp.NotExactlyEquals(arg0)) {
@@ -270,16 +214,13 @@
LoadCurrMethodDirect(TargetReg(kArg1, kRef));
LoadValueDirectFixed(arg2, TargetReg(kArg2, arg2));
ClobberCallerSave();
- CallHelper<pointer_size>(r_tgt, helper_offset, safepoint_pc);
+ CallHelper(r_tgt, trampoline, safepoint_pc);
}
-INSTANTIATE(void Mir2Lir::CallRuntimeHelperRegMethodRegLocation, RegStorage arg0, RegLocation arg2,
- bool safepoint_pc)
-template <size_t pointer_size>
-void Mir2Lir::CallRuntimeHelperRegLocationRegLocation(ThreadOffset<pointer_size> helper_offset,
+void Mir2Lir::CallRuntimeHelperRegLocationRegLocation(QuickEntrypointEnum trampoline,
RegLocation arg0, RegLocation arg1,
bool safepoint_pc) {
- RegStorage r_tgt = CallHelperSetup(helper_offset);
+ RegStorage r_tgt = CallHelperSetup(trampoline);
if (cu_->instruction_set == kArm64 || cu_->instruction_set == kX86_64) {
RegStorage arg0_reg = TargetReg((arg0.fp) ? kFArg0 : kArg0, arg0);
@@ -328,10 +269,8 @@
}
}
ClobberCallerSave();
- CallHelper<pointer_size>(r_tgt, helper_offset, safepoint_pc);
+ CallHelper(r_tgt, trampoline, safepoint_pc);
}
-INSTANTIATE(void Mir2Lir::CallRuntimeHelperRegLocationRegLocation, RegLocation arg0,
- RegLocation arg1, bool safepoint_pc)
void Mir2Lir::CopyToArgumentRegs(RegStorage arg0, RegStorage arg1) {
WideKind arg0_kind = arg0.GetWideKind();
@@ -352,59 +291,47 @@
}
}
-template <size_t pointer_size>
-void Mir2Lir::CallRuntimeHelperRegReg(ThreadOffset<pointer_size> helper_offset, RegStorage arg0,
+void Mir2Lir::CallRuntimeHelperRegReg(QuickEntrypointEnum trampoline, RegStorage arg0,
RegStorage arg1, bool safepoint_pc) {
- RegStorage r_tgt = CallHelperSetup(helper_offset);
+ RegStorage r_tgt = CallHelperSetup(trampoline);
CopyToArgumentRegs(arg0, arg1);
ClobberCallerSave();
- CallHelper<pointer_size>(r_tgt, helper_offset, safepoint_pc);
+ CallHelper(r_tgt, trampoline, safepoint_pc);
}
-INSTANTIATE(void Mir2Lir::CallRuntimeHelperRegReg, RegStorage arg0, RegStorage arg1,
- bool safepoint_pc)
-template <size_t pointer_size>
-void Mir2Lir::CallRuntimeHelperRegRegImm(ThreadOffset<pointer_size> helper_offset, RegStorage arg0,
+void Mir2Lir::CallRuntimeHelperRegRegImm(QuickEntrypointEnum trampoline, RegStorage arg0,
RegStorage arg1, int arg2, bool safepoint_pc) {
- RegStorage r_tgt = CallHelperSetup(helper_offset);
+ RegStorage r_tgt = CallHelperSetup(trampoline);
CopyToArgumentRegs(arg0, arg1);
LoadConstant(TargetReg(kArg2, kNotWide), arg2);
ClobberCallerSave();
- CallHelper<pointer_size>(r_tgt, helper_offset, safepoint_pc);
+ CallHelper(r_tgt, trampoline, safepoint_pc);
}
-INSTANTIATE(void Mir2Lir::CallRuntimeHelperRegRegImm, RegStorage arg0, RegStorage arg1, int arg2,
- bool safepoint_pc)
-template <size_t pointer_size>
-void Mir2Lir::CallRuntimeHelperImmMethodRegLocation(ThreadOffset<pointer_size> helper_offset,
- int arg0, RegLocation arg2, bool safepoint_pc) {
- RegStorage r_tgt = CallHelperSetup(helper_offset);
+void Mir2Lir::CallRuntimeHelperImmMethodRegLocation(QuickEntrypointEnum trampoline, int arg0,
+ RegLocation arg2, bool safepoint_pc) {
+ RegStorage r_tgt = CallHelperSetup(trampoline);
LoadValueDirectFixed(arg2, TargetReg(kArg2, arg2));
LoadCurrMethodDirect(TargetReg(kArg1, kRef));
LoadConstant(TargetReg(kArg0, kNotWide), arg0);
ClobberCallerSave();
- CallHelper<pointer_size>(r_tgt, helper_offset, safepoint_pc);
+ CallHelper(r_tgt, trampoline, safepoint_pc);
}
-INSTANTIATE(void Mir2Lir::CallRuntimeHelperImmMethodRegLocation, int arg0, RegLocation arg2,
- bool safepoint_pc)
-template <size_t pointer_size>
-void Mir2Lir::CallRuntimeHelperImmMethodImm(ThreadOffset<pointer_size> helper_offset, int arg0,
- int arg2, bool safepoint_pc) {
- RegStorage r_tgt = CallHelperSetup(helper_offset);
+void Mir2Lir::CallRuntimeHelperImmMethodImm(QuickEntrypointEnum trampoline, int arg0, int arg2,
+ bool safepoint_pc) {
+ RegStorage r_tgt = CallHelperSetup(trampoline);
LoadCurrMethodDirect(TargetReg(kArg1, kRef));
LoadConstant(TargetReg(kArg2, kNotWide), arg2);
LoadConstant(TargetReg(kArg0, kNotWide), arg0);
ClobberCallerSave();
- CallHelper<pointer_size>(r_tgt, helper_offset, safepoint_pc);
+ CallHelper(r_tgt, trampoline, safepoint_pc);
}
-INSTANTIATE(void Mir2Lir::CallRuntimeHelperImmMethodImm, int arg0, int arg2, bool safepoint_pc)
-template <size_t pointer_size>
-void Mir2Lir::CallRuntimeHelperImmRegLocationRegLocation(ThreadOffset<pointer_size> helper_offset,
- int arg0, RegLocation arg1,
+void Mir2Lir::CallRuntimeHelperImmRegLocationRegLocation(QuickEntrypointEnum trampoline, int arg0,
+ RegLocation arg1,
RegLocation arg2, bool safepoint_pc) {
- RegStorage r_tgt = CallHelperSetup(helper_offset);
+ RegStorage r_tgt = CallHelperSetup(trampoline);
DCHECK_EQ(static_cast<unsigned int>(arg1.wide), 0U); // The static_cast works around an
// instantiation bug in GCC.
LoadValueDirectFixed(arg1, TargetReg(kArg1, arg1));
@@ -415,27 +342,22 @@
}
LoadConstant(TargetReg(kArg0, kNotWide), arg0);
ClobberCallerSave();
- CallHelper<pointer_size>(r_tgt, helper_offset, safepoint_pc);
+ CallHelper(r_tgt, trampoline, safepoint_pc);
}
-INSTANTIATE(void Mir2Lir::CallRuntimeHelperImmRegLocationRegLocation, int arg0, RegLocation arg1,
- RegLocation arg2, bool safepoint_pc)
-template <size_t pointer_size>
void Mir2Lir::CallRuntimeHelperRegLocationRegLocationRegLocation(
- ThreadOffset<pointer_size> helper_offset,
+ QuickEntrypointEnum trampoline,
RegLocation arg0,
RegLocation arg1,
RegLocation arg2,
bool safepoint_pc) {
- RegStorage r_tgt = CallHelperSetup(helper_offset);
+ RegStorage r_tgt = CallHelperSetup(trampoline);
LoadValueDirectFixed(arg0, TargetReg(kArg0, arg0));
LoadValueDirectFixed(arg1, TargetReg(kArg1, arg1));
LoadValueDirectFixed(arg2, TargetReg(kArg2, arg2));
ClobberCallerSave();
- CallHelper<pointer_size>(r_tgt, helper_offset, safepoint_pc);
+ CallHelper(r_tgt, trampoline, safepoint_pc);
}
-INSTANTIATE(void Mir2Lir::CallRuntimeHelperRegLocationRegLocationRegLocation, RegLocation arg0,
- RegLocation arg1, RegLocation arg2, bool safepoint_pc)
/*
* If there are any ins passed in registers that have not been promoted
@@ -727,11 +649,12 @@
return state + 1;
}
-template <size_t pointer_size>
static int NextInvokeInsnSP(CompilationUnit* cu, CallInfo* info,
- ThreadOffset<pointer_size> trampoline, int state,
+ QuickEntrypointEnum trampoline, int state,
const MethodReference& target_method, uint32_t method_idx) {
Mir2Lir* cg = static_cast<Mir2Lir*>(cu->cg.get());
+
+
/*
* This handles the case in which the base method is not fully
* resolved at compile time, we bail to a runtime helper.
@@ -739,8 +662,13 @@
if (state == 0) {
if (cu->instruction_set != kX86 && cu->instruction_set != kX86_64) {
// Load trampoline target
- cg->LoadWordDisp(cg->TargetPtrReg(kSelf), trampoline.Int32Value(),
- cg->TargetPtrReg(kInvokeTgt));
+ int32_t disp;
+ if (cu->target64) {
+ disp = GetThreadOffset<8>(trampoline).Int32Value();
+ } else {
+ disp = GetThreadOffset<4>(trampoline).Int32Value();
+ }
+ cg->LoadWordDisp(cg->TargetPtrReg(kSelf), disp, cg->TargetPtrReg(kInvokeTgt));
}
// Load kArg0 with method index
CHECK_EQ(cu->dex_file, target_method.dex_file);
@@ -755,54 +683,32 @@
const MethodReference& target_method,
uint32_t unused, uintptr_t unused2,
uintptr_t unused3, InvokeType unused4) {
- if (cu->target64) {
- ThreadOffset<8> trampoline = QUICK_ENTRYPOINT_OFFSET(8, pInvokeStaticTrampolineWithAccessCheck);
- return NextInvokeInsnSP<8>(cu, info, trampoline, state, target_method, 0);
- } else {
- ThreadOffset<4> trampoline = QUICK_ENTRYPOINT_OFFSET(4, pInvokeStaticTrampolineWithAccessCheck);
- return NextInvokeInsnSP<4>(cu, info, trampoline, state, target_method, 0);
- }
+ return NextInvokeInsnSP(cu, info, kQuickInvokeStaticTrampolineWithAccessCheck, state,
+ target_method, 0);
}
static int NextDirectCallInsnSP(CompilationUnit* cu, CallInfo* info, int state,
const MethodReference& target_method,
uint32_t unused, uintptr_t unused2,
uintptr_t unused3, InvokeType unused4) {
- if (cu->target64) {
- ThreadOffset<8> trampoline = QUICK_ENTRYPOINT_OFFSET(8, pInvokeDirectTrampolineWithAccessCheck);
- return NextInvokeInsnSP<8>(cu, info, trampoline, state, target_method, 0);
- } else {
- ThreadOffset<4> trampoline = QUICK_ENTRYPOINT_OFFSET(4, pInvokeDirectTrampolineWithAccessCheck);
- return NextInvokeInsnSP<4>(cu, info, trampoline, state, target_method, 0);
- }
+ return NextInvokeInsnSP(cu, info, kQuickInvokeDirectTrampolineWithAccessCheck, state,
+ target_method, 0);
}
static int NextSuperCallInsnSP(CompilationUnit* cu, CallInfo* info, int state,
const MethodReference& target_method,
uint32_t unused, uintptr_t unused2,
uintptr_t unused3, InvokeType unused4) {
- if (cu->target64) {
- ThreadOffset<8> trampoline = QUICK_ENTRYPOINT_OFFSET(8, pInvokeSuperTrampolineWithAccessCheck);
- return NextInvokeInsnSP<8>(cu, info, trampoline, state, target_method, 0);
- } else {
- ThreadOffset<4> trampoline = QUICK_ENTRYPOINT_OFFSET(4, pInvokeSuperTrampolineWithAccessCheck);
- return NextInvokeInsnSP<4>(cu, info, trampoline, state, target_method, 0);
- }
+ return NextInvokeInsnSP(cu, info, kQuickInvokeSuperTrampolineWithAccessCheck, state,
+ target_method, 0);
}
static int NextVCallInsnSP(CompilationUnit* cu, CallInfo* info, int state,
const MethodReference& target_method,
uint32_t unused, uintptr_t unused2,
uintptr_t unused3, InvokeType unused4) {
- if (cu->target64) {
- ThreadOffset<8> trampoline = QUICK_ENTRYPOINT_OFFSET(8,
- pInvokeVirtualTrampolineWithAccessCheck);
- return NextInvokeInsnSP<8>(cu, info, trampoline, state, target_method, 0);
- } else {
- ThreadOffset<4> trampoline = QUICK_ENTRYPOINT_OFFSET(4,
- pInvokeVirtualTrampolineWithAccessCheck);
- return NextInvokeInsnSP<4>(cu, info, trampoline, state, target_method, 0);
- }
+ return NextInvokeInsnSP(cu, info, kQuickInvokeVirtualTrampolineWithAccessCheck, state,
+ target_method, 0);
}
static int NextInterfaceCallInsnWithAccessCheck(CompilationUnit* cu,
@@ -810,15 +716,8 @@
const MethodReference& target_method,
uint32_t unused, uintptr_t unused2,
uintptr_t unused3, InvokeType unused4) {
- if (cu->target64) {
- ThreadOffset<8> trampoline = QUICK_ENTRYPOINT_OFFSET(8,
- pInvokeInterfaceTrampolineWithAccessCheck);
- return NextInvokeInsnSP<8>(cu, info, trampoline, state, target_method, 0);
- } else {
- ThreadOffset<4> trampoline = QUICK_ENTRYPOINT_OFFSET(4,
- pInvokeInterfaceTrampolineWithAccessCheck);
- return NextInvokeInsnSP<4>(cu, info, trampoline, state, target_method, 0);
- }
+ return NextInvokeInsnSP(cu, info, kQuickInvokeInterfaceTrampolineWithAccessCheck, state,
+ target_method, 0);
}
int Mir2Lir::LoadArgRegs(CallInfo* info, int call_state,
@@ -1184,13 +1083,8 @@
// Generate memcpy
OpRegRegImm(kOpAdd, TargetReg(kArg0, kRef), TargetPtrReg(kSp), outs_offset);
OpRegRegImm(kOpAdd, TargetReg(kArg1, kRef), TargetPtrReg(kSp), start_offset);
- if (cu_->target64) {
- CallRuntimeHelperRegRegImm(QUICK_ENTRYPOINT_OFFSET(8, pMemcpy), TargetReg(kArg0, kRef),
- TargetReg(kArg1, kRef), (info->num_arg_words - 3) * 4, false);
- } else {
- CallRuntimeHelperRegRegImm(QUICK_ENTRYPOINT_OFFSET(4, pMemcpy), TargetReg(kArg0, kRef),
- TargetReg(kArg1, kRef), (info->num_arg_words - 3) * 4, false);
- }
+ CallRuntimeHelperRegRegImm(kQuickMemcpy, TargetReg(kArg0, kRef), TargetReg(kArg1, kRef),
+ (info->num_arg_words - 3) * 4, false);
}
call_state = LoadArgRegs(info, call_state, next_call_insn,
@@ -1345,55 +1239,30 @@
RegLocation rl_obj = info->args[0];
RegLocation rl_idx = info->args[1];
rl_obj = LoadValue(rl_obj, kRefReg);
- // X86 wants to avoid putting a constant index into a register.
- if (!((cu_->instruction_set == kX86 || cu_->instruction_set == kX86_64)&& rl_idx.is_const)) {
- rl_idx = LoadValue(rl_idx, kCoreReg);
- }
+ rl_idx = LoadValue(rl_idx, kCoreReg);
RegStorage reg_max;
GenNullCheck(rl_obj.reg, info->opt_flags);
bool range_check = (!(info->opt_flags & MIR_IGNORE_RANGE_CHECK));
LIR* range_check_branch = nullptr;
RegStorage reg_off;
RegStorage reg_ptr;
- if (cu_->instruction_set != kX86 && cu_->instruction_set != kX86_64) {
- reg_off = AllocTemp();
- reg_ptr = AllocTempRef();
- if (range_check) {
- reg_max = AllocTemp();
- Load32Disp(rl_obj.reg, count_offset, reg_max);
- MarkPossibleNullPointerException(info->opt_flags);
- }
- Load32Disp(rl_obj.reg, offset_offset, reg_off);
+ reg_off = AllocTemp();
+ reg_ptr = AllocTempRef();
+ if (range_check) {
+ reg_max = AllocTemp();
+ Load32Disp(rl_obj.reg, count_offset, reg_max);
MarkPossibleNullPointerException(info->opt_flags);
- LoadRefDisp(rl_obj.reg, value_offset, reg_ptr, kNotVolatile);
- if (range_check) {
- // Set up a slow path to allow retry in case of bounds violation */
- OpRegReg(kOpCmp, rl_idx.reg, reg_max);
- FreeTemp(reg_max);
- range_check_branch = OpCondBranch(kCondUge, nullptr);
- }
- OpRegImm(kOpAdd, reg_ptr, data_offset);
- } else {
- if (range_check) {
- // On x86, we can compare to memory directly
- // Set up a launch pad to allow retry in case of bounds violation */
- if (rl_idx.is_const) {
- LIR* comparison;
- range_check_branch = OpCmpMemImmBranch(
- kCondUlt, RegStorage::InvalidReg(), rl_obj.reg, count_offset,
- mir_graph_->ConstantValue(rl_idx.orig_sreg), nullptr, &comparison);
- MarkPossibleNullPointerExceptionAfter(0, comparison);
- } else {
- OpRegMem(kOpCmp, rl_idx.reg, rl_obj.reg, count_offset);
- MarkPossibleNullPointerException(0);
- range_check_branch = OpCondBranch(kCondUge, nullptr);
- }
- }
- reg_off = AllocTemp();
- reg_ptr = AllocTempRef();
- Load32Disp(rl_obj.reg, offset_offset, reg_off);
- LoadRefDisp(rl_obj.reg, value_offset, reg_ptr, kNotVolatile);
}
+ Load32Disp(rl_obj.reg, offset_offset, reg_off);
+ MarkPossibleNullPointerException(info->opt_flags);
+ LoadRefDisp(rl_obj.reg, value_offset, reg_ptr, kNotVolatile);
+ if (range_check) {
+ // Set up a slow path to allow retry in case of bounds violation */
+ OpRegReg(kOpCmp, rl_idx.reg, reg_max);
+ FreeTemp(reg_max);
+ range_check_branch = OpCondBranch(kCondUge, nullptr);
+ }
+ OpRegImm(kOpAdd, reg_ptr, data_offset);
if (rl_idx.is_const) {
OpRegImm(kOpAdd, reg_off, mir_graph_->ConstantValue(rl_idx.orig_sreg));
} else {
@@ -1405,11 +1274,7 @@
}
RegLocation rl_dest = InlineTarget(info);
RegLocation rl_result = EvalLoc(rl_dest, kCoreReg, true);
- if (cu_->instruction_set != kX86 && cu_->instruction_set != kX86_64) {
- LoadBaseIndexed(reg_ptr, reg_off, rl_result.reg, 1, kUnsignedHalf);
- } else {
- LoadBaseIndexedDisp(reg_ptr, reg_off, 1, data_offset, rl_result.reg, kUnsignedHalf);
- }
+ LoadBaseIndexed(reg_ptr, reg_off, rl_result.reg, 1, kUnsignedHalf);
FreeTemp(reg_off);
FreeTemp(reg_ptr);
StoreValue(rl_dest, rl_result);
@@ -1624,9 +1489,7 @@
RegLocation rl_start = info->args[2]; // 3rd arg only present in III flavor of IndexOf.
LoadValueDirectFixed(rl_start, reg_start);
}
- RegStorage r_tgt = cu_->target64 ?
- LoadHelper(QUICK_ENTRYPOINT_OFFSET(8, pIndexOf)) :
- LoadHelper(QUICK_ENTRYPOINT_OFFSET(4, pIndexOf));
+ RegStorage r_tgt = LoadHelper(kQuickIndexOf);
GenExplicitNullCheck(reg_ptr, info->opt_flags);
LIR* high_code_point_branch =
rl_char.is_const ? nullptr : OpCmpImmBranch(kCondGt, reg_char, 0xFFFF, nullptr);
@@ -1665,11 +1528,7 @@
LoadValueDirectFixed(rl_cmp, reg_cmp);
RegStorage r_tgt;
if (cu_->instruction_set != kX86 && cu_->instruction_set != kX86_64) {
- if (cu_->target64) {
- r_tgt = LoadHelper(QUICK_ENTRYPOINT_OFFSET(8, pStringCompareTo));
- } else {
- r_tgt = LoadHelper(QUICK_ENTRYPOINT_OFFSET(4, pStringCompareTo));
- }
+ r_tgt = LoadHelper(kQuickStringCompareTo);
} else {
r_tgt = RegStorage::InvalidReg();
}
@@ -1679,15 +1538,7 @@
LIR* cmp_null_check_branch = OpCmpImmBranch(kCondEq, reg_cmp, 0, nullptr);
AddIntrinsicSlowPath(info, cmp_null_check_branch);
// NOTE: not a safepoint
- if (cu_->instruction_set != kX86 && cu_->instruction_set != kX86_64) {
- OpReg(kOpBlx, r_tgt);
- } else {
- if (cu_->target64) {
- OpThreadMem(kOpBlx, QUICK_ENTRYPOINT_OFFSET(8, pStringCompareTo));
- } else {
- OpThreadMem(kOpBlx, QUICK_ENTRYPOINT_OFFSET(4, pStringCompareTo));
- }
- }
+ CallHelper(r_tgt, kQuickStringCompareTo, false, true);
RegLocation rl_return = GetReturn(kCoreReg);
RegLocation rl_dest = InlineTarget(info);
StoreValue(rl_dest, rl_return);
@@ -1850,29 +1701,29 @@
GenInvokeNoInline(info);
}
-template <size_t pointer_size>
static LIR* GenInvokeNoInlineCall(Mir2Lir* mir_to_lir, InvokeType type) {
- ThreadOffset<pointer_size> trampoline(-1);
+ QuickEntrypointEnum trampoline;
switch (type) {
case kInterface:
- trampoline = QUICK_ENTRYPOINT_OFFSET(pointer_size, pInvokeInterfaceTrampolineWithAccessCheck);
+ trampoline = kQuickInvokeInterfaceTrampolineWithAccessCheck;
break;
case kDirect:
- trampoline = QUICK_ENTRYPOINT_OFFSET(pointer_size, pInvokeDirectTrampolineWithAccessCheck);
+ trampoline = kQuickInvokeDirectTrampolineWithAccessCheck;
break;
case kStatic:
- trampoline = QUICK_ENTRYPOINT_OFFSET(pointer_size, pInvokeStaticTrampolineWithAccessCheck);
+ trampoline = kQuickInvokeStaticTrampolineWithAccessCheck;
break;
case kSuper:
- trampoline = QUICK_ENTRYPOINT_OFFSET(pointer_size, pInvokeSuperTrampolineWithAccessCheck);
+ trampoline = kQuickInvokeSuperTrampolineWithAccessCheck;
break;
case kVirtual:
- trampoline = QUICK_ENTRYPOINT_OFFSET(pointer_size, pInvokeVirtualTrampolineWithAccessCheck);
+ trampoline = kQuickInvokeVirtualTrampolineWithAccessCheck;
break;
default:
LOG(FATAL) << "Unexpected invoke type";
+ trampoline = kQuickInvokeInterfaceTrampolineWithAccessCheck;
}
- return mir_to_lir->OpThreadMem(kOpBlx, trampoline);
+ return mir_to_lir->InvokeTrampoline(kOpBlx, RegStorage::InvalidReg(), trampoline);
}
void Mir2Lir::GenInvokeNoInline(CallInfo* info) {
@@ -1943,12 +1794,7 @@
mirror::ArtMethod::EntryPointFromQuickCompiledCodeOffset().Int32Value());
}
} else {
- // TODO: Extract?
- if (cu_->target64) {
- call_inst = GenInvokeNoInlineCall<8>(this, info->type);
- } else {
- call_inst = GenInvokeNoInlineCall<4>(this, info->type);
- }
+ call_inst = GenInvokeNoInlineCall(this, info->type);
}
}
EndInvoke(info);
diff --git a/compiler/dex/quick/mips/call_mips.cc b/compiler/dex/quick/mips/call_mips.cc
index 26ea6a8..9adddf0 100644
--- a/compiler/dex/quick/mips/call_mips.cc
+++ b/compiler/dex/quick/mips/call_mips.cc
@@ -245,7 +245,7 @@
GenBarrier();
NewLIR0(kMipsCurrPC); // Really a jal to .+8
// Now, fill the branch delay slot with the helper load
- RegStorage r_tgt = LoadHelper(QUICK_ENTRYPOINT_OFFSET(4, pHandleFillArrayData));
+ RegStorage r_tgt = LoadHelper(kQuickHandleFillArrayData);
GenBarrier(); // Scheduling barrier
// Construct BaseLabel and set up table base register
@@ -332,9 +332,9 @@
m2l_->Load32Disp(rs_rMIPS_SP, 0, rs_rRA);
m2l_->OpRegImm(kOpAdd, rs_rMIPS_SP, sp_displace_);
m2l_->ClobberCallerSave();
- ThreadOffset<4> func_offset = QUICK_ENTRYPOINT_OFFSET(4, pThrowStackOverflow);
- RegStorage r_tgt = m2l_->CallHelperSetup(func_offset); // Doesn't clobber LR.
- m2l_->CallHelper(r_tgt, func_offset, false /* MarkSafepointPC */, false /* UseLink */);
+ RegStorage r_tgt = m2l_->CallHelperSetup(kQuickThrowStackOverflow); // Doesn't clobber LR.
+ m2l_->CallHelper(r_tgt, kQuickThrowStackOverflow, false /* MarkSafepointPC */,
+ false /* UseLink */);
}
private:
diff --git a/compiler/dex/quick/mips/codegen_mips.h b/compiler/dex/quick/mips/codegen_mips.h
index bb18ad2..4bd2748 100644
--- a/compiler/dex/quick/mips/codegen_mips.h
+++ b/compiler/dex/quick/mips/codegen_mips.h
@@ -31,22 +31,17 @@
RegLocation rl_dest, int lit);
bool EasyMultiply(RegLocation rl_src, RegLocation rl_dest, int lit) OVERRIDE;
LIR* CheckSuspendUsingLoad() OVERRIDE;
- RegStorage LoadHelper(ThreadOffset<4> offset) OVERRIDE;
- RegStorage LoadHelper(ThreadOffset<8> offset) OVERRIDE;
+ RegStorage LoadHelper(QuickEntrypointEnum trampoline) OVERRIDE;
LIR* LoadBaseDisp(RegStorage r_base, int displacement, RegStorage r_dest,
OpSize size, VolatileKind is_volatile) OVERRIDE;
LIR* LoadBaseIndexed(RegStorage r_base, RegStorage r_index, RegStorage r_dest, int scale,
OpSize size) OVERRIDE;
- LIR* LoadBaseIndexedDisp(RegStorage r_base, RegStorage r_index, int scale, int displacement,
- RegStorage r_dest, OpSize size) OVERRIDE;
LIR* LoadConstantNoClobber(RegStorage r_dest, int value);
LIR* LoadConstantWide(RegStorage r_dest, int64_t value);
LIR* StoreBaseDisp(RegStorage r_base, int displacement, RegStorage r_src,
OpSize size, VolatileKind is_volatile) OVERRIDE;
LIR* StoreBaseIndexed(RegStorage r_base, RegStorage r_index, RegStorage r_src, int scale,
OpSize size) OVERRIDE;
- LIR* StoreBaseIndexedDisp(RegStorage r_base, RegStorage r_index, int scale, int displacement,
- RegStorage r_src, OpSize size) OVERRIDE;
LIR* GenAtomic64Load(RegStorage r_base, int displacement, RegStorage r_dest);
LIR* GenAtomic64Store(RegStorage r_base, int displacement, RegStorage r_src);
void MarkGCCard(RegStorage val_reg, RegStorage tgt_addr_reg);
@@ -166,7 +161,6 @@
void OpRegCopy(RegStorage r_dest, RegStorage r_src);
LIR* OpRegCopyNoInsert(RegStorage r_dest, RegStorage r_src);
LIR* OpRegImm(OpKind op, RegStorage r_dest_src1, int value);
- LIR* OpRegMem(OpKind op, RegStorage r_dest, RegStorage r_base, int offset);
LIR* OpRegReg(OpKind op, RegStorage r_dest_src1, RegStorage r_src2);
LIR* OpMovRegMem(RegStorage r_dest, RegStorage r_base, int offset, MoveType move_type);
LIR* OpMovMemReg(RegStorage r_base, int offset, RegStorage r_src, MoveType move_type);
@@ -174,14 +168,9 @@
LIR* OpRegRegImm(OpKind op, RegStorage r_dest, RegStorage r_src1, int value);
LIR* OpRegRegReg(OpKind op, RegStorage r_dest, RegStorage r_src1, RegStorage r_src2);
LIR* OpTestSuspend(LIR* target);
- LIR* OpThreadMem(OpKind op, ThreadOffset<4> thread_offset) OVERRIDE;
- LIR* OpThreadMem(OpKind op, ThreadOffset<8> thread_offset) OVERRIDE;
LIR* OpVldm(RegStorage r_base, int count);
LIR* OpVstm(RegStorage r_base, int count);
- void OpLea(RegStorage r_base, RegStorage reg1, RegStorage reg2, int scale, int offset);
void OpRegCopyWide(RegStorage dest, RegStorage src);
- void OpTlsCmp(ThreadOffset<4> offset, int val) OVERRIDE;
- void OpTlsCmp(ThreadOffset<8> offset, int val) OVERRIDE;
// TODO: collapse r_dest.
LIR* LoadBaseDispBody(RegStorage r_base, int displacement, RegStorage r_dest,
@@ -204,6 +193,8 @@
return false; // Wide FPRs are formed by pairing.
}
+ LIR* InvokeTrampoline(OpKind op, RegStorage r_tgt, QuickEntrypointEnum trampoline) OVERRIDE;
+
private:
void ConvertShortToLongBranch(LIR* lir);
RegLocation GenDivRem(RegLocation rl_dest, RegLocation rl_src1,
diff --git a/compiler/dex/quick/mips/fp_mips.cc b/compiler/dex/quick/mips/fp_mips.cc
index 7087be9..3a4128a 100644
--- a/compiler/dex/quick/mips/fp_mips.cc
+++ b/compiler/dex/quick/mips/fp_mips.cc
@@ -50,8 +50,7 @@
case Instruction::REM_FLOAT_2ADDR:
case Instruction::REM_FLOAT:
FlushAllRegs(); // Send everything to home location
- CallRuntimeHelperRegLocationRegLocation(QUICK_ENTRYPOINT_OFFSET(4, pFmodf), rl_src1, rl_src2,
- false);
+ CallRuntimeHelperRegLocationRegLocation(kQuickFmodf, rl_src1, rl_src2, false);
rl_result = GetReturn(kFPReg);
StoreValue(rl_dest, rl_result);
return;
@@ -93,8 +92,7 @@
case Instruction::REM_DOUBLE_2ADDR:
case Instruction::REM_DOUBLE:
FlushAllRegs(); // Send everything to home location
- CallRuntimeHelperRegLocationRegLocation(QUICK_ENTRYPOINT_OFFSET(4, pFmod), rl_src1, rl_src2,
- false);
+ CallRuntimeHelperRegLocationRegLocation(kQuickFmod, rl_src1, rl_src2, false);
rl_result = GetReturnWide(kFPReg);
StoreValueWide(rl_dest, rl_result);
return;
@@ -133,22 +131,22 @@
op = kMipsFcvtdw;
break;
case Instruction::FLOAT_TO_INT:
- GenConversionCall(QUICK_ENTRYPOINT_OFFSET(4, pF2iz), rl_dest, rl_src);
+ GenConversionCall(kQuickF2iz, rl_dest, rl_src);
return;
case Instruction::DOUBLE_TO_INT:
- GenConversionCall(QUICK_ENTRYPOINT_OFFSET(4, pD2iz), rl_dest, rl_src);
+ GenConversionCall(kQuickD2iz, rl_dest, rl_src);
return;
case Instruction::LONG_TO_DOUBLE:
- GenConversionCall(QUICK_ENTRYPOINT_OFFSET(4, pL2d), rl_dest, rl_src);
+ GenConversionCall(kQuickL2d, rl_dest, rl_src);
return;
case Instruction::FLOAT_TO_LONG:
- GenConversionCall(QUICK_ENTRYPOINT_OFFSET(4, pF2l), rl_dest, rl_src);
+ GenConversionCall(kQuickF2l, rl_dest, rl_src);
return;
case Instruction::LONG_TO_FLOAT:
- GenConversionCall(QUICK_ENTRYPOINT_OFFSET(4, pL2f), rl_dest, rl_src);
+ GenConversionCall(kQuickL2f, rl_dest, rl_src);
return;
case Instruction::DOUBLE_TO_LONG:
- GenConversionCall(QUICK_ENTRYPOINT_OFFSET(4, pD2l), rl_dest, rl_src);
+ GenConversionCall(kQuickD2l, rl_dest, rl_src);
return;
default:
LOG(FATAL) << "Unexpected opcode: " << opcode;
@@ -170,25 +168,26 @@
void MipsMir2Lir::GenCmpFP(Instruction::Code opcode, RegLocation rl_dest,
RegLocation rl_src1, RegLocation rl_src2) {
bool wide = true;
- ThreadOffset<4> offset(-1);
+ QuickEntrypointEnum target;
switch (opcode) {
case Instruction::CMPL_FLOAT:
- offset = QUICK_ENTRYPOINT_OFFSET(4, pCmplFloat);
+ target = kQuickCmplFloat;
wide = false;
break;
case Instruction::CMPG_FLOAT:
- offset = QUICK_ENTRYPOINT_OFFSET(4, pCmpgFloat);
+ target = kQuickCmpgFloat;
wide = false;
break;
case Instruction::CMPL_DOUBLE:
- offset = QUICK_ENTRYPOINT_OFFSET(4, pCmplDouble);
+ target = kQuickCmplDouble;
break;
case Instruction::CMPG_DOUBLE:
- offset = QUICK_ENTRYPOINT_OFFSET(4, pCmpgDouble);
+ target = kQuickCmpgDouble;
break;
default:
LOG(FATAL) << "Unexpected opcode: " << opcode;
+ target = kQuickCmplFloat;
}
FlushAllRegs();
LockCallTemps();
@@ -201,7 +200,7 @@
LoadValueDirectFixed(rl_src1, rs_rMIPS_FARG0);
LoadValueDirectFixed(rl_src2, rs_rMIPS_FARG2);
}
- RegStorage r_tgt = LoadHelper(offset);
+ RegStorage r_tgt = LoadHelper(target);
// NOTE: not a safepoint
OpReg(kOpBlx, r_tgt);
RegLocation rl_result = GetReturn(kCoreReg);
diff --git a/compiler/dex/quick/mips/int_mips.cc b/compiler/dex/quick/mips/int_mips.cc
index 054514e..d727615 100644
--- a/compiler/dex/quick/mips/int_mips.cc
+++ b/compiler/dex/quick/mips/int_mips.cc
@@ -273,19 +273,6 @@
return rl_dest;
}
-void MipsMir2Lir::OpLea(RegStorage r_base, RegStorage reg1, RegStorage reg2, int scale,
- int offset) {
- LOG(FATAL) << "Unexpected use of OpLea for Arm";
-}
-
-void MipsMir2Lir::OpTlsCmp(ThreadOffset<4> offset, int val) {
- LOG(FATAL) << "Unexpected use of OpTlsCmp for Arm";
-}
-
-void MipsMir2Lir::OpTlsCmp(ThreadOffset<8> offset, int val) {
- UNIMPLEMENTED(FATAL) << "Should not be called.";
-}
-
bool MipsMir2Lir::GenInlinedCas(CallInfo* info, bool is_long, bool is_object) {
DCHECK_NE(cu_->instruction_set, kThumb2);
return false;
diff --git a/compiler/dex/quick/mips/target_mips.cc b/compiler/dex/quick/mips/target_mips.cc
index 4ba94c4..bc91fbcd 100644
--- a/compiler/dex/quick/mips/target_mips.cc
+++ b/compiler/dex/quick/mips/target_mips.cc
@@ -476,17 +476,12 @@
* ensure that all branch instructions can be restarted if
* there is a trap in the shadow. Allocate a temp register.
*/
-RegStorage MipsMir2Lir::LoadHelper(ThreadOffset<4> offset) {
+RegStorage MipsMir2Lir::LoadHelper(QuickEntrypointEnum trampoline) {
// NOTE: native pointer.
- LoadWordDisp(rs_rMIPS_SELF, offset.Int32Value(), rs_rT9);
+ LoadWordDisp(rs_rMIPS_SELF, GetThreadOffset<4>(trampoline).Int32Value(), rs_rT9);
return rs_rT9;
}
-RegStorage MipsMir2Lir::LoadHelper(ThreadOffset<8> offset) {
- UNIMPLEMENTED(FATAL) << "Should not be called.";
- return RegStorage::InvalidReg();
-}
-
LIR* MipsMir2Lir::CheckSuspendUsingLoad() {
RegStorage tmp = AllocTemp();
// NOTE: native pointer.
@@ -503,7 +498,7 @@
LockCallTemps(); // Using fixed registers
RegStorage reg_ptr = TargetReg(kArg0);
OpRegRegImm(kOpAdd, reg_ptr, r_base, displacement);
- RegStorage r_tgt = LoadHelper(QUICK_ENTRYPOINT_OFFSET(4, pA64Load));
+ RegStorage r_tgt = LoadHelper(kQuickA64Load);
LIR *ret = OpReg(kOpBlx, r_tgt);
RegStorage reg_ret = RegStorage::MakeRegPair(TargetReg(kRet0), TargetReg(kRet1));
OpRegCopyWide(r_dest, reg_ret);
@@ -525,7 +520,7 @@
OpRegCopyWide(reg_value, temp_value);
FreeTemp(temp_ptr);
FreeTemp(temp_value);
- RegStorage r_tgt = LoadHelper(QUICK_ENTRYPOINT_OFFSET(4, pA64Store));
+ RegStorage r_tgt = LoadHelper(kQuickA64Store);
return OpReg(kOpBlx, r_tgt);
}
diff --git a/compiler/dex/quick/mips/utility_mips.cc b/compiler/dex/quick/mips/utility_mips.cc
index 0e8188b..7178ede 100644
--- a/compiler/dex/quick/mips/utility_mips.cc
+++ b/compiler/dex/quick/mips/utility_mips.cc
@@ -680,41 +680,18 @@
return store;
}
-LIR* MipsMir2Lir::OpThreadMem(OpKind op, ThreadOffset<4> thread_offset) {
- LOG(FATAL) << "Unexpected use of OpThreadMem for MIPS";
- return NULL;
-}
-
-LIR* MipsMir2Lir::OpThreadMem(OpKind op, ThreadOffset<8> thread_offset) {
- UNIMPLEMENTED(FATAL) << "Should not be called.";
- return nullptr;
-}
-
LIR* MipsMir2Lir::OpMem(OpKind op, RegStorage r_base, int disp) {
LOG(FATAL) << "Unexpected use of OpMem for MIPS";
return NULL;
}
-LIR* MipsMir2Lir::StoreBaseIndexedDisp(RegStorage r_base, RegStorage r_index, int scale,
- int displacement, RegStorage r_src, OpSize size) {
- LOG(FATAL) << "Unexpected use of StoreBaseIndexedDisp for MIPS";
- return NULL;
-}
-
-LIR* MipsMir2Lir::OpRegMem(OpKind op, RegStorage r_dest, RegStorage r_base, int offset) {
- LOG(FATAL) << "Unexpected use of OpRegMem for MIPS";
- return NULL;
-}
-
-LIR* MipsMir2Lir::LoadBaseIndexedDisp(RegStorage r_base, RegStorage r_index, int scale,
- int displacement, RegStorage r_dest, OpSize size) {
- LOG(FATAL) << "Unexpected use of LoadBaseIndexedDisp for MIPS";
- return NULL;
-}
-
LIR* MipsMir2Lir::OpCondBranch(ConditionCode cc, LIR* target) {
LOG(FATAL) << "Unexpected use of OpCondBranch for MIPS";
return NULL;
}
+LIR* MipsMir2Lir::InvokeTrampoline(OpKind op, RegStorage r_tgt, QuickEntrypointEnum trampoline) {
+ return OpReg(op, r_tgt);
+}
+
} // namespace art
diff --git a/compiler/dex/quick/mir_to_lir.h b/compiler/dex/quick/mir_to_lir.h
index f183dc9..b832223 100644
--- a/compiler/dex/quick/mir_to_lir.h
+++ b/compiler/dex/quick/mir_to_lir.h
@@ -28,6 +28,7 @@
#include "driver/compiler_driver.h"
#include "instruction_set.h"
#include "leb128.h"
+#include "entrypoints/quick/quick_entrypoints_enum.h"
#include "safe_map.h"
#include "utils/array_ref.h"
#include "utils/arena_allocator.h"
@@ -805,7 +806,6 @@
void MarkPossibleNullPointerExceptionAfter(int opt_flags, LIR* after);
void MarkPossibleStackOverflowException();
void ForceImplicitNullCheck(RegStorage reg, int opt_flags);
- LIR* GenImmedCheck(ConditionCode c_code, RegStorage reg, int imm_val, ThrowKind kind);
LIR* GenNullCheck(RegStorage m_reg, int opt_flags);
LIR* GenExplicitNullCheck(RegStorage m_reg, int opt_flags);
virtual void GenImplicitNullCheck(RegStorage reg, int opt_flags);
@@ -844,9 +844,7 @@
RegLocation rl_src, int lit);
void GenArithOpLong(Instruction::Code opcode, RegLocation rl_dest,
RegLocation rl_src1, RegLocation rl_src2);
- template <size_t pointer_size>
- void GenConversionCall(ThreadOffset<pointer_size> func_offset, RegLocation rl_dest,
- RegLocation rl_src);
+ void GenConversionCall(QuickEntrypointEnum trampoline, RegLocation rl_dest, RegLocation rl_src);
virtual void GenSuspendTest(int opt_flags);
virtual void GenSuspendTestAndBranch(int opt_flags, LIR* target);
@@ -856,66 +854,44 @@
RegLocation rl_src1, RegLocation rl_src2);
// Shared by all targets - implemented in gen_invoke.cc.
- template <size_t pointer_size>
- LIR* CallHelper(RegStorage r_tgt, ThreadOffset<pointer_size> helper_offset, bool safepoint_pc,
+ LIR* CallHelper(RegStorage r_tgt, QuickEntrypointEnum trampoline, bool safepoint_pc,
bool use_link = true);
- RegStorage CallHelperSetup(ThreadOffset<4> helper_offset);
- RegStorage CallHelperSetup(ThreadOffset<8> helper_offset);
- template <size_t pointer_size>
- void CallRuntimeHelper(ThreadOffset<pointer_size> helper_offset, bool safepoint_pc);
- template <size_t pointer_size>
- void CallRuntimeHelperImm(ThreadOffset<pointer_size> helper_offset, int arg0, bool safepoint_pc);
- template <size_t pointer_size>
- void CallRuntimeHelperReg(ThreadOffset<pointer_size> helper_offset, RegStorage arg0, bool safepoint_pc);
- template <size_t pointer_size>
- void CallRuntimeHelperRegLocation(ThreadOffset<pointer_size> helper_offset, RegLocation arg0,
+ RegStorage CallHelperSetup(QuickEntrypointEnum trampoline);
+
+ void CallRuntimeHelper(QuickEntrypointEnum trampoline, bool safepoint_pc);
+ void CallRuntimeHelperImm(QuickEntrypointEnum trampoline, int arg0, bool safepoint_pc);
+ void CallRuntimeHelperReg(QuickEntrypointEnum trampoline, RegStorage arg0, bool safepoint_pc);
+ void CallRuntimeHelperRegLocation(QuickEntrypointEnum trampoline, RegLocation arg0,
bool safepoint_pc);
- template <size_t pointer_size>
- void CallRuntimeHelperImmImm(ThreadOffset<pointer_size> helper_offset, int arg0, int arg1,
+ void CallRuntimeHelperImmImm(QuickEntrypointEnum trampoline, int arg0, int arg1,
bool safepoint_pc);
- template <size_t pointer_size>
- void CallRuntimeHelperImmRegLocation(ThreadOffset<pointer_size> helper_offset, int arg0,
- RegLocation arg1, bool safepoint_pc);
- template <size_t pointer_size>
- void CallRuntimeHelperRegLocationImm(ThreadOffset<pointer_size> helper_offset, RegLocation arg0,
- int arg1, bool safepoint_pc);
- template <size_t pointer_size>
- void CallRuntimeHelperImmReg(ThreadOffset<pointer_size> helper_offset, int arg0, RegStorage arg1,
+ void CallRuntimeHelperImmRegLocation(QuickEntrypointEnum trampoline, int arg0, RegLocation arg1,
+ bool safepoint_pc);
+ void CallRuntimeHelperRegLocationImm(QuickEntrypointEnum trampoline, RegLocation arg0, int arg1,
+ bool safepoint_pc);
+ void CallRuntimeHelperImmReg(QuickEntrypointEnum trampoline, int arg0, RegStorage arg1,
bool safepoint_pc);
- template <size_t pointer_size>
- void CallRuntimeHelperRegImm(ThreadOffset<pointer_size> helper_offset, RegStorage arg0, int arg1,
+ void CallRuntimeHelperRegImm(QuickEntrypointEnum trampoline, RegStorage arg0, int arg1,
bool safepoint_pc);
- template <size_t pointer_size>
- void CallRuntimeHelperImmMethod(ThreadOffset<pointer_size> helper_offset, int arg0,
+ void CallRuntimeHelperImmMethod(QuickEntrypointEnum trampoline, int arg0, bool safepoint_pc);
+ void CallRuntimeHelperRegMethod(QuickEntrypointEnum trampoline, RegStorage arg0,
bool safepoint_pc);
- template <size_t pointer_size>
- void CallRuntimeHelperRegMethod(ThreadOffset<pointer_size> helper_offset, RegStorage arg0,
- bool safepoint_pc);
- template <size_t pointer_size>
- void CallRuntimeHelperRegMethodRegLocation(ThreadOffset<pointer_size> helper_offset,
- RegStorage arg0, RegLocation arg2, bool safepoint_pc);
- template <size_t pointer_size>
- void CallRuntimeHelperRegLocationRegLocation(ThreadOffset<pointer_size> helper_offset,
- RegLocation arg0, RegLocation arg1,
- bool safepoint_pc);
- template <size_t pointer_size>
- void CallRuntimeHelperRegReg(ThreadOffset<pointer_size> helper_offset, RegStorage arg0,
- RegStorage arg1, bool safepoint_pc);
- template <size_t pointer_size>
- void CallRuntimeHelperRegRegImm(ThreadOffset<pointer_size> helper_offset, RegStorage arg0,
- RegStorage arg1, int arg2, bool safepoint_pc);
- template <size_t pointer_size>
- void CallRuntimeHelperImmMethodRegLocation(ThreadOffset<pointer_size> helper_offset, int arg0,
+ void CallRuntimeHelperRegMethodRegLocation(QuickEntrypointEnum trampoline, RegStorage arg0,
RegLocation arg2, bool safepoint_pc);
- template <size_t pointer_size>
- void CallRuntimeHelperImmMethodImm(ThreadOffset<pointer_size> helper_offset, int arg0, int arg2,
+ void CallRuntimeHelperRegLocationRegLocation(QuickEntrypointEnum trampoline, RegLocation arg0,
+ RegLocation arg1, bool safepoint_pc);
+ void CallRuntimeHelperRegReg(QuickEntrypointEnum trampoline, RegStorage arg0, RegStorage arg1,
+ bool safepoint_pc);
+ void CallRuntimeHelperRegRegImm(QuickEntrypointEnum trampoline, RegStorage arg0,
+ RegStorage arg1, int arg2, bool safepoint_pc);
+ void CallRuntimeHelperImmMethodRegLocation(QuickEntrypointEnum trampoline, int arg0,
+ RegLocation arg2, bool safepoint_pc);
+ void CallRuntimeHelperImmMethodImm(QuickEntrypointEnum trampoline, int arg0, int arg2,
bool safepoint_pc);
- template <size_t pointer_size>
- void CallRuntimeHelperImmRegLocationRegLocation(ThreadOffset<pointer_size> helper_offset,
- int arg0, RegLocation arg1, RegLocation arg2,
+ void CallRuntimeHelperImmRegLocationRegLocation(QuickEntrypointEnum trampoline, int arg0,
+ RegLocation arg1, RegLocation arg2,
bool safepoint_pc);
- template <size_t pointer_size>
- void CallRuntimeHelperRegLocationRegLocationRegLocation(ThreadOffset<pointer_size> helper_offset,
+ void CallRuntimeHelperRegLocationRegLocationRegLocation(QuickEntrypointEnum trampoline,
RegLocation arg0, RegLocation arg1,
RegLocation arg2,
bool safepoint_pc);
@@ -954,7 +930,7 @@
RegLocation InlineTargetWide(CallInfo* info);
bool GenInlinedGet(CallInfo* info);
- bool GenInlinedCharAt(CallInfo* info);
+ virtual bool GenInlinedCharAt(CallInfo* info);
bool GenInlinedStringIsEmptyOrLength(CallInfo* info, bool is_empty);
virtual bool GenInlinedReverseBits(CallInfo* info, OpSize size);
bool GenInlinedReverseBytes(CallInfo* info, OpSize size);
@@ -1132,23 +1108,18 @@
virtual bool EasyMultiply(RegLocation rl_src, RegLocation rl_dest, int lit) = 0;
virtual LIR* CheckSuspendUsingLoad() = 0;
- virtual RegStorage LoadHelper(ThreadOffset<4> offset) = 0;
- virtual RegStorage LoadHelper(ThreadOffset<8> offset) = 0;
+ virtual RegStorage LoadHelper(QuickEntrypointEnum trampoline) = 0;
virtual LIR* LoadBaseDisp(RegStorage r_base, int displacement, RegStorage r_dest,
OpSize size, VolatileKind is_volatile) = 0;
virtual LIR* LoadBaseIndexed(RegStorage r_base, RegStorage r_index, RegStorage r_dest,
int scale, OpSize size) = 0;
- virtual LIR* LoadBaseIndexedDisp(RegStorage r_base, RegStorage r_index, int scale,
- int displacement, RegStorage r_dest, OpSize size) = 0;
virtual LIR* LoadConstantNoClobber(RegStorage r_dest, int value) = 0;
virtual LIR* LoadConstantWide(RegStorage r_dest, int64_t value) = 0;
virtual LIR* StoreBaseDisp(RegStorage r_base, int displacement, RegStorage r_src,
OpSize size, VolatileKind is_volatile) = 0;
virtual LIR* StoreBaseIndexed(RegStorage r_base, RegStorage r_index, RegStorage r_src,
int scale, OpSize size) = 0;
- virtual LIR* StoreBaseIndexedDisp(RegStorage r_base, RegStorage r_index, int scale,
- int displacement, RegStorage r_src, OpSize size) = 0;
virtual void MarkGCCard(RegStorage val_reg, RegStorage tgt_addr_reg) = 0;
// Required for target - register utilities.
@@ -1399,7 +1370,6 @@
virtual void OpRegCopy(RegStorage r_dest, RegStorage r_src) = 0;
virtual LIR* OpRegCopyNoInsert(RegStorage r_dest, RegStorage r_src) = 0;
virtual LIR* OpRegImm(OpKind op, RegStorage r_dest_src1, int value) = 0;
- virtual LIR* OpRegMem(OpKind op, RegStorage r_dest, RegStorage r_base, int offset) = 0;
virtual LIR* OpRegReg(OpKind op, RegStorage r_dest_src1, RegStorage r_src2) = 0;
/**
@@ -1439,15 +1409,9 @@
virtual LIR* OpRegRegReg(OpKind op, RegStorage r_dest, RegStorage r_src1,
RegStorage r_src2) = 0;
virtual LIR* OpTestSuspend(LIR* target) = 0;
- virtual LIR* OpThreadMem(OpKind op, ThreadOffset<4> thread_offset) = 0;
- virtual LIR* OpThreadMem(OpKind op, ThreadOffset<8> thread_offset) = 0;
virtual LIR* OpVldm(RegStorage r_base, int count) = 0;
virtual LIR* OpVstm(RegStorage r_base, int count) = 0;
- virtual void OpLea(RegStorage r_base, RegStorage reg1, RegStorage reg2, int scale,
- int offset) = 0;
virtual void OpRegCopyWide(RegStorage dest, RegStorage src) = 0;
- virtual void OpTlsCmp(ThreadOffset<4> offset, int val) = 0;
- virtual void OpTlsCmp(ThreadOffset<8> offset, int val) = 0;
virtual bool InexpensiveConstantInt(int32_t value) = 0;
virtual bool InexpensiveConstantFloat(int32_t value) = 0;
virtual bool InexpensiveConstantLong(int64_t value) = 0;
@@ -1460,6 +1424,8 @@
// Temp workaround
void Workaround7250540(RegLocation rl_dest, RegStorage zero_reg);
+ virtual LIR* InvokeTrampoline(OpKind op, RegStorage r_tgt, QuickEntrypointEnum trampoline) = 0;
+
protected:
Mir2Lir(CompilationUnit* cu, MIRGraph* mir_graph, ArenaAllocator* arena);
diff --git a/compiler/dex/quick/x86/call_x86.cc b/compiler/dex/quick/x86/call_x86.cc
index 40dd9cc..15aae9e 100644
--- a/compiler/dex/quick/x86/call_x86.cc
+++ b/compiler/dex/quick/x86/call_x86.cc
@@ -171,13 +171,7 @@
}
NewLIR2(kX86PcRelAdr, payload.GetReg(), WrapPointer(tab_rec));
OpRegReg(kOpAdd, payload, method_start);
- if (cu_->target64) {
- CallRuntimeHelperRegReg(QUICK_ENTRYPOINT_OFFSET(8, pHandleFillArrayData), array_ptr,
- payload, true);
- } else {
- CallRuntimeHelperRegReg(QUICK_ENTRYPOINT_OFFSET(4, pHandleFillArrayData), array_ptr,
- payload, true);
- }
+ CallRuntimeHelperRegReg(kQuickHandleFillArrayData, array_ptr, payload, true);
}
void X86Mir2Lir::GenMoveException(RegLocation rl_dest) {
@@ -261,13 +255,8 @@
m2l_->OpRegImm(kOpAdd, rs_rX86_SP, sp_displace_);
m2l_->ClobberCallerSave();
// Assumes codegen and target are in thumb2 mode.
- if (cu_->target64) {
- m2l_->CallHelper(RegStorage::InvalidReg(), QUICK_ENTRYPOINT_OFFSET(8, pThrowStackOverflow),
- false /* MarkSafepointPC */, false /* UseLink */);
- } else {
- m2l_->CallHelper(RegStorage::InvalidReg(), QUICK_ENTRYPOINT_OFFSET(4, pThrowStackOverflow),
- false /* MarkSafepointPC */, false /* UseLink */);
- }
+ m2l_->CallHelper(RegStorage::InvalidReg(), kQuickThrowStackOverflow,
+ false /* MarkSafepointPC */, false /* UseLink */);
}
private:
diff --git a/compiler/dex/quick/x86/codegen_x86.h b/compiler/dex/quick/x86/codegen_x86.h
index 49c0a03..3bc79ad 100644
--- a/compiler/dex/quick/x86/codegen_x86.h
+++ b/compiler/dex/quick/x86/codegen_x86.h
@@ -68,14 +68,13 @@
RegLocation rl_dest, int lit);
bool EasyMultiply(RegLocation rl_src, RegLocation rl_dest, int lit) OVERRIDE;
LIR* CheckSuspendUsingLoad() OVERRIDE;
- RegStorage LoadHelper(ThreadOffset<4> offset) OVERRIDE;
- RegStorage LoadHelper(ThreadOffset<8> offset) OVERRIDE;
+ RegStorage LoadHelper(QuickEntrypointEnum trampoline) OVERRIDE;
LIR* LoadBaseDisp(RegStorage r_base, int displacement, RegStorage r_dest,
OpSize size, VolatileKind is_volatile) OVERRIDE;
LIR* LoadBaseIndexed(RegStorage r_base, RegStorage r_index, RegStorage r_dest, int scale,
OpSize size) OVERRIDE;
LIR* LoadBaseIndexedDisp(RegStorage r_base, RegStorage r_index, int scale, int displacement,
- RegStorage r_dest, OpSize size) OVERRIDE;
+ RegStorage r_dest, OpSize size);
LIR* LoadConstantNoClobber(RegStorage r_dest, int value);
LIR* LoadConstantWide(RegStorage r_dest, int64_t value);
LIR* StoreBaseDisp(RegStorage r_base, int displacement, RegStorage r_src,
@@ -83,7 +82,7 @@
LIR* StoreBaseIndexed(RegStorage r_base, RegStorage r_index, RegStorage r_src, int scale,
OpSize size) OVERRIDE;
LIR* StoreBaseIndexedDisp(RegStorage r_base, RegStorage r_index, int scale, int displacement,
- RegStorage r_src, OpSize size) OVERRIDE;
+ RegStorage r_src, OpSize size);
void MarkGCCard(RegStorage val_reg, RegStorage tgt_addr_reg);
void GenImplicitNullCheck(RegStorage reg, int opt_flags);
@@ -179,6 +178,7 @@
bool GenInlinedAbsDouble(CallInfo* info) OVERRIDE;
bool GenInlinedPeek(CallInfo* info, OpSize size);
bool GenInlinedPoke(CallInfo* info, OpSize size);
+ bool GenInlinedCharAt(CallInfo* info) OVERRIDE;
void GenNotLong(RegLocation rl_dest, RegLocation rl_src);
void GenNegLong(RegLocation rl_dest, RegLocation rl_src);
void GenOrLong(Instruction::Code opcode, RegLocation rl_dest, RegLocation rl_src1,
@@ -300,14 +300,14 @@
LIR* OpRegRegImm(OpKind op, RegStorage r_dest, RegStorage r_src1, int value);
LIR* OpRegRegReg(OpKind op, RegStorage r_dest, RegStorage r_src1, RegStorage r_src2);
LIR* OpTestSuspend(LIR* target);
- LIR* OpThreadMem(OpKind op, ThreadOffset<4> thread_offset) OVERRIDE;
- LIR* OpThreadMem(OpKind op, ThreadOffset<8> thread_offset) OVERRIDE;
+ LIR* OpThreadMem(OpKind op, ThreadOffset<4> thread_offset);
+ LIR* OpThreadMem(OpKind op, ThreadOffset<8> thread_offset);
LIR* OpVldm(RegStorage r_base, int count);
LIR* OpVstm(RegStorage r_base, int count);
void OpLea(RegStorage r_base, RegStorage reg1, RegStorage reg2, int scale, int offset);
void OpRegCopyWide(RegStorage dest, RegStorage src);
- void OpTlsCmp(ThreadOffset<4> offset, int val) OVERRIDE;
- void OpTlsCmp(ThreadOffset<8> offset, int val) OVERRIDE;
+ void OpTlsCmp(ThreadOffset<4> offset, int val);
+ void OpTlsCmp(ThreadOffset<8> offset, int val);
void OpRegThreadMem(OpKind op, RegStorage r_dest, ThreadOffset<4> thread_offset);
void OpRegThreadMem(OpKind op, RegStorage r_dest, ThreadOffset<8> thread_offset);
@@ -402,6 +402,8 @@
*/
std::vector<uint8_t>* ReturnCallFrameInformation();
+ LIR* InvokeTrampoline(OpKind op, RegStorage r_tgt, QuickEntrypointEnum trampoline) OVERRIDE;
+
protected:
// Casting of RegStorage
RegStorage As32BitReg(RegStorage reg) {
diff --git a/compiler/dex/quick/x86/fp_x86.cc b/compiler/dex/quick/x86/fp_x86.cc
index 62053fd..2920fb6 100755
--- a/compiler/dex/quick/x86/fp_x86.cc
+++ b/compiler/dex/quick/x86/fp_x86.cc
@@ -292,7 +292,7 @@
branch_normal->target = NewLIR0(kPseudoTargetLabel);
StoreValueWide(rl_dest, rl_result);
} else {
- GenConversionCall(QUICK_ENTRYPOINT_OFFSET(4, pF2l), rl_dest, rl_src);
+ GenConversionCall(kQuickF2l, rl_dest, rl_src);
}
return;
case Instruction::DOUBLE_TO_LONG:
@@ -317,7 +317,7 @@
branch_normal->target = NewLIR0(kPseudoTargetLabel);
StoreValueWide(rl_dest, rl_result);
} else {
- GenConversionCall(QUICK_ENTRYPOINT_OFFSET(4, pD2l), rl_dest, rl_src);
+ GenConversionCall(kQuickD2l, rl_dest, rl_src);
}
return;
default:
diff --git a/compiler/dex/quick/x86/int_x86.cc b/compiler/dex/quick/x86/int_x86.cc
index 724ee7e..b9abdbf 100755
--- a/compiler/dex/quick/x86/int_x86.cc
+++ b/compiler/dex/quick/x86/int_x86.cc
@@ -1142,14 +1142,10 @@
}
}
// Load array length to kArg1.
- m2l_->OpRegMem(kOpMov, m2l_->TargetReg(kArg1, kNotWide), array_base_, len_offset_);
- if (cu_->target64) {
- m2l_->CallRuntimeHelperRegReg(QUICK_ENTRYPOINT_OFFSET(8, pThrowArrayBounds),
- new_index, m2l_->TargetReg(kArg1, kNotWide), true);
- } else {
- m2l_->CallRuntimeHelperRegReg(QUICK_ENTRYPOINT_OFFSET(4, pThrowArrayBounds),
- new_index, m2l_->TargetReg(kArg1, kNotWide), true);
- }
+ X86Mir2Lir* x86_m2l = static_cast<X86Mir2Lir*>(m2l_);
+ x86_m2l->OpRegMem(kOpMov, m2l_->TargetReg(kArg1, kNotWide), array_base_, len_offset_);
+ x86_m2l->CallRuntimeHelperRegReg(kQuickThrowArrayBounds, new_index,
+ m2l_->TargetReg(kArg1, kNotWide), true);
}
private:
@@ -1182,17 +1178,11 @@
GenerateTargetLabel(kPseudoThrowTarget);
// Load array length to kArg1.
- m2l_->OpRegMem(kOpMov, m2l_->TargetReg(kArg1, kNotWide), array_base_, len_offset_);
- m2l_->LoadConstant(m2l_->TargetReg(kArg0, kNotWide), index_);
- if (cu_->target64) {
- m2l_->CallRuntimeHelperRegReg(QUICK_ENTRYPOINT_OFFSET(8, pThrowArrayBounds),
- m2l_->TargetReg(kArg0, kNotWide),
- m2l_->TargetReg(kArg1, kNotWide), true);
- } else {
- m2l_->CallRuntimeHelperRegReg(QUICK_ENTRYPOINT_OFFSET(4, pThrowArrayBounds),
- m2l_->TargetReg(kArg0, kNotWide),
- m2l_->TargetReg(kArg1, kNotWide), true);
- }
+ X86Mir2Lir* x86_m2l = static_cast<X86Mir2Lir*>(m2l_);
+ x86_m2l->OpRegMem(kOpMov, m2l_->TargetReg(kArg1, kNotWide), array_base_, len_offset_);
+ x86_m2l->LoadConstant(m2l_->TargetReg(kArg0, kNotWide), index_);
+ x86_m2l->CallRuntimeHelperRegReg(kQuickThrowArrayBounds, m2l_->TargetReg(kArg0, kNotWide),
+ m2l_->TargetReg(kArg1, kNotWide), true);
}
private:
diff --git a/compiler/dex/quick/x86/target_x86.cc b/compiler/dex/quick/x86/target_x86.cc
index 451ae8b..3111025 100755
--- a/compiler/dex/quick/x86/target_x86.cc
+++ b/compiler/dex/quick/x86/target_x86.cc
@@ -871,14 +871,8 @@
return new X86Mir2Lir(cu, mir_graph, arena);
}
-// Not used in x86
-RegStorage X86Mir2Lir::LoadHelper(ThreadOffset<4> offset) {
- LOG(FATAL) << "Unexpected use of LoadHelper in x86";
- return RegStorage::InvalidReg();
-}
-
-// Not used in x86
-RegStorage X86Mir2Lir::LoadHelper(ThreadOffset<8> offset) {
+// Not used in x86(-64)
+RegStorage X86Mir2Lir::LoadHelper(QuickEntrypointEnum trampoline) {
LOG(FATAL) << "Unexpected use of LoadHelper in x86";
return RegStorage::InvalidReg();
}
@@ -2716,4 +2710,69 @@
return call_state;
}
+bool X86Mir2Lir::GenInlinedCharAt(CallInfo* info) {
+ // Location of reference to data array
+ int value_offset = mirror::String::ValueOffset().Int32Value();
+ // Location of count
+ int count_offset = mirror::String::CountOffset().Int32Value();
+ // Starting offset within data array
+ int offset_offset = mirror::String::OffsetOffset().Int32Value();
+ // Start of char data with array_
+ int data_offset = mirror::Array::DataOffset(sizeof(uint16_t)).Int32Value();
+
+ RegLocation rl_obj = info->args[0];
+ RegLocation rl_idx = info->args[1];
+ rl_obj = LoadValue(rl_obj, kRefReg);
+ // X86 wants to avoid putting a constant index into a register.
+ if (!rl_idx.is_const) {
+ rl_idx = LoadValue(rl_idx, kCoreReg);
+ }
+ RegStorage reg_max;
+ GenNullCheck(rl_obj.reg, info->opt_flags);
+ bool range_check = (!(info->opt_flags & MIR_IGNORE_RANGE_CHECK));
+ LIR* range_check_branch = nullptr;
+ RegStorage reg_off;
+ RegStorage reg_ptr;
+ if (range_check) {
+ // On x86, we can compare to memory directly
+ // Set up a launch pad to allow retry in case of bounds violation */
+ if (rl_idx.is_const) {
+ LIR* comparison;
+ range_check_branch = OpCmpMemImmBranch(
+ kCondUlt, RegStorage::InvalidReg(), rl_obj.reg, count_offset,
+ mir_graph_->ConstantValue(rl_idx.orig_sreg), nullptr, &comparison);
+ MarkPossibleNullPointerExceptionAfter(0, comparison);
+ } else {
+ OpRegMem(kOpCmp, rl_idx.reg, rl_obj.reg, count_offset);
+ MarkPossibleNullPointerException(0);
+ range_check_branch = OpCondBranch(kCondUge, nullptr);
+ }
+ }
+ reg_off = AllocTemp();
+ reg_ptr = AllocTempRef();
+ Load32Disp(rl_obj.reg, offset_offset, reg_off);
+ LoadRefDisp(rl_obj.reg, value_offset, reg_ptr, kNotVolatile);
+ if (rl_idx.is_const) {
+ OpRegImm(kOpAdd, reg_off, mir_graph_->ConstantValue(rl_idx.orig_sreg));
+ } else {
+ OpRegReg(kOpAdd, reg_off, rl_idx.reg);
+ }
+ FreeTemp(rl_obj.reg);
+ if (rl_idx.location == kLocPhysReg) {
+ FreeTemp(rl_idx.reg);
+ }
+ RegLocation rl_dest = InlineTarget(info);
+ RegLocation rl_result = EvalLoc(rl_dest, kCoreReg, true);
+ LoadBaseIndexedDisp(reg_ptr, reg_off, 1, data_offset, rl_result.reg, kUnsignedHalf);
+ FreeTemp(reg_off);
+ FreeTemp(reg_ptr);
+ StoreValue(rl_dest, rl_result);
+ if (range_check) {
+ DCHECK(range_check_branch != nullptr);
+ info->opt_flags |= MIR_IGNORE_NULL_CHECK; // Record that we've already null checked.
+ AddIntrinsicSlowPath(info, range_check_branch);
+ }
+ return true;
+}
+
} // namespace art
diff --git a/compiler/dex/quick/x86/utility_x86.cc b/compiler/dex/quick/x86/utility_x86.cc
index bae01d9..ccffe5b 100644
--- a/compiler/dex/quick/x86/utility_x86.cc
+++ b/compiler/dex/quick/x86/utility_x86.cc
@@ -1059,4 +1059,13 @@
}
}
}
+
+LIR* X86Mir2Lir::InvokeTrampoline(OpKind op, RegStorage r_tgt, QuickEntrypointEnum trampoline) {
+ if (cu_->target64) {
+ return OpThreadMem(op, GetThreadOffset<8>(trampoline));
+ } else {
+ return OpThreadMem(op, GetThreadOffset<4>(trampoline));
+ }
+}
+
} // namespace art
diff --git a/runtime/entrypoints/quick/quick_entrypoints.h b/runtime/entrypoints/quick/quick_entrypoints.h
index 473687c..8c108a8 100644
--- a/runtime/entrypoints/quick/quick_entrypoints.h
+++ b/runtime/entrypoints/quick/quick_entrypoints.h
@@ -37,111 +37,11 @@
// Pointers to functions that are called by quick compiler generated code via thread-local storage.
struct PACKED(4) QuickEntryPoints {
- // Alloc
- void* (*pAllocArray)(uint32_t, void*, int32_t);
- void* (*pAllocArrayResolved)(void*, void*, int32_t);
- void* (*pAllocArrayWithAccessCheck)(uint32_t, void*, int32_t);
- void* (*pAllocObject)(uint32_t, void*);
- void* (*pAllocObjectResolved)(void*, void*);
- void* (*pAllocObjectInitialized)(void*, void*);
- void* (*pAllocObjectWithAccessCheck)(uint32_t, void*);
- void* (*pCheckAndAllocArray)(uint32_t, void*, int32_t);
- void* (*pCheckAndAllocArrayWithAccessCheck)(uint32_t, void*, int32_t);
-
- // Cast
- uint32_t (*pInstanceofNonTrivial)(const mirror::Class*, const mirror::Class*);
- void (*pCheckCast)(void*, void*);
-
- // DexCache
- void* (*pInitializeStaticStorage)(uint32_t, void*);
- void* (*pInitializeTypeAndVerifyAccess)(uint32_t, void*);
- void* (*pInitializeType)(uint32_t, void*);
- void* (*pResolveString)(void*, uint32_t);
-
- // Field
- int (*pSet32Instance)(uint32_t, void*, int32_t); // field_idx, obj, src
- int (*pSet32Static)(uint32_t, int32_t);
- int (*pSet64Instance)(uint32_t, void*, int64_t);
- int (*pSet64Static)(uint32_t, int64_t);
- int (*pSetObjInstance)(uint32_t, void*, void*);
- int (*pSetObjStatic)(uint32_t, void*);
- int32_t (*pGet32Instance)(uint32_t, void*);
- int32_t (*pGet32Static)(uint32_t);
- int64_t (*pGet64Instance)(uint32_t, void*);
- int64_t (*pGet64Static)(uint32_t);
- void* (*pGetObjInstance)(uint32_t, void*);
- void* (*pGetObjStatic)(uint32_t);
-
- // Array
- void (*pAputObjectWithNullAndBoundCheck)(void*, uint32_t, void*); // array, index, src
- void (*pAputObjectWithBoundCheck)(void*, uint32_t, void*); // array, index, src
- void (*pAputObject)(void*, uint32_t, void*); // array, index, src
- void (*pHandleFillArrayData)(void*, void*);
-
- // JNI
- uint32_t (*pJniMethodStart)(Thread*);
- uint32_t (*pJniMethodStartSynchronized)(jobject to_lock, Thread* self);
- void (*pJniMethodEnd)(uint32_t cookie, Thread* self);
- void (*pJniMethodEndSynchronized)(uint32_t cookie, jobject locked, Thread* self);
- mirror::Object* (*pJniMethodEndWithReference)(jobject result, uint32_t cookie, Thread* self);
- mirror::Object* (*pJniMethodEndWithReferenceSynchronized)(jobject result, uint32_t cookie,
- jobject locked, Thread* self);
- void (*pQuickGenericJniTrampoline)(mirror::ArtMethod*);
-
- // Locks
- void (*pLockObject)(void*);
- void (*pUnlockObject)(void*);
-
- // Math
- int32_t (*pCmpgDouble)(double, double);
- int32_t (*pCmpgFloat)(float, float);
- int32_t (*pCmplDouble)(double, double);
- int32_t (*pCmplFloat)(float, float);
- double (*pFmod)(double, double);
- double (*pL2d)(int64_t);
- float (*pFmodf)(float, float);
- float (*pL2f)(int64_t);
- int32_t (*pD2iz)(double);
- int32_t (*pF2iz)(float);
- int32_t (*pIdivmod)(int32_t, int32_t);
- int64_t (*pD2l)(double);
- int64_t (*pF2l)(float);
- int64_t (*pLdiv)(int64_t, int64_t);
- int64_t (*pLmod)(int64_t, int64_t);
- int64_t (*pLmul)(int64_t, int64_t);
- uint64_t (*pShlLong)(uint64_t, uint32_t);
- uint64_t (*pShrLong)(uint64_t, uint32_t);
- uint64_t (*pUshrLong)(uint64_t, uint32_t);
-
- // Intrinsics
- int32_t (*pIndexOf)(void*, uint32_t, uint32_t, uint32_t);
- int32_t (*pStringCompareTo)(void*, void*);
- void* (*pMemcpy)(void*, const void*, size_t);
-
- // Invocation
- void (*pQuickImtConflictTrampoline)(mirror::ArtMethod*);
- void (*pQuickResolutionTrampoline)(mirror::ArtMethod*);
- void (*pQuickToInterpreterBridge)(mirror::ArtMethod*);
- void (*pInvokeDirectTrampolineWithAccessCheck)(uint32_t, void*);
- void (*pInvokeInterfaceTrampolineWithAccessCheck)(uint32_t, void*);
- void (*pInvokeStaticTrampolineWithAccessCheck)(uint32_t, void*);
- void (*pInvokeSuperTrampolineWithAccessCheck)(uint32_t, void*);
- void (*pInvokeVirtualTrampolineWithAccessCheck)(uint32_t, void*);
-
- // Thread
- void (*pTestSuspend)(); // Stub that is periodically called to test the suspend count
-
- // Throws
- void (*pDeliverException)(void*);
- void (*pThrowArrayBounds)(int32_t, int32_t);
- void (*pThrowDivZero)();
- void (*pThrowNoSuchMethod)(int32_t);
- void (*pThrowNullPointer)();
- void (*pThrowStackOverflow)(void*);
-
- // Atomic 64-bit load/store
- int64_t (*pA64Load)(volatile const int64_t *);
- void (*pA64Store)(volatile int64_t *, int64_t);
+#define ENTRYPOINT_ENUM(name, rettype, ...) rettype ( * p ## name )( __VA_ARGS__ );
+#include "quick_entrypoints_list.h"
+ QUICK_ENTRYPOINT_LIST(ENTRYPOINT_ENUM)
+#undef QUICK_ENTRYPOINT_LIST
+#undef ENTRYPOINT_ENUM
};
diff --git a/runtime/entrypoints/quick/quick_entrypoints_enum.h b/runtime/entrypoints/quick/quick_entrypoints_enum.h
new file mode 100644
index 0000000..84158cd
--- /dev/null
+++ b/runtime/entrypoints/quick/quick_entrypoints_enum.h
@@ -0,0 +1,56 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ART_RUNTIME_ENTRYPOINTS_QUICK_QUICK_ENTRYPOINTS_ENUM_H_
+#define ART_RUNTIME_ENTRYPOINTS_QUICK_QUICK_ENTRYPOINTS_ENUM_H_
+
+#include "quick_entrypoints.h"
+#include "thread.h"
+
+namespace art {
+
+// Define an enum for the entrypoints. Names are prepended a 'kQuick'.
+enum QuickEntrypointEnum
+{ // NOLINT(whitespace/braces)
+#define ENTRYPOINT_ENUM(name, rettype, ...) kQuick ## name,
+#include "quick_entrypoints_list.h"
+ QUICK_ENTRYPOINT_LIST(ENTRYPOINT_ENUM)
+#undef QUICK_ENTRYPOINT_LIST
+#undef ENTRYPOINT_ENUM
+};
+
+std::ostream& operator<<(std::ostream& os, const QuickEntrypointEnum& kind);
+
+// Translate a QuickEntrypointEnum value to the corresponding ThreadOffset.
+template <size_t pointer_size>
+static ThreadOffset<pointer_size> GetThreadOffset(QuickEntrypointEnum trampoline) {
+ switch (trampoline)
+ { // NOLINT(whitespace/braces)
+ #define ENTRYPOINT_ENUM(name, rettype, ...) case kQuick ## name : \
+ return QUICK_ENTRYPOINT_OFFSET(pointer_size, p ## name);
+ #include "quick_entrypoints_list.h"
+ QUICK_ENTRYPOINT_LIST(ENTRYPOINT_ENUM)
+ #undef QUICK_ENTRYPOINT_LIST
+ #undef ENTRYPOINT_ENUM
+ };
+ LOG(FATAL) << "Unexpected trampoline " << static_cast<int>(trampoline);
+ return ThreadOffset<pointer_size>(-1);
+}
+
+} // namespace art
+
+
+#endif // ART_RUNTIME_ENTRYPOINTS_QUICK_QUICK_ENTRYPOINTS_ENUM_H_
diff --git a/runtime/entrypoints/quick/quick_entrypoints_list.h b/runtime/entrypoints/quick/quick_entrypoints_list.h
new file mode 100644
index 0000000..f858743
--- /dev/null
+++ b/runtime/entrypoints/quick/quick_entrypoints_list.h
@@ -0,0 +1,117 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ART_RUNTIME_ENTRYPOINTS_QUICK_QUICK_ENTRYPOINTS_LIST_H_
+#define ART_RUNTIME_ENTRYPOINTS_QUICK_QUICK_ENTRYPOINTS_LIST_H_
+
+// All quick entrypoints. Format is name, return type, argument types.
+
+#define QUICK_ENTRYPOINT_LIST(V) \
+ V(AllocArray, void*, uint32_t, void*, int32_t) \
+ V(AllocArrayResolved, void*, void*, void*, int32_t) \
+ V(AllocArrayWithAccessCheck, void*, uint32_t, void*, int32_t) \
+ V(AllocObject, void*, uint32_t, void*) \
+ V(AllocObjectResolved, void*, void*, void*) \
+ V(AllocObjectInitialized, void*, void*, void*) \
+ V(AllocObjectWithAccessCheck, void*, uint32_t, void*) \
+ V(CheckAndAllocArray, void*, uint32_t, void*, int32_t) \
+ V(CheckAndAllocArrayWithAccessCheck, void*, uint32_t, void*, int32_t) \
+\
+ V(InstanceofNonTrivial, uint32_t, const mirror::Class*, const mirror::Class*) \
+ V(CheckCast, void , void*, void*) \
+\
+ V(InitializeStaticStorage, void*, uint32_t, void*) \
+ V(InitializeTypeAndVerifyAccess, void*, uint32_t, void*) \
+ V(InitializeType, void*, uint32_t, void*) \
+ V(ResolveString, void*, void*, uint32_t) \
+\
+ V(Set32Instance, int, uint32_t, void*, int32_t) \
+ V(Set32Static, int, uint32_t, int32_t) \
+ V(Set64Instance, int, uint32_t, void*, int64_t) \
+ V(Set64Static, int, uint32_t, int64_t) \
+ V(SetObjInstance, int, uint32_t, void*, void*) \
+ V(SetObjStatic, int, uint32_t, void*) \
+ V(Get32Instance, int32_t, uint32_t, void*) \
+ V(Get32Static, int32_t, uint32_t) \
+ V(Get64Instance, int64_t, uint32_t, void*) \
+ V(Get64Static, int64_t, uint32_t) \
+ V(GetObjInstance, void*, uint32_t, void*) \
+ V(GetObjStatic, void*, uint32_t) \
+\
+ V(AputObjectWithNullAndBoundCheck, void, void*, uint32_t, void*) \
+ V(AputObjectWithBoundCheck, void, void*, uint32_t, void*) \
+ V(AputObject, void, void*, uint32_t, void*) \
+ V(HandleFillArrayData, void, void*, void*) \
+\
+ V(JniMethodStart, uint32_t, Thread*) \
+ V(JniMethodStartSynchronized, uint32_t, jobject to_lock, Thread* self) \
+ V(JniMethodEnd, void, uint32_t cookie, Thread* self) \
+ V(JniMethodEndSynchronized, void, uint32_t cookie, jobject locked, Thread* self) \
+ V(JniMethodEndWithReference, mirror::Object*, jobject result, uint32_t cookie, Thread* self) \
+ V(JniMethodEndWithReferenceSynchronized, mirror::Object*, jobject result, uint32_t cookie, jobject locked, Thread* self) \
+ V(QuickGenericJniTrampoline, void, mirror::ArtMethod*) \
+\
+ V(LockObject, void, void*) \
+ V(UnlockObject, void, void*) \
+\
+ V(CmpgDouble, int32_t, double, double) \
+ V(CmpgFloat, int32_t, float, float) \
+ V(CmplDouble, int32_t, double, double) \
+ V(CmplFloat, int32_t, float, float) \
+ V(Fmod, double, double, double) \
+ V(L2d, double, int64_t) \
+ V(Fmodf, float, float, float) \
+ V(L2f, float, int64_t) \
+ V(D2iz, int32_t, double) \
+ V(F2iz, int32_t, float) \
+ V(Idivmod, int32_t, int32_t, int32_t) \
+ V(D2l, int64_t, double) \
+ V(F2l, int64_t, float) \
+ V(Ldiv, int64_t, int64_t, int64_t) \
+ V(Lmod, int64_t, int64_t, int64_t) \
+ V(Lmul, int64_t, int64_t, int64_t) \
+ V(ShlLong, uint64_t, uint64_t, uint32_t) \
+ V(ShrLong, uint64_t, uint64_t, uint32_t) \
+ V(UshrLong, uint64_t, uint64_t, uint32_t) \
+\
+ V(IndexOf, int32_t, void*, uint32_t, uint32_t, uint32_t) \
+ V(StringCompareTo, int32_t, void*, void*) \
+ V(Memcpy, void*, void*, const void*, size_t) \
+\
+ V(QuickImtConflictTrampoline, void, mirror::ArtMethod*) \
+ V(QuickResolutionTrampoline, void, mirror::ArtMethod*) \
+ V(QuickToInterpreterBridge, void, mirror::ArtMethod*) \
+ V(InvokeDirectTrampolineWithAccessCheck, void, uint32_t, void*) \
+ V(InvokeInterfaceTrampolineWithAccessCheck, void, uint32_t, void*) \
+ V(InvokeStaticTrampolineWithAccessCheck, void, uint32_t, void*) \
+ V(InvokeSuperTrampolineWithAccessCheck, void, uint32_t, void*) \
+ V(InvokeVirtualTrampolineWithAccessCheck, void, uint32_t, void*) \
+\
+ V(TestSuspend, void, void) \
+\
+ V(DeliverException, void, void*) \
+ V(ThrowArrayBounds, void, int32_t, int32_t) \
+ V(ThrowDivZero, void, void) \
+ V(ThrowNoSuchMethod, void, int32_t) \
+ V(ThrowNullPointer, void, void) \
+ V(ThrowStackOverflow, void, void*) \
+\
+ V(A64Load, int64_t, volatile const int64_t *) \
+ V(A64Store, void, volatile int64_t *, int64_t)
+
+
+#endif // ART_RUNTIME_ENTRYPOINTS_QUICK_QUICK_ENTRYPOINTS_LIST_H_
+#undef ART_RUNTIME_ENTRYPOINTS_QUICK_QUICK_ENTRYPOINTS_LIST_H_ // #define is only for lint.