Skip to content

Commit 2300163

Browse files
committed
WIP bsr
Signed-off-by: Davide Bettio <davide@uninstall.it>
1 parent 8ae849a commit 2300163

File tree

4 files changed

+70
-4
lines changed

4 files changed

+70
-4
lines changed

src/libAtomVM/bif.c

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1628,9 +1628,7 @@ term bif_erlang_bsr_2(Context *ctx, uint32_t fail_label, int live, term arg1, te
16281628
args_to_bigint(arg1, arg2, tmp_buf1, tmp_buf2, &m, &m_len, &m_sign, &n, &n_len, &n_sign);
16291629

16301630
intn_digit_t bigres[INTN_MAX_RES_LEN];
1631-
size_t bigres_len;
1632-
//intn_bsl(m, m_len, b, bigres, &bigres_len); //FIXME TODO CHANGE ME
1633-
abort();
1631+
size_t bigres_len = intn_bsr(m, m_len, b, bigres);
16341632

16351633
return make_bigint(ctx, fail_label, live, bigres, bigres_len, m_sign);
16361634
} else {

src/libAtomVM/intn.c

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -604,6 +604,55 @@ size_t intn_bsl(const uint32_t num[], size_t len, size_t n, uint32_t *out)
604604
return initial_zeros + i;
605605
}
606606

607+
size_t intn_bsr(const uint32_t num[], size_t len, size_t n, uint32_t *out)
608+
{
609+
size_t digit_bit_size = sizeof(uint32_t) * 8;
610+
611+
size_t digit_right_bit_shift = n % 32;
612+
size_t left_shift_n = (32 - digit_right_bit_shift);
613+
614+
size_t counted_digits = intn_count_digits(num, len);
615+
size_t ms_digit_bits = 32 - uint32_nlz(num[counted_digits - 1]);
616+
size_t effective_bits_len = (counted_digits - 1) * digit_bit_size + ms_digit_bits;
617+
size_t new_bits_len = size_round_to(effective_bits_len - n, digit_bit_size);
618+
619+
size_t new_digits_count = new_bits_len / digit_bit_size;
620+
621+
if (new_digits_count > INTN_BSL_MAX_OUT_LEN) {
622+
return new_digits_count;
623+
}
624+
625+
size_t discarded = MIN(n / digit_bit_size, len);
626+
627+
if (left_shift_n == 32) {
628+
memcpy(out, num + discarded, (len - discarded) * sizeof(uint32_t));
629+
return len - discarded;
630+
}
631+
632+
size_t i;
633+
for (i = discarded; i < counted_digits - 1; i++) {
634+
uint32_t next_digit = num[i + 1];
635+
uint32_t digit = num[i];
636+
out[i - discarded] = (digit >> digit_right_bit_shift) | (next_digit << left_shift_n);
637+
}
638+
uint32_t maybe_last_out = (num[i] >> digit_right_bit_shift);
639+
640+
/*
641+
if (initial_zeros + i > new_digits_count) {
642+
abort();
643+
}
644+
*/
645+
646+
if (maybe_last_out) {
647+
out[i - discarded] = maybe_last_out;
648+
return i - discarded + 1;
649+
}
650+
651+
return i - discarded;
652+
}
653+
654+
655+
607656
/*
608657
uint32_t last_digit = 0;
609658
for (size_t i = initial_zeros; i < out_len - 1; i++) {

src/libAtomVM/intn.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,7 @@ size_t intn_bxormn(const intn_digit_t m[], size_t m_len, intn_integer_sign_t m_s
8686
intn_integer_sign_t *out_sign);
8787

8888
size_t intn_bsl(const uint32_t num[], size_t len, size_t n, uint32_t *out);
89+
size_t intn_bsr(const uint32_t num[], size_t len, size_t n, uint32_t *out);
8990

9091
size_t intn_count_digits(const intn_digit_t *num, size_t num_len);
9192

tests/erlang_tests/bigint.erl

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,8 @@ start() ->
5555
big_literals() +
5656
to_external_term() +
5757
test_bor() +
58-
test_bsl().
58+
test_bsl() +
59+
test_bsr().
5960

6061
test_mul() ->
6162
Expected_INT64_MIN = ?MODULE:pow(-2, 63),
@@ -890,6 +891,23 @@ test_bsl() ->
890891

891892
0.
892893

894+
test_bsr() ->
895+
erlang:display('bsr'),
896+
%% versione negativa
897+
Pattern1 = erlang:binary_to_integer(?MODULE:id(<<"CAFE1234AABBCCDD98765432987654321">>), 16),
898+
<<"CAFE1234AABBCCDD98765432987">> = erlang:integer_to_binary(Pattern1 bsr ?MODULE:id(24), 16),
899+
<<"657F091A555DE66ECC3B2A194C">> = erlang:integer_to_binary(Pattern1 bsr ?MODULE:id(29), 16),
900+
<<"CAFE1234AABBCCDD987654329">> = erlang:integer_to_binary(Pattern1 bsr ?MODULE:id(32), 16),
901+
<<"195FC2469557799BB30ECA865">> = erlang:integer_to_binary(Pattern1 bsr ?MODULE:id(35), 16),
902+
<<"CAFE1234AABBCCDD98765">> = erlang:integer_to_binary(Pattern1 bsr ?MODULE:id(48), 16),
903+
<<"195FC2469557799BB30EC">> = erlang:integer_to_binary(Pattern1 bsr ?MODULE:id(51), 16),
904+
<<"CAFE1234AABBCCDD9">> = erlang:integer_to_binary(Pattern1 bsr ?MODULE:id(64), 16),
905+
<<"C">> = erlang:integer_to_binary(Pattern1 bsr ?MODULE:id(128), 16),
906+
907+
0.
908+
909+
910+
893911

894912
id(X) ->
895913
X.

0 commit comments

Comments
 (0)