diff --git a/erts/emulator/beam/jit/arm/instr_arith.cpp b/erts/emulator/beam/jit/arm/instr_arith.cpp index 6ba25ae9a14a..45f5b99669ec 100644 --- a/erts/emulator/beam/jit/arm/instr_arith.cpp +++ b/erts/emulator/beam/jit/arm/instr_arith.cpp @@ -1520,23 +1520,18 @@ void BeamModuleAssembler::emit_i_bsr(const ArgLabel &Fail, /* Ensure that both operands are small and that the shift * count is positive. */ ERTS_CT_ASSERT(_TAG_IMMED1_SMALL == _TAG_IMMED1_MASK); - a.and_(TMP1, lhs.reg, rhs.reg); - if (std::get<0>(getClampedRange(RHS)) >= 0) { - a.and_(TMP1, TMP1, imm(_TAG_IMMED1_MASK)); - a.cmp(TMP1, imm(_TAG_IMMED1_SMALL)); - a.b_ne(generic); - } else { - a.mvn(TMP1, TMP1); - a.tst(TMP1, imm(_TAG_IMMED1_MASK)); - a.ccmp(rhs.reg, imm(0), imm(NZCV::kSigned), arm::CondCode::kEQ); - a.b_lt(generic); - } + a.ands(TMP1, rhs.reg, imm((1ull << 63) | _TAG_IMMED1_MASK)); + a.and_(TMP1, lhs.reg, TMP1); + a.ccmp(TMP1, imm(_TAG_IMMED1_SMALL), imm(NZCV::kNone), arm::CondCode::kPL); + a.b_ne(generic); + /* Calculate shift count. */ a.asr(TMP1, rhs.reg, imm(_TAG_IMMED1_SIZE)); mov_imm(TMP2, 63); a.cmp(TMP1, TMP2); a.csel(TMP1, TMP1, TMP2, imm(arm::CondCode::kLE)); + /* Shift right. */ ERTS_CT_ASSERT(_TAG_IMMED1_MASK == _TAG_IMMED1_SMALL); a.asr(dst.reg, lhs.reg, TMP1); a.orr(dst.reg, dst.reg, imm(_TAG_IMMED1_SMALL));