diff options
Diffstat (limited to 'compiler')
-rw-r--r-- | compiler/dex/quick/arm/call_arm.cc | 12 | ||||
-rw-r--r-- | compiler/dex/quick/arm/codegen_arm.h | 1 | ||||
-rw-r--r-- | compiler/dex/quick/arm/fp_arm.cc | 8 | ||||
-rw-r--r-- | compiler/dex/quick/arm/int_arm.cc | 52 | ||||
-rw-r--r-- | compiler/dex/quick/gen_common.cc | 15 | ||||
-rw-r--r-- | compiler/dex/quick/mips/codegen_mips.h | 1 | ||||
-rw-r--r-- | compiler/dex/quick/mips/int_mips.cc | 5 | ||||
-rw-r--r-- | compiler/dex/quick/mir_to_lir.h | 1 | ||||
-rw-r--r-- | compiler/dex/quick/x86/codegen_x86.h | 1 | ||||
-rw-r--r-- | compiler/dex/quick/x86/int_x86.cc | 4 | ||||
-rw-r--r-- | compiler/oat_writer.cc | 7 | ||||
-rw-r--r-- | compiler/utils/arm64/assembler_arm64.h | 11 |
12 files changed, 71 insertions, 47 deletions
diff --git a/compiler/dex/quick/arm/call_arm.cc b/compiler/dex/quick/arm/call_arm.cc index 8c9f8ea..d0d0e6b 100644 --- a/compiler/dex/quick/arm/call_arm.cc +++ b/compiler/dex/quick/arm/call_arm.cc @@ -81,8 +81,9 @@ void ArmMir2Lir::GenSparseSwitch(MIR* mir, uint32_t table_offset, NewLIR2(kThumb2LdmiaWB, r_base.GetReg(), (1 << r_key.GetReg()) | (1 << r_disp.GetReg())); OpRegReg(kOpCmp, r_key, rl_src.reg); // Go if match. NOTE: No instruction set switch here - must stay Thumb2 - OpIT(kCondEq, ""); + LIR* it = OpIT(kCondEq, ""); LIR* switch_branch = NewLIR1(kThumb2AddPCR, r_disp.GetReg()); + OpEndIT(it); tab_rec->anchor = switch_branch; // Needs to use setflags encoding here OpRegRegImm(kOpSub, r_idx, r_idx, 1); // For value == 1, this should set flags. @@ -222,14 +223,16 @@ void ArmMir2Lir::GenMonitorEnter(int opt_flags, RegLocation rl_src) { NewLIR3(kThumb2Ldrex, r1, r0, mirror::Object::MonitorOffset().Int32Value() >> 2); MarkPossibleNullPointerException(opt_flags); OpRegImm(kOpCmp, rs_r1, 0); - OpIT(kCondEq, ""); + LIR* it = OpIT(kCondEq, ""); NewLIR4(kThumb2Strex/*eq*/, r1, r2, r0, mirror::Object::MonitorOffset().Int32Value() >> 2); + OpEndIT(it); OpRegImm(kOpCmp, rs_r1, 0); - OpIT(kCondNe, "T"); + it = OpIT(kCondNe, "T"); // Go expensive route - artLockObjectFromCode(self, obj); LoadWordDisp/*ne*/(rs_rARM_SELF, QUICK_ENTRYPOINT_OFFSET(4, pLockObject).Int32Value(), rs_rARM_LR); ClobberCallerSave(); LIR* call_inst = OpReg(kOpBlx/*ne*/, rs_rARM_LR); + OpEndIT(it); MarkSafepointPC(call_inst); GenMemBarrier(kLoadLoad); } @@ -287,13 +290,14 @@ void ArmMir2Lir::GenMonitorExit(int opt_flags, RegLocation rl_src) { LoadConstantNoClobber(rs_r3, 0); // Is lock unheld on lock or held by us (==thread_id) on unlock? OpRegReg(kOpCmp, rs_r1, rs_r2); - OpIT(kCondEq, "EE"); + LIR* it = OpIT(kCondEq, "EE"); StoreWordDisp/*eq*/(rs_r0, mirror::Object::MonitorOffset().Int32Value(), rs_r3); // Go expensive route - UnlockObjectFromCode(obj); LoadWordDisp/*ne*/(rs_rARM_SELF, QUICK_ENTRYPOINT_OFFSET(4, pUnlockObject).Int32Value(), rs_rARM_LR); ClobberCallerSave(); LIR* call_inst = OpReg(kOpBlx/*ne*/, rs_rARM_LR); + OpEndIT(it); MarkSafepointPC(call_inst); GenMemBarrier(kStoreLoad); } diff --git a/compiler/dex/quick/arm/codegen_arm.h b/compiler/dex/quick/arm/codegen_arm.h index 0ad2b70..13fa635 100644 --- a/compiler/dex/quick/arm/codegen_arm.h +++ b/compiler/dex/quick/arm/codegen_arm.h @@ -158,6 +158,7 @@ class ArmMir2Lir FINAL : public Mir2Lir { LIR* OpDecAndBranch(ConditionCode c_code, RegStorage reg, LIR* target); LIR* OpFpRegCopy(RegStorage r_dest, RegStorage r_src); LIR* OpIT(ConditionCode cond, const char* guide); + void OpEndIT(LIR* it); LIR* OpMem(OpKind op, RegStorage r_base, int disp); LIR* OpPcRelLoad(RegStorage reg, LIR* target); LIR* OpReg(OpKind op, RegStorage r_dest_src); diff --git a/compiler/dex/quick/arm/fp_arm.cc b/compiler/dex/quick/arm/fp_arm.cc index 07a13ce..d72f596 100644 --- a/compiler/dex/quick/arm/fp_arm.cc +++ b/compiler/dex/quick/arm/fp_arm.cc @@ -314,14 +314,14 @@ void ArmMir2Lir::GenCmpFP(Instruction::Code opcode, RegLocation rl_dest, DCHECK(!ARM_FPREG(rl_result.reg.GetReg())); NewLIR0(kThumb2Fmstat); - OpIT((default_result == -1) ? kCondGt : kCondMi, ""); + LIR* it = OpIT((default_result == -1) ? kCondGt : kCondMi, ""); NewLIR2(kThumb2MovI8M, rl_result.reg.GetReg(), ModifiedImmediate(-default_result)); // Must not alter ccodes - GenBarrier(); + OpEndIT(it); - OpIT(kCondEq, ""); + it = OpIT(kCondEq, ""); LoadConstant(rl_result.reg, 0); - GenBarrier(); + OpEndIT(it); StoreValue(rl_dest, rl_result); } diff --git a/compiler/dex/quick/arm/int_arm.cc b/compiler/dex/quick/arm/int_arm.cc index 8177999..1c563bb 100644 --- a/compiler/dex/quick/arm/int_arm.cc +++ b/compiler/dex/quick/arm/int_arm.cc @@ -67,6 +67,14 @@ LIR* ArmMir2Lir::OpIT(ConditionCode ccode, const char* guide) { return NewLIR2(kThumb2It, code, mask); } +void ArmMir2Lir::OpEndIT(LIR* it) { + // TODO: use the 'it' pointer to do some checks with the LIR, for example + // we could check that the number of instructions matches the mask + // in the IT instruction. + CHECK(it != nullptr); + GenBarrier(); +} + /* * 64-bit 3way compare function. * mov rX, #-1 @@ -96,10 +104,10 @@ void ArmMir2Lir::GenCmpLong(RegLocation rl_dest, RegLocation rl_src1, OpRegRegReg(kOpSub, t_reg, rl_src1.reg, rl_src2.reg); LIR* branch3 = OpCondBranch(kCondEq, NULL); - OpIT(kCondHi, "E"); + LIR* it = OpIT(kCondHi, "E"); NewLIR2(kThumb2MovI8M, t_reg.GetReg(), ModifiedImmediate(-1)); LoadConstant(t_reg, 1); - GenBarrier(); + OpEndIT(it); target2 = NewLIR0(kPseudoTargetLabel); OpRegReg(kOpNeg, t_reg, t_reg); @@ -187,21 +195,21 @@ void ArmMir2Lir::GenSelect(BasicBlock* bb, MIR* mir) { if (cheap_false_val && ccode == kCondEq && (true_val == 0 || true_val == -1)) { OpRegRegImm(kOpSub, rl_result.reg, rl_src.reg, -true_val); DCHECK(last_lir_insn_->u.m.def_mask & ENCODE_CCODE); - OpIT(true_val == 0 ? kCondNe : kCondUge, ""); + LIR* it = OpIT(true_val == 0 ? kCondNe : kCondUge, ""); LoadConstant(rl_result.reg, false_val); - GenBarrier(); // Add a scheduling barrier to keep the IT shadow intact + OpEndIT(it); // Add a scheduling barrier to keep the IT shadow intact } else if (cheap_false_val && ccode == kCondEq && true_val == 1) { OpRegRegImm(kOpRsub, rl_result.reg, rl_src.reg, 1); DCHECK(last_lir_insn_->u.m.def_mask & ENCODE_CCODE); - OpIT(kCondLs, ""); + LIR* it = OpIT(kCondLs, ""); LoadConstant(rl_result.reg, false_val); - GenBarrier(); // Add a scheduling barrier to keep the IT shadow intact + OpEndIT(it); // Add a scheduling barrier to keep the IT shadow intact } else if (cheap_false_val && InexpensiveConstantInt(true_val)) { OpRegImm(kOpCmp, rl_src.reg, 0); - OpIT(ccode, "E"); + LIR* it = OpIT(ccode, "E"); LoadConstant(rl_result.reg, true_val); LoadConstant(rl_result.reg, false_val); - GenBarrier(); // Add a scheduling barrier to keep the IT shadow intact + OpEndIT(it); // Add a scheduling barrier to keep the IT shadow intact } else { // Unlikely case - could be tuned. RegStorage t_reg1 = AllocTemp(); @@ -209,10 +217,10 @@ void ArmMir2Lir::GenSelect(BasicBlock* bb, MIR* mir) { LoadConstant(t_reg1, true_val); LoadConstant(t_reg2, false_val); OpRegImm(kOpCmp, rl_src.reg, 0); - OpIT(ccode, "E"); + LIR* it = OpIT(ccode, "E"); OpRegCopy(rl_result.reg, t_reg1); OpRegCopy(rl_result.reg, t_reg2); - GenBarrier(); // Add a scheduling barrier to keep the IT shadow intact + OpEndIT(it); // Add a scheduling barrier to keep the IT shadow intact } } else { // MOVE case @@ -222,18 +230,19 @@ void ArmMir2Lir::GenSelect(BasicBlock* bb, MIR* mir) { rl_false = LoadValue(rl_false, kCoreReg); rl_result = EvalLoc(rl_dest, kCoreReg, true); OpRegImm(kOpCmp, rl_src.reg, 0); + LIR* it = nullptr; if (rl_result.reg.GetReg() == rl_true.reg.GetReg()) { // Is the "true" case already in place? - OpIT(NegateComparison(ccode), ""); + it = OpIT(NegateComparison(ccode), ""); OpRegCopy(rl_result.reg, rl_false.reg); } else if (rl_result.reg.GetReg() == rl_false.reg.GetReg()) { // False case in place? - OpIT(ccode, ""); + it = OpIT(ccode, ""); OpRegCopy(rl_result.reg, rl_true.reg); } else { // Normal - select between the two. - OpIT(ccode, "E"); + it = OpIT(ccode, "E"); OpRegCopy(rl_result.reg, rl_true.reg); OpRegCopy(rl_result.reg, rl_false.reg); } - GenBarrier(); // Add a scheduling barrier to keep the IT shadow intact + OpEndIT(it); // Add a scheduling barrier to keep the IT shadow intact } StoreValue(rl_dest, rl_result); } @@ -623,10 +632,10 @@ bool ArmMir2Lir::GenInlinedMinMaxInt(CallInfo* info, bool is_min) { RegLocation rl_dest = InlineTarget(info); RegLocation rl_result = EvalLoc(rl_dest, kCoreReg, true); OpRegReg(kOpCmp, rl_src1.reg, rl_src2.reg); - OpIT((is_min) ? kCondGt : kCondLt, "E"); + LIR* it = OpIT((is_min) ? kCondGt : kCondLt, "E"); OpRegReg(kOpMov, rl_result.reg, rl_src2.reg); OpRegReg(kOpMov, rl_result.reg, rl_src1.reg); - GenBarrier(); + OpEndIT(it); StoreValue(rl_dest, rl_result); return true; } @@ -783,6 +792,7 @@ bool ArmMir2Lir::GenInlinedCas(CallInfo* info, bool is_long, bool is_object) { RegStorage r_tmp = AllocTemp(); LIR* target = NewLIR0(kPseudoTargetLabel); + LIR* it = nullptr; if (is_long) { RegStorage r_tmp_high = AllocTemp(); if (!load_early) { @@ -803,20 +813,20 @@ bool ArmMir2Lir::GenInlinedCas(CallInfo* info, bool is_long, bool is_object) { FreeTemp(r_tmp_high); // Now unneeded DCHECK(last_lir_insn_->u.m.def_mask & ENCODE_CCODE); - OpIT(kCondEq, "T"); + it = OpIT(kCondEq, "T"); NewLIR4(kThumb2Strexd /* eq */, r_tmp.GetReg(), rl_new_value.reg.GetLowReg(), rl_new_value.reg.GetHighReg(), r_ptr.GetReg()); } else { NewLIR3(kThumb2Ldrex, r_tmp.GetReg(), r_ptr.GetReg(), 0); OpRegReg(kOpSub, r_tmp, rl_expected.reg); DCHECK(last_lir_insn_->u.m.def_mask & ENCODE_CCODE); - OpIT(kCondEq, "T"); + it = OpIT(kCondEq, "T"); NewLIR4(kThumb2Strex /* eq */, r_tmp.GetReg(), rl_new_value.reg.GetReg(), r_ptr.GetReg(), 0); } // Still one conditional left from OpIT(kCondEq, "T") from either branch OpRegImm(kOpCmp /* eq */, r_tmp, 1); - GenBarrier(); + OpEndIT(it); OpCondBranch(kCondEq, target); @@ -828,10 +838,10 @@ bool ArmMir2Lir::GenInlinedCas(CallInfo* info, bool is_long, bool is_object) { RegLocation rl_result = EvalLoc(rl_dest, kCoreReg, true); OpRegRegImm(kOpRsub, rl_result.reg, r_tmp, 1); DCHECK(last_lir_insn_->u.m.def_mask & ENCODE_CCODE); - OpIT(kCondUlt, ""); + it = OpIT(kCondUlt, ""); LoadConstant(rl_result.reg, 0); /* cc */ FreeTemp(r_tmp); // Now unneeded. - GenBarrier(); // Barrier to terminate OpIT. + OpEndIT(it); // Barrier to terminate OpIT. StoreValue(rl_dest, rl_result); diff --git a/compiler/dex/quick/gen_common.cc b/compiler/dex/quick/gen_common.cc index c5c42e8..bfa22da 100644 --- a/compiler/dex/quick/gen_common.cc +++ b/compiler/dex/quick/gen_common.cc @@ -1082,9 +1082,9 @@ void Mir2Lir::GenInstanceofFinal(bool use_declaring_class, uint32_t type_idx, Re LIR* ne_branchover = NULL; if (cu_->instruction_set == kThumb2) { OpRegReg(kOpCmp, check_class, object_class); // Same? - OpIT(kCondEq, ""); // if-convert the test + LIR* it = OpIT(kCondEq, ""); // if-convert the test LoadConstant(result_reg, 1); // .eq case - load true - GenBarrier(); + OpEndIT(it); } else { ne_branchover = OpCmpBranch(kCondNe, check_class, object_class, NULL); LoadConstant(result_reg, 1); // eq case - load true @@ -1166,10 +1166,10 @@ void Mir2Lir::GenInstanceofCallingHelper(bool needs_access_check, bool type_know // rl_result == ref == null == 0. if (cu_->instruction_set == kThumb2) { OpRegReg(kOpCmp, TargetReg(kArg1), TargetReg(kArg2)); // Same? - OpIT(kCondEq, "E"); // if-convert the test + LIR* it = OpIT(kCondEq, "E"); // if-convert the test LoadConstant(rl_result.reg, 1); // .eq case - load true LoadConstant(rl_result.reg, 0); // .ne case - load false - GenBarrier(); + OpEndIT(it); } else { LoadConstant(rl_result.reg, 0); // ne case - load false branchover = OpCmpBranch(kCondNe, TargetReg(kArg1), TargetReg(kArg2), NULL); @@ -1178,15 +1178,18 @@ void Mir2Lir::GenInstanceofCallingHelper(bool needs_access_check, bool type_know } else { if (cu_->instruction_set == kThumb2) { RegStorage r_tgt = LoadHelper(QUICK_ENTRYPOINT_OFFSET(4, pInstanceofNonTrivial)); + LIR* it = nullptr; if (!type_known_abstract) { /* Uses conditional nullification */ OpRegReg(kOpCmp, TargetReg(kArg1), TargetReg(kArg2)); // Same? - OpIT(kCondEq, "EE"); // if-convert the test + it = OpIT(kCondEq, "EE"); // if-convert the test LoadConstant(TargetReg(kArg0), 1); // .eq case - load true } OpRegCopy(TargetReg(kArg0), TargetReg(kArg2)); // .ne case - arg0 <= class OpReg(kOpBlx, r_tgt); // .ne case: helper(class, ref->class) - GenBarrier(); + if (it != nullptr) { + OpEndIT(it); + } FreeTemp(r_tgt); } else { if (!type_known_abstract) { diff --git a/compiler/dex/quick/mips/codegen_mips.h b/compiler/dex/quick/mips/codegen_mips.h index c962ea3..5089111 100644 --- a/compiler/dex/quick/mips/codegen_mips.h +++ b/compiler/dex/quick/mips/codegen_mips.h @@ -157,6 +157,7 @@ class MipsMir2Lir FINAL : public Mir2Lir { LIR* OpDecAndBranch(ConditionCode c_code, RegStorage reg, LIR* target); LIR* OpFpRegCopy(RegStorage r_dest, RegStorage r_src); LIR* OpIT(ConditionCode cond, const char* guide); + void OpEndIT(LIR* it); LIR* OpMem(OpKind op, RegStorage r_base, int disp); LIR* OpPcRelLoad(RegStorage reg, LIR* target); LIR* OpReg(OpKind op, RegStorage r_dest_src); diff --git a/compiler/dex/quick/mips/int_mips.cc b/compiler/dex/quick/mips/int_mips.cc index f394185..5fe96d2 100644 --- a/compiler/dex/quick/mips/int_mips.cc +++ b/compiler/dex/quick/mips/int_mips.cc @@ -378,6 +378,11 @@ LIR* MipsMir2Lir::OpIT(ConditionCode cond, const char* guide) { return NULL; } +void MipsMir2Lir::OpEndIT(LIR* it) { + LOG(FATAL) << "Unexpected use of OpEndIT in Mips"; +} + + void MipsMir2Lir::GenMulLong(Instruction::Code opcode, RegLocation rl_dest, RegLocation rl_src1, RegLocation rl_src2) { LOG(FATAL) << "Unexpected use of GenMulLong for Mips"; diff --git a/compiler/dex/quick/mir_to_lir.h b/compiler/dex/quick/mir_to_lir.h index 1ad636b..35f948e 100644 --- a/compiler/dex/quick/mir_to_lir.h +++ b/compiler/dex/quick/mir_to_lir.h @@ -1010,6 +1010,7 @@ class Mir2Lir : public Backend { virtual LIR* OpDecAndBranch(ConditionCode c_code, RegStorage reg, LIR* target) = 0; virtual LIR* OpFpRegCopy(RegStorage r_dest, RegStorage r_src) = 0; virtual LIR* OpIT(ConditionCode cond, const char* guide) = 0; + virtual void OpEndIT(LIR* it) = 0; virtual LIR* OpMem(OpKind op, RegStorage r_base, int disp) = 0; virtual LIR* OpPcRelLoad(RegStorage reg, LIR* target) = 0; virtual LIR* OpReg(OpKind op, RegStorage r_dest_src) = 0; diff --git a/compiler/dex/quick/x86/codegen_x86.h b/compiler/dex/quick/x86/codegen_x86.h index 940a1da..af2a140 100644 --- a/compiler/dex/quick/x86/codegen_x86.h +++ b/compiler/dex/quick/x86/codegen_x86.h @@ -230,6 +230,7 @@ class X86Mir2Lir FINAL : public Mir2Lir { LIR* OpDecAndBranch(ConditionCode c_code, RegStorage reg, LIR* target); LIR* OpFpRegCopy(RegStorage r_dest, RegStorage r_src); LIR* OpIT(ConditionCode cond, const char* guide); + void OpEndIT(LIR* it); LIR* OpMem(OpKind op, RegStorage r_base, int disp); LIR* OpPcRelLoad(RegStorage reg, LIR* target); LIR* OpReg(OpKind op, RegStorage r_dest_src); diff --git a/compiler/dex/quick/x86/int_x86.cc b/compiler/dex/quick/x86/int_x86.cc index bbcedc3..c1d1e01 100644 --- a/compiler/dex/quick/x86/int_x86.cc +++ b/compiler/dex/quick/x86/int_x86.cc @@ -919,6 +919,10 @@ LIR* X86Mir2Lir::OpIT(ConditionCode cond, const char* guide) { return NULL; } +void X86Mir2Lir::OpEndIT(LIR* it) { + LOG(FATAL) << "Unexpected use of OpEndIT in x86"; +} + void X86Mir2Lir::GenImulRegImm(RegStorage dest, RegStorage src, int val) { switch (val) { case 0: diff --git a/compiler/oat_writer.cc b/compiler/oat_writer.cc index a07aebc..2d45a2f 100644 --- a/compiler/oat_writer.cc +++ b/compiler/oat_writer.cc @@ -508,7 +508,12 @@ size_t OatWriter::InitOatCodeMethod(size_t offset, size_t oat_class_index, refs++; } } - size_t sirt_size = StackIndirectReferenceTable::GetAlignedSirtSize(refs); + InstructionSet trg_isa = compiler_driver_->GetInstructionSet(); + size_t pointer_size = 4; + if (trg_isa == kArm64 || trg_isa == kX86_64) { + pointer_size = 8; + } + size_t sirt_size = StackIndirectReferenceTable::GetAlignedSirtSizeTarget(pointer_size, refs); // Get the generic spill masks and base frame size. mirror::ArtMethod* callee_save_method = diff --git a/compiler/utils/arm64/assembler_arm64.h b/compiler/utils/arm64/assembler_arm64.h index 3abcaad..0220724 100644 --- a/compiler/utils/arm64/assembler_arm64.h +++ b/compiler/utils/arm64/assembler_arm64.h @@ -85,17 +85,6 @@ class Arm64Assembler FINAL : public Assembler { vixl_masm_(new vixl::MacroAssembler(vixl_buf_, BUF_SIZE)) {} virtual ~Arm64Assembler() { - if (kIsDebugBuild) { - vixl::Decoder *decoder = new vixl::Decoder(); - vixl::PrintDisassembler *test = new vixl::PrintDisassembler(stdout); - decoder->AppendVisitor(test); - - for (size_t i = 0; i < CodeSize() / vixl::kInstructionSize; ++i) { - vixl::Instruction *instr = - reinterpret_cast<vixl::Instruction*>(vixl_buf_ + i * vixl::kInstructionSize); - decoder->Decode(instr); - } - } delete[] vixl_buf_; } |