@@ -550,6 +550,74 @@ size_t intn_bxormn(const intn_digit_t m[], size_t m_len, intn_integer_sign_t m_s
550
550
return res_count ;
551
551
}
552
552
553
+ #define INTN_BSL_MAX_OUT_LEN 8
554
+
555
+ static inline size_t size_round_to (size_t n , size_t round_to )
556
+ {
557
+ return (n + (round_to - 1 )) & ~(round_to - 1 );
558
+ }
559
+
560
+ size_t intn_bsl (const uint32_t num [], size_t len , size_t n , uint32_t * out )
561
+ {
562
+ size_t digit_bit_size = sizeof (uint32_t ) * 8 ;
563
+
564
+ size_t digit_left_bit_shift = n % 32 ;
565
+ size_t right_shift_n = (32 - digit_left_bit_shift );
566
+
567
+ size_t counted_digits = intn_count_digits (num , len );
568
+ size_t ms_digit_bits = 32 - uint32_nlz (num [counted_digits - 1 ]);
569
+ size_t effective_bits_len = (counted_digits - 1 ) * digit_bit_size + ms_digit_bits ;
570
+ size_t new_bits_len = size_round_to (effective_bits_len + n , digit_bit_size );
571
+
572
+ size_t new_digits_count = new_bits_len / digit_bit_size ;
573
+
574
+ if (new_digits_count > INTN_BSL_MAX_OUT_LEN ) {
575
+ return new_digits_count ;
576
+ }
577
+
578
+ size_t initial_zeros = MIN (n / digit_bit_size , INTN_BSL_MAX_OUT_LEN );
579
+ memset (out , 0 , initial_zeros * sizeof (uint32_t ));
580
+
581
+ if (right_shift_n == 32 ) {
582
+ memcpy (out + initial_zeros , num , len * sizeof (uint32_t ));
583
+ return initial_zeros + len ;
584
+ }
585
+
586
+ uint32_t last_digit = 0 ;
587
+ size_t i ;
588
+ for (i = 0 ; i < counted_digits ; i ++ ) {
589
+ uint32_t digit = num [i ];
590
+ out [initial_zeros + i ] = (digit << digit_left_bit_shift ) | (last_digit >> right_shift_n );
591
+ last_digit = digit ;
592
+ }
593
+ uint32_t maybe_last_out = (last_digit >> right_shift_n );
594
+
595
+ if (initial_zeros + i > new_digits_count ) {
596
+ abort ();
597
+ }
598
+
599
+ if (maybe_last_out ) {
600
+ out [initial_zeros + i ] = maybe_last_out ;
601
+ return initial_zeros + i + 1 ;
602
+ }
603
+
604
+ return initial_zeros + i ;
605
+ }
606
+
607
+ /*
608
+ uint32_t last_digit = 0;
609
+ for (size_t i = initial_zeros; i < out_len - 1; i++) {
610
+ uint32_t digit = num[i - initial_zeros];
611
+ if (i - initial_zeros >= counted_digits) {
612
+ abort();
613
+ }
614
+ out[i] = (digit << digit_left_bit_shift) | (last_digit >> right_shift_n);
615
+ last_digit = digit;
616
+ fprintf(stderr, "in: %i, (%i), last_digit: %i\n", (int) i - initial_zeros, (int) i, (int) last_digit);
617
+ }
618
+ out[out_len - 1] = (last_digit >> right_shift_n);
619
+ */
620
+
553
621
size_t intn_count_digits (const intn_digit_t * num , size_t num_len )
554
622
{
555
623
int i ;
0 commit comments