ART: Refactor GenSelect, refactor gen_common accordingly
This adds a GenSelect method meant for selection of constants. The
general-purpose GenInstanceof code is refactored to take advantage of
this. This cleans up code and squashes a branch-over on ARM64 to a
cset.
Also add a slow-path for type initialization in GenInstanceof.
Change-Id: Ie4494858bb8c26d386cf2e628172b81bba911ae5
diff --git a/compiler/dex/quick/x86/int_x86.cc b/compiler/dex/quick/x86/int_x86.cc
index 2f27482..30b87ba 100755
--- a/compiler/dex/quick/x86/int_x86.cc
+++ b/compiler/dex/quick/x86/int_x86.cc
@@ -206,6 +206,38 @@
}
}
+// Set rs_dest to 0 or 1 depending on the comparison between left_op and right_op.
+// rs_dest := (left_op <code> right_op) ? [true_val] : [!true_val]
+//
+// Implemented as:
+// true_val = true => rs_dest := 0;
+// rs_dest := (left_op <code> right_op) ? 1 : rs_dest;
+// true_val = false => rs_dest := 0;
+// rs_dest := (left_op <~code> right_op) ? 1 : rs_dest;
+void X86Mir2Lir::GenSelectConst01(RegStorage left_op, RegStorage right_op, ConditionCode code,
+ bool true_val, RegStorage rs_dest) {
+ LoadConstant(rs_dest, 0);
+ OpRegReg(kOpCmp, left_op, right_op);
+ // Set the low byte of the result to 0 or 1 from the compare condition code.
+ NewLIR2(kX86Set8R, rs_dest.GetReg(),
+ X86ConditionEncoding(true_val ? code : FlipComparisonOrder(code)));
+}
+
+void X86Mir2Lir::GenSelectConst32(RegStorage left_op, RegStorage right_op, ConditionCode code,
+ int32_t true_val, int32_t false_val, RegStorage rs_dest,
+ int dest_reg_class) {
+ if ((true_val == 0 && false_val == 1) || (true_val == 1 && false_val == 0)) {
+ // Can we use Setcc?
+ if (rs_dest.Is64Bit() || rs_dest.GetRegNum() < 4) {
+ GenSelectConst01(left_op, right_op, code, true_val == 1, rs_dest);
+ return;
+ }
+ }
+
+ // TODO: Refactor the code below to make this more general.
+ UNIMPLEMENTED(FATAL) << "General GenSelectConst32 not implemented for x86.";
+}
+
void X86Mir2Lir::GenSelect(BasicBlock* bb, MIR* mir) {
RegLocation rl_result;
RegLocation rl_src = mir_graph_->GetSrc(mir, 0);
@@ -2459,9 +2491,6 @@
OpRegCopy(rl_result.reg, ref_reg);
}
- // For 32-bit, SETcc only works with EAX..EDX.
- DCHECK_LT(rl_result.reg.GetRegNum(), 4);
-
// Is the class NULL?
LIR* branch1 = OpCmpImmBranch(kCondEq, ref_reg, 0, NULL);
@@ -2473,11 +2502,7 @@
/* kArg0 is ref, kArg1 is ref->klass_, kArg2 is class. */
LIR* branchover = nullptr;
if (type_known_final) {
- // Ensure top 3 bytes of result are 0.
- LoadConstant(rl_result.reg, 0);
- OpRegReg(kOpCmp, ref_class_reg, class_reg);
- // Set the low byte of the result to 0 or 1 from the compare condition code.
- NewLIR2(kX86Set8R, rl_result.reg.GetReg(), kX86CondEq);
+ GenSelectConst32(ref_class_reg, class_reg, kCondEq, 1, 0, rl_result.reg, kCoreReg);
} else {
if (!type_known_abstract) {
LoadConstant(rl_result.reg, 1); // Assume result succeeds.