summaryrefslogtreecommitdiffstats
path: root/compiler
diff options
context:
space:
mode:
Diffstat (limited to 'compiler')
-rw-r--r--compiler/dex/quick/arm/call_arm.cc12
-rw-r--r--compiler/dex/quick/arm/codegen_arm.h1
-rw-r--r--compiler/dex/quick/arm/fp_arm.cc8
-rw-r--r--compiler/dex/quick/arm/int_arm.cc52
-rw-r--r--compiler/dex/quick/gen_common.cc15
-rw-r--r--compiler/dex/quick/mips/codegen_mips.h1
-rw-r--r--compiler/dex/quick/mips/int_mips.cc5
-rw-r--r--compiler/dex/quick/mir_to_lir.h1
-rw-r--r--compiler/dex/quick/x86/codegen_x86.h1
-rw-r--r--compiler/dex/quick/x86/int_x86.cc4
-rw-r--r--compiler/oat_writer.cc7
-rw-r--r--compiler/utils/arm64/assembler_arm64.h11
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_;
}