diff options
| author | 2014-07-11 16:31:28 +0100 | |
|---|---|---|
| committer | 2014-07-11 18:26:19 +0100 | |
| commit | 873c371eea7d8700c8037d790de168b5ed7c20d0 (patch) | |
| tree | 50fdf84df3a46ad58511a171e6f2881f43e9a83b | |
| parent | 3641ac7de8b51c0853eaaa2ba3a3ab7e65a837c5 (diff) | |
ART: Fix GenSelect for ARM64
Add CSINV and replace CSNEG in GenSelect.
Some tests were failing in 083-complier-regression as CSNEG
was used instead of CSINV. CSNEG on xzr yields 0, whereas
CSINV negates the bits and yields -1, which was the intention.
Change-Id: I60557e34483f98310f7d33f18d8db203fba6e78f
Signed-off-by: Stuart Monteith <stuart.monteith@arm.com>
| -rw-r--r-- | compiler/dex/quick/arm64/arm64_lir.h | 1 | ||||
| -rw-r--r-- | compiler/dex/quick/arm64/assemble_arm64.cc | 4 | ||||
| -rw-r--r-- | compiler/dex/quick/arm64/int_arm64.cc | 4 |
3 files changed, 7 insertions, 2 deletions
diff --git a/compiler/dex/quick/arm64/arm64_lir.h b/compiler/dex/quick/arm64/arm64_lir.h index 5077d11a73..7490646b9b 100644 --- a/compiler/dex/quick/arm64/arm64_lir.h +++ b/compiler/dex/quick/arm64/arm64_lir.h @@ -245,6 +245,7 @@ enum ArmOpcode { kA64Cmp3RdT, // cmp [01110001] shift[23-22] imm_12[21-10] rn[9-5] [11111]. kA64Csel4rrrc, // csel[s0011010100] rm[20-16] cond[15-12] [00] rn[9-5] rd[4-0]. kA64Csinc4rrrc, // csinc [s0011010100] rm[20-16] cond[15-12] [01] rn[9-5] rd[4-0]. + kA64Csinv4rrrc, // csinv [s1011010100] rm[20-16] cond[15-12] [00] rn[9-5] rd[4-0]. kA64Csneg4rrrc, // csneg [s1011010100] rm[20-16] cond[15-12] [01] rn[9-5] rd[4-0]. kA64Dmb1B, // dmb [11010101000000110011] CRm[11-8] [10111111]. kA64Eor3Rrl, // eor [s10100100] N[22] imm_r[21-16] imm_s[15-10] rn[9-5] rd[4-0]. diff --git a/compiler/dex/quick/arm64/assemble_arm64.cc b/compiler/dex/quick/arm64/assemble_arm64.cc index e10f7cfe67..3bfe9a1a89 100644 --- a/compiler/dex/quick/arm64/assemble_arm64.cc +++ b/compiler/dex/quick/arm64/assemble_arm64.cc @@ -204,6 +204,10 @@ const ArmEncodingMap Arm64Mir2Lir::EncodingMap[kA64Last] = { kFmtRegR, 4, 0, kFmtRegR, 9, 5, kFmtRegR, 20, 16, kFmtBitBlt, 15, 12, IS_QUAD_OP | REG_DEF0_USE12 | USES_CCODES, "csinc", "!0r, !1r, !2r, !3c", kFixupNone), + ENCODING_MAP(WIDE(kA64Csinv4rrrc), SF_VARIANTS(0x5a800000), + kFmtRegR, 4, 0, kFmtRegR, 9, 5, kFmtRegR, 20, 16, + kFmtBitBlt, 15, 12, IS_QUAD_OP | REG_DEF0_USE12 | USES_CCODES, + "csinv", "!0r, !1r, !2r, !3c", kFixupNone), ENCODING_MAP(WIDE(kA64Csneg4rrrc), SF_VARIANTS(0x5a800400), kFmtRegR, 4, 0, kFmtRegR, 9, 5, kFmtRegR, 20, 16, kFmtBitBlt, 15, 12, IS_QUAD_OP | REG_DEF0_USE12 | USES_CCODES, diff --git a/compiler/dex/quick/arm64/int_arm64.cc b/compiler/dex/quick/arm64/int_arm64.cc index 3ee3e2e61d..a7ca685fd5 100644 --- a/compiler/dex/quick/arm64/int_arm64.cc +++ b/compiler/dex/quick/arm64/int_arm64.cc @@ -131,7 +131,7 @@ void Arm64Mir2Lir::GenSelect(BasicBlock* bb, MIR* mir) { } left_op = right_op = zero_reg; - opcode = is_wide ? WIDE(kA64Csneg4rrrc) : kA64Csneg4rrrc; + opcode = is_wide ? WIDE(kA64Csinv4rrrc) : kA64Csinv4rrrc; } else if (true_val == 0 || false_val == 0) { // Csel half cheap based on wzr. rl_result = EvalLoc(rl_dest, result_reg_class, true); @@ -167,7 +167,7 @@ void Arm64Mir2Lir::GenSelect(BasicBlock* bb, MIR* mir) { LoadConstantNoClobber(rl_result.reg, true_val == 0xFFFFFFFF ? false_val : true_val); left_op = rl_result.reg.GetReg(); right_op = zero_reg; - opcode = is_wide ? WIDE(kA64Csneg4rrrc) : kA64Csneg4rrrc; + opcode = is_wide ? WIDE(kA64Csinv4rrrc) : kA64Csinv4rrrc; } else { // Csel. The rest. Use rl_result and a temp. // TODO: To minimize the constants being loaded, check whether one can be inexpensively |