From 2ac171fa16bd24e43d4f133b6dc49c6f7cfe7ea5 Mon Sep 17 00:00:00 2001 From: Denys Zadorozhnyi Date: Fri, 19 Apr 2024 16:52:06 +0300 Subject: [PATCH] test: add semantic tests for Felt intrinsics (add, sub, mul, div, neg, eq) --- sdk/prelude/src/intrinsics/felt.rs | 30 +- tests/integration/Cargo.toml | 2 +- tests/integration/expected/add_felt.hir | 21 + tests/integration/expected/add_felt.masm | 669 +++++++++++++++++ tests/integration/expected/add_felt.wat | 14 + tests/integration/expected/div_felt.hir | 21 + tests/integration/expected/div_felt.masm | 669 +++++++++++++++++ tests/integration/expected/div_felt.wat | 14 + tests/integration/expected/eq_felt.hir | 25 + tests/integration/expected/eq_felt.masm | 671 ++++++++++++++++++ tests/integration/expected/eq_felt.wat | 16 + tests/integration/expected/ge_felt.hir | 25 + tests/integration/expected/ge_felt.masm | 671 ++++++++++++++++++ tests/integration/expected/ge_felt.wat | 16 + tests/integration/expected/gt_felt.hir | 25 + tests/integration/expected/gt_felt.masm | 671 ++++++++++++++++++ tests/integration/expected/gt_felt.wat | 16 + tests/integration/expected/le_felt.hir | 25 + tests/integration/expected/le_felt.masm | 670 +++++++++++++++++ tests/integration/expected/le_felt.wat | 16 + tests/integration/expected/lt_felt.hir | 25 + tests/integration/expected/lt_felt.masm | 670 +++++++++++++++++ tests/integration/expected/lt_felt.wat | 16 + tests/integration/expected/mul_felt.hir | 21 + tests/integration/expected/mul_felt.masm | 669 +++++++++++++++++ tests/integration/expected/mul_felt.wat | 14 + tests/integration/expected/neg_felt.hir | 21 + tests/integration/expected/neg_felt.masm | 669 +++++++++++++++++ tests/integration/expected/neg_felt.wat | 14 + tests/integration/expected/sub_felt.hir | 21 + tests/integration/expected/sub_felt.masm | 669 +++++++++++++++++ tests/integration/expected/sub_felt.wat | 14 + tests/integration/src/felt_conversion.rs | 19 + .../src/rust_masm_tests/intrinsics.rs | 117 ++- 34 files changed, 7219 insertions(+), 27 deletions(-) create mode 100644 tests/integration/expected/add_felt.hir create mode 100644 tests/integration/expected/add_felt.masm create mode 100644 tests/integration/expected/add_felt.wat create mode 100644 tests/integration/expected/div_felt.hir create mode 100644 tests/integration/expected/div_felt.masm create mode 100644 tests/integration/expected/div_felt.wat create mode 100644 tests/integration/expected/eq_felt.hir create mode 100644 tests/integration/expected/eq_felt.masm create mode 100644 tests/integration/expected/eq_felt.wat create mode 100644 tests/integration/expected/ge_felt.hir create mode 100644 tests/integration/expected/ge_felt.masm create mode 100644 tests/integration/expected/ge_felt.wat create mode 100644 tests/integration/expected/gt_felt.hir create mode 100644 tests/integration/expected/gt_felt.masm create mode 100644 tests/integration/expected/gt_felt.wat create mode 100644 tests/integration/expected/le_felt.hir create mode 100644 tests/integration/expected/le_felt.masm create mode 100644 tests/integration/expected/le_felt.wat create mode 100644 tests/integration/expected/lt_felt.hir create mode 100644 tests/integration/expected/lt_felt.masm create mode 100644 tests/integration/expected/lt_felt.wat create mode 100644 tests/integration/expected/mul_felt.hir create mode 100644 tests/integration/expected/mul_felt.masm create mode 100644 tests/integration/expected/mul_felt.wat create mode 100644 tests/integration/expected/neg_felt.hir create mode 100644 tests/integration/expected/neg_felt.masm create mode 100644 tests/integration/expected/neg_felt.wat create mode 100644 tests/integration/expected/sub_felt.hir create mode 100644 tests/integration/expected/sub_felt.masm create mode 100644 tests/integration/expected/sub_felt.wat diff --git a/sdk/prelude/src/intrinsics/felt.rs b/sdk/prelude/src/intrinsics/felt.rs index 141123837..460d55c02 100644 --- a/sdk/prelude/src/intrinsics/felt.rs +++ b/sdk/prelude/src/intrinsics/felt.rs @@ -1,4 +1,4 @@ -use core::ops::{Add, Div, Mul, Neg, Sub}; +use core::ops::{Add, AddAssign, Div, DivAssign, Mul, MulAssign, Neg, Sub, SubAssign}; #[link(wasm_import_module = "miden:prelude/intrinsics_felt")] extern "C" { @@ -171,6 +171,13 @@ impl Add for Felt { } } +impl AddAssign for Felt { + #[inline(always)] + fn add_assign(&mut self, other: Self) { + *self = *self + other; + } +} + impl Sub for Felt { type Output = Self; @@ -180,6 +187,13 @@ impl Sub for Felt { } } +impl SubAssign for Felt { + #[inline(always)] + fn sub_assign(&mut self, other: Self) { + *self = *self - other; + } +} + impl Mul for Felt { type Output = Self; @@ -189,6 +203,13 @@ impl Mul for Felt { } } +impl MulAssign for Felt { + #[inline(always)] + fn mul_assign(&mut self, other: Self) { + *self = *self * other; + } +} + impl Div for Felt { type Output = Self; @@ -198,6 +219,13 @@ impl Div for Felt { } } +impl DivAssign for Felt { + #[inline(always)] + fn div_assign(&mut self, other: Self) { + *self = *self / other; + } +} + impl Neg for Felt { type Output = Self; diff --git a/tests/integration/Cargo.toml b/tests/integration/Cargo.toml index 2cd94ab01..89e707eca 100644 --- a/tests/integration/Cargo.toml +++ b/tests/integration/Cargo.toml @@ -33,8 +33,8 @@ cargo-util = "0.2" filetime = "0.2.23" glob = "0.3.1" walkdir = "2.5.0" +proptest.workspace = true [dev-dependencies] miden-core.workspace = true -proptest.workspace = true concat-idents = "1.1" diff --git a/tests/integration/expected/add_felt.hir b/tests/integration/expected/add_felt.hir new file mode 100644 index 000000000..7bdcb4680 --- /dev/null +++ b/tests/integration/expected/add_felt.hir @@ -0,0 +1,21 @@ +(component + ;; Modules + (module #add_felt + ;; Constants + (const (id 0) 0x00100000) + + ;; Global Variables + (global (export #__stack_pointer) (id 0) (type i32) (const 0)) + + ;; Functions + (func (export #entrypoint) (param felt) (param felt) (result felt) + (block 0 (param v0 felt) (param v1 felt) + (let (v3 felt) (add.unchecked v0 v1)) + (br (block 1 v3))) + + (block 1 (param v2 felt) + (ret v2)) + ) + ) + +) diff --git a/tests/integration/expected/add_felt.masm b/tests/integration/expected/add_felt.masm new file mode 100644 index 000000000..2262c117f --- /dev/null +++ b/tests/integration/expected/add_felt.masm @@ -0,0 +1,669 @@ +mod add_felt + +export.entrypoint + swap.1 + add +end + +mod intrinsics::i32 + +export.is_signed + push.2147483648 + u32and + push.2147483648 + eq +end + +export.unchecked_neg + u32not + u32wrapping_add.1 +end + +export.checked_neg + dup.0 + push.2147483648 + eq + assertz + exec.unchecked_neg +end + +export.overflowing_add + u32assert2 + dup.0 + exec.is_signed + dup.2 + exec.is_signed + dup.1 + eq + movup.3 + movup.3 + u32wrapping_add + dup.0 + exec.is_signed + movup.3 + neq + movup.2 + and +end + +export.wrapping_add + exec.overflowing_add + drop +end + +export.checked_add + exec.overflowing_add + assertz +end + +export.overflowing_sub + u32assert2 + dup.0 + push.2147483648 + eq + if.true + drop + push.2147483647 + dup.1 + exec.is_signed + dup.0 + eq.0 + movup.3 + movup.3 + u32wrapping_add + push.1 + u32wrapping_add + dup.0 + exec.is_signed + movup.3 + neq + movup.2 + and + else + exec.unchecked_neg + exec.overflowing_add + end +end + +export.wrapping_sub + exec.overflowing_sub + drop +end + +export.checked_sub + exec.overflowing_sub + assertz +end + +export.overflowing_mul + u32assert2 + dup.0 + push.2147483648 + eq + dup.2 + push.2147483648 + eq + or + if.true + dup.0 + eq.1 + dup.2 + eq.1 + or + movup.2 + push.4294967295 + eq + movup.2 + push.4294967295 + eq + or + dup.1 + or + push.2147483648 + push.0 + swap.2 + cdrop + swap.1 + not + else + dup.0 + exec.is_signed + dup.2 + exec.is_signed + dup.1 + dup.1 + neq + movdn.4 + movup.3 + dup.0 + exec.unchecked_neg + movup.2 + cdrop + swap.2 + dup.0 + exec.unchecked_neg + movup.2 + cdrop + u32overflowing_mul + dup.1 + exec.is_signed + or + swap.1 + dup.0 + exec.unchecked_neg + movup.3 + cdrop + swap.1 + end +end + +export.wrapping_mul + exec.overflowing_mul + drop +end + +export.checked_mul + exec.overflowing_mul + assertz +end + +export.checked_div + u32assert2 + dup.1 + exec.unchecked_neg + dup.2 + swap.1 + movup.3 + exec.is_signed + dup.0 + movdn.4 + cdrop + dup.1 + exec.unchecked_neg + dup.2 + swap.1 + movup.3 + exec.is_signed + dup.0 + movdn.5 + cdrop + u32div + movdn.2 + neq + dup.1 + exec.unchecked_neg + swap.1 + cdrop +end + +export.icmp + dup.1 + dup.1 + push.2147483648 + u32and + swap.1 + push.2147483648 + u32and + eq.0 + swap.1 + eq.0 + swap.1 + dup.1 + neq + if.true + movdn.2 + drop + drop + push.4294967295 + push.1 + swap.2 + cdrop + else + drop + dup.1 + dup.1 + u32gt + movdn.2 + u32lt + push.0 + push.4294967295 + push.1 + swap.3 + cdrop + swap.2 + cdrop + end +end + +export.is_lt + exec.icmp + push.4294967295 + eq +end + +export.is_lte + exec.icmp + neq.1 +end + +export.is_gt + exec.icmp + eq.1 +end + +export.is_gte + exec.icmp + push.4294967295 + neq +end + +export.pow2 + dup.0 + push.31 + u32lt + assert + push.1 + swap.1 + u32shl +end + +export.ipow + dup.0 + push.31 + u32lt + assert + dup.0 + eq.0 + dup.2 + eq.0 + or + if.true + eq.0 + push.1 + push.0 + swap.2 + cdrop + swap.1 + drop + else + push.1 + dup.1 + push.1 + u32gt + while.true + dup.2 + dup.1 + u32wrapping_mul + dup.2 + push.1 + u32and + eq.1 + cdrop + swap.1 + u32div.2 + movup.2 + dup.0 + u32wrapping_mul + swap.1 + movup.2 + dup.1 + push.1 + u32gt + end + swap.1 + drop + u32wrapping_mul + end +end + +export.checked_shr + dup.0 + push.32 + u32lt + assert + dup.0 + eq.0 + dup.2 + eq.0 + or + if.true + eq.0 + swap.1 + push.0 + swap.2 + cdrop + else + dup.1 + push.2147483648 + u32and + push.2147483648 + eq + if.true + swap.1 + dup.1 + u32shr + push.1 + dup.2 + u32shl + sub.1 + push.32 + movup.3 + sub + u32shl + u32or + u32assert + else + u32shr + u32assert + end + end +end + +mod intrinsics::mem + +export.extract_element + dup.0 + push.3 + lte + assert + dup.0 + push.3 + lt + movdn.5 + dup.0 + push.2 + lt + movdn.5 + push.1 + lt + cdrop + movup.3 + cdrop + movup.2 + cdrop +end + +proc.load_felt_unchecked + padw + movup.4 + mem_loadw + movup.4 + exec.extract_element +end + +export.load_felt + movup.2 + assertz + exec.load_felt_unchecked +end + +export.load_sw + dup.2 + eq.0 + dup.3 + push.8 + u32lt + assert + if.true + movup.2 + drop + exec.load_felt_unchecked + else + dup.1 + eq.0 + if.true + swap.1 + drop + padw + movup.4 + mem_loadw + movup.3 + movup.3 + drop + drop + dup.2 + u32shl + swap.1 + push.32 + movup.3 + u32overflowing_sub + assertz + u32shr + u32or + else + dup.1 + eq.1 + if.true + swap.1 + drop + padw + movup.4 + mem_loadw + drop + movdn.2 + movdn.2 + drop + dup.2 + u32shl + swap.1 + push.32 + movup.3 + u32overflowing_sub + assertz + u32shr + u32or + else + swap.1 + eq.2 + if.true + padw + movup.4 + mem_loadw + drop + drop + dup.2 + u32shl + swap.1 + push.32 + movup.3 + u32overflowing_sub + assertz + u32shr + u32or + else + dup.0 + u32overflowing_add.1 + assertz + padw + movup.4 + mem_loadw + movdn.4 + drop + drop + drop + push.32 + dup.3 + u32overflowing_sub + assertz + u32shr + swap.1 + padw + movup.4 + mem_loadw + drop + drop + drop + movup.2 + u32shl + u32or + end + end + end + end +end + +export.realign_dw + dup.3 + u32shl + movdn.2 + dup.0 + push.32 + dup.4 + u32shr + movup.4 + u32or + movdn.2 + dup.3 + u32shl + swap.1 + push.32 + movup.4 + u32shr + u32or + swap.1 +end + +export.load_dw + dup.2 + eq.0 + dup.3 + push.8 + u32lt + assert + if.true + movup.2 + drop + dup.1 + eq.0 + if.true + swap.1 + drop + padw + movup.4 + mem_loadw + movup.4 + movup.4 + drop + drop + else + dup.1 + eq.1 + if.true + swap.1 + drop + padw + movup.4 + mem_loadw + drop + movup.3 + drop + else + swap.1 + eq.2 + if.true + padw + movup.4 + mem_loadw + drop + drop + else + dup.0 + u32overflowing_add.1 + assertz + padw + movup.4 + mem_loadw + movup.4 + movup.4 + movup.4 + drop + drop + drop + movup.4 + padw + movup.4 + mem_loadw + drop + drop + drop + end + end + end + else + dup.1 + eq.0 + if.true + swap.1 + drop + padw + movup.4 + mem_loadw + movup.4 + drop + exec.realign_dw + else + dup.1 + eq.1 + if.true + swap.1 + drop + padw + movup.4 + mem_loadw + drop + exec.realign_dw + else + swap.1 + eq.2 + if.true + dup.0 + u32overflowing_add.1 + assertz + padw + movup.4 + mem_loadw + movup.4 + movup.4 + movup.4 + drop + drop + drop + swap.1 + padw + movup.4 + mem_loadw + drop + drop + exec.realign_dw + else + dup.0 + u32overflowing_add.1 + assertz + padw + movup.4 + mem_loadw + movup.4 + movup.4 + drop + drop + movup.2 + padw + movup.4 + mem_loadw + drop + drop + drop + exec.realign_dw + end + end + end + end +end + +program + +use add_felt + +begin + exec.add_felt::entrypoint +end diff --git a/tests/integration/expected/add_felt.wat b/tests/integration/expected/add_felt.wat new file mode 100644 index 000000000..ee7953121 --- /dev/null +++ b/tests/integration/expected/add_felt.wat @@ -0,0 +1,14 @@ +(module $add_felt.wasm + (type (;0;) (func (param f64 f64) (result f64))) + (import "miden:prelude/intrinsics_felt" "add" (func $miden_prelude::intrinsics::felt::extern_add (;0;) (type 0))) + (func $entrypoint (;1;) (type 0) (param f64 f64) (result f64) + local.get 0 + local.get 1 + call $miden_prelude::intrinsics::felt::extern_add + ) + (table (;0;) 1 1 funcref) + (memory (;0;) 16) + (global $__stack_pointer (;0;) (mut i32) i32.const 1048576) + (export "memory" (memory 0)) + (export "entrypoint" (func $entrypoint)) +) \ No newline at end of file diff --git a/tests/integration/expected/div_felt.hir b/tests/integration/expected/div_felt.hir new file mode 100644 index 000000000..4f0d41b79 --- /dev/null +++ b/tests/integration/expected/div_felt.hir @@ -0,0 +1,21 @@ +(component + ;; Modules + (module #div_felt + ;; Constants + (const (id 0) 0x00100000) + + ;; Global Variables + (global (export #__stack_pointer) (id 0) (type i32) (const 0)) + + ;; Functions + (func (export #entrypoint) (param felt) (param felt) (result felt) + (block 0 (param v0 felt) (param v1 felt) + (let (v3 felt) (div.unchecked v0 v1)) + (br (block 1 v3))) + + (block 1 (param v2 felt) + (ret v2)) + ) + ) + +) diff --git a/tests/integration/expected/div_felt.masm b/tests/integration/expected/div_felt.masm new file mode 100644 index 000000000..5288db37a --- /dev/null +++ b/tests/integration/expected/div_felt.masm @@ -0,0 +1,669 @@ +mod div_felt + +export.entrypoint + swap.1 + div +end + +mod intrinsics::i32 + +export.is_signed + push.2147483648 + u32and + push.2147483648 + eq +end + +export.unchecked_neg + u32not + u32wrapping_add.1 +end + +export.checked_neg + dup.0 + push.2147483648 + eq + assertz + exec.unchecked_neg +end + +export.overflowing_add + u32assert2 + dup.0 + exec.is_signed + dup.2 + exec.is_signed + dup.1 + eq + movup.3 + movup.3 + u32wrapping_add + dup.0 + exec.is_signed + movup.3 + neq + movup.2 + and +end + +export.wrapping_add + exec.overflowing_add + drop +end + +export.checked_add + exec.overflowing_add + assertz +end + +export.overflowing_sub + u32assert2 + dup.0 + push.2147483648 + eq + if.true + drop + push.2147483647 + dup.1 + exec.is_signed + dup.0 + eq.0 + movup.3 + movup.3 + u32wrapping_add + push.1 + u32wrapping_add + dup.0 + exec.is_signed + movup.3 + neq + movup.2 + and + else + exec.unchecked_neg + exec.overflowing_add + end +end + +export.wrapping_sub + exec.overflowing_sub + drop +end + +export.checked_sub + exec.overflowing_sub + assertz +end + +export.overflowing_mul + u32assert2 + dup.0 + push.2147483648 + eq + dup.2 + push.2147483648 + eq + or + if.true + dup.0 + eq.1 + dup.2 + eq.1 + or + movup.2 + push.4294967295 + eq + movup.2 + push.4294967295 + eq + or + dup.1 + or + push.2147483648 + push.0 + swap.2 + cdrop + swap.1 + not + else + dup.0 + exec.is_signed + dup.2 + exec.is_signed + dup.1 + dup.1 + neq + movdn.4 + movup.3 + dup.0 + exec.unchecked_neg + movup.2 + cdrop + swap.2 + dup.0 + exec.unchecked_neg + movup.2 + cdrop + u32overflowing_mul + dup.1 + exec.is_signed + or + swap.1 + dup.0 + exec.unchecked_neg + movup.3 + cdrop + swap.1 + end +end + +export.wrapping_mul + exec.overflowing_mul + drop +end + +export.checked_mul + exec.overflowing_mul + assertz +end + +export.checked_div + u32assert2 + dup.1 + exec.unchecked_neg + dup.2 + swap.1 + movup.3 + exec.is_signed + dup.0 + movdn.4 + cdrop + dup.1 + exec.unchecked_neg + dup.2 + swap.1 + movup.3 + exec.is_signed + dup.0 + movdn.5 + cdrop + u32div + movdn.2 + neq + dup.1 + exec.unchecked_neg + swap.1 + cdrop +end + +export.icmp + dup.1 + dup.1 + push.2147483648 + u32and + swap.1 + push.2147483648 + u32and + eq.0 + swap.1 + eq.0 + swap.1 + dup.1 + neq + if.true + movdn.2 + drop + drop + push.4294967295 + push.1 + swap.2 + cdrop + else + drop + dup.1 + dup.1 + u32gt + movdn.2 + u32lt + push.0 + push.4294967295 + push.1 + swap.3 + cdrop + swap.2 + cdrop + end +end + +export.is_lt + exec.icmp + push.4294967295 + eq +end + +export.is_lte + exec.icmp + neq.1 +end + +export.is_gt + exec.icmp + eq.1 +end + +export.is_gte + exec.icmp + push.4294967295 + neq +end + +export.pow2 + dup.0 + push.31 + u32lt + assert + push.1 + swap.1 + u32shl +end + +export.ipow + dup.0 + push.31 + u32lt + assert + dup.0 + eq.0 + dup.2 + eq.0 + or + if.true + eq.0 + push.1 + push.0 + swap.2 + cdrop + swap.1 + drop + else + push.1 + dup.1 + push.1 + u32gt + while.true + dup.2 + dup.1 + u32wrapping_mul + dup.2 + push.1 + u32and + eq.1 + cdrop + swap.1 + u32div.2 + movup.2 + dup.0 + u32wrapping_mul + swap.1 + movup.2 + dup.1 + push.1 + u32gt + end + swap.1 + drop + u32wrapping_mul + end +end + +export.checked_shr + dup.0 + push.32 + u32lt + assert + dup.0 + eq.0 + dup.2 + eq.0 + or + if.true + eq.0 + swap.1 + push.0 + swap.2 + cdrop + else + dup.1 + push.2147483648 + u32and + push.2147483648 + eq + if.true + swap.1 + dup.1 + u32shr + push.1 + dup.2 + u32shl + sub.1 + push.32 + movup.3 + sub + u32shl + u32or + u32assert + else + u32shr + u32assert + end + end +end + +mod intrinsics::mem + +export.extract_element + dup.0 + push.3 + lte + assert + dup.0 + push.3 + lt + movdn.5 + dup.0 + push.2 + lt + movdn.5 + push.1 + lt + cdrop + movup.3 + cdrop + movup.2 + cdrop +end + +proc.load_felt_unchecked + padw + movup.4 + mem_loadw + movup.4 + exec.extract_element +end + +export.load_felt + movup.2 + assertz + exec.load_felt_unchecked +end + +export.load_sw + dup.2 + eq.0 + dup.3 + push.8 + u32lt + assert + if.true + movup.2 + drop + exec.load_felt_unchecked + else + dup.1 + eq.0 + if.true + swap.1 + drop + padw + movup.4 + mem_loadw + movup.3 + movup.3 + drop + drop + dup.2 + u32shl + swap.1 + push.32 + movup.3 + u32overflowing_sub + assertz + u32shr + u32or + else + dup.1 + eq.1 + if.true + swap.1 + drop + padw + movup.4 + mem_loadw + drop + movdn.2 + movdn.2 + drop + dup.2 + u32shl + swap.1 + push.32 + movup.3 + u32overflowing_sub + assertz + u32shr + u32or + else + swap.1 + eq.2 + if.true + padw + movup.4 + mem_loadw + drop + drop + dup.2 + u32shl + swap.1 + push.32 + movup.3 + u32overflowing_sub + assertz + u32shr + u32or + else + dup.0 + u32overflowing_add.1 + assertz + padw + movup.4 + mem_loadw + movdn.4 + drop + drop + drop + push.32 + dup.3 + u32overflowing_sub + assertz + u32shr + swap.1 + padw + movup.4 + mem_loadw + drop + drop + drop + movup.2 + u32shl + u32or + end + end + end + end +end + +export.realign_dw + dup.3 + u32shl + movdn.2 + dup.0 + push.32 + dup.4 + u32shr + movup.4 + u32or + movdn.2 + dup.3 + u32shl + swap.1 + push.32 + movup.4 + u32shr + u32or + swap.1 +end + +export.load_dw + dup.2 + eq.0 + dup.3 + push.8 + u32lt + assert + if.true + movup.2 + drop + dup.1 + eq.0 + if.true + swap.1 + drop + padw + movup.4 + mem_loadw + movup.4 + movup.4 + drop + drop + else + dup.1 + eq.1 + if.true + swap.1 + drop + padw + movup.4 + mem_loadw + drop + movup.3 + drop + else + swap.1 + eq.2 + if.true + padw + movup.4 + mem_loadw + drop + drop + else + dup.0 + u32overflowing_add.1 + assertz + padw + movup.4 + mem_loadw + movup.4 + movup.4 + movup.4 + drop + drop + drop + movup.4 + padw + movup.4 + mem_loadw + drop + drop + drop + end + end + end + else + dup.1 + eq.0 + if.true + swap.1 + drop + padw + movup.4 + mem_loadw + movup.4 + drop + exec.realign_dw + else + dup.1 + eq.1 + if.true + swap.1 + drop + padw + movup.4 + mem_loadw + drop + exec.realign_dw + else + swap.1 + eq.2 + if.true + dup.0 + u32overflowing_add.1 + assertz + padw + movup.4 + mem_loadw + movup.4 + movup.4 + movup.4 + drop + drop + drop + swap.1 + padw + movup.4 + mem_loadw + drop + drop + exec.realign_dw + else + dup.0 + u32overflowing_add.1 + assertz + padw + movup.4 + mem_loadw + movup.4 + movup.4 + drop + drop + movup.2 + padw + movup.4 + mem_loadw + drop + drop + drop + exec.realign_dw + end + end + end + end +end + +program + +use div_felt + +begin + exec.div_felt::entrypoint +end diff --git a/tests/integration/expected/div_felt.wat b/tests/integration/expected/div_felt.wat new file mode 100644 index 000000000..a47436670 --- /dev/null +++ b/tests/integration/expected/div_felt.wat @@ -0,0 +1,14 @@ +(module $div_felt.wasm + (type (;0;) (func (param f64 f64) (result f64))) + (import "miden:prelude/intrinsics_felt" "div" (func $miden_prelude::intrinsics::felt::extern_div (;0;) (type 0))) + (func $entrypoint (;1;) (type 0) (param f64 f64) (result f64) + local.get 0 + local.get 1 + call $miden_prelude::intrinsics::felt::extern_div + ) + (table (;0;) 1 1 funcref) + (memory (;0;) 16) + (global $__stack_pointer (;0;) (mut i32) i32.const 1048576) + (export "memory" (memory 0)) + (export "entrypoint" (func $entrypoint)) +) \ No newline at end of file diff --git a/tests/integration/expected/eq_felt.hir b/tests/integration/expected/eq_felt.hir new file mode 100644 index 000000000..934012644 --- /dev/null +++ b/tests/integration/expected/eq_felt.hir @@ -0,0 +1,25 @@ +(component + ;; Modules + (module #eq_felt + ;; Constants + (const (id 0) 0x00100000) + + ;; Global Variables + (global (export #__stack_pointer) (id 0) (type i32) (const 0)) + + ;; Functions + (func (export #entrypoint) (param felt) (param felt) (result i32) + (block 0 (param v0 felt) (param v1 felt) + (let (v3 i1) (eq v0 v1)) + (let (v4 i32) (cast v3)) + (let (v5 i32) (const.i32 1)) + (let (v6 i1) (eq v4 v5)) + (let (v7 i32) (cast v6)) + (br (block 1 v7))) + + (block 1 (param v2 i32) + (ret v2)) + ) + ) + +) diff --git a/tests/integration/expected/eq_felt.masm b/tests/integration/expected/eq_felt.masm new file mode 100644 index 000000000..347ec3797 --- /dev/null +++ b/tests/integration/expected/eq_felt.masm @@ -0,0 +1,671 @@ +mod eq_felt + +export.entrypoint + swap.1 + eq + push.1 + eq +end + +mod intrinsics::i32 + +export.is_signed + push.2147483648 + u32and + push.2147483648 + eq +end + +export.unchecked_neg + u32not + u32wrapping_add.1 +end + +export.checked_neg + dup.0 + push.2147483648 + eq + assertz + exec.unchecked_neg +end + +export.overflowing_add + u32assert2 + dup.0 + exec.is_signed + dup.2 + exec.is_signed + dup.1 + eq + movup.3 + movup.3 + u32wrapping_add + dup.0 + exec.is_signed + movup.3 + neq + movup.2 + and +end + +export.wrapping_add + exec.overflowing_add + drop +end + +export.checked_add + exec.overflowing_add + assertz +end + +export.overflowing_sub + u32assert2 + dup.0 + push.2147483648 + eq + if.true + drop + push.2147483647 + dup.1 + exec.is_signed + dup.0 + eq.0 + movup.3 + movup.3 + u32wrapping_add + push.1 + u32wrapping_add + dup.0 + exec.is_signed + movup.3 + neq + movup.2 + and + else + exec.unchecked_neg + exec.overflowing_add + end +end + +export.wrapping_sub + exec.overflowing_sub + drop +end + +export.checked_sub + exec.overflowing_sub + assertz +end + +export.overflowing_mul + u32assert2 + dup.0 + push.2147483648 + eq + dup.2 + push.2147483648 + eq + or + if.true + dup.0 + eq.1 + dup.2 + eq.1 + or + movup.2 + push.4294967295 + eq + movup.2 + push.4294967295 + eq + or + dup.1 + or + push.2147483648 + push.0 + swap.2 + cdrop + swap.1 + not + else + dup.0 + exec.is_signed + dup.2 + exec.is_signed + dup.1 + dup.1 + neq + movdn.4 + movup.3 + dup.0 + exec.unchecked_neg + movup.2 + cdrop + swap.2 + dup.0 + exec.unchecked_neg + movup.2 + cdrop + u32overflowing_mul + dup.1 + exec.is_signed + or + swap.1 + dup.0 + exec.unchecked_neg + movup.3 + cdrop + swap.1 + end +end + +export.wrapping_mul + exec.overflowing_mul + drop +end + +export.checked_mul + exec.overflowing_mul + assertz +end + +export.checked_div + u32assert2 + dup.1 + exec.unchecked_neg + dup.2 + swap.1 + movup.3 + exec.is_signed + dup.0 + movdn.4 + cdrop + dup.1 + exec.unchecked_neg + dup.2 + swap.1 + movup.3 + exec.is_signed + dup.0 + movdn.5 + cdrop + u32div + movdn.2 + neq + dup.1 + exec.unchecked_neg + swap.1 + cdrop +end + +export.icmp + dup.1 + dup.1 + push.2147483648 + u32and + swap.1 + push.2147483648 + u32and + eq.0 + swap.1 + eq.0 + swap.1 + dup.1 + neq + if.true + movdn.2 + drop + drop + push.4294967295 + push.1 + swap.2 + cdrop + else + drop + dup.1 + dup.1 + u32gt + movdn.2 + u32lt + push.0 + push.4294967295 + push.1 + swap.3 + cdrop + swap.2 + cdrop + end +end + +export.is_lt + exec.icmp + push.4294967295 + eq +end + +export.is_lte + exec.icmp + neq.1 +end + +export.is_gt + exec.icmp + eq.1 +end + +export.is_gte + exec.icmp + push.4294967295 + neq +end + +export.pow2 + dup.0 + push.31 + u32lt + assert + push.1 + swap.1 + u32shl +end + +export.ipow + dup.0 + push.31 + u32lt + assert + dup.0 + eq.0 + dup.2 + eq.0 + or + if.true + eq.0 + push.1 + push.0 + swap.2 + cdrop + swap.1 + drop + else + push.1 + dup.1 + push.1 + u32gt + while.true + dup.2 + dup.1 + u32wrapping_mul + dup.2 + push.1 + u32and + eq.1 + cdrop + swap.1 + u32div.2 + movup.2 + dup.0 + u32wrapping_mul + swap.1 + movup.2 + dup.1 + push.1 + u32gt + end + swap.1 + drop + u32wrapping_mul + end +end + +export.checked_shr + dup.0 + push.32 + u32lt + assert + dup.0 + eq.0 + dup.2 + eq.0 + or + if.true + eq.0 + swap.1 + push.0 + swap.2 + cdrop + else + dup.1 + push.2147483648 + u32and + push.2147483648 + eq + if.true + swap.1 + dup.1 + u32shr + push.1 + dup.2 + u32shl + sub.1 + push.32 + movup.3 + sub + u32shl + u32or + u32assert + else + u32shr + u32assert + end + end +end + +mod intrinsics::mem + +export.extract_element + dup.0 + push.3 + lte + assert + dup.0 + push.3 + lt + movdn.5 + dup.0 + push.2 + lt + movdn.5 + push.1 + lt + cdrop + movup.3 + cdrop + movup.2 + cdrop +end + +proc.load_felt_unchecked + padw + movup.4 + mem_loadw + movup.4 + exec.extract_element +end + +export.load_felt + movup.2 + assertz + exec.load_felt_unchecked +end + +export.load_sw + dup.2 + eq.0 + dup.3 + push.8 + u32lt + assert + if.true + movup.2 + drop + exec.load_felt_unchecked + else + dup.1 + eq.0 + if.true + swap.1 + drop + padw + movup.4 + mem_loadw + movup.3 + movup.3 + drop + drop + dup.2 + u32shl + swap.1 + push.32 + movup.3 + u32overflowing_sub + assertz + u32shr + u32or + else + dup.1 + eq.1 + if.true + swap.1 + drop + padw + movup.4 + mem_loadw + drop + movdn.2 + movdn.2 + drop + dup.2 + u32shl + swap.1 + push.32 + movup.3 + u32overflowing_sub + assertz + u32shr + u32or + else + swap.1 + eq.2 + if.true + padw + movup.4 + mem_loadw + drop + drop + dup.2 + u32shl + swap.1 + push.32 + movup.3 + u32overflowing_sub + assertz + u32shr + u32or + else + dup.0 + u32overflowing_add.1 + assertz + padw + movup.4 + mem_loadw + movdn.4 + drop + drop + drop + push.32 + dup.3 + u32overflowing_sub + assertz + u32shr + swap.1 + padw + movup.4 + mem_loadw + drop + drop + drop + movup.2 + u32shl + u32or + end + end + end + end +end + +export.realign_dw + dup.3 + u32shl + movdn.2 + dup.0 + push.32 + dup.4 + u32shr + movup.4 + u32or + movdn.2 + dup.3 + u32shl + swap.1 + push.32 + movup.4 + u32shr + u32or + swap.1 +end + +export.load_dw + dup.2 + eq.0 + dup.3 + push.8 + u32lt + assert + if.true + movup.2 + drop + dup.1 + eq.0 + if.true + swap.1 + drop + padw + movup.4 + mem_loadw + movup.4 + movup.4 + drop + drop + else + dup.1 + eq.1 + if.true + swap.1 + drop + padw + movup.4 + mem_loadw + drop + movup.3 + drop + else + swap.1 + eq.2 + if.true + padw + movup.4 + mem_loadw + drop + drop + else + dup.0 + u32overflowing_add.1 + assertz + padw + movup.4 + mem_loadw + movup.4 + movup.4 + movup.4 + drop + drop + drop + movup.4 + padw + movup.4 + mem_loadw + drop + drop + drop + end + end + end + else + dup.1 + eq.0 + if.true + swap.1 + drop + padw + movup.4 + mem_loadw + movup.4 + drop + exec.realign_dw + else + dup.1 + eq.1 + if.true + swap.1 + drop + padw + movup.4 + mem_loadw + drop + exec.realign_dw + else + swap.1 + eq.2 + if.true + dup.0 + u32overflowing_add.1 + assertz + padw + movup.4 + mem_loadw + movup.4 + movup.4 + movup.4 + drop + drop + drop + swap.1 + padw + movup.4 + mem_loadw + drop + drop + exec.realign_dw + else + dup.0 + u32overflowing_add.1 + assertz + padw + movup.4 + mem_loadw + movup.4 + movup.4 + drop + drop + movup.2 + padw + movup.4 + mem_loadw + drop + drop + drop + exec.realign_dw + end + end + end + end +end + +program + +use eq_felt + +begin + exec.eq_felt::entrypoint +end diff --git a/tests/integration/expected/eq_felt.wat b/tests/integration/expected/eq_felt.wat new file mode 100644 index 000000000..8f8212ea1 --- /dev/null +++ b/tests/integration/expected/eq_felt.wat @@ -0,0 +1,16 @@ +(module $eq_felt.wasm + (type (;0;) (func (param f64 f64) (result i32))) + (import "miden:prelude/intrinsics_felt" "eq" (func $miden_prelude::intrinsics::felt::extern_eq (;0;) (type 0))) + (func $entrypoint (;1;) (type 0) (param f64 f64) (result i32) + local.get 0 + local.get 1 + call $miden_prelude::intrinsics::felt::extern_eq + i32.const 1 + i32.eq + ) + (table (;0;) 1 1 funcref) + (memory (;0;) 16) + (global $__stack_pointer (;0;) (mut i32) i32.const 1048576) + (export "memory" (memory 0)) + (export "entrypoint" (func $entrypoint)) +) \ No newline at end of file diff --git a/tests/integration/expected/ge_felt.hir b/tests/integration/expected/ge_felt.hir new file mode 100644 index 000000000..46a832676 --- /dev/null +++ b/tests/integration/expected/ge_felt.hir @@ -0,0 +1,25 @@ +(component + ;; Modules + (module #ge_felt + ;; Constants + (const (id 0) 0x00100000) + + ;; Global Variables + (global (export #__stack_pointer) (id 0) (type i32) (const 0)) + + ;; Functions + (func (export #entrypoint) (param felt) (param felt) (result i32) + (block 0 (param v0 felt) (param v1 felt) + (let (v3 i1) (gte v0 v1)) + (let (v4 i32) (cast v3)) + (let (v5 i32) (const.i32 0)) + (let (v6 i1) (neq v4 v5)) + (let (v7 i32) (cast v6)) + (br (block 1 v7))) + + (block 1 (param v2 i32) + (ret v2)) + ) + ) + +) diff --git a/tests/integration/expected/ge_felt.masm b/tests/integration/expected/ge_felt.masm new file mode 100644 index 000000000..9b95bf20b --- /dev/null +++ b/tests/integration/expected/ge_felt.masm @@ -0,0 +1,671 @@ +mod ge_felt + +export.entrypoint + swap.1 + gte + push.0 + neq +end + +mod intrinsics::i32 + +export.is_signed + push.2147483648 + u32and + push.2147483648 + eq +end + +export.unchecked_neg + u32not + u32wrapping_add.1 +end + +export.checked_neg + dup.0 + push.2147483648 + eq + assertz + exec.unchecked_neg +end + +export.overflowing_add + u32assert2 + dup.0 + exec.is_signed + dup.2 + exec.is_signed + dup.1 + eq + movup.3 + movup.3 + u32wrapping_add + dup.0 + exec.is_signed + movup.3 + neq + movup.2 + and +end + +export.wrapping_add + exec.overflowing_add + drop +end + +export.checked_add + exec.overflowing_add + assertz +end + +export.overflowing_sub + u32assert2 + dup.0 + push.2147483648 + eq + if.true + drop + push.2147483647 + dup.1 + exec.is_signed + dup.0 + eq.0 + movup.3 + movup.3 + u32wrapping_add + push.1 + u32wrapping_add + dup.0 + exec.is_signed + movup.3 + neq + movup.2 + and + else + exec.unchecked_neg + exec.overflowing_add + end +end + +export.wrapping_sub + exec.overflowing_sub + drop +end + +export.checked_sub + exec.overflowing_sub + assertz +end + +export.overflowing_mul + u32assert2 + dup.0 + push.2147483648 + eq + dup.2 + push.2147483648 + eq + or + if.true + dup.0 + eq.1 + dup.2 + eq.1 + or + movup.2 + push.4294967295 + eq + movup.2 + push.4294967295 + eq + or + dup.1 + or + push.2147483648 + push.0 + swap.2 + cdrop + swap.1 + not + else + dup.0 + exec.is_signed + dup.2 + exec.is_signed + dup.1 + dup.1 + neq + movdn.4 + movup.3 + dup.0 + exec.unchecked_neg + movup.2 + cdrop + swap.2 + dup.0 + exec.unchecked_neg + movup.2 + cdrop + u32overflowing_mul + dup.1 + exec.is_signed + or + swap.1 + dup.0 + exec.unchecked_neg + movup.3 + cdrop + swap.1 + end +end + +export.wrapping_mul + exec.overflowing_mul + drop +end + +export.checked_mul + exec.overflowing_mul + assertz +end + +export.checked_div + u32assert2 + dup.1 + exec.unchecked_neg + dup.2 + swap.1 + movup.3 + exec.is_signed + dup.0 + movdn.4 + cdrop + dup.1 + exec.unchecked_neg + dup.2 + swap.1 + movup.3 + exec.is_signed + dup.0 + movdn.5 + cdrop + u32div + movdn.2 + neq + dup.1 + exec.unchecked_neg + swap.1 + cdrop +end + +export.icmp + dup.1 + dup.1 + push.2147483648 + u32and + swap.1 + push.2147483648 + u32and + eq.0 + swap.1 + eq.0 + swap.1 + dup.1 + neq + if.true + movdn.2 + drop + drop + push.4294967295 + push.1 + swap.2 + cdrop + else + drop + dup.1 + dup.1 + u32gt + movdn.2 + u32lt + push.0 + push.4294967295 + push.1 + swap.3 + cdrop + swap.2 + cdrop + end +end + +export.is_lt + exec.icmp + push.4294967295 + eq +end + +export.is_lte + exec.icmp + neq.1 +end + +export.is_gt + exec.icmp + eq.1 +end + +export.is_gte + exec.icmp + push.4294967295 + neq +end + +export.pow2 + dup.0 + push.31 + u32lt + assert + push.1 + swap.1 + u32shl +end + +export.ipow + dup.0 + push.31 + u32lt + assert + dup.0 + eq.0 + dup.2 + eq.0 + or + if.true + eq.0 + push.1 + push.0 + swap.2 + cdrop + swap.1 + drop + else + push.1 + dup.1 + push.1 + u32gt + while.true + dup.2 + dup.1 + u32wrapping_mul + dup.2 + push.1 + u32and + eq.1 + cdrop + swap.1 + u32div.2 + movup.2 + dup.0 + u32wrapping_mul + swap.1 + movup.2 + dup.1 + push.1 + u32gt + end + swap.1 + drop + u32wrapping_mul + end +end + +export.checked_shr + dup.0 + push.32 + u32lt + assert + dup.0 + eq.0 + dup.2 + eq.0 + or + if.true + eq.0 + swap.1 + push.0 + swap.2 + cdrop + else + dup.1 + push.2147483648 + u32and + push.2147483648 + eq + if.true + swap.1 + dup.1 + u32shr + push.1 + dup.2 + u32shl + sub.1 + push.32 + movup.3 + sub + u32shl + u32or + u32assert + else + u32shr + u32assert + end + end +end + +mod intrinsics::mem + +export.extract_element + dup.0 + push.3 + lte + assert + dup.0 + push.3 + lt + movdn.5 + dup.0 + push.2 + lt + movdn.5 + push.1 + lt + cdrop + movup.3 + cdrop + movup.2 + cdrop +end + +proc.load_felt_unchecked + padw + movup.4 + mem_loadw + movup.4 + exec.extract_element +end + +export.load_felt + movup.2 + assertz + exec.load_felt_unchecked +end + +export.load_sw + dup.2 + eq.0 + dup.3 + push.8 + u32lt + assert + if.true + movup.2 + drop + exec.load_felt_unchecked + else + dup.1 + eq.0 + if.true + swap.1 + drop + padw + movup.4 + mem_loadw + movup.3 + movup.3 + drop + drop + dup.2 + u32shl + swap.1 + push.32 + movup.3 + u32overflowing_sub + assertz + u32shr + u32or + else + dup.1 + eq.1 + if.true + swap.1 + drop + padw + movup.4 + mem_loadw + drop + movdn.2 + movdn.2 + drop + dup.2 + u32shl + swap.1 + push.32 + movup.3 + u32overflowing_sub + assertz + u32shr + u32or + else + swap.1 + eq.2 + if.true + padw + movup.4 + mem_loadw + drop + drop + dup.2 + u32shl + swap.1 + push.32 + movup.3 + u32overflowing_sub + assertz + u32shr + u32or + else + dup.0 + u32overflowing_add.1 + assertz + padw + movup.4 + mem_loadw + movdn.4 + drop + drop + drop + push.32 + dup.3 + u32overflowing_sub + assertz + u32shr + swap.1 + padw + movup.4 + mem_loadw + drop + drop + drop + movup.2 + u32shl + u32or + end + end + end + end +end + +export.realign_dw + dup.3 + u32shl + movdn.2 + dup.0 + push.32 + dup.4 + u32shr + movup.4 + u32or + movdn.2 + dup.3 + u32shl + swap.1 + push.32 + movup.4 + u32shr + u32or + swap.1 +end + +export.load_dw + dup.2 + eq.0 + dup.3 + push.8 + u32lt + assert + if.true + movup.2 + drop + dup.1 + eq.0 + if.true + swap.1 + drop + padw + movup.4 + mem_loadw + movup.4 + movup.4 + drop + drop + else + dup.1 + eq.1 + if.true + swap.1 + drop + padw + movup.4 + mem_loadw + drop + movup.3 + drop + else + swap.1 + eq.2 + if.true + padw + movup.4 + mem_loadw + drop + drop + else + dup.0 + u32overflowing_add.1 + assertz + padw + movup.4 + mem_loadw + movup.4 + movup.4 + movup.4 + drop + drop + drop + movup.4 + padw + movup.4 + mem_loadw + drop + drop + drop + end + end + end + else + dup.1 + eq.0 + if.true + swap.1 + drop + padw + movup.4 + mem_loadw + movup.4 + drop + exec.realign_dw + else + dup.1 + eq.1 + if.true + swap.1 + drop + padw + movup.4 + mem_loadw + drop + exec.realign_dw + else + swap.1 + eq.2 + if.true + dup.0 + u32overflowing_add.1 + assertz + padw + movup.4 + mem_loadw + movup.4 + movup.4 + movup.4 + drop + drop + drop + swap.1 + padw + movup.4 + mem_loadw + drop + drop + exec.realign_dw + else + dup.0 + u32overflowing_add.1 + assertz + padw + movup.4 + mem_loadw + movup.4 + movup.4 + drop + drop + movup.2 + padw + movup.4 + mem_loadw + drop + drop + drop + exec.realign_dw + end + end + end + end +end + +program + +use ge_felt + +begin + exec.ge_felt::entrypoint +end diff --git a/tests/integration/expected/ge_felt.wat b/tests/integration/expected/ge_felt.wat new file mode 100644 index 000000000..c57434a6a --- /dev/null +++ b/tests/integration/expected/ge_felt.wat @@ -0,0 +1,16 @@ +(module $ge_felt.wasm + (type (;0;) (func (param f64 f64) (result i32))) + (import "miden:prelude/intrinsics_felt" "ge" (func $miden_prelude::intrinsics::felt::extern_ge (;0;) (type 0))) + (func $entrypoint (;1;) (type 0) (param f64 f64) (result i32) + local.get 0 + local.get 1 + call $miden_prelude::intrinsics::felt::extern_ge + i32.const 0 + i32.ne + ) + (table (;0;) 1 1 funcref) + (memory (;0;) 16) + (global $__stack_pointer (;0;) (mut i32) i32.const 1048576) + (export "memory" (memory 0)) + (export "entrypoint" (func $entrypoint)) +) \ No newline at end of file diff --git a/tests/integration/expected/gt_felt.hir b/tests/integration/expected/gt_felt.hir new file mode 100644 index 000000000..317326cab --- /dev/null +++ b/tests/integration/expected/gt_felt.hir @@ -0,0 +1,25 @@ +(component + ;; Modules + (module #gt_felt + ;; Constants + (const (id 0) 0x00100000) + + ;; Global Variables + (global (export #__stack_pointer) (id 0) (type i32) (const 0)) + + ;; Functions + (func (export #entrypoint) (param felt) (param felt) (result i32) + (block 0 (param v0 felt) (param v1 felt) + (let (v3 i1) (gt v0 v1)) + (let (v4 i32) (cast v3)) + (let (v5 i32) (const.i32 0)) + (let (v6 i1) (neq v4 v5)) + (let (v7 i32) (cast v6)) + (br (block 1 v7))) + + (block 1 (param v2 i32) + (ret v2)) + ) + ) + +) diff --git a/tests/integration/expected/gt_felt.masm b/tests/integration/expected/gt_felt.masm new file mode 100644 index 000000000..e3b73e749 --- /dev/null +++ b/tests/integration/expected/gt_felt.masm @@ -0,0 +1,671 @@ +mod gt_felt + +export.entrypoint + swap.1 + gt + push.0 + neq +end + +mod intrinsics::i32 + +export.is_signed + push.2147483648 + u32and + push.2147483648 + eq +end + +export.unchecked_neg + u32not + u32wrapping_add.1 +end + +export.checked_neg + dup.0 + push.2147483648 + eq + assertz + exec.unchecked_neg +end + +export.overflowing_add + u32assert2 + dup.0 + exec.is_signed + dup.2 + exec.is_signed + dup.1 + eq + movup.3 + movup.3 + u32wrapping_add + dup.0 + exec.is_signed + movup.3 + neq + movup.2 + and +end + +export.wrapping_add + exec.overflowing_add + drop +end + +export.checked_add + exec.overflowing_add + assertz +end + +export.overflowing_sub + u32assert2 + dup.0 + push.2147483648 + eq + if.true + drop + push.2147483647 + dup.1 + exec.is_signed + dup.0 + eq.0 + movup.3 + movup.3 + u32wrapping_add + push.1 + u32wrapping_add + dup.0 + exec.is_signed + movup.3 + neq + movup.2 + and + else + exec.unchecked_neg + exec.overflowing_add + end +end + +export.wrapping_sub + exec.overflowing_sub + drop +end + +export.checked_sub + exec.overflowing_sub + assertz +end + +export.overflowing_mul + u32assert2 + dup.0 + push.2147483648 + eq + dup.2 + push.2147483648 + eq + or + if.true + dup.0 + eq.1 + dup.2 + eq.1 + or + movup.2 + push.4294967295 + eq + movup.2 + push.4294967295 + eq + or + dup.1 + or + push.2147483648 + push.0 + swap.2 + cdrop + swap.1 + not + else + dup.0 + exec.is_signed + dup.2 + exec.is_signed + dup.1 + dup.1 + neq + movdn.4 + movup.3 + dup.0 + exec.unchecked_neg + movup.2 + cdrop + swap.2 + dup.0 + exec.unchecked_neg + movup.2 + cdrop + u32overflowing_mul + dup.1 + exec.is_signed + or + swap.1 + dup.0 + exec.unchecked_neg + movup.3 + cdrop + swap.1 + end +end + +export.wrapping_mul + exec.overflowing_mul + drop +end + +export.checked_mul + exec.overflowing_mul + assertz +end + +export.checked_div + u32assert2 + dup.1 + exec.unchecked_neg + dup.2 + swap.1 + movup.3 + exec.is_signed + dup.0 + movdn.4 + cdrop + dup.1 + exec.unchecked_neg + dup.2 + swap.1 + movup.3 + exec.is_signed + dup.0 + movdn.5 + cdrop + u32div + movdn.2 + neq + dup.1 + exec.unchecked_neg + swap.1 + cdrop +end + +export.icmp + dup.1 + dup.1 + push.2147483648 + u32and + swap.1 + push.2147483648 + u32and + eq.0 + swap.1 + eq.0 + swap.1 + dup.1 + neq + if.true + movdn.2 + drop + drop + push.4294967295 + push.1 + swap.2 + cdrop + else + drop + dup.1 + dup.1 + u32gt + movdn.2 + u32lt + push.0 + push.4294967295 + push.1 + swap.3 + cdrop + swap.2 + cdrop + end +end + +export.is_lt + exec.icmp + push.4294967295 + eq +end + +export.is_lte + exec.icmp + neq.1 +end + +export.is_gt + exec.icmp + eq.1 +end + +export.is_gte + exec.icmp + push.4294967295 + neq +end + +export.pow2 + dup.0 + push.31 + u32lt + assert + push.1 + swap.1 + u32shl +end + +export.ipow + dup.0 + push.31 + u32lt + assert + dup.0 + eq.0 + dup.2 + eq.0 + or + if.true + eq.0 + push.1 + push.0 + swap.2 + cdrop + swap.1 + drop + else + push.1 + dup.1 + push.1 + u32gt + while.true + dup.2 + dup.1 + u32wrapping_mul + dup.2 + push.1 + u32and + eq.1 + cdrop + swap.1 + u32div.2 + movup.2 + dup.0 + u32wrapping_mul + swap.1 + movup.2 + dup.1 + push.1 + u32gt + end + swap.1 + drop + u32wrapping_mul + end +end + +export.checked_shr + dup.0 + push.32 + u32lt + assert + dup.0 + eq.0 + dup.2 + eq.0 + or + if.true + eq.0 + swap.1 + push.0 + swap.2 + cdrop + else + dup.1 + push.2147483648 + u32and + push.2147483648 + eq + if.true + swap.1 + dup.1 + u32shr + push.1 + dup.2 + u32shl + sub.1 + push.32 + movup.3 + sub + u32shl + u32or + u32assert + else + u32shr + u32assert + end + end +end + +mod intrinsics::mem + +export.extract_element + dup.0 + push.3 + lte + assert + dup.0 + push.3 + lt + movdn.5 + dup.0 + push.2 + lt + movdn.5 + push.1 + lt + cdrop + movup.3 + cdrop + movup.2 + cdrop +end + +proc.load_felt_unchecked + padw + movup.4 + mem_loadw + movup.4 + exec.extract_element +end + +export.load_felt + movup.2 + assertz + exec.load_felt_unchecked +end + +export.load_sw + dup.2 + eq.0 + dup.3 + push.8 + u32lt + assert + if.true + movup.2 + drop + exec.load_felt_unchecked + else + dup.1 + eq.0 + if.true + swap.1 + drop + padw + movup.4 + mem_loadw + movup.3 + movup.3 + drop + drop + dup.2 + u32shl + swap.1 + push.32 + movup.3 + u32overflowing_sub + assertz + u32shr + u32or + else + dup.1 + eq.1 + if.true + swap.1 + drop + padw + movup.4 + mem_loadw + drop + movdn.2 + movdn.2 + drop + dup.2 + u32shl + swap.1 + push.32 + movup.3 + u32overflowing_sub + assertz + u32shr + u32or + else + swap.1 + eq.2 + if.true + padw + movup.4 + mem_loadw + drop + drop + dup.2 + u32shl + swap.1 + push.32 + movup.3 + u32overflowing_sub + assertz + u32shr + u32or + else + dup.0 + u32overflowing_add.1 + assertz + padw + movup.4 + mem_loadw + movdn.4 + drop + drop + drop + push.32 + dup.3 + u32overflowing_sub + assertz + u32shr + swap.1 + padw + movup.4 + mem_loadw + drop + drop + drop + movup.2 + u32shl + u32or + end + end + end + end +end + +export.realign_dw + dup.3 + u32shl + movdn.2 + dup.0 + push.32 + dup.4 + u32shr + movup.4 + u32or + movdn.2 + dup.3 + u32shl + swap.1 + push.32 + movup.4 + u32shr + u32or + swap.1 +end + +export.load_dw + dup.2 + eq.0 + dup.3 + push.8 + u32lt + assert + if.true + movup.2 + drop + dup.1 + eq.0 + if.true + swap.1 + drop + padw + movup.4 + mem_loadw + movup.4 + movup.4 + drop + drop + else + dup.1 + eq.1 + if.true + swap.1 + drop + padw + movup.4 + mem_loadw + drop + movup.3 + drop + else + swap.1 + eq.2 + if.true + padw + movup.4 + mem_loadw + drop + drop + else + dup.0 + u32overflowing_add.1 + assertz + padw + movup.4 + mem_loadw + movup.4 + movup.4 + movup.4 + drop + drop + drop + movup.4 + padw + movup.4 + mem_loadw + drop + drop + drop + end + end + end + else + dup.1 + eq.0 + if.true + swap.1 + drop + padw + movup.4 + mem_loadw + movup.4 + drop + exec.realign_dw + else + dup.1 + eq.1 + if.true + swap.1 + drop + padw + movup.4 + mem_loadw + drop + exec.realign_dw + else + swap.1 + eq.2 + if.true + dup.0 + u32overflowing_add.1 + assertz + padw + movup.4 + mem_loadw + movup.4 + movup.4 + movup.4 + drop + drop + drop + swap.1 + padw + movup.4 + mem_loadw + drop + drop + exec.realign_dw + else + dup.0 + u32overflowing_add.1 + assertz + padw + movup.4 + mem_loadw + movup.4 + movup.4 + drop + drop + movup.2 + padw + movup.4 + mem_loadw + drop + drop + drop + exec.realign_dw + end + end + end + end +end + +program + +use gt_felt + +begin + exec.gt_felt::entrypoint +end diff --git a/tests/integration/expected/gt_felt.wat b/tests/integration/expected/gt_felt.wat new file mode 100644 index 000000000..ca81b7a5f --- /dev/null +++ b/tests/integration/expected/gt_felt.wat @@ -0,0 +1,16 @@ +(module $gt_felt.wasm + (type (;0;) (func (param f64 f64) (result i32))) + (import "miden:prelude/intrinsics_felt" "gt" (func $miden_prelude::intrinsics::felt::extern_gt (;0;) (type 0))) + (func $entrypoint (;1;) (type 0) (param f64 f64) (result i32) + local.get 0 + local.get 1 + call $miden_prelude::intrinsics::felt::extern_gt + i32.const 0 + i32.ne + ) + (table (;0;) 1 1 funcref) + (memory (;0;) 16) + (global $__stack_pointer (;0;) (mut i32) i32.const 1048576) + (export "memory" (memory 0)) + (export "entrypoint" (func $entrypoint)) +) \ No newline at end of file diff --git a/tests/integration/expected/le_felt.hir b/tests/integration/expected/le_felt.hir new file mode 100644 index 000000000..5b7305e90 --- /dev/null +++ b/tests/integration/expected/le_felt.hir @@ -0,0 +1,25 @@ +(component + ;; Modules + (module #le_felt + ;; Constants + (const (id 0) 0x00100000) + + ;; Global Variables + (global (export #__stack_pointer) (id 0) (type i32) (const 0)) + + ;; Functions + (func (export #entrypoint) (param felt) (param felt) (result i32) + (block 0 (param v0 felt) (param v1 felt) + (let (v3 i1) (lte v1 v0)) + (let (v4 i32) (cast v3)) + (let (v5 i32) (const.i32 0)) + (let (v6 i1) (neq v4 v5)) + (let (v7 i32) (cast v6)) + (br (block 1 v7))) + + (block 1 (param v2 i32) + (ret v2)) + ) + ) + +) diff --git a/tests/integration/expected/le_felt.masm b/tests/integration/expected/le_felt.masm new file mode 100644 index 000000000..4e272906c --- /dev/null +++ b/tests/integration/expected/le_felt.masm @@ -0,0 +1,670 @@ +mod intrinsics::i32 + +export.is_signed + push.2147483648 + u32and + push.2147483648 + eq +end + +export.unchecked_neg + u32not + u32wrapping_add.1 +end + +export.checked_neg + dup.0 + push.2147483648 + eq + assertz + exec.unchecked_neg +end + +export.overflowing_add + u32assert2 + dup.0 + exec.is_signed + dup.2 + exec.is_signed + dup.1 + eq + movup.3 + movup.3 + u32wrapping_add + dup.0 + exec.is_signed + movup.3 + neq + movup.2 + and +end + +export.wrapping_add + exec.overflowing_add + drop +end + +export.checked_add + exec.overflowing_add + assertz +end + +export.overflowing_sub + u32assert2 + dup.0 + push.2147483648 + eq + if.true + drop + push.2147483647 + dup.1 + exec.is_signed + dup.0 + eq.0 + movup.3 + movup.3 + u32wrapping_add + push.1 + u32wrapping_add + dup.0 + exec.is_signed + movup.3 + neq + movup.2 + and + else + exec.unchecked_neg + exec.overflowing_add + end +end + +export.wrapping_sub + exec.overflowing_sub + drop +end + +export.checked_sub + exec.overflowing_sub + assertz +end + +export.overflowing_mul + u32assert2 + dup.0 + push.2147483648 + eq + dup.2 + push.2147483648 + eq + or + if.true + dup.0 + eq.1 + dup.2 + eq.1 + or + movup.2 + push.4294967295 + eq + movup.2 + push.4294967295 + eq + or + dup.1 + or + push.2147483648 + push.0 + swap.2 + cdrop + swap.1 + not + else + dup.0 + exec.is_signed + dup.2 + exec.is_signed + dup.1 + dup.1 + neq + movdn.4 + movup.3 + dup.0 + exec.unchecked_neg + movup.2 + cdrop + swap.2 + dup.0 + exec.unchecked_neg + movup.2 + cdrop + u32overflowing_mul + dup.1 + exec.is_signed + or + swap.1 + dup.0 + exec.unchecked_neg + movup.3 + cdrop + swap.1 + end +end + +export.wrapping_mul + exec.overflowing_mul + drop +end + +export.checked_mul + exec.overflowing_mul + assertz +end + +export.checked_div + u32assert2 + dup.1 + exec.unchecked_neg + dup.2 + swap.1 + movup.3 + exec.is_signed + dup.0 + movdn.4 + cdrop + dup.1 + exec.unchecked_neg + dup.2 + swap.1 + movup.3 + exec.is_signed + dup.0 + movdn.5 + cdrop + u32div + movdn.2 + neq + dup.1 + exec.unchecked_neg + swap.1 + cdrop +end + +export.icmp + dup.1 + dup.1 + push.2147483648 + u32and + swap.1 + push.2147483648 + u32and + eq.0 + swap.1 + eq.0 + swap.1 + dup.1 + neq + if.true + movdn.2 + drop + drop + push.4294967295 + push.1 + swap.2 + cdrop + else + drop + dup.1 + dup.1 + u32gt + movdn.2 + u32lt + push.0 + push.4294967295 + push.1 + swap.3 + cdrop + swap.2 + cdrop + end +end + +export.is_lt + exec.icmp + push.4294967295 + eq +end + +export.is_lte + exec.icmp + neq.1 +end + +export.is_gt + exec.icmp + eq.1 +end + +export.is_gte + exec.icmp + push.4294967295 + neq +end + +export.pow2 + dup.0 + push.31 + u32lt + assert + push.1 + swap.1 + u32shl +end + +export.ipow + dup.0 + push.31 + u32lt + assert + dup.0 + eq.0 + dup.2 + eq.0 + or + if.true + eq.0 + push.1 + push.0 + swap.2 + cdrop + swap.1 + drop + else + push.1 + dup.1 + push.1 + u32gt + while.true + dup.2 + dup.1 + u32wrapping_mul + dup.2 + push.1 + u32and + eq.1 + cdrop + swap.1 + u32div.2 + movup.2 + dup.0 + u32wrapping_mul + swap.1 + movup.2 + dup.1 + push.1 + u32gt + end + swap.1 + drop + u32wrapping_mul + end +end + +export.checked_shr + dup.0 + push.32 + u32lt + assert + dup.0 + eq.0 + dup.2 + eq.0 + or + if.true + eq.0 + swap.1 + push.0 + swap.2 + cdrop + else + dup.1 + push.2147483648 + u32and + push.2147483648 + eq + if.true + swap.1 + dup.1 + u32shr + push.1 + dup.2 + u32shl + sub.1 + push.32 + movup.3 + sub + u32shl + u32or + u32assert + else + u32shr + u32assert + end + end +end + +mod intrinsics::mem + +export.extract_element + dup.0 + push.3 + lte + assert + dup.0 + push.3 + lt + movdn.5 + dup.0 + push.2 + lt + movdn.5 + push.1 + lt + cdrop + movup.3 + cdrop + movup.2 + cdrop +end + +proc.load_felt_unchecked + padw + movup.4 + mem_loadw + movup.4 + exec.extract_element +end + +export.load_felt + movup.2 + assertz + exec.load_felt_unchecked +end + +export.load_sw + dup.2 + eq.0 + dup.3 + push.8 + u32lt + assert + if.true + movup.2 + drop + exec.load_felt_unchecked + else + dup.1 + eq.0 + if.true + swap.1 + drop + padw + movup.4 + mem_loadw + movup.3 + movup.3 + drop + drop + dup.2 + u32shl + swap.1 + push.32 + movup.3 + u32overflowing_sub + assertz + u32shr + u32or + else + dup.1 + eq.1 + if.true + swap.1 + drop + padw + movup.4 + mem_loadw + drop + movdn.2 + movdn.2 + drop + dup.2 + u32shl + swap.1 + push.32 + movup.3 + u32overflowing_sub + assertz + u32shr + u32or + else + swap.1 + eq.2 + if.true + padw + movup.4 + mem_loadw + drop + drop + dup.2 + u32shl + swap.1 + push.32 + movup.3 + u32overflowing_sub + assertz + u32shr + u32or + else + dup.0 + u32overflowing_add.1 + assertz + padw + movup.4 + mem_loadw + movdn.4 + drop + drop + drop + push.32 + dup.3 + u32overflowing_sub + assertz + u32shr + swap.1 + padw + movup.4 + mem_loadw + drop + drop + drop + movup.2 + u32shl + u32or + end + end + end + end +end + +export.realign_dw + dup.3 + u32shl + movdn.2 + dup.0 + push.32 + dup.4 + u32shr + movup.4 + u32or + movdn.2 + dup.3 + u32shl + swap.1 + push.32 + movup.4 + u32shr + u32or + swap.1 +end + +export.load_dw + dup.2 + eq.0 + dup.3 + push.8 + u32lt + assert + if.true + movup.2 + drop + dup.1 + eq.0 + if.true + swap.1 + drop + padw + movup.4 + mem_loadw + movup.4 + movup.4 + drop + drop + else + dup.1 + eq.1 + if.true + swap.1 + drop + padw + movup.4 + mem_loadw + drop + movup.3 + drop + else + swap.1 + eq.2 + if.true + padw + movup.4 + mem_loadw + drop + drop + else + dup.0 + u32overflowing_add.1 + assertz + padw + movup.4 + mem_loadw + movup.4 + movup.4 + movup.4 + drop + drop + drop + movup.4 + padw + movup.4 + mem_loadw + drop + drop + drop + end + end + end + else + dup.1 + eq.0 + if.true + swap.1 + drop + padw + movup.4 + mem_loadw + movup.4 + drop + exec.realign_dw + else + dup.1 + eq.1 + if.true + swap.1 + drop + padw + movup.4 + mem_loadw + drop + exec.realign_dw + else + swap.1 + eq.2 + if.true + dup.0 + u32overflowing_add.1 + assertz + padw + movup.4 + mem_loadw + movup.4 + movup.4 + movup.4 + drop + drop + drop + swap.1 + padw + movup.4 + mem_loadw + drop + drop + exec.realign_dw + else + dup.0 + u32overflowing_add.1 + assertz + padw + movup.4 + mem_loadw + movup.4 + movup.4 + drop + drop + movup.2 + padw + movup.4 + mem_loadw + drop + drop + drop + exec.realign_dw + end + end + end + end +end + +mod le_felt + +export.entrypoint + lte + push.0 + neq +end + +program + +use le_felt + +begin + exec.le_felt::entrypoint +end diff --git a/tests/integration/expected/le_felt.wat b/tests/integration/expected/le_felt.wat new file mode 100644 index 000000000..94ad3c26a --- /dev/null +++ b/tests/integration/expected/le_felt.wat @@ -0,0 +1,16 @@ +(module $le_felt.wasm + (type (;0;) (func (param f64 f64) (result i32))) + (import "miden:prelude/intrinsics_felt" "le" (func $miden_prelude::intrinsics::felt::extern_le (;0;) (type 0))) + (func $entrypoint (;1;) (type 0) (param f64 f64) (result i32) + local.get 1 + local.get 0 + call $miden_prelude::intrinsics::felt::extern_le + i32.const 0 + i32.ne + ) + (table (;0;) 1 1 funcref) + (memory (;0;) 16) + (global $__stack_pointer (;0;) (mut i32) i32.const 1048576) + (export "memory" (memory 0)) + (export "entrypoint" (func $entrypoint)) +) \ No newline at end of file diff --git a/tests/integration/expected/lt_felt.hir b/tests/integration/expected/lt_felt.hir new file mode 100644 index 000000000..60ab39c69 --- /dev/null +++ b/tests/integration/expected/lt_felt.hir @@ -0,0 +1,25 @@ +(component + ;; Modules + (module #lt_felt + ;; Constants + (const (id 0) 0x00100000) + + ;; Global Variables + (global (export #__stack_pointer) (id 0) (type i32) (const 0)) + + ;; Functions + (func (export #entrypoint) (param felt) (param felt) (result i32) + (block 0 (param v0 felt) (param v1 felt) + (let (v3 i1) (lt v1 v0)) + (let (v4 i32) (cast v3)) + (let (v5 i32) (const.i32 0)) + (let (v6 i1) (neq v4 v5)) + (let (v7 i32) (cast v6)) + (br (block 1 v7))) + + (block 1 (param v2 i32) + (ret v2)) + ) + ) + +) diff --git a/tests/integration/expected/lt_felt.masm b/tests/integration/expected/lt_felt.masm new file mode 100644 index 000000000..c31efc284 --- /dev/null +++ b/tests/integration/expected/lt_felt.masm @@ -0,0 +1,670 @@ +mod intrinsics::i32 + +export.is_signed + push.2147483648 + u32and + push.2147483648 + eq +end + +export.unchecked_neg + u32not + u32wrapping_add.1 +end + +export.checked_neg + dup.0 + push.2147483648 + eq + assertz + exec.unchecked_neg +end + +export.overflowing_add + u32assert2 + dup.0 + exec.is_signed + dup.2 + exec.is_signed + dup.1 + eq + movup.3 + movup.3 + u32wrapping_add + dup.0 + exec.is_signed + movup.3 + neq + movup.2 + and +end + +export.wrapping_add + exec.overflowing_add + drop +end + +export.checked_add + exec.overflowing_add + assertz +end + +export.overflowing_sub + u32assert2 + dup.0 + push.2147483648 + eq + if.true + drop + push.2147483647 + dup.1 + exec.is_signed + dup.0 + eq.0 + movup.3 + movup.3 + u32wrapping_add + push.1 + u32wrapping_add + dup.0 + exec.is_signed + movup.3 + neq + movup.2 + and + else + exec.unchecked_neg + exec.overflowing_add + end +end + +export.wrapping_sub + exec.overflowing_sub + drop +end + +export.checked_sub + exec.overflowing_sub + assertz +end + +export.overflowing_mul + u32assert2 + dup.0 + push.2147483648 + eq + dup.2 + push.2147483648 + eq + or + if.true + dup.0 + eq.1 + dup.2 + eq.1 + or + movup.2 + push.4294967295 + eq + movup.2 + push.4294967295 + eq + or + dup.1 + or + push.2147483648 + push.0 + swap.2 + cdrop + swap.1 + not + else + dup.0 + exec.is_signed + dup.2 + exec.is_signed + dup.1 + dup.1 + neq + movdn.4 + movup.3 + dup.0 + exec.unchecked_neg + movup.2 + cdrop + swap.2 + dup.0 + exec.unchecked_neg + movup.2 + cdrop + u32overflowing_mul + dup.1 + exec.is_signed + or + swap.1 + dup.0 + exec.unchecked_neg + movup.3 + cdrop + swap.1 + end +end + +export.wrapping_mul + exec.overflowing_mul + drop +end + +export.checked_mul + exec.overflowing_mul + assertz +end + +export.checked_div + u32assert2 + dup.1 + exec.unchecked_neg + dup.2 + swap.1 + movup.3 + exec.is_signed + dup.0 + movdn.4 + cdrop + dup.1 + exec.unchecked_neg + dup.2 + swap.1 + movup.3 + exec.is_signed + dup.0 + movdn.5 + cdrop + u32div + movdn.2 + neq + dup.1 + exec.unchecked_neg + swap.1 + cdrop +end + +export.icmp + dup.1 + dup.1 + push.2147483648 + u32and + swap.1 + push.2147483648 + u32and + eq.0 + swap.1 + eq.0 + swap.1 + dup.1 + neq + if.true + movdn.2 + drop + drop + push.4294967295 + push.1 + swap.2 + cdrop + else + drop + dup.1 + dup.1 + u32gt + movdn.2 + u32lt + push.0 + push.4294967295 + push.1 + swap.3 + cdrop + swap.2 + cdrop + end +end + +export.is_lt + exec.icmp + push.4294967295 + eq +end + +export.is_lte + exec.icmp + neq.1 +end + +export.is_gt + exec.icmp + eq.1 +end + +export.is_gte + exec.icmp + push.4294967295 + neq +end + +export.pow2 + dup.0 + push.31 + u32lt + assert + push.1 + swap.1 + u32shl +end + +export.ipow + dup.0 + push.31 + u32lt + assert + dup.0 + eq.0 + dup.2 + eq.0 + or + if.true + eq.0 + push.1 + push.0 + swap.2 + cdrop + swap.1 + drop + else + push.1 + dup.1 + push.1 + u32gt + while.true + dup.2 + dup.1 + u32wrapping_mul + dup.2 + push.1 + u32and + eq.1 + cdrop + swap.1 + u32div.2 + movup.2 + dup.0 + u32wrapping_mul + swap.1 + movup.2 + dup.1 + push.1 + u32gt + end + swap.1 + drop + u32wrapping_mul + end +end + +export.checked_shr + dup.0 + push.32 + u32lt + assert + dup.0 + eq.0 + dup.2 + eq.0 + or + if.true + eq.0 + swap.1 + push.0 + swap.2 + cdrop + else + dup.1 + push.2147483648 + u32and + push.2147483648 + eq + if.true + swap.1 + dup.1 + u32shr + push.1 + dup.2 + u32shl + sub.1 + push.32 + movup.3 + sub + u32shl + u32or + u32assert + else + u32shr + u32assert + end + end +end + +mod intrinsics::mem + +export.extract_element + dup.0 + push.3 + lte + assert + dup.0 + push.3 + lt + movdn.5 + dup.0 + push.2 + lt + movdn.5 + push.1 + lt + cdrop + movup.3 + cdrop + movup.2 + cdrop +end + +proc.load_felt_unchecked + padw + movup.4 + mem_loadw + movup.4 + exec.extract_element +end + +export.load_felt + movup.2 + assertz + exec.load_felt_unchecked +end + +export.load_sw + dup.2 + eq.0 + dup.3 + push.8 + u32lt + assert + if.true + movup.2 + drop + exec.load_felt_unchecked + else + dup.1 + eq.0 + if.true + swap.1 + drop + padw + movup.4 + mem_loadw + movup.3 + movup.3 + drop + drop + dup.2 + u32shl + swap.1 + push.32 + movup.3 + u32overflowing_sub + assertz + u32shr + u32or + else + dup.1 + eq.1 + if.true + swap.1 + drop + padw + movup.4 + mem_loadw + drop + movdn.2 + movdn.2 + drop + dup.2 + u32shl + swap.1 + push.32 + movup.3 + u32overflowing_sub + assertz + u32shr + u32or + else + swap.1 + eq.2 + if.true + padw + movup.4 + mem_loadw + drop + drop + dup.2 + u32shl + swap.1 + push.32 + movup.3 + u32overflowing_sub + assertz + u32shr + u32or + else + dup.0 + u32overflowing_add.1 + assertz + padw + movup.4 + mem_loadw + movdn.4 + drop + drop + drop + push.32 + dup.3 + u32overflowing_sub + assertz + u32shr + swap.1 + padw + movup.4 + mem_loadw + drop + drop + drop + movup.2 + u32shl + u32or + end + end + end + end +end + +export.realign_dw + dup.3 + u32shl + movdn.2 + dup.0 + push.32 + dup.4 + u32shr + movup.4 + u32or + movdn.2 + dup.3 + u32shl + swap.1 + push.32 + movup.4 + u32shr + u32or + swap.1 +end + +export.load_dw + dup.2 + eq.0 + dup.3 + push.8 + u32lt + assert + if.true + movup.2 + drop + dup.1 + eq.0 + if.true + swap.1 + drop + padw + movup.4 + mem_loadw + movup.4 + movup.4 + drop + drop + else + dup.1 + eq.1 + if.true + swap.1 + drop + padw + movup.4 + mem_loadw + drop + movup.3 + drop + else + swap.1 + eq.2 + if.true + padw + movup.4 + mem_loadw + drop + drop + else + dup.0 + u32overflowing_add.1 + assertz + padw + movup.4 + mem_loadw + movup.4 + movup.4 + movup.4 + drop + drop + drop + movup.4 + padw + movup.4 + mem_loadw + drop + drop + drop + end + end + end + else + dup.1 + eq.0 + if.true + swap.1 + drop + padw + movup.4 + mem_loadw + movup.4 + drop + exec.realign_dw + else + dup.1 + eq.1 + if.true + swap.1 + drop + padw + movup.4 + mem_loadw + drop + exec.realign_dw + else + swap.1 + eq.2 + if.true + dup.0 + u32overflowing_add.1 + assertz + padw + movup.4 + mem_loadw + movup.4 + movup.4 + movup.4 + drop + drop + drop + swap.1 + padw + movup.4 + mem_loadw + drop + drop + exec.realign_dw + else + dup.0 + u32overflowing_add.1 + assertz + padw + movup.4 + mem_loadw + movup.4 + movup.4 + drop + drop + movup.2 + padw + movup.4 + mem_loadw + drop + drop + drop + exec.realign_dw + end + end + end + end +end + +mod lt_felt + +export.entrypoint + lt + push.0 + neq +end + +program + +use lt_felt + +begin + exec.lt_felt::entrypoint +end diff --git a/tests/integration/expected/lt_felt.wat b/tests/integration/expected/lt_felt.wat new file mode 100644 index 000000000..04c79aee6 --- /dev/null +++ b/tests/integration/expected/lt_felt.wat @@ -0,0 +1,16 @@ +(module $lt_felt.wasm + (type (;0;) (func (param f64 f64) (result i32))) + (import "miden:prelude/intrinsics_felt" "lt" (func $miden_prelude::intrinsics::felt::extern_lt (;0;) (type 0))) + (func $entrypoint (;1;) (type 0) (param f64 f64) (result i32) + local.get 1 + local.get 0 + call $miden_prelude::intrinsics::felt::extern_lt + i32.const 0 + i32.ne + ) + (table (;0;) 1 1 funcref) + (memory (;0;) 16) + (global $__stack_pointer (;0;) (mut i32) i32.const 1048576) + (export "memory" (memory 0)) + (export "entrypoint" (func $entrypoint)) +) \ No newline at end of file diff --git a/tests/integration/expected/mul_felt.hir b/tests/integration/expected/mul_felt.hir new file mode 100644 index 000000000..4b1b8b2c1 --- /dev/null +++ b/tests/integration/expected/mul_felt.hir @@ -0,0 +1,21 @@ +(component + ;; Modules + (module #mul_felt + ;; Constants + (const (id 0) 0x00100000) + + ;; Global Variables + (global (export #__stack_pointer) (id 0) (type i32) (const 0)) + + ;; Functions + (func (export #entrypoint) (param felt) (param felt) (result felt) + (block 0 (param v0 felt) (param v1 felt) + (let (v3 felt) (mul.unchecked v0 v1)) + (br (block 1 v3))) + + (block 1 (param v2 felt) + (ret v2)) + ) + ) + +) diff --git a/tests/integration/expected/mul_felt.masm b/tests/integration/expected/mul_felt.masm new file mode 100644 index 000000000..dbc7ad2d3 --- /dev/null +++ b/tests/integration/expected/mul_felt.masm @@ -0,0 +1,669 @@ +mod intrinsics::i32 + +export.is_signed + push.2147483648 + u32and + push.2147483648 + eq +end + +export.unchecked_neg + u32not + u32wrapping_add.1 +end + +export.checked_neg + dup.0 + push.2147483648 + eq + assertz + exec.unchecked_neg +end + +export.overflowing_add + u32assert2 + dup.0 + exec.is_signed + dup.2 + exec.is_signed + dup.1 + eq + movup.3 + movup.3 + u32wrapping_add + dup.0 + exec.is_signed + movup.3 + neq + movup.2 + and +end + +export.wrapping_add + exec.overflowing_add + drop +end + +export.checked_add + exec.overflowing_add + assertz +end + +export.overflowing_sub + u32assert2 + dup.0 + push.2147483648 + eq + if.true + drop + push.2147483647 + dup.1 + exec.is_signed + dup.0 + eq.0 + movup.3 + movup.3 + u32wrapping_add + push.1 + u32wrapping_add + dup.0 + exec.is_signed + movup.3 + neq + movup.2 + and + else + exec.unchecked_neg + exec.overflowing_add + end +end + +export.wrapping_sub + exec.overflowing_sub + drop +end + +export.checked_sub + exec.overflowing_sub + assertz +end + +export.overflowing_mul + u32assert2 + dup.0 + push.2147483648 + eq + dup.2 + push.2147483648 + eq + or + if.true + dup.0 + eq.1 + dup.2 + eq.1 + or + movup.2 + push.4294967295 + eq + movup.2 + push.4294967295 + eq + or + dup.1 + or + push.2147483648 + push.0 + swap.2 + cdrop + swap.1 + not + else + dup.0 + exec.is_signed + dup.2 + exec.is_signed + dup.1 + dup.1 + neq + movdn.4 + movup.3 + dup.0 + exec.unchecked_neg + movup.2 + cdrop + swap.2 + dup.0 + exec.unchecked_neg + movup.2 + cdrop + u32overflowing_mul + dup.1 + exec.is_signed + or + swap.1 + dup.0 + exec.unchecked_neg + movup.3 + cdrop + swap.1 + end +end + +export.wrapping_mul + exec.overflowing_mul + drop +end + +export.checked_mul + exec.overflowing_mul + assertz +end + +export.checked_div + u32assert2 + dup.1 + exec.unchecked_neg + dup.2 + swap.1 + movup.3 + exec.is_signed + dup.0 + movdn.4 + cdrop + dup.1 + exec.unchecked_neg + dup.2 + swap.1 + movup.3 + exec.is_signed + dup.0 + movdn.5 + cdrop + u32div + movdn.2 + neq + dup.1 + exec.unchecked_neg + swap.1 + cdrop +end + +export.icmp + dup.1 + dup.1 + push.2147483648 + u32and + swap.1 + push.2147483648 + u32and + eq.0 + swap.1 + eq.0 + swap.1 + dup.1 + neq + if.true + movdn.2 + drop + drop + push.4294967295 + push.1 + swap.2 + cdrop + else + drop + dup.1 + dup.1 + u32gt + movdn.2 + u32lt + push.0 + push.4294967295 + push.1 + swap.3 + cdrop + swap.2 + cdrop + end +end + +export.is_lt + exec.icmp + push.4294967295 + eq +end + +export.is_lte + exec.icmp + neq.1 +end + +export.is_gt + exec.icmp + eq.1 +end + +export.is_gte + exec.icmp + push.4294967295 + neq +end + +export.pow2 + dup.0 + push.31 + u32lt + assert + push.1 + swap.1 + u32shl +end + +export.ipow + dup.0 + push.31 + u32lt + assert + dup.0 + eq.0 + dup.2 + eq.0 + or + if.true + eq.0 + push.1 + push.0 + swap.2 + cdrop + swap.1 + drop + else + push.1 + dup.1 + push.1 + u32gt + while.true + dup.2 + dup.1 + u32wrapping_mul + dup.2 + push.1 + u32and + eq.1 + cdrop + swap.1 + u32div.2 + movup.2 + dup.0 + u32wrapping_mul + swap.1 + movup.2 + dup.1 + push.1 + u32gt + end + swap.1 + drop + u32wrapping_mul + end +end + +export.checked_shr + dup.0 + push.32 + u32lt + assert + dup.0 + eq.0 + dup.2 + eq.0 + or + if.true + eq.0 + swap.1 + push.0 + swap.2 + cdrop + else + dup.1 + push.2147483648 + u32and + push.2147483648 + eq + if.true + swap.1 + dup.1 + u32shr + push.1 + dup.2 + u32shl + sub.1 + push.32 + movup.3 + sub + u32shl + u32or + u32assert + else + u32shr + u32assert + end + end +end + +mod intrinsics::mem + +export.extract_element + dup.0 + push.3 + lte + assert + dup.0 + push.3 + lt + movdn.5 + dup.0 + push.2 + lt + movdn.5 + push.1 + lt + cdrop + movup.3 + cdrop + movup.2 + cdrop +end + +proc.load_felt_unchecked + padw + movup.4 + mem_loadw + movup.4 + exec.extract_element +end + +export.load_felt + movup.2 + assertz + exec.load_felt_unchecked +end + +export.load_sw + dup.2 + eq.0 + dup.3 + push.8 + u32lt + assert + if.true + movup.2 + drop + exec.load_felt_unchecked + else + dup.1 + eq.0 + if.true + swap.1 + drop + padw + movup.4 + mem_loadw + movup.3 + movup.3 + drop + drop + dup.2 + u32shl + swap.1 + push.32 + movup.3 + u32overflowing_sub + assertz + u32shr + u32or + else + dup.1 + eq.1 + if.true + swap.1 + drop + padw + movup.4 + mem_loadw + drop + movdn.2 + movdn.2 + drop + dup.2 + u32shl + swap.1 + push.32 + movup.3 + u32overflowing_sub + assertz + u32shr + u32or + else + swap.1 + eq.2 + if.true + padw + movup.4 + mem_loadw + drop + drop + dup.2 + u32shl + swap.1 + push.32 + movup.3 + u32overflowing_sub + assertz + u32shr + u32or + else + dup.0 + u32overflowing_add.1 + assertz + padw + movup.4 + mem_loadw + movdn.4 + drop + drop + drop + push.32 + dup.3 + u32overflowing_sub + assertz + u32shr + swap.1 + padw + movup.4 + mem_loadw + drop + drop + drop + movup.2 + u32shl + u32or + end + end + end + end +end + +export.realign_dw + dup.3 + u32shl + movdn.2 + dup.0 + push.32 + dup.4 + u32shr + movup.4 + u32or + movdn.2 + dup.3 + u32shl + swap.1 + push.32 + movup.4 + u32shr + u32or + swap.1 +end + +export.load_dw + dup.2 + eq.0 + dup.3 + push.8 + u32lt + assert + if.true + movup.2 + drop + dup.1 + eq.0 + if.true + swap.1 + drop + padw + movup.4 + mem_loadw + movup.4 + movup.4 + drop + drop + else + dup.1 + eq.1 + if.true + swap.1 + drop + padw + movup.4 + mem_loadw + drop + movup.3 + drop + else + swap.1 + eq.2 + if.true + padw + movup.4 + mem_loadw + drop + drop + else + dup.0 + u32overflowing_add.1 + assertz + padw + movup.4 + mem_loadw + movup.4 + movup.4 + movup.4 + drop + drop + drop + movup.4 + padw + movup.4 + mem_loadw + drop + drop + drop + end + end + end + else + dup.1 + eq.0 + if.true + swap.1 + drop + padw + movup.4 + mem_loadw + movup.4 + drop + exec.realign_dw + else + dup.1 + eq.1 + if.true + swap.1 + drop + padw + movup.4 + mem_loadw + drop + exec.realign_dw + else + swap.1 + eq.2 + if.true + dup.0 + u32overflowing_add.1 + assertz + padw + movup.4 + mem_loadw + movup.4 + movup.4 + movup.4 + drop + drop + drop + swap.1 + padw + movup.4 + mem_loadw + drop + drop + exec.realign_dw + else + dup.0 + u32overflowing_add.1 + assertz + padw + movup.4 + mem_loadw + movup.4 + movup.4 + drop + drop + movup.2 + padw + movup.4 + mem_loadw + drop + drop + drop + exec.realign_dw + end + end + end + end +end + +mod mul_felt + +export.entrypoint + swap.1 + mul +end + +program + +use mul_felt + +begin + exec.mul_felt::entrypoint +end diff --git a/tests/integration/expected/mul_felt.wat b/tests/integration/expected/mul_felt.wat new file mode 100644 index 000000000..fb3b00151 --- /dev/null +++ b/tests/integration/expected/mul_felt.wat @@ -0,0 +1,14 @@ +(module $mul_felt.wasm + (type (;0;) (func (param f64 f64) (result f64))) + (import "miden:prelude/intrinsics_felt" "mul" (func $miden_prelude::intrinsics::felt::extern_mul (;0;) (type 0))) + (func $entrypoint (;1;) (type 0) (param f64 f64) (result f64) + local.get 0 + local.get 1 + call $miden_prelude::intrinsics::felt::extern_mul + ) + (table (;0;) 1 1 funcref) + (memory (;0;) 16) + (global $__stack_pointer (;0;) (mut i32) i32.const 1048576) + (export "memory" (memory 0)) + (export "entrypoint" (func $entrypoint)) +) \ No newline at end of file diff --git a/tests/integration/expected/neg_felt.hir b/tests/integration/expected/neg_felt.hir new file mode 100644 index 000000000..3a2d32653 --- /dev/null +++ b/tests/integration/expected/neg_felt.hir @@ -0,0 +1,21 @@ +(component + ;; Modules + (module #neg_felt + ;; Constants + (const (id 0) 0x00100000) + + ;; Global Variables + (global (export #__stack_pointer) (id 0) (type i32) (const 0)) + + ;; Functions + (func (export #entrypoint) (param felt) (param felt) (result felt) + (block 0 (param v0 felt) (param v1 felt) + (let (v3 felt) (sub.unchecked v0 v1)) + (br (block 1 v3))) + + (block 1 (param v2 felt) + (ret v2)) + ) + ) + +) diff --git a/tests/integration/expected/neg_felt.masm b/tests/integration/expected/neg_felt.masm new file mode 100644 index 000000000..7401d4e96 --- /dev/null +++ b/tests/integration/expected/neg_felt.masm @@ -0,0 +1,669 @@ +mod intrinsics::i32 + +export.is_signed + push.2147483648 + u32and + push.2147483648 + eq +end + +export.unchecked_neg + u32not + u32wrapping_add.1 +end + +export.checked_neg + dup.0 + push.2147483648 + eq + assertz + exec.unchecked_neg +end + +export.overflowing_add + u32assert2 + dup.0 + exec.is_signed + dup.2 + exec.is_signed + dup.1 + eq + movup.3 + movup.3 + u32wrapping_add + dup.0 + exec.is_signed + movup.3 + neq + movup.2 + and +end + +export.wrapping_add + exec.overflowing_add + drop +end + +export.checked_add + exec.overflowing_add + assertz +end + +export.overflowing_sub + u32assert2 + dup.0 + push.2147483648 + eq + if.true + drop + push.2147483647 + dup.1 + exec.is_signed + dup.0 + eq.0 + movup.3 + movup.3 + u32wrapping_add + push.1 + u32wrapping_add + dup.0 + exec.is_signed + movup.3 + neq + movup.2 + and + else + exec.unchecked_neg + exec.overflowing_add + end +end + +export.wrapping_sub + exec.overflowing_sub + drop +end + +export.checked_sub + exec.overflowing_sub + assertz +end + +export.overflowing_mul + u32assert2 + dup.0 + push.2147483648 + eq + dup.2 + push.2147483648 + eq + or + if.true + dup.0 + eq.1 + dup.2 + eq.1 + or + movup.2 + push.4294967295 + eq + movup.2 + push.4294967295 + eq + or + dup.1 + or + push.2147483648 + push.0 + swap.2 + cdrop + swap.1 + not + else + dup.0 + exec.is_signed + dup.2 + exec.is_signed + dup.1 + dup.1 + neq + movdn.4 + movup.3 + dup.0 + exec.unchecked_neg + movup.2 + cdrop + swap.2 + dup.0 + exec.unchecked_neg + movup.2 + cdrop + u32overflowing_mul + dup.1 + exec.is_signed + or + swap.1 + dup.0 + exec.unchecked_neg + movup.3 + cdrop + swap.1 + end +end + +export.wrapping_mul + exec.overflowing_mul + drop +end + +export.checked_mul + exec.overflowing_mul + assertz +end + +export.checked_div + u32assert2 + dup.1 + exec.unchecked_neg + dup.2 + swap.1 + movup.3 + exec.is_signed + dup.0 + movdn.4 + cdrop + dup.1 + exec.unchecked_neg + dup.2 + swap.1 + movup.3 + exec.is_signed + dup.0 + movdn.5 + cdrop + u32div + movdn.2 + neq + dup.1 + exec.unchecked_neg + swap.1 + cdrop +end + +export.icmp + dup.1 + dup.1 + push.2147483648 + u32and + swap.1 + push.2147483648 + u32and + eq.0 + swap.1 + eq.0 + swap.1 + dup.1 + neq + if.true + movdn.2 + drop + drop + push.4294967295 + push.1 + swap.2 + cdrop + else + drop + dup.1 + dup.1 + u32gt + movdn.2 + u32lt + push.0 + push.4294967295 + push.1 + swap.3 + cdrop + swap.2 + cdrop + end +end + +export.is_lt + exec.icmp + push.4294967295 + eq +end + +export.is_lte + exec.icmp + neq.1 +end + +export.is_gt + exec.icmp + eq.1 +end + +export.is_gte + exec.icmp + push.4294967295 + neq +end + +export.pow2 + dup.0 + push.31 + u32lt + assert + push.1 + swap.1 + u32shl +end + +export.ipow + dup.0 + push.31 + u32lt + assert + dup.0 + eq.0 + dup.2 + eq.0 + or + if.true + eq.0 + push.1 + push.0 + swap.2 + cdrop + swap.1 + drop + else + push.1 + dup.1 + push.1 + u32gt + while.true + dup.2 + dup.1 + u32wrapping_mul + dup.2 + push.1 + u32and + eq.1 + cdrop + swap.1 + u32div.2 + movup.2 + dup.0 + u32wrapping_mul + swap.1 + movup.2 + dup.1 + push.1 + u32gt + end + swap.1 + drop + u32wrapping_mul + end +end + +export.checked_shr + dup.0 + push.32 + u32lt + assert + dup.0 + eq.0 + dup.2 + eq.0 + or + if.true + eq.0 + swap.1 + push.0 + swap.2 + cdrop + else + dup.1 + push.2147483648 + u32and + push.2147483648 + eq + if.true + swap.1 + dup.1 + u32shr + push.1 + dup.2 + u32shl + sub.1 + push.32 + movup.3 + sub + u32shl + u32or + u32assert + else + u32shr + u32assert + end + end +end + +mod intrinsics::mem + +export.extract_element + dup.0 + push.3 + lte + assert + dup.0 + push.3 + lt + movdn.5 + dup.0 + push.2 + lt + movdn.5 + push.1 + lt + cdrop + movup.3 + cdrop + movup.2 + cdrop +end + +proc.load_felt_unchecked + padw + movup.4 + mem_loadw + movup.4 + exec.extract_element +end + +export.load_felt + movup.2 + assertz + exec.load_felt_unchecked +end + +export.load_sw + dup.2 + eq.0 + dup.3 + push.8 + u32lt + assert + if.true + movup.2 + drop + exec.load_felt_unchecked + else + dup.1 + eq.0 + if.true + swap.1 + drop + padw + movup.4 + mem_loadw + movup.3 + movup.3 + drop + drop + dup.2 + u32shl + swap.1 + push.32 + movup.3 + u32overflowing_sub + assertz + u32shr + u32or + else + dup.1 + eq.1 + if.true + swap.1 + drop + padw + movup.4 + mem_loadw + drop + movdn.2 + movdn.2 + drop + dup.2 + u32shl + swap.1 + push.32 + movup.3 + u32overflowing_sub + assertz + u32shr + u32or + else + swap.1 + eq.2 + if.true + padw + movup.4 + mem_loadw + drop + drop + dup.2 + u32shl + swap.1 + push.32 + movup.3 + u32overflowing_sub + assertz + u32shr + u32or + else + dup.0 + u32overflowing_add.1 + assertz + padw + movup.4 + mem_loadw + movdn.4 + drop + drop + drop + push.32 + dup.3 + u32overflowing_sub + assertz + u32shr + swap.1 + padw + movup.4 + mem_loadw + drop + drop + drop + movup.2 + u32shl + u32or + end + end + end + end +end + +export.realign_dw + dup.3 + u32shl + movdn.2 + dup.0 + push.32 + dup.4 + u32shr + movup.4 + u32or + movdn.2 + dup.3 + u32shl + swap.1 + push.32 + movup.4 + u32shr + u32or + swap.1 +end + +export.load_dw + dup.2 + eq.0 + dup.3 + push.8 + u32lt + assert + if.true + movup.2 + drop + dup.1 + eq.0 + if.true + swap.1 + drop + padw + movup.4 + mem_loadw + movup.4 + movup.4 + drop + drop + else + dup.1 + eq.1 + if.true + swap.1 + drop + padw + movup.4 + mem_loadw + drop + movup.3 + drop + else + swap.1 + eq.2 + if.true + padw + movup.4 + mem_loadw + drop + drop + else + dup.0 + u32overflowing_add.1 + assertz + padw + movup.4 + mem_loadw + movup.4 + movup.4 + movup.4 + drop + drop + drop + movup.4 + padw + movup.4 + mem_loadw + drop + drop + drop + end + end + end + else + dup.1 + eq.0 + if.true + swap.1 + drop + padw + movup.4 + mem_loadw + movup.4 + drop + exec.realign_dw + else + dup.1 + eq.1 + if.true + swap.1 + drop + padw + movup.4 + mem_loadw + drop + exec.realign_dw + else + swap.1 + eq.2 + if.true + dup.0 + u32overflowing_add.1 + assertz + padw + movup.4 + mem_loadw + movup.4 + movup.4 + movup.4 + drop + drop + drop + swap.1 + padw + movup.4 + mem_loadw + drop + drop + exec.realign_dw + else + dup.0 + u32overflowing_add.1 + assertz + padw + movup.4 + mem_loadw + movup.4 + movup.4 + drop + drop + movup.2 + padw + movup.4 + mem_loadw + drop + drop + drop + exec.realign_dw + end + end + end + end +end + +mod neg_felt + +export.entrypoint + swap.1 + sub +end + +program + +use neg_felt + +begin + exec.neg_felt::entrypoint +end diff --git a/tests/integration/expected/neg_felt.wat b/tests/integration/expected/neg_felt.wat new file mode 100644 index 000000000..0d2ae43b3 --- /dev/null +++ b/tests/integration/expected/neg_felt.wat @@ -0,0 +1,14 @@ +(module $neg_felt.wasm + (type (;0;) (func (param f64 f64) (result f64))) + (import "miden:prelude/intrinsics_felt" "sub" (func $miden_prelude::intrinsics::felt::extern_sub (;0;) (type 0))) + (func $entrypoint (;1;) (type 0) (param f64 f64) (result f64) + local.get 0 + local.get 1 + call $miden_prelude::intrinsics::felt::extern_sub + ) + (table (;0;) 1 1 funcref) + (memory (;0;) 16) + (global $__stack_pointer (;0;) (mut i32) i32.const 1048576) + (export "memory" (memory 0)) + (export "entrypoint" (func $entrypoint)) +) \ No newline at end of file diff --git a/tests/integration/expected/sub_felt.hir b/tests/integration/expected/sub_felt.hir new file mode 100644 index 000000000..9ff0f4a57 --- /dev/null +++ b/tests/integration/expected/sub_felt.hir @@ -0,0 +1,21 @@ +(component + ;; Modules + (module #sub_felt + ;; Constants + (const (id 0) 0x00100000) + + ;; Global Variables + (global (export #__stack_pointer) (id 0) (type i32) (const 0)) + + ;; Functions + (func (export #entrypoint) (param felt) (param felt) (result felt) + (block 0 (param v0 felt) (param v1 felt) + (let (v3 felt) (sub.unchecked v0 v1)) + (br (block 1 v3))) + + (block 1 (param v2 felt) + (ret v2)) + ) + ) + +) diff --git a/tests/integration/expected/sub_felt.masm b/tests/integration/expected/sub_felt.masm new file mode 100644 index 000000000..7e239c846 --- /dev/null +++ b/tests/integration/expected/sub_felt.masm @@ -0,0 +1,669 @@ +mod intrinsics::i32 + +export.is_signed + push.2147483648 + u32and + push.2147483648 + eq +end + +export.unchecked_neg + u32not + u32wrapping_add.1 +end + +export.checked_neg + dup.0 + push.2147483648 + eq + assertz + exec.unchecked_neg +end + +export.overflowing_add + u32assert2 + dup.0 + exec.is_signed + dup.2 + exec.is_signed + dup.1 + eq + movup.3 + movup.3 + u32wrapping_add + dup.0 + exec.is_signed + movup.3 + neq + movup.2 + and +end + +export.wrapping_add + exec.overflowing_add + drop +end + +export.checked_add + exec.overflowing_add + assertz +end + +export.overflowing_sub + u32assert2 + dup.0 + push.2147483648 + eq + if.true + drop + push.2147483647 + dup.1 + exec.is_signed + dup.0 + eq.0 + movup.3 + movup.3 + u32wrapping_add + push.1 + u32wrapping_add + dup.0 + exec.is_signed + movup.3 + neq + movup.2 + and + else + exec.unchecked_neg + exec.overflowing_add + end +end + +export.wrapping_sub + exec.overflowing_sub + drop +end + +export.checked_sub + exec.overflowing_sub + assertz +end + +export.overflowing_mul + u32assert2 + dup.0 + push.2147483648 + eq + dup.2 + push.2147483648 + eq + or + if.true + dup.0 + eq.1 + dup.2 + eq.1 + or + movup.2 + push.4294967295 + eq + movup.2 + push.4294967295 + eq + or + dup.1 + or + push.2147483648 + push.0 + swap.2 + cdrop + swap.1 + not + else + dup.0 + exec.is_signed + dup.2 + exec.is_signed + dup.1 + dup.1 + neq + movdn.4 + movup.3 + dup.0 + exec.unchecked_neg + movup.2 + cdrop + swap.2 + dup.0 + exec.unchecked_neg + movup.2 + cdrop + u32overflowing_mul + dup.1 + exec.is_signed + or + swap.1 + dup.0 + exec.unchecked_neg + movup.3 + cdrop + swap.1 + end +end + +export.wrapping_mul + exec.overflowing_mul + drop +end + +export.checked_mul + exec.overflowing_mul + assertz +end + +export.checked_div + u32assert2 + dup.1 + exec.unchecked_neg + dup.2 + swap.1 + movup.3 + exec.is_signed + dup.0 + movdn.4 + cdrop + dup.1 + exec.unchecked_neg + dup.2 + swap.1 + movup.3 + exec.is_signed + dup.0 + movdn.5 + cdrop + u32div + movdn.2 + neq + dup.1 + exec.unchecked_neg + swap.1 + cdrop +end + +export.icmp + dup.1 + dup.1 + push.2147483648 + u32and + swap.1 + push.2147483648 + u32and + eq.0 + swap.1 + eq.0 + swap.1 + dup.1 + neq + if.true + movdn.2 + drop + drop + push.4294967295 + push.1 + swap.2 + cdrop + else + drop + dup.1 + dup.1 + u32gt + movdn.2 + u32lt + push.0 + push.4294967295 + push.1 + swap.3 + cdrop + swap.2 + cdrop + end +end + +export.is_lt + exec.icmp + push.4294967295 + eq +end + +export.is_lte + exec.icmp + neq.1 +end + +export.is_gt + exec.icmp + eq.1 +end + +export.is_gte + exec.icmp + push.4294967295 + neq +end + +export.pow2 + dup.0 + push.31 + u32lt + assert + push.1 + swap.1 + u32shl +end + +export.ipow + dup.0 + push.31 + u32lt + assert + dup.0 + eq.0 + dup.2 + eq.0 + or + if.true + eq.0 + push.1 + push.0 + swap.2 + cdrop + swap.1 + drop + else + push.1 + dup.1 + push.1 + u32gt + while.true + dup.2 + dup.1 + u32wrapping_mul + dup.2 + push.1 + u32and + eq.1 + cdrop + swap.1 + u32div.2 + movup.2 + dup.0 + u32wrapping_mul + swap.1 + movup.2 + dup.1 + push.1 + u32gt + end + swap.1 + drop + u32wrapping_mul + end +end + +export.checked_shr + dup.0 + push.32 + u32lt + assert + dup.0 + eq.0 + dup.2 + eq.0 + or + if.true + eq.0 + swap.1 + push.0 + swap.2 + cdrop + else + dup.1 + push.2147483648 + u32and + push.2147483648 + eq + if.true + swap.1 + dup.1 + u32shr + push.1 + dup.2 + u32shl + sub.1 + push.32 + movup.3 + sub + u32shl + u32or + u32assert + else + u32shr + u32assert + end + end +end + +mod intrinsics::mem + +export.extract_element + dup.0 + push.3 + lte + assert + dup.0 + push.3 + lt + movdn.5 + dup.0 + push.2 + lt + movdn.5 + push.1 + lt + cdrop + movup.3 + cdrop + movup.2 + cdrop +end + +proc.load_felt_unchecked + padw + movup.4 + mem_loadw + movup.4 + exec.extract_element +end + +export.load_felt + movup.2 + assertz + exec.load_felt_unchecked +end + +export.load_sw + dup.2 + eq.0 + dup.3 + push.8 + u32lt + assert + if.true + movup.2 + drop + exec.load_felt_unchecked + else + dup.1 + eq.0 + if.true + swap.1 + drop + padw + movup.4 + mem_loadw + movup.3 + movup.3 + drop + drop + dup.2 + u32shl + swap.1 + push.32 + movup.3 + u32overflowing_sub + assertz + u32shr + u32or + else + dup.1 + eq.1 + if.true + swap.1 + drop + padw + movup.4 + mem_loadw + drop + movdn.2 + movdn.2 + drop + dup.2 + u32shl + swap.1 + push.32 + movup.3 + u32overflowing_sub + assertz + u32shr + u32or + else + swap.1 + eq.2 + if.true + padw + movup.4 + mem_loadw + drop + drop + dup.2 + u32shl + swap.1 + push.32 + movup.3 + u32overflowing_sub + assertz + u32shr + u32or + else + dup.0 + u32overflowing_add.1 + assertz + padw + movup.4 + mem_loadw + movdn.4 + drop + drop + drop + push.32 + dup.3 + u32overflowing_sub + assertz + u32shr + swap.1 + padw + movup.4 + mem_loadw + drop + drop + drop + movup.2 + u32shl + u32or + end + end + end + end +end + +export.realign_dw + dup.3 + u32shl + movdn.2 + dup.0 + push.32 + dup.4 + u32shr + movup.4 + u32or + movdn.2 + dup.3 + u32shl + swap.1 + push.32 + movup.4 + u32shr + u32or + swap.1 +end + +export.load_dw + dup.2 + eq.0 + dup.3 + push.8 + u32lt + assert + if.true + movup.2 + drop + dup.1 + eq.0 + if.true + swap.1 + drop + padw + movup.4 + mem_loadw + movup.4 + movup.4 + drop + drop + else + dup.1 + eq.1 + if.true + swap.1 + drop + padw + movup.4 + mem_loadw + drop + movup.3 + drop + else + swap.1 + eq.2 + if.true + padw + movup.4 + mem_loadw + drop + drop + else + dup.0 + u32overflowing_add.1 + assertz + padw + movup.4 + mem_loadw + movup.4 + movup.4 + movup.4 + drop + drop + drop + movup.4 + padw + movup.4 + mem_loadw + drop + drop + drop + end + end + end + else + dup.1 + eq.0 + if.true + swap.1 + drop + padw + movup.4 + mem_loadw + movup.4 + drop + exec.realign_dw + else + dup.1 + eq.1 + if.true + swap.1 + drop + padw + movup.4 + mem_loadw + drop + exec.realign_dw + else + swap.1 + eq.2 + if.true + dup.0 + u32overflowing_add.1 + assertz + padw + movup.4 + mem_loadw + movup.4 + movup.4 + movup.4 + drop + drop + drop + swap.1 + padw + movup.4 + mem_loadw + drop + drop + exec.realign_dw + else + dup.0 + u32overflowing_add.1 + assertz + padw + movup.4 + mem_loadw + movup.4 + movup.4 + drop + drop + movup.2 + padw + movup.4 + mem_loadw + drop + drop + drop + exec.realign_dw + end + end + end + end +end + +mod sub_felt + +export.entrypoint + swap.1 + sub +end + +program + +use sub_felt + +begin + exec.sub_felt::entrypoint +end diff --git a/tests/integration/expected/sub_felt.wat b/tests/integration/expected/sub_felt.wat new file mode 100644 index 000000000..733dd10a0 --- /dev/null +++ b/tests/integration/expected/sub_felt.wat @@ -0,0 +1,14 @@ +(module $sub_felt.wasm + (type (;0;) (func (param f64 f64) (result f64))) + (import "miden:prelude/intrinsics_felt" "sub" (func $miden_prelude::intrinsics::felt::extern_sub (;0;) (type 0))) + (func $entrypoint (;1;) (type 0) (param f64 f64) (result f64) + local.get 0 + local.get 1 + call $miden_prelude::intrinsics::felt::extern_sub + ) + (table (;0;) 1 1 funcref) + (memory (;0;) 16) + (global $__stack_pointer (;0;) (mut i32) i32.const 1048576) + (export "memory" (memory 0)) + (export "entrypoint" (func $entrypoint)) +) \ No newline at end of file diff --git a/tests/integration/src/felt_conversion.rs b/tests/integration/src/felt_conversion.rs index b7381cb70..c4578b683 100644 --- a/tests/integration/src/felt_conversion.rs +++ b/tests/integration/src/felt_conversion.rs @@ -1,10 +1,20 @@ use miden_core::{Felt, StarkField}; +use proptest::{ + arbitrary::Arbitrary, + strategy::{BoxedStrategy, Strategy}, +}; /// Wrapper around `Felt` that implements `From` for a bunch of types that are want to support in /// tests #[derive(Clone, Copy, Debug, PartialEq, Eq)] pub struct TestFelt(pub Felt); +impl From for Felt { + fn from(f: TestFelt) -> Self { + f.0 + } +} + impl From for TestFelt { fn from(b: bool) -> Self { Self(Felt::from(b as u32)) @@ -114,3 +124,12 @@ impl From for i64 { f.0.as_int() as i64 } } + +impl Arbitrary for TestFelt { + type Parameters = (); + type Strategy = BoxedStrategy; + + fn arbitrary_with(_args: Self::Parameters) -> Self::Strategy { + (0u64..u64::MAX).prop_map(|v| TestFelt(Felt::from(v))).boxed() + } +} diff --git a/tests/integration/src/rust_masm_tests/intrinsics.rs b/tests/integration/src/rust_masm_tests/intrinsics.rs index d4d5629f9..aa7a76a85 100644 --- a/tests/integration/src/rust_masm_tests/intrinsics.rs +++ b/tests/integration/src/rust_masm_tests/intrinsics.rs @@ -1,6 +1,7 @@ use core::panic; use expect_test::expect_file; +use miden_core::Felt; use proptest::{ arbitrary::any, test_runner::{TestError, TestRunner}, @@ -8,30 +9,96 @@ use proptest::{ use crate::{felt_conversion::TestFelt, rust_masm_tests::run_masm_vs_rust, CompilerTest}; -#[test] -fn test_felt_plus() { - let main_fn = format!("(a: Felt, b: Felt) -> Felt {{ a + b }}"); - let artifact_name = "felt_plus"; - let mut test = CompilerTest::rust_fn_body_with_prelude(&artifact_name, &main_fn); - // Test expected compilation artifacts - test.expect_wasm(expect_file![format!("../../expected/{artifact_name}.wat")]); - test.expect_ir(expect_file![format!("../../expected/{artifact_name}.hir")]); - test.expect_masm(expect_file![format!("../../expected/{artifact_name}.masm")]); - let ir_masm = test.ir_masm_program(); - let vm_program = test.vm_masm_program(); - - // Run the Rust and compiled MASM code against a bunch of random inputs and compare the results - // TODO: generate proper felt values, i.e. in the range [0, M) - let res = TestRunner::default().run(&(any::(), any::()), move |(a, b)| { - let rust_out = a.wrapping_add(b); - let args = [TestFelt::from(a).0, TestFelt::from(b).0]; - run_masm_vs_rust(rust_out, &vm_program, ir_masm.clone(), &args) - }); - match res { - Err(TestError::Fail(_, value)) => { - panic!("Found minimal(shrinked) failing case: {:?}", value); - } - Ok(_) => (), - _ => panic!("Unexpected test result: {:?}", res), +/// Compiles, runs VM vs. Rust fuzzing the inputs via proptest +macro_rules! test_bin_op { + ($name:ident, $op:tt, $op_ty:tt, $res_ty:tt, $a_range:expr, $b_range:expr) => { + concat_idents::concat_idents!(test_name = $name { + #[test] + fn test_name() { + let op_str = stringify!($op); + let op_ty_str = stringify!($op_ty); + let res_ty_str = stringify!($res_ty); + let main_fn = format!("(a: {op_ty_str}, b: {op_ty_str}) -> {res_ty_str} {{ a {op_str} b }}"); + let artifact_name = format!("{}_{}", stringify!($name), stringify!($op_ty).to_lowercase()); + let mut test = CompilerTest::rust_fn_body_with_prelude(&artifact_name, &main_fn); + // Test expected compilation artifacts + test.expect_wasm(expect_file![format!("../../expected/{artifact_name}.wat")]); + test.expect_ir(expect_file![format!("../../expected/{artifact_name}.hir")]); + test.expect_masm(expect_file![format!("../../expected/{artifact_name}.masm")]); + let ir_masm = test.ir_masm_program(); + let vm_program = test.vm_masm_program(); + + // Run the Rust and compiled MASM code against a bunch of random inputs and compare the results + let res = TestRunner::default() + .run(&($a_range, $b_range), move |(a, b)| { + dbg!(a, b); + let a_felt: Felt = a.0; + let b_felt: Felt = b.0; + let rs_out = a_felt $op b_felt; + dbg!(&rs_out); + let args = [a.0, b.0]; + run_masm_vs_rust(rs_out, &vm_program, ir_masm.clone(), &args) + }); + match res { + Err(TestError::Fail(_, value)) => { + panic!("Found minimal(shrinked) failing case: {:?}", value); + }, + Ok(_) => (), + _ => panic!("Unexpected test result: {:?}", res), } + } + }); + }; +} + +/// Compiles given binary operation +macro_rules! test_compile_comparison_op { + ($name:ident, $op:tt) => { + concat_idents::concat_idents!(test_name = $name { + #[test] + fn test_name() { + let op_str = stringify!($op); + let main_fn = format!("(a: Felt, b: Felt) -> bool {{ a {op_str} b }}"); + let artifact_name = format!("{}_felt", stringify!($name)); + let mut test = CompilerTest::rust_fn_body_with_prelude(&artifact_name, &main_fn); + // Test expected compilation artifacts + test.expect_wasm(expect_file![format!("../../expected/{artifact_name}.wat")]); + test.expect_ir(expect_file![format!("../../expected/{artifact_name}.hir")]); + test.expect_masm(expect_file![format!("../../expected/{artifact_name}.masm")]); + } + }); + }; } + +macro_rules! test_bin_op_total { + ($name:ident, $op:tt) => { + test_bin_op!($name, $op, Felt, Felt, any::(), any::()); + }; +} + +macro_rules! test_bool_op_total { + ($name:ident, $op:tt) => { + test_bin_op!($name, $op, Felt, bool, any::(), any::()); + }; +} + +test_bin_op_total!(add, +); +test_bin_op_total!(sub, -); +test_bin_op_total!(mul, *); +test_bin_op_total!(div, /); +test_bin_op_total!(neg, -); + +test_bool_op_total!(eq, ==); + +// TODO: Comparison operators are not defined for Felt, so we cannot compile a Rust equivalent for +// the semantic test +// see https://github.com/0xPolygonMiden/compiler/issues/175 +// test_bool_op_total!(gt, >); +// test_bool_op_total!(lt, <); +// test_bool_op_total!(ge, >=); +// test_bool_op_total!(le, <=); + +test_compile_comparison_op!(gt, >); +test_compile_comparison_op!(lt, <); +test_compile_comparison_op!(ge, >=); +test_compile_comparison_op!(le, <=);