65 lines
2.6 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.
// Stores a * b in output_loc, leaving a and b unchanged.
// Both a and b have length len; a * b will have length 2 * len.
2023-02-16 11:36:40 -08:00
// output_loc must be initialized as 2 * len zeroes.
// TODO: possible optimization: allow output_loc to be uninitialized, and write over it with a[0:len] * b[0] (a multiplication
// with carry) in place of the first addmul.
2023-02-10 16:31:35 -08:00
global mul_bignum:
2023-02-16 11:36:40 -08:00
// stack: len, a_start_loc, b_start_loc, output_loc, retdest
2023-02-10 16:31:35 -08:00
DUP1
2023-03-14 15:33:36 -07:00
// stack: len, len, a_start_loc, b_start_loc, output_loc, retdest
ISZERO
%jumpi(len_zero)
DUP1
2023-02-16 11:36:40 -08:00
// stack: n=len, len, a_start_loc, bi=b_start_loc, output_cur=output_loc, retdest
2023-02-10 16:31:35 -08:00
mul_loop:
2023-02-16 11:36:40 -08:00
// stack: n, len, a_start_loc, bi, output_cur, retdest
2023-03-15 13:39:43 -07:00
PUSH mul_addmul_return
// stack: mul_addmul_return, n, len, a_start_loc, bi, output_cur, retdest
2023-02-10 16:31:35 -08:00
DUP5
2023-03-15 13:39:43 -07:00
// stack: bi, mul_addmul_return, n, len, a_start_loc, bi, output_cur, retdest
2023-02-10 16:31:35 -08:00
%mload_kernel_general
2023-03-15 13:39:43 -07:00
// stack: b[i], mul_addmul_return, n, len, a_start_loc, bi, output_cur, retdest, b
2023-02-13 12:53:49 -08:00
DUP5
2023-03-15 13:39:43 -07:00
// stack: a_start_loc, b[i], mul_addmul_return, n, len, a_start_loc, bi, output_cur, retdest, b
2023-02-10 16:31:35 -08:00
DUP8
2023-03-15 13:39:43 -07:00
// stack: output_loc, a_start_loc, b[i], mul_addmul_return, n, len, a_start_loc, bi, output_cur, retdest, b
2023-02-16 11:36:40 -08:00
DUP6
2023-03-15 13:39:43 -07:00
// stack: len, output_loc, a_start_loc, b[i], mul_addmul_return, n, len, a_start_loc, bi, output_cur, retdest, b
2023-02-13 12:53:49 -08:00
%jump(addmul_bignum)
2023-03-15 13:39:43 -07:00
mul_addmul_return:
// stack: carry_limb, n, len, a_start_loc, bi, output_cur, retdest
2023-02-10 16:31:35 -08:00
DUP6
2023-03-15 13:39:43 -07:00
// stack: output_cur, carry_limb, n, len, a_start_loc, bi, output_cur, retdest
2023-02-16 11:36:40 -08:00
DUP4
2023-03-15 13:39:43 -07:00
// stack: len, output_cur, carry_limb, n, len, a_start_loc, bi, output_cur, retdest
2023-02-10 16:31:35 -08:00
ADD
2023-03-15 13:39:43 -07:00
// stack: output_cur + len, carry_limb, n, len, a_start_loc, bi, output_cur, retdest
2023-02-10 16:31:35 -08:00
%mstore_kernel_general
2023-02-16 11:36:40 -08:00
// stack: n, len, a_start_loc, bi, output_cur, retdest
%decrement
// stack: n-1, len, a_start_loc, bi, output_cur, retdest
SWAP3
2023-02-10 16:31:35 -08:00
%increment
2023-02-16 11:36:40 -08:00
SWAP3
// stack: n-1, len, a_start_loc, bi+1, output_cur, retdest
SWAP4
2023-02-10 16:31:35 -08:00
%increment
2023-02-16 11:36:40 -08:00
SWAP4
// stack: n-1, len, a_start_loc, bi+1, output_cur+1, retdest
DUP1
// stack: n-1, n-1, len, a_start_loc, bi+1, output_cur+1, retdest
2023-02-10 16:31:35 -08:00
%jumpi(mul_loop)
2023-02-16 11:36:40 -08:00
mul_end:
// stack: n-1, len, a_start_loc, bi+1, output_cur+1, retdest
%pop5
// stack: retdest
2023-02-10 16:31:35 -08:00
JUMP
2023-03-14 15:33:36 -07:00
len_zero:
// stack: len, a_start_loc, b_start_loc, output_loc, retdest
%pop4
// stack: retdest
JUMP