From 563401b24d1af2714f3e2be2796c7988e1efdfcf Mon Sep 17 00:00:00 2001 From: Daniel Lubarov Date: Sun, 17 Jul 2022 09:14:24 -0700 Subject: [PATCH] More basic ASM utility functions To be used in upcoming RLP code. --- evm/src/cpu/kernel/asm/assertions.asm | 74 ++++++++++++++++++++++++ evm/src/cpu/kernel/asm/basic_macros.asm | 77 +++++++++++++++++++++++++ 2 files changed, 151 insertions(+) create mode 100644 evm/src/cpu/kernel/asm/assertions.asm diff --git a/evm/src/cpu/kernel/asm/assertions.asm b/evm/src/cpu/kernel/asm/assertions.asm new file mode 100644 index 00000000..2a7d845e --- /dev/null +++ b/evm/src/cpu/kernel/asm/assertions.asm @@ -0,0 +1,74 @@ +// It is convenient to have a single panic routine, which we can jump to from +// anywhere. +global panic: + JUMPDEST + PANIC + +// Consumes the top element and asserts that it is zero. +%macro assert_zero + %jumpi panic +%endmacro + +// Consumes the top element and asserts that it is nonzero. +%macro assert_nonzero + ISZERO + %jumpi panic +%endmacro + +%macro assert_eq + EQ + %assert_nonzero +%endmacro + +%macro assert_lt + LT + %assert_nonzero +%endmacro + +%macro assert_le + LE + %assert_nonzero +%endmacro + +%macro assert_gt + GT + %assert_nonzero +%endmacro + +%macro assert_ge + GE + %assert_nonzero +%endmacro + +%macro assert_eq_const(c) + %eq_const(c) + %assert_nonzero +%endmacro + +%macro assert_lt_const(c) + // %assert_zero is cheaper than %assert_nonzero, so we will leverage the + // fact that (x < c) == !(x >= c). + %ge_const(c) + %assert_zero +%endmacro + +%macro assert_le_const(c) + // %assert_zero is cheaper than %assert_nonzero, so we will leverage the + // fact that (x <= c) == !(x > c). + %gt_const(c) + %assert_zero +%endmacro + +%macro assert_gt_const(c) + // %assert_zero is cheaper than %assert_nonzero, so we will leverage the + // fact that (x > c) == !(x <= c). + %le_const(c) + %assert_zero +%endmacro + +%macro assert_ge_const(c) + // %assert_zero is cheaper than %assert_nonzero, so we will leverage the + // fact that (x >= c) == !(x < c). + %lt_const(c) + %assert_zero +%endmacro diff --git a/evm/src/cpu/kernel/asm/basic_macros.asm b/evm/src/cpu/kernel/asm/basic_macros.asm index 9e884fea..7230772d 100644 --- a/evm/src/cpu/kernel/asm/basic_macros.asm +++ b/evm/src/cpu/kernel/asm/basic_macros.asm @@ -26,6 +26,83 @@ %endrep %endmacro +%macro add_const(c) + // stack: input, ... + PUSH $c + ADD + // stack: input + c, ... +%endmacro + +// Slightly inefficient as we need to swap the inputs. +// Consider avoiding this in performance-critical code. +%macro sub_const(c) + // stack: input, ... + PUSH $c + // stack: c, input, ... + SWAP1 + // stack: input, c, ... + SUB + // stack: input - c, ... +%endmacro + +%macro mul_const(c) + // stack: input, ... + PUSH $c + MUL + // stack: input * c, ... +%endmacro + +// Slightly inefficient as we need to swap the inputs. +// Consider avoiding this in performance-critical code. +%macro div_const(c) + // stack: input, ... + PUSH $c + // stack: c, input, ... + SWAP1 + // stack: input, c, ... + SUB + // stack: input / c, ... +%endmacro + +%macro eq_const(c) + // stack: input, ... + PUSH $c + EQ + // stack: input == c, ... +%endmacro + +%macro lt_const(c) + // stack: input, ... + PUSH $c + // stack: c, input, ... + GT // Check it backwards: (input < c) == (c > input) + // stack: input <= c, ... +%endmacro + +%macro le_const(c) + // stack: input, ... + PUSH $c + // stack: c, input, ... + GE // Check it backwards: (input <= c) == (c >= input) + // stack: input <= c, ... +%endmacro + +%macro gt_const(c) + // stack: input, ... + PUSH $c + // stack: c, input, ... + LT // Check it backwards: (input > c) == (c < input) + // stack: input >= c, ... +%endmacro + +%macro ge_const(c) + // stack: input, ... + PUSH $c + // stack: c, input, ... + LE // Check it backwards: (input >= c) == (c <= input) + // stack: input >= c, ... +%endmacro + // If pred is zero, yields z; otherwise, yields nz %macro select // stack: pred, nz, z