ART: Rework quick entrypoint code in Mir2Lir, cleanup
To reduce the complexity of calling trampolines in generic code,
introduce an enumeration for entrypoints. Introduce a header that lists
the entrypoint enum and exposes a templatized method that translates an
enum value to the corresponding thread offset value.
Call helpers are rewritten to have an enum parameter instead of the
thread offset. Also rewrite LoadHelper and GenConversionCall this way.
It is now LoadHelper's duty to select the right thread offset size.
Introduce InvokeTrampoline virtual method to Mir2Lir. This allows to
further simplify the call helpers, as well as make OpThreadMem specific
to X86 only (removed from Mir2Lir).
Make GenInlinedCharAt virtual, move a copy to X86 backend, and simplify
both copies. Remove LoadBaseIndexedDisp and OpRegMem from Mir2Lir, as they
are now specific to X86 only.
Remove StoreBaseIndexedDisp from Mir2Lir, as it was only ever used in the
X86 backend.
Remove OpTlsCmp from Mir2Lir, as it was only ever used in the X86 backend.
Remove OpLea from Mir2Lir, as it was only ever defined in the X86 backend.
Remove GenImmedCheck from Mir2Lir as it was neither used nor implemented.
Change-Id: If0a6182288c5d57653e3979bf547840a4c47626e
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..bc91fbc 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