mirror of
https://github.com/logos-storage/plonky2.git
synced 2026-01-06 07:43:10 +00:00
starting on sha2
This commit is contained in:
parent
24d2414178
commit
042da0c8e9
98
evm/src/cpu/kernel/asm/helper_functions.asm
Normal file
98
evm/src/cpu/kernel/asm/helper_functions.asm
Normal file
@ -0,0 +1,98 @@
|
||||
global swapn
|
||||
// stack: n, ...
|
||||
%eq(1)
|
||||
%jumpi(case1)
|
||||
%eq(2)
|
||||
%jumpi(case2)
|
||||
%eq(3)
|
||||
%jumpi(case3)
|
||||
%eq(4)
|
||||
%jumpi(case4)
|
||||
%eq(5)
|
||||
%jumpi(case5)
|
||||
%eq(6)
|
||||
%jumpi(case6)
|
||||
%eq(7)
|
||||
%jumpi(case7)
|
||||
%eq(8)
|
||||
%jumpi(case8)
|
||||
%eq(9)
|
||||
%jumpi(case9)
|
||||
%eq(10)
|
||||
%jumpi(case10)
|
||||
%eq(11)
|
||||
%jumpi(case11)
|
||||
%eq(12)
|
||||
%jumpi(case12)
|
||||
%eq(13)
|
||||
%jumpi(case13)
|
||||
%eq(14)
|
||||
%jumpi(case14)
|
||||
%eq(15)
|
||||
%jumpi(case15)
|
||||
%eq(16)
|
||||
%jumpi(case16)
|
||||
case1:
|
||||
swap1
|
||||
case2:
|
||||
swap2
|
||||
case3:
|
||||
swap3
|
||||
case4:
|
||||
swap4
|
||||
case5:
|
||||
swap5
|
||||
case6:
|
||||
swap6
|
||||
case7:
|
||||
swap7
|
||||
case8:
|
||||
swap8
|
||||
case9:
|
||||
swap9
|
||||
case10:
|
||||
swap10
|
||||
case11:
|
||||
swap11
|
||||
case12:
|
||||
swap12
|
||||
case13:
|
||||
swap13
|
||||
case14:
|
||||
swap14
|
||||
case15:
|
||||
swap15
|
||||
case16:
|
||||
swap16
|
||||
swapn_end:
|
||||
|
||||
|
||||
global insertn:
|
||||
// stack: n, val, ...
|
||||
dup
|
||||
// stack: n, n, val, ...
|
||||
swap2
|
||||
// stack: val, n, n, ...
|
||||
swap1
|
||||
// stack: n, val, n, ...
|
||||
%swapn
|
||||
// stack: [nth], n, ..., val
|
||||
swap1
|
||||
// stack: n, [nth], ..., val
|
||||
swap_back_loop:
|
||||
// stack: k, k, [kth], ..., [k-1st]
|
||||
dup
|
||||
// stack: k, k, [kth], ..., [k-1st]
|
||||
swap2
|
||||
// stack: [kth], k, k, ..., [k-1st]
|
||||
swap1
|
||||
// stack: k, [kth], k, ..., [k-1st]
|
||||
%swapn
|
||||
// stack: [k-1st], k, ..., [k-2nd], [kth]
|
||||
swap1
|
||||
// stack: k, [k-1st], ..., [k-2nd], [kth]
|
||||
%decrement
|
||||
// stack: k-1, [k-1st], ..., [k-2nd], [kth]
|
||||
iszero
|
||||
not
|
||||
%jumpi(swap_back_loop)
|
||||
459
evm/src/cpu/kernel/asm/sha2.asm
Normal file
459
evm/src/cpu/kernel/asm/sha2.asm
Normal file
@ -0,0 +1,459 @@
|
||||
global count_bits:
|
||||
// stack: n (assumed to be > 0)
|
||||
push 0
|
||||
// stack: 0, n
|
||||
swap1
|
||||
// stack: n, 0
|
||||
count_bits_loop:
|
||||
// stack: k, bits
|
||||
%div2
|
||||
// stack: k//2, bits
|
||||
swap1
|
||||
// stack: bits, k//2
|
||||
%increment
|
||||
// stack: bits+1, k//2
|
||||
swap1
|
||||
// stack: k//2, bits+1
|
||||
%jumpi(count_bits_loop)
|
||||
// stack: 0, bits
|
||||
pop
|
||||
// stack: bits
|
||||
|
||||
// Appends a 1 to the end of the u256 at the top of the stack.
|
||||
global append_1:
|
||||
dup
|
||||
count_bits
|
||||
%eq(256)
|
||||
%jumpi(append_if256)
|
||||
%jump(append_else)
|
||||
append_if256:
|
||||
push 1
|
||||
swap1
|
||||
%jump(append_end)
|
||||
append_else:
|
||||
push 2
|
||||
mul
|
||||
push 1
|
||||
add
|
||||
append_end:
|
||||
|
||||
|
||||
global sha2_append_1:
|
||||
// stack: num_u256s, x[0], x[1], x[2], ... , x[num_u256s-1]
|
||||
// (assume num_u256s <= 16)
|
||||
dup
|
||||
// stack: num_u256s, num_u256s, x[0], x[1], x[2], ... , x[num_u256s-1]
|
||||
dup
|
||||
// stack: num_u256s, num_u256s, num_u256s, x[0], x[1], x[2], ... , x[num_u256s-1]
|
||||
%increment
|
||||
// stack: num_u256s+1, num_u256s, x[0], x[1], x[2], ... , x[num_u256s-1]
|
||||
swapn
|
||||
// stack: x[num_u256s-1], num_u256s, x[0], x[1], x[2], ... , x[num_u256s-2], num_u256s
|
||||
dup
|
||||
// stack: x[num_u256s-1], x[num_u256s-1], num_u256s, x[0], x[1], x[2], ... , x[num_u256s-2], num_u256s
|
||||
%count_bits
|
||||
// stack: num_bits, x[num_u256s-1], num_u256s, x[0], x[1], x[2], ... , x[num_u256s-2], num_u256s
|
||||
%eq(256)
|
||||
%jumpi(append_if256)
|
||||
%jump(append_else)
|
||||
append_if256:
|
||||
push 1
|
||||
// stack: 1, x[num_u256s-1], num_u256s, x[0], x[1], x[2], ... , x[num_u256s-2], num_u256s
|
||||
dup2
|
||||
// stack: num_u256s, 1, x[num_u256s-1], num_u256s, x[0], x[1], x[2], ... , x[num_u256s-2], num_u256s
|
||||
push 3
|
||||
add
|
||||
// stack: num_u256s+3, 1, x[num_u256s-1], num_u256s, x[0], x[1], x[2], ... , x[num_u256s-2], num_u256s, []
|
||||
swapn
|
||||
// stack: [], x[num_u256s-1], num_u256s, x[0], x[1], x[2], ... , x[num_u256s-2], num_u256s,
|
||||
%jump(append_continue)
|
||||
append_else:
|
||||
append_continue:
|
||||
|
||||
dup
|
||||
|
||||
|
||||
|
||||
|
||||
global sha2_pad:
|
||||
// stack: num_u256s, x[0], x[1], x[2], ... , x[num_u256s-1]
|
||||
%jumpi()
|
||||
|
||||
|
||||
append 1:
|
||||
if length of last = 256
|
||||
increment length; add new value of 10000000..0
|
||||
|
||||
stick 1 on the end (last one:)
|
||||
|
||||
if length even:
|
||||
pad last one to
|
||||
|
||||
if length odd:
|
||||
|
||||
|
||||
// stack: num_blocks, block[0][0], block[0][1], ..., block[num_blocks-1][3]
|
||||
|
||||
|
||||
// #define K0 0x30644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd47
|
||||
|
||||
|
||||
// BN254 elliptic curve addition.
|
||||
// Uses the standard affine addition formula.
|
||||
global ec_add:
|
||||
// Uncomment for test inputs.
|
||||
// PUSH 0xdeadbeef
|
||||
// PUSH 2
|
||||
// PUSH 1
|
||||
// PUSH 0x1bf9384aa3f0b3ad763aee81940cacdde1af71617c06f46e11510f14f3d5d121
|
||||
// PUSH 0xe7313274bb29566ff0c8220eb9841de1d96c2923c6a4028f7dd3c6a14cee770
|
||||
JUMPDEST
|
||||
// stack: x0, y0, x1, y1, retdest
|
||||
|
||||
// Check if points are valid BN254 points.
|
||||
DUP2
|
||||
// stack: y0, x0, y0, x1, y1, retdest
|
||||
DUP2
|
||||
// stack: x0, y0, x0, y0, x1, y1, retdest
|
||||
%ec_check
|
||||
// stack: isValid(x0, y0), x0, y0, x1, y1, retdest
|
||||
DUP5
|
||||
// stack: x1, isValid(x0, y0), x0, y0, x1, y1, retdest
|
||||
DUP5
|
||||
// stack: x1, y1, isValid(x0, y0), x0, y0, x1, y1, retdest
|
||||
%ec_check
|
||||
// stack: isValid(x1, y1), isValid(x0, y0), x0, y0, x1, y1, retdest
|
||||
AND
|
||||
// stack: isValid(x1, y1) & isValid(x0, y0), x0, y0, x1, y1, retdest
|
||||
%jumpi(ec_add_valid_points)
|
||||
// stack: x0, y0, x1, y1, retdest
|
||||
|
||||
// Otherwise return
|
||||
%pop4
|
||||
// stack: retdest
|
||||
%ec_invalid_input
|
||||
|
||||
// BN254 elliptic curve addition.
|
||||
// Assumption: (x0,y0) and (x1,y1) are valid points.
|
||||
global ec_add_valid_points:
|
||||
JUMPDEST
|
||||
// stack: x0, y0, x1, y1, retdest
|
||||
|
||||
// Check if the first point is the identity.
|
||||
DUP2
|
||||
// stack: y0, x0, y0, x1, y1, retdest
|
||||
DUP2
|
||||
// stack: x0, y0, x0, y0, x1, y1, retdest
|
||||
%ec_isidentity
|
||||
// stack: (x0,y0)==(0,0), x0, y0, x1, y1, retdest
|
||||
%jumpi(ec_add_first_zero)
|
||||
// stack: x0, y0, x1, y1, retdest
|
||||
|
||||
// Check if the first point is the identity.
|
||||
DUP4
|
||||
// stack: y1, x0, y0, x1, y1, retdest
|
||||
DUP4
|
||||
// stack: x1, y1, x0, y0, x1, y1, retdest
|
||||
%ec_isidentity
|
||||
// stack: (x1,y1)==(0,0), x0, y0, x1, y1, retdest
|
||||
%jumpi(ec_add_snd_zero)
|
||||
// stack: x0, y0, x1, y1, retdest
|
||||
|
||||
// Check if both points have the same x-coordinate.
|
||||
DUP3
|
||||
// stack: x1, x0, y0, x1, y1, retdest
|
||||
DUP2
|
||||
// stack: x0, x1, x0, y0, x1, y1, retdest
|
||||
EQ
|
||||
// stack: x0 == x1, x0, y0, x1, y1, retdest
|
||||
%jumpi(ec_add_equal_first_coord)
|
||||
// stack: x0, y0, x1, y1, retdest
|
||||
|
||||
// Otherwise, we can use the standard formula.
|
||||
// Compute lambda = (y0 - y1)/(x0 - x1)
|
||||
DUP4
|
||||
// stack: y1, x0, y0, x1, y1, retdest
|
||||
DUP3
|
||||
// stack: y0, y1, x0, y0, x1, y1, retdest
|
||||
%submod
|
||||
// stack: y0 - y1, x0, y0, x1, y1, retdest
|
||||
DUP4
|
||||
// stack: x1, y0 - y1, x0, y0, x1, y1, retdest
|
||||
DUP3
|
||||
// stack: x0, x1, y0 - y1, x0, y0, x1, y1, retdest
|
||||
%submod
|
||||
// stack: x0 - x1, y0 - y1, x0, y0, x1, y1, retdest
|
||||
%moddiv
|
||||
// stack: lambda, x0, y0, x1, y1, retdest
|
||||
%jump(ec_add_valid_points_with_lambda)
|
||||
|
||||
// BN254 elliptic curve addition.
|
||||
// Assumption: (x0,y0) == (0,0)
|
||||
ec_add_first_zero:
|
||||
JUMPDEST
|
||||
// stack: x0, y0, x1, y1, retdest
|
||||
|
||||
// Just return (x1,y1)
|
||||
%pop2
|
||||
// stack: x1, y1, retdest
|
||||
SWAP1
|
||||
// stack: y1, x1, retdest
|
||||
SWAP2
|
||||
// stack: retdest, x1, y1
|
||||
JUMP
|
||||
|
||||
// BN254 elliptic curve addition.
|
||||
// Assumption: (x1,y1) == (0,0)
|
||||
ec_add_snd_zero:
|
||||
JUMPDEST
|
||||
// stack: x0, y0, x1, y1, retdest
|
||||
|
||||
// Just return (x1,y1)
|
||||
SWAP2
|
||||
// stack: x1, y0, x0, y1, retdest
|
||||
POP
|
||||
// stack: y0, x0, y1, retdest
|
||||
SWAP2
|
||||
// stack: y1, x0, y0, retdest
|
||||
POP
|
||||
// stack: x0, y0, retdest
|
||||
SWAP1
|
||||
// stack: y0, x0, retdest
|
||||
SWAP2
|
||||
// stack: retdest, x0, y0
|
||||
JUMP
|
||||
|
||||
// BN254 elliptic curve addition.
|
||||
// Assumption: lambda = (y0 - y1)/(x0 - x1)
|
||||
ec_add_valid_points_with_lambda:
|
||||
JUMPDEST
|
||||
// stack: lambda, x0, y0, x1, y1, retdest
|
||||
|
||||
// Compute x2 = lambda^2 - x1 - x0
|
||||
DUP2
|
||||
// stack: x0, lambda, x0, y0, x1, y1, retdest
|
||||
DUP5
|
||||
// stack: x1, x0, lambda, x0, y0, x1, y1, retdest
|
||||
%bn_base
|
||||
// stack: N, x1, x0, lambda, x0, y0, x1, y1, retdest
|
||||
DUP4
|
||||
// stack: lambda, N, x1, x0, lambda, x0, y0, x1, y1, retdest
|
||||
DUP1
|
||||
// stack: lambda, lambda, N, x1, x0, lambda, x0, y0, x1, y1, retdest
|
||||
MULMOD
|
||||
// stack: lambda^2, x1, x0, lambda, x0, y0, x1, y1, retdest
|
||||
%submod
|
||||
// stack: lambda^2 - x1, x0, lambda, x0, y0, x1, y1, retdest
|
||||
%submod
|
||||
// stack: x2, lambda, x0, y0, x1, y1, retdest
|
||||
|
||||
// Compute y2 = lambda*(x1 - x2) - y1
|
||||
%bn_base
|
||||
// stack: N, x2, lambda, x0, y0, x1, y1, retdest
|
||||
DUP2
|
||||
// stack: x2, N, x2, lambda, x0, y0, x1, y1, retdest
|
||||
DUP7
|
||||
// stack: x1, x2, N, x2, lambda, x0, y0, x1, y1, retdest
|
||||
%submod
|
||||
// stack: x1 - x2, N, x2, lambda, x0, y0, x1, y1, retdest
|
||||
DUP4
|
||||
// stack: lambda, x1 - x2, N, x2, lambda, x0, y0, x1, y1, retdest
|
||||
MULMOD
|
||||
// stack: lambda * (x1 - x2), x2, lambda, x0, y0, x1, y1, retdest
|
||||
DUP7
|
||||
// stack: y1, lambda * (x1 - x2), x2, lambda, x0, y0, x1, y1, retdest
|
||||
SWAP1
|
||||
// stack: lambda * (x1 - x2), y1, x2, lambda, x0, y0, x1, y1, retdest
|
||||
%submod
|
||||
// stack: y2, x2, lambda, x0, y0, x1, y1, retdest
|
||||
|
||||
// Return x2,y2
|
||||
SWAP5
|
||||
// stack: x1, x2, lambda, x0, y0, y2, y1, retdest
|
||||
POP
|
||||
// stack: x2, lambda, x0, y0, y2, y1, retdest
|
||||
SWAP5
|
||||
// stack: y1, lambda, x0, y0, y2, x2, retdest
|
||||
%pop4
|
||||
// stack: y2, x2, retdest
|
||||
SWAP2
|
||||
// stack: retdest, x2, y2
|
||||
JUMP
|
||||
|
||||
// BN254 elliptic curve addition.
|
||||
// Assumption: (x0,y0) and (x1,y1) are valid points and x0 == x1
|
||||
ec_add_equal_first_coord:
|
||||
JUMPDEST
|
||||
// stack: x0, y0, x1, y1, retdest with x0 == x1
|
||||
|
||||
// Check if the points are equal
|
||||
DUP2
|
||||
// stack: y0, x0, y0, x1, y1, retdest
|
||||
DUP5
|
||||
// stack: y1, y0, x0, y0, x1, y1, retdest
|
||||
EQ
|
||||
// stack: y1 == y0, x0, y0, x1, y1, retdest
|
||||
%jumpi(ec_add_equal_points)
|
||||
// stack: x0, y0, x1, y1, retdest
|
||||
|
||||
// Otherwise, one is the negation of the other so we can return (0,0).
|
||||
%pop4
|
||||
// stack: retdest
|
||||
PUSH 0
|
||||
// stack: 0, retdest
|
||||
PUSH 0
|
||||
// stack: 0, 0, retdest
|
||||
SWAP2
|
||||
// stack: retdest, 0, 0
|
||||
JUMP
|
||||
|
||||
|
||||
// BN254 elliptic curve addition.
|
||||
// Assumption: x0 == x1 and y0 == y1
|
||||
// Standard doubling formula.
|
||||
ec_add_equal_points:
|
||||
JUMPDEST
|
||||
// stack: x0, y0, x1, y1, retdest
|
||||
|
||||
// Compute lambda = 3/2 * x0^2 / y0
|
||||
%bn_base
|
||||
// stack: N, x0, y0, x1, y1, retdest
|
||||
%bn_base
|
||||
// stack: N, N, x0, y0, x1, y1, retdest
|
||||
DUP3
|
||||
// stack: x0, N, N, x0, y0, x1, y1, retdest
|
||||
DUP1
|
||||
// stack: x0, x0, N, N, x0, y0, x1, y1, retdest
|
||||
MULMOD
|
||||
// stack: x0^2, N, x0, y0, x1, y1, retdest with
|
||||
PUSH 0x183227397098d014dc2822db40c0ac2ecbc0b548b438e5469e10460b6c3e7ea5 // 3/2 in the base field
|
||||
// stack: 3/2, x0^2, N, x0, y0, x1, y1, retdest
|
||||
MULMOD
|
||||
// stack: 3/2 * x0^2, x0, y0, x1, y1, retdest
|
||||
DUP3
|
||||
// stack: y0, 3/2 * x0^2, x0, y0, x1, y1, retdest
|
||||
%moddiv
|
||||
// stack: lambda, x0, y0, x1, y1, retdest
|
||||
%jump(ec_add_valid_points_with_lambda)
|
||||
|
||||
// BN254 elliptic curve doubling.
|
||||
// Assumption: (x0,y0) is a valid point.
|
||||
// Standard doubling formula.
|
||||
global ec_double:
|
||||
JUMPDEST
|
||||
// stack: x0, y0, retdest
|
||||
DUP2
|
||||
// stack: y0, x0, y0, retdest
|
||||
DUP2
|
||||
// stack: x0, y0, x0, y0, retdest
|
||||
%jump(ec_add_equal_points)
|
||||
|
||||
// Push the order of the BN254 base field.
|
||||
%macro bn_base
|
||||
PUSH 0x30644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd47
|
||||
%endmacro
|
||||
|
||||
// Assumption: x, y < N and 2N < 2^256.
|
||||
// Note: Doesn't hold for Secp256k1 base field.
|
||||
%macro submod
|
||||
// stack: x, y
|
||||
%bn_base
|
||||
// stack: N, x, y
|
||||
ADD
|
||||
// stack: N + x, y // Doesn't overflow since 2N < 2^256
|
||||
SUB
|
||||
// stack: N + x - y // Doesn't underflow since y < N
|
||||
%bn_base
|
||||
// stack: N, N + x - y
|
||||
SWAP1
|
||||
// stack: N + x - y, N
|
||||
MOD
|
||||
// stack: (N + x - y) % N = (x-y) % N
|
||||
%endmacro
|
||||
|
||||
// Check if (x,y) is a valid curve point.
|
||||
// Puts y^2 % N == (x^3 + 3) % N & (x < N) & (y < N) || (x,y)==(0,0) on top of the stack.
|
||||
%macro ec_check
|
||||
// stack: x, y
|
||||
%bn_base
|
||||
// stack: N, x, y
|
||||
DUP2
|
||||
// stack: x, N, x, y
|
||||
LT
|
||||
// stack: x < N, x, y
|
||||
%bn_base
|
||||
// stack: N, x < N, x, y
|
||||
DUP4
|
||||
// stack: y, N, x < N, x, y
|
||||
LT
|
||||
// stack: y < N, x < N, x, y
|
||||
AND
|
||||
// stack: (y < N) & (x < N), x, y
|
||||
SWAP2
|
||||
// stack: y, x, (y < N) & (x < N), x
|
||||
SWAP1
|
||||
// stack: x, y, (y < N) & (x < N)
|
||||
%bn_base
|
||||
// stack: N, x, y, b
|
||||
%bn_base
|
||||
// stack: N, N, x, y, b
|
||||
DUP3
|
||||
// stack: x, N, N, x, y, b
|
||||
%bn_base
|
||||
// stack: N, x, N, N, x, y, b
|
||||
DUP2
|
||||
// stack: x, N, x, N, N, x, y, b
|
||||
DUP1
|
||||
// stack: x, x, N, x, N, N, x, y, b
|
||||
MULMOD
|
||||
// stack: x^2 % N, x, N, N, x, y, b
|
||||
MULMOD
|
||||
// stack: x^3 % N, N, x, y, b
|
||||
PUSH 3
|
||||
// stack: 3, x^3 % N, N, x, y, b
|
||||
ADDMOD
|
||||
// stack: (x^3 + 3) % N, x, y, b
|
||||
DUP3
|
||||
// stack: y, (x^3 + 3) % N, x, y, b
|
||||
%bn_base
|
||||
// stack: N, y, (x^3 + 3) % N, x, y, b
|
||||
SWAP1
|
||||
// stack: y, N, (x^3 + 3) % N, x, y, b
|
||||
DUP1
|
||||
// stack: y, y, N, (x^3 + 3) % N, x, y, b
|
||||
MULMOD
|
||||
// stack: y^2 % N, (x^3 + 3) % N, x, y, b
|
||||
EQ
|
||||
// stack: y^2 % N == (x^3 + 3) % N, x, y, b
|
||||
SWAP2
|
||||
// stack: y, x, y^2 % N == (x^3 + 3) % N, b
|
||||
%ec_isidentity
|
||||
// stack: (x,y)==(0,0), y^2 % N == (x^3 + 3) % N, b
|
||||
SWAP2
|
||||
// stack: b, y^2 % N == (x^3 + 3) % N, (x,y)==(0,0)
|
||||
AND
|
||||
// stack: y^2 % N == (x^3 + 3) % N & (x < N) & (y < N), (x,y)==(0,0)
|
||||
OR
|
||||
// stack: y^2 % N == (x^3 + 3) % N & (x < N) & (y < N) || (x,y)==(0,0)
|
||||
%endmacro
|
||||
|
||||
// Check if (x,y)==(0,0)
|
||||
%macro ec_isidentity
|
||||
// stack: x, y
|
||||
OR
|
||||
// stack: x | y
|
||||
ISZERO
|
||||
// stack: (x,y) == (0,0)
|
||||
%endmacro
|
||||
|
||||
// Return (u256::MAX, u256::MAX) which is used to indicate the input was invalid.
|
||||
%macro ec_invalid_input
|
||||
// stack: retdest
|
||||
PUSH 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
|
||||
// stack: u256::MAX, retdest
|
||||
PUSH 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
|
||||
// stack: u256::MAX, u256::MAX, retdest
|
||||
SWAP2
|
||||
// stack: retdest, u256::MAX, u256::MAX
|
||||
JUMP
|
||||
%endmacro
|
||||
@ -229,3 +229,27 @@
|
||||
%select_bool
|
||||
// stack: max
|
||||
%endmacro
|
||||
|
||||
%macro increment
|
||||
push 1
|
||||
swap1
|
||||
sub
|
||||
%endmacro
|
||||
|
||||
%macro decrement
|
||||
push 1
|
||||
swap1
|
||||
sub
|
||||
%endmacro
|
||||
|
||||
%macro div2
|
||||
push 2
|
||||
swap1
|
||||
div
|
||||
%endmacro
|
||||
|
||||
%macro eq(x)
|
||||
dup1
|
||||
push $x
|
||||
eq
|
||||
%endmacro
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user