diff options
-rw-r--r-- | erts/emulator/beam/arith_instrs.tab | 49 |
1 files changed, 24 insertions, 25 deletions
diff --git a/erts/emulator/beam/arith_instrs.tab b/erts/emulator/beam/arith_instrs.tab index 224945287b..67cd7c6a2a 100644 --- a/erts/emulator/beam/arith_instrs.tab +++ b/erts/emulator/beam/arith_instrs.tab @@ -226,9 +226,6 @@ i_bsr := shift.setup_bsr.execute; shift.head() { Eterm Op1, Op2; Sint shift_left_count; - Sint ires; - Eterm* bigp; - Eterm tmp_big[2]; } shift.setup_bsr(Src1, Src2) { @@ -272,35 +269,37 @@ shift.setup_bsl(Src1, Src2) { } shift.execute(Fail, Live, Dst) { + Uint big_words_needed; + if (is_small(Op1)) { - ires = signed_val(Op1); - if (shift_left_count == 0 || ires == 0) { + Sint int_res = signed_val(Op1); + if (shift_left_count == 0 || int_res == 0) { if (is_not_integer(Op2)) { goto shift_error; } - if (ires == 0) { + if (int_res == 0) { $Dst = Op1; $NEXT0(); } } else if (shift_left_count < 0) { /* Right shift */ + Eterm bsr_res; shift_left_count = -shift_left_count; if (shift_left_count >= SMALL_BITS-1) { - $Dst = (ires < 0) ? SMALL_MINUS_ONE : SMALL_ZERO; + bsr_res = (int_res < 0) ? SMALL_MINUS_ONE : SMALL_ZERO; } else { - $Dst = make_small(ires >> shift_left_count); + bsr_res = make_small(int_res >> shift_left_count); } + $Dst = bsr_res; $NEXT0(); } else if (shift_left_count < SMALL_BITS-1) { /* Left shift */ - if ((ires > 0 && - ((~(Uint)0 << ((SMALL_BITS-1)-shift_left_count)) & - ires) == 0) || - ((~(Uint)0 << ((SMALL_BITS-1)-shift_left_count)) & - ~ires) == 0) { - $Dst = make_small(ires << shift_left_count); + if ((int_res > 0 && + ((~(Uint)0 << ((SMALL_BITS-1)-shift_left_count)) & int_res) == 0) || + ((~(Uint)0 << ((SMALL_BITS-1)-shift_left_count)) & ~int_res) == 0) { + $Dst = make_small(int_res << shift_left_count); $NEXT0(); } } - ires = 1; /* big_size(small_to_big(Op1)) */ + big_words_needed = 1; /* big_size(small_to_big(Op1)) */ goto big_shift; } else if (is_big(Op1)) { if (shift_left_count == 0) { @@ -310,20 +309,21 @@ shift.execute(Fail, Live, Dst) { $Dst = Op1; $NEXT0(); } - ires = big_size(Op1); + big_words_needed = big_size(Op1); big_shift: if (shift_left_count > 0) { /* Left shift. */ - ires += (shift_left_count / D_EXP); + big_words_needed += (shift_left_count / D_EXP); } else { /* Right shift. */ - if (ires <= (-shift_left_count / D_EXP)) { - ires = 3; /* ??? */ + if (big_words_needed <= (-shift_left_count / D_EXP)) { + big_words_needed = 3; /* ??? */ } else { - ires -= (-shift_left_count / D_EXP); + big_words_needed -= (-shift_left_count / D_EXP); } } { - ires = BIG_NEED_SIZE(ires+1); + Eterm tmp_big[2]; + Sint big_need_size = BIG_NEED_SIZE(big_words_needed+1); /* * Slightly conservative check the size to avoid @@ -331,15 +331,14 @@ shift.execute(Fail, Live, Dst) { * clearly would overflow the arity in the header * word. */ - if (ires-8 > BIG_ARITY_MAX) { + if (big_need_size-8 > BIG_ARITY_MAX) { $SYSTEM_LIMIT($Fail); } - $GC_TEST_PRESERVE(ires+1, $Live, Op1); + $GC_TEST_PRESERVE(big_need_size+1, $Live, Op1); if (is_small(Op1)) { Op1 = small_to_big(signed_val(Op1), tmp_big); } - bigp = HTOP; - Op1 = big_lshift(Op1, shift_left_count, bigp); + Op1 = big_lshift(Op1, shift_left_count, HTOP); if (is_big(Op1)) { HTOP += bignum_header_arity(*HTOP) + 1; } |