69 lines
2.1 KiB
NASM
Raw Normal View History

2023-02-10 16:31:35 -08:00
// Arithmetic on little-endian integers represented with 128-bit limbs.
// All integers must be under a given length bound, and are padded with leading zeroes.
// Shifts a given bignum right by one bit (in place).
2023-03-14 12:20:38 -07:00
// Assumes that len > 0.
2023-02-10 16:31:35 -08:00
global shr_bignum:
2023-03-14 14:28:21 -07:00
// stack: len, start_loc, retdest
DUP1
// stack: len, len, start_loc, retdest
ISZERO
2023-03-14 15:33:36 -07:00
%jumpi(len_zero)
2023-02-10 16:31:35 -08:00
// stack: len, start_loc, retdest
DUP2
// stack: start_loc, len, start_loc, retdest
ADD
// stack: start_loc + len, start_loc, retdest
%decrement
// stack: end_loc, start_loc, retdest
%stack (e) -> (e, 0)
// stack: i=end_loc, carry=0, start_loc, retdest
shr_loop:
// stack: i, carry, start_loc, retdest
DUP1
// stack: i, i, carry, start_loc, retdest
%mload_kernel_general
// stack: a[i], i, carry, start_loc, retdest
DUP1
// stack: a[i], a[i], i, carry, start_loc, retdest
%shr_const(1)
// stack: a[i] >> 1, a[i], i, carry, start_loc, retdest
SWAP1
// stack: a[i], a[i] >> 1, i, carry, start_loc, retdest
%mod_const(2)
// stack: new_carry = a[i] % 2, a[i] >> 1, i, carry, start_loc, retdest
SWAP3
// stack: carry, a[i] >> 1, i, new_carry, start_loc, retdest
%shl_const(127)
// stack: carry << 127, a[i] >> 1, i, new_carry, start_loc, retdest
2023-03-14 12:20:38 -07:00
ADD
2023-02-10 16:31:35 -08:00
// stack: carry << 127 | a[i] >> 1, i, new_carry, start_loc, retdest
DUP2
// stack: i, carry << 127 | a[i] >> 1, i, new_carry, start_loc, retdest
%mstore_kernel_general
// stack: i, new_carry, start_loc, retdest
DUP1
// stack: i, i, new_carry, start_loc, retdest
%decrement
// stack: i-1, i, new_carry, start_loc, retdest
SWAP1
// stack: i, i-1, new_carry, start_loc, retdest
DUP4
// stack: start_loc, i, i-1, new_carry, start_loc, retdest
EQ
// stack: i == start_loc, i-1, new_carry, start_loc, retdest
ISZERO
// stack: i != start_loc, i-1, new_carry, start_loc, retdest
%jumpi(shr_loop)
shr_end:
// stack: i, new_carry, start_loc, retdest
%pop3
// stack: retdest
JUMP
2023-03-28 11:54:14 -07:00
2023-03-14 15:33:36 -07:00
len_zero:
2023-03-14 14:28:21 -07:00
// stack: len, start_loc, retdest
%pop2
// stack: retdest
JUMP