diff options
author | Andreas Gampe <agampe@google.com> | 2014-07-15 23:02:11 -0700 |
---|---|---|
committer | Andreas Gampe <agampe@google.com> | 2014-07-17 10:02:10 -0700 |
commit | 90969af6deb19b1dbe356d62fe68d8f5698d3d8f (patch) | |
tree | 6d144bcd219ce718ba9d17240eade0bec51f3400 /compiler/dex/quick/arm | |
parent | aab012d6196bd29b3167963ec8acb0b9780672b2 (diff) | |
download | android_art-90969af6deb19b1dbe356d62fe68d8f5698d3d8f.tar.gz android_art-90969af6deb19b1dbe356d62fe68d8f5698d3d8f.tar.bz2 android_art-90969af6deb19b1dbe356d62fe68d8f5698d3d8f.zip |
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
Diffstat (limited to 'compiler/dex/quick/arm')
-rw-r--r-- | compiler/dex/quick/arm/codegen_arm.h | 3 | ||||
-rw-r--r-- | compiler/dex/quick/arm/int_arm.cc | 24 |
2 files changed, 27 insertions, 0 deletions
diff --git a/compiler/dex/quick/arm/codegen_arm.h b/compiler/dex/quick/arm/codegen_arm.h index d4b0de7b4e..23e8486d5b 100644 --- a/compiler/dex/quick/arm/codegen_arm.h +++ b/compiler/dex/quick/arm/codegen_arm.h @@ -138,6 +138,9 @@ class ArmMir2Lir FINAL : public Mir2Lir { void GenFusedFPCmpBranch(BasicBlock* bb, MIR* mir, bool gt_bias, bool is_double); void GenFusedLongCmpBranch(BasicBlock* bb, MIR* mir); void GenSelect(BasicBlock* bb, MIR* mir); + void GenSelectConst32(RegStorage left_op, RegStorage right_op, ConditionCode code, + int32_t true_val, int32_t false_val, RegStorage rs_dest, + int dest_reg_class) OVERRIDE; bool GenMemBarrier(MemBarrierKind barrier_kind); void GenMonitorEnter(int opt_flags, RegLocation rl_src); void GenMonitorExit(int opt_flags, RegLocation rl_src); diff --git a/compiler/dex/quick/arm/int_arm.cc b/compiler/dex/quick/arm/int_arm.cc index 2fcc3a5abc..a85b74021b 100644 --- a/compiler/dex/quick/arm/int_arm.cc +++ b/compiler/dex/quick/arm/int_arm.cc @@ -203,6 +203,30 @@ void ArmMir2Lir::GenFusedLongCmpImmBranch(BasicBlock* bb, RegLocation rl_src1, OpCmpImmBranch(ccode, low_reg, val_lo, taken); } +void ArmMir2Lir::GenSelectConst32(RegStorage left_op, RegStorage right_op, ConditionCode code, + int32_t true_val, int32_t false_val, RegStorage rs_dest, + int dest_reg_class) { + // TODO: Generalize the IT below to accept more than one-instruction loads. + DCHECK(InexpensiveConstantInt(true_val)); + DCHECK(InexpensiveConstantInt(false_val)); + + if ((true_val == 0 && code == kCondEq) || + (false_val == 0 && code == kCondNe)) { + OpRegRegReg(kOpSub, rs_dest, left_op, right_op); + DCHECK(last_lir_insn_->u.m.def_mask->HasBit(ResourceMask::kCCode)); + LIR* it = OpIT(kCondNe, ""); + LoadConstant(rs_dest, code == kCondEq ? false_val : true_val); + OpEndIT(it); + return; + } + + OpRegReg(kOpCmp, left_op, right_op); // Same? + LIR* it = OpIT(code, "E"); // if-convert the test + LoadConstant(rs_dest, true_val); // .eq case - load true + LoadConstant(rs_dest, false_val); // .eq case - load true + OpEndIT(it); +} + void ArmMir2Lir::GenSelect(BasicBlock* bb, MIR* mir) { RegLocation rl_result; RegLocation rl_src = mir_graph_->GetSrc(mir, 0); |