diff --git a/CHANGELOG.md b/CHANGELOG.md index b0eea7ad17..aa593ff329 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,7 @@ - Introduced the `emit.` assembly instruction (#1119). - Introduced the `procref.` assembly instruction (#1113). - Added the ability to use constants as counters in `repeat` loops (#1124). +- All `checked` versions of the u32 instructions were removed. All `unchecked` versions were renamed: this mode specification was removed from their titles (#1115). #### Stdlib - Introduced `std::utils` module with `is_empty_word` procedure. Refactored `std::collections::smt` diff --git a/assembly/src/assembler/instruction/field_ops.rs b/assembly/src/assembler/instruction/field_ops.rs index 7246b38be3..0619c1596d 100644 --- a/assembly/src/assembler/instruction/field_ops.rs +++ b/assembly/src/assembler/instruction/field_ops.rs @@ -275,7 +275,7 @@ pub fn eqw(span: &mut SpanBuilder) -> Result, AssemblyError> { ]) } -/// Appends a sequence of operations to to pop the top 2 elements off the stack and do a "less +/// Appends a sequence of operations to pop the top 2 elements off the stack and do a "less /// than" comparison. The stack is expected to be arranged as [b, a, ...] (from the top). A value /// of 1 is pushed onto the stack if a < b. Otherwise, 0 is pushed. /// diff --git a/assembly/src/assembler/instruction/mod.rs b/assembly/src/assembler/instruction/mod.rs index dc19c370c3..7fa4f2412c 100644 --- a/assembly/src/assembler/instruction/mod.rs +++ b/assembly/src/assembler/instruction/mod.rs @@ -112,8 +112,6 @@ impl Assembler { Instruction::U32Cast => span.add_ops([U32split, Drop]), Instruction::U32Split => span.add_op(U32split), - Instruction::U32CheckedAdd => u32_ops::u32add(span, Checked, None), - Instruction::U32CheckedAddImm(v) => u32_ops::u32add(span, Checked, Some(*v)), Instruction::U32OverflowingAdd => u32_ops::u32add(span, Overflowing, None), Instruction::U32OverflowingAddImm(v) => u32_ops::u32add(span, Overflowing, Some(*v)), Instruction::U32WrappingAdd => u32_ops::u32add(span, Wrapping, None), @@ -121,15 +119,11 @@ impl Assembler { Instruction::U32OverflowingAdd3 => span.add_op(U32add3), Instruction::U32WrappingAdd3 => span.add_ops([U32add3, Drop]), - Instruction::U32CheckedSub => u32_ops::u32sub(span, Checked, None), - Instruction::U32CheckedSubImm(v) => u32_ops::u32sub(span, Checked, Some(*v)), Instruction::U32OverflowingSub => u32_ops::u32sub(span, Overflowing, None), Instruction::U32OverflowingSubImm(v) => u32_ops::u32sub(span, Overflowing, Some(*v)), Instruction::U32WrappingSub => u32_ops::u32sub(span, Wrapping, None), Instruction::U32WrappingSubImm(v) => u32_ops::u32sub(span, Wrapping, Some(*v)), - Instruction::U32CheckedMul => u32_ops::u32mul(span, Checked, None), - Instruction::U32CheckedMulImm(v) => u32_ops::u32mul(span, Checked, Some(*v)), Instruction::U32OverflowingMul => u32_ops::u32mul(span, Overflowing, None), Instruction::U32OverflowingMulImm(v) => u32_ops::u32mul(span, Overflowing, Some(*v)), Instruction::U32WrappingMul => u32_ops::u32mul(span, Wrapping, None), @@ -137,58 +131,33 @@ impl Assembler { Instruction::U32OverflowingMadd => span.add_op(U32madd), Instruction::U32WrappingMadd => span.add_ops([U32madd, Drop]), - Instruction::U32CheckedDiv => u32_ops::u32div(span, Checked, None), - Instruction::U32CheckedDivImm(v) => u32_ops::u32div(span, Checked, Some(*v)), - Instruction::U32UncheckedDiv => u32_ops::u32div(span, Unchecked, None), - Instruction::U32UncheckedDivImm(v) => u32_ops::u32div(span, Unchecked, Some(*v)), - Instruction::U32CheckedMod => u32_ops::u32mod(span, Checked, None), - Instruction::U32CheckedModImm(v) => u32_ops::u32mod(span, Checked, Some(*v)), - Instruction::U32UncheckedMod => u32_ops::u32mod(span, Unchecked, None), - Instruction::U32UncheckedModImm(v) => u32_ops::u32mod(span, Unchecked, Some(*v)), - Instruction::U32CheckedDivMod => u32_ops::u32divmod(span, Checked, None), - Instruction::U32CheckedDivModImm(v) => u32_ops::u32divmod(span, Checked, Some(*v)), - Instruction::U32UncheckedDivMod => u32_ops::u32divmod(span, Unchecked, None), - Instruction::U32UncheckedDivModImm(v) => u32_ops::u32divmod(span, Unchecked, Some(*v)), - - Instruction::U32CheckedAnd => span.add_op(U32and), - Instruction::U32CheckedOr => span.add_ops([Dup1, Dup1, U32and, Neg, Add, Add]), - Instruction::U32CheckedXor => span.add_op(U32xor), - Instruction::U32CheckedNot => u32_ops::u32not(span), - Instruction::U32CheckedShl => u32_ops::u32shl(span, Checked, None), - Instruction::U32CheckedShlImm(v) => u32_ops::u32shl(span, Checked, Some(*v)), - Instruction::U32UncheckedShl => u32_ops::u32shl(span, Unchecked, None), - Instruction::U32UncheckedShlImm(v) => u32_ops::u32shl(span, Unchecked, Some(*v)), - Instruction::U32CheckedShr => u32_ops::u32shr(span, Checked, None), - Instruction::U32CheckedShrImm(v) => u32_ops::u32shr(span, Checked, Some(*v)), - Instruction::U32UncheckedShr => u32_ops::u32shr(span, Unchecked, None), - Instruction::U32UncheckedShrImm(v) => u32_ops::u32shr(span, Unchecked, Some(*v)), - Instruction::U32CheckedRotl => u32_ops::u32rotl(span, Checked, None), - Instruction::U32CheckedRotlImm(v) => u32_ops::u32rotl(span, Checked, Some(*v)), - Instruction::U32UncheckedRotl => u32_ops::u32rotl(span, Unchecked, None), - Instruction::U32UncheckedRotlImm(v) => u32_ops::u32rotl(span, Unchecked, Some(*v)), - Instruction::U32CheckedRotr => u32_ops::u32rotr(span, Checked, None), - Instruction::U32CheckedRotrImm(v) => u32_ops::u32rotr(span, Checked, Some(*v)), - Instruction::U32UncheckedRotr => u32_ops::u32rotr(span, Unchecked, None), - Instruction::U32UncheckedRotrImm(v) => u32_ops::u32rotr(span, Unchecked, Some(*v)), - Instruction::U32CheckedPopcnt => u32_ops::u32popcnt(span, Checked), - Instruction::U32UncheckedPopcnt => u32_ops::u32popcnt(span, Unchecked), - - Instruction::U32CheckedEq => u32_ops::u32eq(span, None), - Instruction::U32CheckedEqImm(v) => u32_ops::u32eq(span, Some(*v)), - Instruction::U32CheckedNeq => u32_ops::u32neq(span, None), - Instruction::U32CheckedNeqImm(v) => u32_ops::u32neq(span, Some(*v)), - Instruction::U32CheckedLt => u32_ops::u32lt(span, Checked), - Instruction::U32UncheckedLt => u32_ops::u32lt(span, Unchecked), - Instruction::U32CheckedLte => u32_ops::u32lte(span, Checked), - Instruction::U32UncheckedLte => u32_ops::u32lte(span, Unchecked), - Instruction::U32CheckedGt => u32_ops::u32gt(span, Checked), - Instruction::U32UncheckedGt => u32_ops::u32gt(span, Unchecked), - Instruction::U32CheckedGte => u32_ops::u32gte(span, Checked), - Instruction::U32UncheckedGte => u32_ops::u32gte(span, Unchecked), - Instruction::U32CheckedMin => u32_ops::u32min(span, Checked), - Instruction::U32UncheckedMin => u32_ops::u32min(span, Unchecked), - Instruction::U32CheckedMax => u32_ops::u32max(span, Checked), - Instruction::U32UncheckedMax => u32_ops::u32max(span, Unchecked), + Instruction::U32Div => u32_ops::u32div(span, None), + Instruction::U32DivImm(v) => u32_ops::u32div(span, Some(*v)), + Instruction::U32Mod => u32_ops::u32mod(span, None), + Instruction::U32ModImm(v) => u32_ops::u32mod(span, Some(*v)), + Instruction::U32DivMod => u32_ops::u32divmod(span, None), + Instruction::U32DivModImm(v) => u32_ops::u32divmod(span, Some(*v)), + + Instruction::U32And => span.add_op(U32and), + Instruction::U32Or => span.add_ops([Dup1, Dup1, U32and, Neg, Add, Add]), + Instruction::U32Xor => span.add_op(U32xor), + Instruction::U32Not => u32_ops::u32not(span), + Instruction::U32Shl => u32_ops::u32shl(span, None), + Instruction::U32ShlImm(v) => u32_ops::u32shl(span, Some(*v)), + Instruction::U32Shr => u32_ops::u32shr(span, None), + Instruction::U32ShrImm(v) => u32_ops::u32shr(span, Some(*v)), + Instruction::U32Rotl => u32_ops::u32rotl(span, None), + Instruction::U32RotlImm(v) => u32_ops::u32rotl(span, Some(*v)), + Instruction::U32Rotr => u32_ops::u32rotr(span, None), + Instruction::U32RotrImm(v) => u32_ops::u32rotr(span, Some(*v)), + Instruction::U32Popcnt => u32_ops::u32popcnt(span), + + Instruction::U32Lt => u32_ops::u32lt(span), + Instruction::U32Lte => u32_ops::u32lte(span), + Instruction::U32Gt => u32_ops::u32gt(span), + Instruction::U32Gte => u32_ops::u32gte(span), + Instruction::U32Min => u32_ops::u32min(span), + Instruction::U32Max => u32_ops::u32max(span), // ----- stack manipulation ----------------------------------------------------------- Instruction::Drop => span.add_op(Drop), diff --git a/assembly/src/assembler/instruction/u32_ops.rs b/assembly/src/assembler/instruction/u32_ops.rs index 156fe8d3f9..8675a05b0e 100644 --- a/assembly/src/assembler/instruction/u32_ops.rs +++ b/assembly/src/assembler/instruction/u32_ops.rs @@ -12,8 +12,6 @@ use crate::{MAX_U32_ROTATE_VALUE, MAX_U32_SHIFT_VALUE}; /// This enum is intended to determine the mode of operation passed to the parsing function #[derive(PartialEq, Eq)] pub enum U32OpMode { - Checked, - Unchecked, Wrapping, Overflowing, } @@ -77,10 +75,6 @@ pub fn u32assertw( /// inserted. Please refer to the docs of `handle_arithmetic_operation` for more details. /// /// VM cycles per mode: -/// - u32checked_add: 4 cycles -/// - u32checked_add.b: -/// - 6 cycles if b = 1 -/// - 5 cycles if b != 1 /// - u32wrapping_add: 2 cycles /// - u32wrapping_add.b: 3 cycles /// - u32overflowing_add: 1 cycles @@ -99,10 +93,6 @@ pub fn u32add( /// inserted. Please refer to the docs of `handle_arithmetic_operation` for more details. /// /// VM cycles per mode: -/// - u32checked_sub: 4 cycles -/// - u32checked_sub.b: -/// - 6 cycles if b = 1 -/// - 5 cycles if b != 1 /// - u32wrapping_sub: 2 cycles /// - u32wrapping_sub.b: 3 cycles /// - u32overflowing_sub: 1 cycles @@ -121,10 +111,6 @@ pub fn u32sub( /// inserted. Please refer to the docs of `handle_arithmetic_operation` for more details. /// /// VM cycles per mode: -/// - u32checked_mul: 4 cycles -/// - u32checked_mul.b: -/// - 6 cycles if b = 1 -/// - 5 cycles if b != 1 /// - u32wrapping_mul: 2 cycles /// - u32wrapping_mul.b: 3 cycles /// - u32overflowing_mul: 1 cycles @@ -140,66 +126,51 @@ pub fn u32mul( /// Translates u32div assembly instructions to VM operations. /// /// VM cycles per mode: -/// - u32checked_div: 3 cycles -/// - u32checked_div.b: -/// - 5 cycles if b is 1 -/// - 4 cycles if b is not 1 -/// - u32unchecked_div: 2 cycles -/// - u32unchecked_div.b: +/// - u32div: 2 cycles +/// - u32div.b: /// - 4 cycles if b is 1 /// - 3 cycles if b is not 1 pub fn u32div( span: &mut SpanBuilder, - op_mode: U32OpMode, imm: Option, ) -> Result, AssemblyError> { - handle_division(span, op_mode, imm)?; + handle_division(span, imm)?; span.add_op(Drop) } /// Translates u32mod assembly instructions to VM operations. /// /// VM cycles per mode: -/// - u32checked_mod: 4 cycles -/// - u32checked_mod.b: -/// - 6 cycles if b is 1 -/// - 5 cycles if b is not 1 -/// - u32unchecked_mod: 3 cycle -/// - u32unchecked_mod.b: +/// - u32mod: 3 cycle +/// - u32mod.b: /// - 5 cycles if b is 1 /// - 4 cycles if b is not 1 pub fn u32mod( span: &mut SpanBuilder, - op_mode: U32OpMode, imm: Option, ) -> Result, AssemblyError> { - handle_division(span, op_mode, imm)?; + handle_division(span, imm)?; span.add_ops([Swap, Drop]) } /// Translates u32divmod assembly instructions to VM operations. /// /// VM cycles per mode: -/// - u32checked_divmod: 2 cycles -/// - u32checked_divmod.b: -/// - 4 cycles if b is 1 -/// - 3 cycles if b is not 1 -/// - u32unchecked_divmod: 1 cycle -/// - u32unchecked_divmod.b: +/// - u32divmod: 1 cycle +/// - u32divmod.b: /// - 3 cycles if b is 1 /// - 2 cycles if b is not 1 pub fn u32divmod( span: &mut SpanBuilder, - op_mode: U32OpMode, imm: Option, ) -> Result, AssemblyError> { - handle_division(span, op_mode, imm) + handle_division(span, imm) } // BITWISE OPERATIONS // ================================================================================================ -/// Translates u32checked_not assembly instruction to VM operations. +/// Translates u32not assembly instruction to VM operations. /// /// The reason this method works is because 2^32 -1 provides a bit mask of ones, which after /// subtracting the element, flips the bits of the original value to perform a bitwise NOT. @@ -223,135 +194,91 @@ pub fn u32not(span: &mut SpanBuilder) -> Result, AssemblyError /// Translates u32shl assembly instructions to VM operations. /// /// The operation is implemented by putting a power of 2 on the stack, then multiplying it with -/// the value to be shifted and splitting the result. For checked variants, the shift value is -/// asserted to be between 0-31 and the value to be shifted is asserted to be a 32-bit value. +/// the value to be shifted and splitting the result. /// /// VM cycles per mode: -/// - u32checked_shl: 19 cycles -/// - u32checked_shl.b: 4 cycles -/// - u32unchecked_shl: 18 cycles -/// - u32unchecked_shl.b: 3 cycles -pub fn u32shl( - span: &mut SpanBuilder, - op_mode: U32OpMode, - imm: Option, -) -> Result, AssemblyError> { - prepare_bitwise::(span, imm, op_mode, [U32mul, Drop]) +/// - u32shl: 18 cycles +/// - u32shl.b: 3 cycles +pub fn u32shl(span: &mut SpanBuilder, imm: Option) -> Result, AssemblyError> { + prepare_bitwise::(span, imm)?; + if imm != Some(0) { + span.add_ops([U32mul, Drop]) + } else { + Ok(None) + } } /// Translates u32shr assembly instructions to VM operations. /// /// The operation is implemented by putting a power of 2 on the stack, then dividing the value to -/// be shifted by it and returning the quotient. For checked variants, the shift value is asserted -/// to be between 0-31 and the value to be shifted is asserted to be a 32-bit value. +/// be shifted by it and returning the quotient. /// /// VM cycles per mode: -/// - u32checked_shr: 19 cycles -/// - u32checked_shr.b: 4 cycles -/// - u32unchecked_shr: 18 cycles -/// - u32unchecked_shr.b: 3 cycles -pub fn u32shr( - span: &mut SpanBuilder, - op_mode: U32OpMode, - imm: Option, -) -> Result, AssemblyError> { - prepare_bitwise::(span, imm, op_mode, [U32div, Drop]) +/// - u32shr: 18 cycles +/// - u32shr.b: 3 cycles +pub fn u32shr(span: &mut SpanBuilder, imm: Option) -> Result, AssemblyError> { + prepare_bitwise::(span, imm)?; + if imm != Some(0) { + span.add_ops([U32div, Drop]) + } else { + Ok(None) + } } /// Translates u32rotl assembly instructions to VM operations. /// /// The base operation is implemented by putting a power of 2 on the stack, then multiplying the -/// value to be shifted by it and adding the overflow limb to the shifted limb. For the checked -/// variants, the shift value is asserted to be between 0-31 and the value to be shifted is -/// asserted to be a 32-bit value. +/// value to be shifted by it and adding the overflow limb to the shifted limb. /// /// VM cycles per mode: -/// - u32checked_rotl: 19 cycles -/// - u32checked_rotl.b: 4 cycles -/// - u32unchecked_rotl: 18 cycles -/// - u32unchecked_rotl.b: 3 cycles +/// - u32rotl: 18 cycles +/// - u32rotl.b: 3 cycles pub fn u32rotl( span: &mut SpanBuilder, - op_mode: U32OpMode, imm: Option, ) -> Result, AssemblyError> { - prepare_bitwise::(span, imm, op_mode, [U32mul, Add]) + prepare_bitwise::(span, imm)?; + if imm != Some(0) { + span.add_ops([U32mul, Add]) + } else { + Ok(None) + } } /// Translates u32rotr assembly instructions to VM operations. /// /// The base operation is implemented by multiplying the value to be shifted by 2^(32-b), where -/// b is the shift amount, then adding the overflow limb to the shifted limb. For the checked -/// variants, the shift value is asserted to be between 0-31 and the value to be shifted is -/// asserted to be a 32-bit value. +/// b is the shift amount, then adding the overflow limb to the shifted limb. /// /// VM cycles per mode: -/// - u32checked_rotr: 31 cycles -/// - u32checked_rotr.b: 6 cycles -/// - u32unchecked_rotr: 22 cycles -/// - u32unchecked_rotr.b: 3 cycles +/// - u32rotr: 22 cycles +/// - u32rotr.b: 3 cycles pub fn u32rotr( span: &mut SpanBuilder, - op_mode: U32OpMode, imm: Option, ) -> Result, AssemblyError> { - match (imm, op_mode) { - (Some(0), U32OpMode::Checked) => { - // if rotation is performed by 0, just verify that stack top is u32 - span.push_ops([Pad, U32assert2(ZERO), Drop]); - return Ok(None); - } - (Some(imm), U32OpMode::Checked) => { - validate_param(imm, 1..=MAX_U32_ROTATE_VALUE)?; - span.push_ops([Push(Felt::new(1 << (32 - imm))), U32assert2(ZERO)]); - } - (Some(0), U32OpMode::Unchecked) => { + match imm { + Some(0) => { // if rotation is performed by 0, do nothing (Noop) span.push_op(Noop); return Ok(None); } - (Some(imm), U32OpMode::Unchecked) => { + Some(imm) => { validate_param(imm, 1..=MAX_U32_ROTATE_VALUE)?; span.push_op(Push(Felt::new(1 << (32 - imm)))); } - (None, U32OpMode::Checked) => { - #[rustfmt::skip] - span.push_ops([ - // Verify both b and a are u32. - U32assert2(ZERO), - - // Calculate 32 - b and assert that the shift value b <= 31. - Push(Felt::from(MAX_U32_ROTATE_VALUE)), Dup1, U32sub, Not, Assert(ZERO), Incr, Dup1, - - // If 32-b = 32, replace it with 0. - Eqz, Not, CSwap, Drop, - ]); - append_pow2_op(span); - span.push_op(Swap); - } - (None, U32OpMode::Unchecked) => { + None => { span.push_ops([Push(Felt::new(32)), Swap, U32sub, Drop]); append_pow2_op(span); } - _ => unreachable!("unsupported operation mode"), } span.add_ops([U32mul, Add]) } /// Translates u32popcnt assembly instructions to VM operations. /// -/// VM cycles per mode: -/// - u32checked_popcnt: 36 cycles -/// - u32unchecked_popcnt: 33 cycles -pub fn u32popcnt( - span: &mut SpanBuilder, - op_mode: U32OpMode, -) -> Result, AssemblyError> { - match op_mode { - U32OpMode::Checked => span.push_ops([Pad, U32assert2(ZERO), Drop]), - U32OpMode::Unchecked => (), - _ => unreachable!("unsupported operation mode"), - } +/// This operation takes 33 cycles. +pub fn u32popcnt(span: &mut SpanBuilder) -> Result, AssemblyError> { #[rustfmt::skip] let ops = [ // i = i - ((i >> 1) & 0x55555555); @@ -383,11 +310,10 @@ pub fn u32popcnt( span.add_ops(ops) } -/// Handles U32ADD, U32SUB, and U32MUL operations in checked, wrapping, and overflowing modes, -/// including handling of immediate parameters. +/// Handles U32ADD, U32SUB, and U32MUL operations in wrapping, and overflowing modes, including +/// handling of immediate parameters. /// /// Specifically handles these specific inputs per the spec. -/// - Checked: fails if either of the inputs or the output is not a u32 value. /// - Wrapping: does not check if the inputs are u32 values; overflow or underflow bits are /// discarded. /// - Overflowing: does not check if the inputs are u32 values; overflow or underflow bits are @@ -398,41 +324,24 @@ fn handle_arithmetic_operation( op_mode: U32OpMode, imm: Option, ) -> Result, AssemblyError> { - let mut drop_high_bits = false; - let mut assert_u32_res = false; - if let Some(imm) = imm { push_u32_value(span, imm); } - match op_mode { - U32OpMode::Checked => { - span.push_op(U32assert2(ZERO)); - assert_u32_res = true; - } - U32OpMode::Wrapping => { - drop_high_bits = true; - } - U32OpMode::Overflowing => {} - _ => unreachable!("unsupported operation mode"), - } - span.push_op(op); - if assert_u32_res { - span.add_ops([Eqz, Assert(ZERO)]) - } else if drop_high_bits { + // in the wrapping mode, drop high 32 bits + if matches!(op_mode, U32OpMode::Wrapping) { span.add_op(Drop) } else { Ok(None) } } -/// Handles common parts of u32div, u32mod, and u32divmod operations in checked and unchecked modes, -/// including handling of immediate parameters. +/// Handles common parts of u32div, u32mod, and u32divmod operations, including handling of +/// immediate parameters. fn handle_division( span: &mut SpanBuilder, - op_mode: U32OpMode, imm: Option, ) -> Result, AssemblyError> { if let Some(imm) = imm { @@ -442,14 +351,6 @@ fn handle_division( push_u32_value(span, imm); } - match op_mode { - U32OpMode::Checked => { - span.push_op(U32assert2(ZERO)); - } - U32OpMode::Unchecked => {} - _ => unreachable!("unsupported operation mode"), - } - span.add_op(U32div) } @@ -458,99 +359,33 @@ fn handle_division( /// Mutate the first two elements of the stack from `[b, a, ..]` into `[2^b, a, ..]`, with `b` /// either as a provided immediate value, or as an element that already exists in the stack. -/// -/// If the used mode is `checked`, the function will assert that both `[b, a]` are valid `u32`. -/// This function is equivalent to a bit shift operation, so the exponent shouldn't cause a number -/// to be greater than `u32::MAX`; therefore, the maximum valid value must be `31`, as defined in -/// the helper constants. -/// -/// This function supports only checked and unchecked modes; if some other mode is provided, it -/// will panic. fn prepare_bitwise( span: &mut SpanBuilder, imm: Option, - op_mode: U32OpMode, - final_ops: [Operation; 2], -) -> Result, AssemblyError> { - match (imm, op_mode) { - (Some(0), U32OpMode::Checked) => { - // if shift/rotation is performed by 0, just verify that stack top is u32 - span.push_ops([Pad, U32assert2(ZERO), Drop]); - return Ok(None); - } - (Some(imm), U32OpMode::Checked) => { - validate_param(imm, 1..=MAX_VALUE)?; - span.push_ops([Push(Felt::new(1 << imm)), U32assert2(ZERO)]); - } - (Some(0), U32OpMode::Unchecked) => { +) -> Result<(), AssemblyError> { + match imm { + Some(0) => { // if shift/rotation is performed by 0, do nothing (Noop) span.push_op(Noop); - return Ok(None); } - (Some(imm), U32OpMode::Unchecked) => { + Some(imm) => { + validate_param(imm, 1..=MAX_U32_ROTATE_VALUE)?; span.push_op(Push(Felt::new(1 << imm))); } - (None, U32OpMode::Checked) => { - // Assume the dynamic shift value b is on top of the stack. + None => { append_pow2_op(span); - span.push_op(U32assert2(ZERO)); } - (None, U32OpMode::Unchecked) => append_pow2_op(span), - _ => unreachable!("unsupported operation mode"), } - span.add_ops(final_ops) + Ok(()) } // COMPARISON OPERATIONS // ================================================================================================ -/// Translates u32checked_eq assembly instruction to VM operations. -/// -/// Specifically we test the first two numbers to be u32, then perform a EQ to check the equality. -/// -/// VM cycles per mode: -/// - u32checked_eq: 2 cycles -/// - u32checked_eq.b: 3 cycles -pub fn u32eq(span: &mut SpanBuilder, imm: Option) -> Result, AssemblyError> { - if let Some(imm) = imm { - push_u32_value(span, imm); - } - - span.add_ops([U32assert2(ZERO), Eq]) -} - -/// Translates u32checked_neq assembly instruction to VM operations. -/// -/// Specifically we test the first two numbers to be u32, then perform a `EQ NOT` to check the -/// equality. -/// -/// VM cycles per mode: -/// - u32checked_neq: 3 cycles -/// - u32checked_neq.b: 4 cycles -pub fn u32neq( - span: &mut SpanBuilder, - imm: Option, -) -> Result, AssemblyError> { - if let Some(imm) = imm { - push_u32_value(span, imm); - } - - span.add_ops([U32assert2(ZERO), Eq, Not]) -} - /// Translates u32lt assembly instructions to VM operations. /// -/// Specifically we test the first two numbers to be u32, then perform a `U32SUB EQZ NOT` to check -/// the underflow flag. -/// -/// VM cycles per mode: -/// - u32checked_lt: 6 cycles -/// - u32unchecked_lt 5 cycles -pub fn u32lt( - span: &mut SpanBuilder, - op_mode: U32OpMode, -) -> Result, AssemblyError> { - handle_u32_and_unchecked_mode(span, op_mode); +/// This operation takes 5 cycles. +pub fn u32lt(span: &mut SpanBuilder) -> Result, AssemblyError> { compute_lt(span); Ok(None) @@ -558,18 +393,8 @@ pub fn u32lt( /// Translates u32lte assembly instructions to VM operations. /// -/// Specifically we test the first two numbers to be u32, then perform a gt check and flip the -/// results. -/// -/// VM cycles per mode: -/// - u32checked_lte: 8 cycles -/// - u32unchecked_lte: 7 cycles -pub fn u32lte( - span: &mut SpanBuilder, - op_mode: U32OpMode, -) -> Result, AssemblyError> { - handle_u32_and_unchecked_mode(span, op_mode); - +/// This operation takes 7 cycles. +pub fn u32lte(span: &mut SpanBuilder) -> Result, AssemblyError> { // Compute the lt with reversed number to get a gt check span.push_op(Swap); compute_lt(span); @@ -580,18 +405,8 @@ pub fn u32lte( /// Translates u32gt assembly instructions to VM operations. /// -/// Specifically we test the first two numbers to be u32, then perform a lt check with the -/// numbers swapped. -/// -/// VM cycles per mode: -/// - u32checked_gt: 7 cycles -/// - u32unchecked_gt: 6 cycles -pub fn u32gt( - span: &mut SpanBuilder, - op_mode: U32OpMode, -) -> Result, AssemblyError> { - handle_u32_and_unchecked_mode(span, op_mode); - +/// This operation takes 6 cycles. +pub fn u32gt(span: &mut SpanBuilder) -> Result, AssemblyError> { // Reverse the numbers so we can get a gt check. span.push_op(Swap); @@ -602,18 +417,8 @@ pub fn u32gt( /// Translates u32gte assembly instructions to VM operations. /// -/// Specifically we test the first two numbers to be u32, then compute a lt check and flip the -/// results. -/// -/// VM cycles per mode: -/// - u32checked_gte: 7 cycles -/// - u32unchecked_gte: 6 cycles -pub fn u32gte( - span: &mut SpanBuilder, - op_mode: U32OpMode, -) -> Result, AssemblyError> { - handle_u32_and_unchecked_mode(span, op_mode); - +/// This operation takes 6 cycles. +pub fn u32gte(span: &mut SpanBuilder) -> Result, AssemblyError> { compute_lt(span); // Flip the final results to get the gte results. @@ -622,19 +427,13 @@ pub fn u32gte( /// Translates u32min assembly instructions to VM operations. /// -/// Specifically, we test the first two numbers to be u32 (U32SPLIT NOT ASSERT), subtract the top -/// value from the second to the top value (U32SUB), check the underflow flag (EQZ), and perform a -/// conditional swap (CSWAP) to have the max number in front. Then we finally drop the top element -/// to keep the min. +/// Specifically, we subtract the top value from the second to the top value (U32SUB), check the +/// underflow flag (EQZ), and perform a conditional swap (CSWAP) to have the max number in front. +/// Then we finally drop the top element to keep the min. /// -/// VM cycles per mode: -/// - u32checked_min: 9 cycles -/// - u32unchecked_min: 8 cycles -pub fn u32min( - span: &mut SpanBuilder, - op_mode: U32OpMode, -) -> Result, AssemblyError> { - compute_max_and_min(span, op_mode); +/// This operation takes 8 cycles. +pub fn u32min(span: &mut SpanBuilder) -> Result, AssemblyError> { + compute_max_and_min(span); // Drop the max and keep the min span.add_op(Drop) @@ -642,19 +441,13 @@ pub fn u32min( /// Translates u32max assembly instructions to VM operations. /// -/// Specifically, we test the first two values to be u32 (U32SPLIT NOT ASSERT), subtract the top -/// value from the second to the top value (U32SUB), check the underflow flag (EQZ), and perform -/// a conditional swap (CSWAP) to have the max number in front. then we finally drop the 2nd -/// element to keep the max. +/// Specifically, we subtract the top value from the second to the top value (U32SUB), check the +/// underflow flag (EQZ), and perform a conditional swap (CSWAP) to have the max number in front. +/// Then we finally drop the 2nd element to keep the max. /// -/// VM cycles per mode: -/// - u32checked_max: 10 cycles -/// - u32unchecked_max: 9 cycles -pub fn u32max( - span: &mut SpanBuilder, - op_mode: U32OpMode, -) -> Result, AssemblyError> { - compute_max_and_min(span, op_mode); +/// This operation takes 9 cycles. +pub fn u32max(span: &mut SpanBuilder) -> Result, AssemblyError> { + compute_max_and_min(span); // Drop the min and keep the max span.add_ops([Swap, Drop]) @@ -663,13 +456,6 @@ pub fn u32max( // COMPARISON OPERATIONS - HELPERS // ================================================================================================ -/// Handles u32 assertion and unchecked mode for any u32 operation. -fn handle_u32_and_unchecked_mode(span: &mut SpanBuilder, op_mode: U32OpMode) { - if op_mode == U32OpMode::Checked { - span.push_op(U32assert2(ZERO)); - } -} - /// Inserts the VM operations to check if the second element is less than /// the top element. This takes 5 cycles. fn compute_lt(span: &mut SpanBuilder) { @@ -679,16 +465,12 @@ fn compute_lt(span: &mut SpanBuilder) { ]) } -/// Duplicate the top two elements in the stack and check both are u32, and determine the min -/// and max between them. +/// Duplicate the top two elements in the stack and determine the min and max between them. /// /// The maximum number will be at the top of the stack and minimum will be at the 2nd index. -fn compute_max_and_min(span: &mut SpanBuilder, op_mode: U32OpMode) { +fn compute_max_and_min(span: &mut SpanBuilder) { // Copy top two elements of the stack. span.push_ops([Dup1, Dup1]); - if op_mode == U32OpMode::Checked { - span.push_op(U32assert2(ZERO)); - } #[rustfmt::skip] span.push_ops([ diff --git a/assembly/src/ast/nodes/mod.rs b/assembly/src/ast/nodes/mod.rs index dc10fa25ba..a772ba03a5 100644 --- a/assembly/src/ast/nodes/mod.rs +++ b/assembly/src/ast/nodes/mod.rs @@ -98,78 +98,47 @@ pub enum Instruction { U32AssertWWithError(ErrorCode), U32Split, U32Cast, - U32CheckedAdd, - U32CheckedAddImm(u32), U32WrappingAdd, U32WrappingAddImm(u32), U32OverflowingAdd, U32OverflowingAddImm(u32), U32OverflowingAdd3, U32WrappingAdd3, - U32CheckedSub, - U32CheckedSubImm(u32), U32WrappingSub, U32WrappingSubImm(u32), U32OverflowingSub, U32OverflowingSubImm(u32), - U32CheckedMul, - U32CheckedMulImm(u32), U32WrappingMul, U32WrappingMulImm(u32), U32OverflowingMul, U32OverflowingMulImm(u32), U32OverflowingMadd, U32WrappingMadd, - U32CheckedDiv, - U32CheckedDivImm(u32), - U32UncheckedDiv, - U32UncheckedDivImm(u32), - U32CheckedMod, - U32CheckedModImm(u32), - U32UncheckedMod, - U32UncheckedModImm(u32), - U32CheckedDivMod, - U32CheckedDivModImm(u32), - U32UncheckedDivMod, - U32UncheckedDivModImm(u32), - U32CheckedAnd, - U32CheckedOr, - U32CheckedXor, - U32CheckedNot, - U32CheckedShr, - U32CheckedShrImm(u8), - U32UncheckedShr, - U32UncheckedShrImm(u8), - U32CheckedShl, - U32CheckedShlImm(u8), - U32UncheckedShl, - U32UncheckedShlImm(u8), - U32CheckedRotr, - U32CheckedRotrImm(u8), - U32UncheckedRotr, - U32UncheckedRotrImm(u8), - U32CheckedRotl, - U32CheckedRotlImm(u8), - U32UncheckedRotl, - U32UncheckedRotlImm(u8), - U32CheckedPopcnt, - U32UncheckedPopcnt, - U32CheckedEq, - U32CheckedEqImm(u32), - U32CheckedNeq, - U32CheckedNeqImm(u32), - U32CheckedLt, - U32UncheckedLt, - U32CheckedLte, - U32UncheckedLte, - U32CheckedGt, - U32UncheckedGt, - U32CheckedGte, - U32UncheckedGte, - U32CheckedMin, - U32UncheckedMin, - U32CheckedMax, - U32UncheckedMax, + U32Div, + U32DivImm(u32), + U32Mod, + U32ModImm(u32), + U32DivMod, + U32DivModImm(u32), + U32And, + U32Or, + U32Xor, + U32Not, + U32Shr, + U32ShrImm(u8), + U32Shl, + U32ShlImm(u8), + U32Rotr, + U32RotrImm(u8), + U32Rotl, + U32RotlImm(u8), + U32Popcnt, + U32Lt, + U32Lte, + U32Gt, + U32Gte, + U32Min, + U32Max, // ----- stack manipulation ------------------------------------------------------------------- Drop, @@ -387,78 +356,47 @@ impl fmt::Display for Instruction { Self::U32AssertWWithError(err_code) => write!(f, "u32assertw.err={err_code}"), Self::U32Split => write!(f, "u32split"), Self::U32Cast => write!(f, "u32cast"), - Self::U32CheckedAdd => write!(f, "u32checked_add"), - Self::U32CheckedAddImm(value) => write!(f, "u32checked_add.{value}"), Self::U32WrappingAdd => write!(f, "u32wrapping_add"), Self::U32WrappingAddImm(value) => write!(f, "u32wrapping_add.{value}"), Self::U32OverflowingAdd => write!(f, "u32overflowing_add"), Self::U32OverflowingAddImm(value) => write!(f, "u32overflowing_add.{value}"), Self::U32OverflowingAdd3 => write!(f, "u32overflowing_add3"), Self::U32WrappingAdd3 => write!(f, "u32wrapping_add3"), - Self::U32CheckedSub => write!(f, "u32checked_sub"), - Self::U32CheckedSubImm(value) => write!(f, "u32checked_sub.{value}"), Self::U32WrappingSub => write!(f, "u32wrapping_sub"), Self::U32WrappingSubImm(value) => write!(f, "u32wrapping_sub.{value}"), Self::U32OverflowingSub => write!(f, "u32overflowing_sub"), Self::U32OverflowingSubImm(value) => write!(f, "u32overflowing_sub.{value}"), - Self::U32CheckedMul => write!(f, "u32checked_mul"), - Self::U32CheckedMulImm(value) => write!(f, "u32checked_mul.{value}"), Self::U32WrappingMul => write!(f, "u32wrapping_mul"), Self::U32WrappingMulImm(value) => write!(f, "u32wrapping_mul.{value}"), Self::U32OverflowingMul => write!(f, "u32overflowing_mul"), Self::U32OverflowingMulImm(value) => write!(f, "u32overflowing_mul.{value}"), Self::U32OverflowingMadd => write!(f, "u32overflowing_madd"), Self::U32WrappingMadd => write!(f, "u32wrapping_madd"), - Self::U32CheckedDiv => write!(f, "u32checked_div"), - Self::U32CheckedDivImm(value) => write!(f, "u32checked_div.{value}"), - Self::U32UncheckedDiv => write!(f, "u32unchecked_div"), - Self::U32UncheckedDivImm(value) => write!(f, "u32unchecked_div.{value}"), - Self::U32CheckedMod => write!(f, "u32checked_mod"), - Self::U32CheckedModImm(value) => write!(f, "u32checked_mod.{value}"), - Self::U32UncheckedMod => write!(f, "u32unchecked_mod"), - Self::U32UncheckedModImm(value) => write!(f, "u32unchecked_mod.{value}"), - Self::U32CheckedDivMod => write!(f, "u32checked_divmod"), - Self::U32CheckedDivModImm(value) => write!(f, "u32checked_divmod.{value}"), - Self::U32UncheckedDivMod => write!(f, "u32unchecked_divmod"), - Self::U32UncheckedDivModImm(value) => write!(f, "u32unchecked_divmod.{value}"), - Self::U32CheckedAnd => write!(f, "u32checked_and"), - Self::U32CheckedOr => write!(f, "u32checked_or"), - Self::U32CheckedXor => write!(f, "u32checked_xor"), - Self::U32CheckedNot => write!(f, "u32checked_not"), - Self::U32CheckedShr => write!(f, "u32checked_shr"), - Self::U32CheckedShrImm(value) => write!(f, "u32checked_shr.{value}"), - Self::U32UncheckedShr => write!(f, "u32unchecked_shr"), - Self::U32UncheckedShrImm(value) => write!(f, "u32unchecked_shr.{value}"), - Self::U32CheckedShl => write!(f, "u32checked_shl"), - Self::U32CheckedShlImm(value) => write!(f, "u32checked_shl.{value}"), - Self::U32UncheckedShl => write!(f, "u32unchecked_shl"), - Self::U32UncheckedShlImm(value) => write!(f, "u32unchecked_shl.{value}"), - Self::U32CheckedRotr => write!(f, "u32checked_rotr"), - Self::U32CheckedRotrImm(value) => write!(f, "u32checked_rotr.{value}"), - Self::U32UncheckedRotr => write!(f, "u32unchecked_rotr"), - Self::U32UncheckedRotrImm(value) => write!(f, "u32unchecked_rotr.{value}"), - Self::U32CheckedRotl => write!(f, "u32checked_rotl"), - Self::U32CheckedRotlImm(value) => write!(f, "u32checked_rotl.{value}"), - Self::U32UncheckedRotl => write!(f, "u32unchecked_rotl"), - Self::U32UncheckedRotlImm(value) => write!(f, "u32unchecked_rotl.{value}"), - Self::U32CheckedPopcnt => write!(f, "u32checked_popcnt"), - Self::U32UncheckedPopcnt => write!(f, "u32unchecked_popcnt"), - Self::U32CheckedEq => write!(f, "u32checked_eq"), - Self::U32CheckedEqImm(value) => write!(f, "u32checked_eq.{value}"), - Self::U32CheckedNeq => write!(f, "u32checked_neq"), - Self::U32CheckedNeqImm(value) => write!(f, "u32checked_neq.{value}"), - Self::U32CheckedLt => write!(f, "u32checked_lt"), - Self::U32UncheckedLt => write!(f, "u32unchecked_lt"), - Self::U32CheckedLte => write!(f, "u32checked_lte"), - Self::U32UncheckedLte => write!(f, "u32unchecked_lte"), - Self::U32CheckedGt => write!(f, "u32checked_gt"), - Self::U32UncheckedGt => write!(f, "u32unchecked_gt"), - Self::U32CheckedGte => write!(f, "u32checked_gte"), - Self::U32UncheckedGte => write!(f, "u32unchecked_gte"), - Self::U32CheckedMin => write!(f, "u32checked_min"), - Self::U32UncheckedMin => write!(f, "u32unchecked_min"), - Self::U32CheckedMax => write!(f, "u32checked_max"), - Self::U32UncheckedMax => write!(f, "u32unchecked_max"), + Self::U32Div => write!(f, "u32div"), + Self::U32DivImm(value) => write!(f, "u32div.{value}"), + Self::U32Mod => write!(f, "u32mod"), + Self::U32ModImm(value) => write!(f, "u32mod.{value}"), + Self::U32DivMod => write!(f, "u32divmod"), + Self::U32DivModImm(value) => write!(f, "u32divmod.{value}"), + Self::U32And => write!(f, "u32and"), + Self::U32Or => write!(f, "u32or"), + Self::U32Xor => write!(f, "u32xor"), + Self::U32Not => write!(f, "u32not"), + Self::U32Shr => write!(f, "u32shr"), + Self::U32ShrImm(value) => write!(f, "u32shr.{value}"), + Self::U32Shl => write!(f, "u32shl"), + Self::U32ShlImm(value) => write!(f, "u32shl.{value}"), + Self::U32Rotr => write!(f, "u32rotr"), + Self::U32RotrImm(value) => write!(f, "u32rotr.{value}"), + Self::U32Rotl => write!(f, "u32rotl"), + Self::U32RotlImm(value) => write!(f, "u32rotl.{value}"), + Self::U32Popcnt => write!(f, "u32popcnt"), + Self::U32Lt => write!(f, "u32lt"), + Self::U32Lte => write!(f, "u32lte"), + Self::U32Gt => write!(f, "u32gt"), + Self::U32Gte => write!(f, "u32gte"), + Self::U32Min => write!(f, "u32min"), + Self::U32Max => write!(f, "u32max"), // ----- stack manipulation --------------------------------------------------------------- Self::Drop => write!(f, "drop"), diff --git a/assembly/src/ast/nodes/serde/deserialization.rs b/assembly/src/ast/nodes/serde/deserialization.rs index 8632af6721..1195e4c299 100644 --- a/assembly/src/ast/nodes/serde/deserialization.rs +++ b/assembly/src/ast/nodes/serde/deserialization.rs @@ -115,8 +115,6 @@ impl Deserializable for Instruction { OpCode::U32AssertWWithError => Ok(Instruction::U32AssertWWithError(source.read_u32()?)), OpCode::U32Split => Ok(Instruction::U32Split), OpCode::U32Cast => Ok(Instruction::U32Cast), - OpCode::U32CheckedAdd => Ok(Instruction::U32CheckedAdd), - OpCode::U32CheckedAddImm => Ok(Instruction::U32CheckedAddImm(source.read_u32()?)), OpCode::U32WrappingAdd => Ok(Instruction::U32WrappingAdd), OpCode::U32WrappingAddImm => Ok(Instruction::U32WrappingAddImm(source.read_u32()?)), OpCode::U32OverflowingAdd => Ok(Instruction::U32OverflowingAdd), @@ -125,16 +123,12 @@ impl Deserializable for Instruction { } OpCode::U32OverflowingAdd3 => Ok(Instruction::U32OverflowingAdd3), OpCode::U32WrappingAdd3 => Ok(Instruction::U32WrappingAdd3), - OpCode::U32CheckedSub => Ok(Instruction::U32CheckedSub), - OpCode::U32CheckedSubImm => Ok(Instruction::U32CheckedSubImm(source.read_u32()?)), OpCode::U32WrappingSub => Ok(Instruction::U32WrappingSub), OpCode::U32WrappingSubImm => Ok(Instruction::U32WrappingSubImm(source.read_u32()?)), OpCode::U32OverflowingSub => Ok(Instruction::U32OverflowingSub), OpCode::U32OverflowingSubImm => { Ok(Instruction::U32OverflowingSubImm(source.read_u32()?)) } - OpCode::U32CheckedMul => Ok(Instruction::U32CheckedMul), - OpCode::U32CheckedMulImm => Ok(Instruction::U32CheckedMulImm(source.read_u32()?)), OpCode::U32WrappingMul => Ok(Instruction::U32WrappingMul), OpCode::U32WrappingMulImm => Ok(Instruction::U32WrappingMulImm(source.read_u32()?)), OpCode::U32OverflowingMul => Ok(Instruction::U32OverflowingMul), @@ -143,58 +137,31 @@ impl Deserializable for Instruction { } OpCode::U32OverflowingMadd => Ok(Instruction::U32OverflowingMadd), OpCode::U32WrappingMadd => Ok(Instruction::U32WrappingMadd), - OpCode::U32CheckedDiv => Ok(Instruction::U32CheckedDiv), - OpCode::U32CheckedDivImm => Ok(Instruction::U32CheckedDivImm(source.read_u32()?)), - OpCode::U32UncheckedDiv => Ok(Instruction::U32UncheckedDiv), - OpCode::U32UncheckedDivImm => Ok(Instruction::U32UncheckedDivImm(source.read_u32()?)), - OpCode::U32CheckedMod => Ok(Instruction::U32CheckedMod), - OpCode::U32CheckedModImm => Ok(Instruction::U32CheckedModImm(source.read_u32()?)), - OpCode::U32UncheckedMod => Ok(Instruction::U32UncheckedMod), - OpCode::U32UncheckedModImm => Ok(Instruction::U32UncheckedModImm(source.read_u32()?)), - OpCode::U32CheckedDivMod => Ok(Instruction::U32CheckedDivMod), - OpCode::U32CheckedDivModImm => Ok(Instruction::U32CheckedDivModImm(source.read_u32()?)), - OpCode::U32UncheckedDivMod => Ok(Instruction::U32UncheckedDivMod), - OpCode::U32UncheckedDivModImm => { - Ok(Instruction::U32UncheckedDivModImm(source.read_u32()?)) - } - OpCode::U32CheckedAnd => Ok(Instruction::U32CheckedAnd), - OpCode::U32CheckedOr => Ok(Instruction::U32CheckedOr), - OpCode::U32CheckedXor => Ok(Instruction::U32CheckedXor), - OpCode::U32CheckedNot => Ok(Instruction::U32CheckedNot), - OpCode::U32CheckedShr => Ok(Instruction::U32CheckedShr), - OpCode::U32CheckedShrImm => Ok(Instruction::U32CheckedShrImm(source.read_u8()?)), - OpCode::U32UncheckedShr => Ok(Instruction::U32UncheckedShr), - OpCode::U32UncheckedShrImm => Ok(Instruction::U32UncheckedShrImm(source.read_u8()?)), - OpCode::U32CheckedShl => Ok(Instruction::U32CheckedShl), - OpCode::U32CheckedShlImm => Ok(Instruction::U32CheckedShlImm(source.read_u8()?)), - OpCode::U32UncheckedShl => Ok(Instruction::U32UncheckedShl), - OpCode::U32UncheckedShlImm => Ok(Instruction::U32UncheckedShlImm(source.read_u8()?)), - OpCode::U32CheckedRotr => Ok(Instruction::U32CheckedRotr), - OpCode::U32CheckedRotrImm => Ok(Instruction::U32CheckedRotrImm(source.read_u8()?)), - OpCode::U32UncheckedRotr => Ok(Instruction::U32UncheckedRotr), - OpCode::U32UncheckedRotrImm => Ok(Instruction::U32UncheckedRotrImm(source.read_u8()?)), - OpCode::U32CheckedRotl => Ok(Instruction::U32CheckedRotl), - OpCode::U32CheckedRotlImm => Ok(Instruction::U32CheckedRotlImm(source.read_u8()?)), - OpCode::U32UncheckedRotl => Ok(Instruction::U32UncheckedRotl), - OpCode::U32UncheckedRotlImm => Ok(Instruction::U32UncheckedRotlImm(source.read_u8()?)), - OpCode::U32CheckedPopcnt => Ok(Instruction::U32CheckedPopcnt), - OpCode::U32UncheckedPopcnt => Ok(Instruction::U32UncheckedPopcnt), - OpCode::U32CheckedEq => Ok(Instruction::U32CheckedEq), - OpCode::U32CheckedEqImm => Ok(Instruction::U32CheckedEqImm(source.read_u32()?)), - OpCode::U32CheckedNeq => Ok(Instruction::U32CheckedNeq), - OpCode::U32CheckedNeqImm => Ok(Instruction::U32CheckedNeqImm(source.read_u32()?)), - OpCode::U32CheckedLt => Ok(Instruction::U32CheckedLt), - OpCode::U32UncheckedLt => Ok(Instruction::U32UncheckedLt), - OpCode::U32CheckedLte => Ok(Instruction::U32CheckedLte), - OpCode::U32UncheckedLte => Ok(Instruction::U32UncheckedLte), - OpCode::U32CheckedGt => Ok(Instruction::U32CheckedGt), - OpCode::U32UncheckedGt => Ok(Instruction::U32UncheckedGt), - OpCode::U32CheckedGte => Ok(Instruction::U32CheckedGte), - OpCode::U32UncheckedGte => Ok(Instruction::U32UncheckedGte), - OpCode::U32CheckedMin => Ok(Instruction::U32CheckedMin), - OpCode::U32UncheckedMin => Ok(Instruction::U32UncheckedMin), - OpCode::U32CheckedMax => Ok(Instruction::U32CheckedMax), - OpCode::U32UncheckedMax => Ok(Instruction::U32UncheckedMax), + OpCode::U32Div => Ok(Instruction::U32Div), + OpCode::U32DivImm => Ok(Instruction::U32DivImm(source.read_u32()?)), + OpCode::U32Mod => Ok(Instruction::U32Mod), + OpCode::U32ModImm => Ok(Instruction::U32ModImm(source.read_u32()?)), + OpCode::U32DivMod => Ok(Instruction::U32DivMod), + OpCode::U32DivModImm => Ok(Instruction::U32DivModImm(source.read_u32()?)), + OpCode::U32And => Ok(Instruction::U32And), + OpCode::U32Or => Ok(Instruction::U32Or), + OpCode::U32Xor => Ok(Instruction::U32Xor), + OpCode::U32Not => Ok(Instruction::U32Not), + OpCode::U32Shr => Ok(Instruction::U32Shr), + OpCode::U32ShrImm => Ok(Instruction::U32ShrImm(source.read_u8()?)), + OpCode::U32Shl => Ok(Instruction::U32Shl), + OpCode::U32ShlImm => Ok(Instruction::U32ShlImm(source.read_u8()?)), + OpCode::U32Rotr => Ok(Instruction::U32Rotr), + OpCode::U32RotrImm => Ok(Instruction::U32RotrImm(source.read_u8()?)), + OpCode::U32Rotl => Ok(Instruction::U32Rotl), + OpCode::U32RotlImm => Ok(Instruction::U32RotlImm(source.read_u8()?)), + OpCode::U32Popcnt => Ok(Instruction::U32Popcnt), + OpCode::U32Lt => Ok(Instruction::U32Lt), + OpCode::U32Lte => Ok(Instruction::U32Lte), + OpCode::U32Gt => Ok(Instruction::U32Gt), + OpCode::U32Gte => Ok(Instruction::U32Gte), + OpCode::U32Min => Ok(Instruction::U32Min), + OpCode::U32Max => Ok(Instruction::U32Max), // ----- stack manipulation ----------------------------------------------------------- OpCode::Drop => Ok(Instruction::Drop), diff --git a/assembly/src/ast/nodes/serde/mod.rs b/assembly/src/ast/nodes/serde/mod.rs index 22efc46e6c..dfab410523 100644 --- a/assembly/src/ast/nodes/serde/mod.rs +++ b/assembly/src/ast/nodes/serde/mod.rs @@ -71,225 +71,194 @@ pub enum OpCode { U32AssertWWithError = 50, U32Split = 51, U32Cast = 52, - U32CheckedAdd = 53, - U32CheckedAddImm = 54, - U32WrappingAdd = 55, - U32WrappingAddImm = 56, - U32OverflowingAdd = 57, - U32OverflowingAddImm = 58, - U32OverflowingAdd3 = 59, - U32WrappingAdd3 = 60, - U32CheckedSub = 61, - U32CheckedSubImm = 62, - U32WrappingSub = 63, - U32WrappingSubImm = 64, - U32OverflowingSub = 65, - U32OverflowingSubImm = 66, - U32CheckedMul = 67, - U32CheckedMulImm = 68, - U32WrappingMul = 69, - U32WrappingMulImm = 70, - U32OverflowingMul = 71, - U32OverflowingMulImm = 72, - U32OverflowingMadd = 73, - U32WrappingMadd = 74, - U32CheckedDiv = 75, - U32CheckedDivImm = 76, - U32UncheckedDiv = 77, - U32UncheckedDivImm = 78, - U32CheckedMod = 79, - U32CheckedModImm = 80, - U32UncheckedMod = 81, - U32UncheckedModImm = 82, - U32CheckedDivMod = 83, - U32CheckedDivModImm = 84, - U32UncheckedDivMod = 85, - U32UncheckedDivModImm = 86, - U32CheckedAnd = 87, - U32CheckedOr = 88, - U32CheckedXor = 89, - U32CheckedNot = 90, - U32CheckedShr = 91, - U32CheckedShrImm = 92, - U32UncheckedShr = 93, - U32UncheckedShrImm = 94, - U32CheckedShl = 95, - U32CheckedShlImm = 96, - U32UncheckedShl = 97, - U32UncheckedShlImm = 98, - U32CheckedRotr = 99, - U32CheckedRotrImm = 100, - U32UncheckedRotr = 101, - U32UncheckedRotrImm = 102, - U32CheckedRotl = 103, - U32CheckedRotlImm = 104, - U32UncheckedRotl = 105, - U32UncheckedRotlImm = 106, - U32CheckedPopcnt = 107, - U32UncheckedPopcnt = 108, - U32CheckedEq = 109, - U32CheckedEqImm = 110, - U32CheckedNeq = 111, - U32CheckedNeqImm = 112, - U32CheckedLt = 113, - U32UncheckedLt = 114, - U32CheckedLte = 115, - U32UncheckedLte = 116, - U32CheckedGt = 117, - U32UncheckedGt = 118, - U32CheckedGte = 119, - U32UncheckedGte = 120, - U32CheckedMin = 121, - U32UncheckedMin = 122, - U32CheckedMax = 123, - U32UncheckedMax = 124, + U32WrappingAdd = 53, + U32WrappingAddImm = 54, + U32OverflowingAdd = 55, + U32OverflowingAddImm = 56, + U32OverflowingAdd3 = 57, + U32WrappingAdd3 = 58, + U32WrappingSub = 59, + U32WrappingSubImm = 60, + U32OverflowingSub = 61, + U32OverflowingSubImm = 62, + U32WrappingMul = 63, + U32WrappingMulImm = 64, + U32OverflowingMul = 65, + U32OverflowingMulImm = 66, + U32OverflowingMadd = 67, + U32WrappingMadd = 68, + U32Div = 69, + U32DivImm = 70, + U32Mod = 71, + U32ModImm = 72, + U32DivMod = 73, + U32DivModImm = 74, + U32And = 75, + U32Or = 76, + U32Xor = 77, + U32Not = 78, + U32Shr = 79, + U32ShrImm = 80, + U32Shl = 81, + U32ShlImm = 82, + U32Rotr = 83, + U32RotrImm = 84, + U32Rotl = 85, + U32RotlImm = 86, + U32Popcnt = 87, + U32Lt = 88, + U32Lte = 89, + U32Gt = 90, + U32Gte = 91, + U32Min = 92, + U32Max = 93, // ----- stack manipulation ------------------------------------------------------------------- - Drop = 125, - DropW = 126, - PadW = 127, - Dup0 = 128, - Dup1 = 129, - Dup2 = 130, - Dup3 = 131, - Dup4 = 132, - Dup5 = 133, - Dup6 = 134, - Dup7 = 135, - Dup8 = 136, - Dup9 = 137, - Dup10 = 138, - Dup11 = 139, - Dup12 = 140, - Dup13 = 141, - Dup14 = 142, - Dup15 = 143, - DupW0 = 144, - DupW1 = 145, - DupW2 = 146, - DupW3 = 147, - Swap1 = 148, - Swap2 = 149, - Swap3 = 150, - Swap4 = 151, - Swap5 = 152, - Swap6 = 153, - Swap7 = 154, - Swap8 = 155, - Swap9 = 156, - Swap10 = 157, - Swap11 = 158, - Swap12 = 159, - Swap13 = 160, - Swap14 = 161, - Swap15 = 162, - SwapW1 = 163, - SwapW2 = 164, - SwapW3 = 165, - SwapDW = 166, - MovUp2 = 167, - MovUp3 = 168, - MovUp4 = 169, - MovUp5 = 170, - MovUp6 = 171, - MovUp7 = 172, - MovUp8 = 173, - MovUp9 = 174, - MovUp10 = 175, - MovUp11 = 176, - MovUp12 = 177, - MovUp13 = 178, - MovUp14 = 179, - MovUp15 = 180, - MovUpW2 = 181, - MovUpW3 = 182, - MovDn2 = 183, - MovDn3 = 184, - MovDn4 = 185, - MovDn5 = 186, - MovDn6 = 187, - MovDn7 = 188, - MovDn8 = 189, - MovDn9 = 190, - MovDn10 = 191, - MovDn11 = 192, - MovDn12 = 193, - MovDn13 = 194, - MovDn14 = 195, - MovDn15 = 196, - MovDnW2 = 197, - MovDnW3 = 198, - CSwap = 199, - CSwapW = 200, - CDrop = 201, - CDropW = 202, + Drop = 94, + DropW = 95, + PadW = 96, + Dup0 = 97, + Dup1 = 98, + Dup2 = 99, + Dup3 = 100, + Dup4 = 101, + Dup5 = 102, + Dup6 = 103, + Dup7 = 104, + Dup8 = 105, + Dup9 = 106, + Dup10 = 107, + Dup11 = 108, + Dup12 = 109, + Dup13 = 110, + Dup14 = 111, + Dup15 = 112, + DupW0 = 113, + DupW1 = 114, + DupW2 = 115, + DupW3 = 116, + Swap1 = 117, + Swap2 = 118, + Swap3 = 119, + Swap4 = 120, + Swap5 = 121, + Swap6 = 122, + Swap7 = 123, + Swap8 = 124, + Swap9 = 125, + Swap10 = 126, + Swap11 = 127, + Swap12 = 128, + Swap13 = 129, + Swap14 = 130, + Swap15 = 131, + SwapW1 = 132, + SwapW2 = 133, + SwapW3 = 134, + SwapDW = 135, + MovUp2 = 136, + MovUp3 = 137, + MovUp4 = 138, + MovUp5 = 139, + MovUp6 = 140, + MovUp7 = 141, + MovUp8 = 142, + MovUp9 = 143, + MovUp10 = 144, + MovUp11 = 145, + MovUp12 = 146, + MovUp13 = 147, + MovUp14 = 148, + MovUp15 = 149, + MovUpW2 = 150, + MovUpW3 = 151, + MovDn2 = 152, + MovDn3 = 153, + MovDn4 = 154, + MovDn5 = 155, + MovDn6 = 156, + MovDn7 = 157, + MovDn8 = 158, + MovDn9 = 159, + MovDn10 = 160, + MovDn11 = 161, + MovDn12 = 162, + MovDn13 = 163, + MovDn14 = 164, + MovDn15 = 165, + MovDnW2 = 166, + MovDnW3 = 167, + CSwap = 168, + CSwapW = 169, + CDrop = 170, + CDropW = 171, // ----- input / output operations ------------------------------------------------------------ - PushU8 = 203, - PushU16 = 204, - PushU32 = 205, - PushFelt = 206, - PushWord = 207, - PushU8List = 208, - PushU16List = 209, - PushU32List = 210, - PushFeltList = 211, + PushU8 = 172, + PushU16 = 173, + PushU32 = 174, + PushFelt = 175, + PushWord = 176, + PushU8List = 177, + PushU16List = 178, + PushU32List = 179, + PushFeltList = 180, - Locaddr = 212, - Sdepth = 213, - Caller = 214, - Clk = 215, + Locaddr = 181, + Sdepth = 182, + Caller = 183, + Clk = 184, - MemLoad = 216, - MemLoadImm = 217, - MemLoadW = 218, - MemLoadWImm = 219, - LocLoad = 220, - LocLoadW = 221, - MemStore = 222, - MemStoreImm = 223, - LocStore = 224, - MemStoreW = 225, - MemStoreWImm = 226, - LocStoreW = 227, + MemLoad = 185, + MemLoadImm = 186, + MemLoadW = 187, + MemLoadWImm = 188, + LocLoad = 189, + LocLoadW = 190, + MemStore = 191, + MemStoreImm = 192, + LocStore = 193, + MemStoreW = 194, + MemStoreWImm = 195, + LocStoreW = 196, - MemStream = 228, - AdvPipe = 229, + MemStream = 197, + AdvPipe = 198, - AdvPush = 230, - AdvLoadW = 231, + AdvPush = 199, + AdvLoadW = 200, - AdvInject = 232, + AdvInject = 201, // ----- cryptographic operations ------------------------------------------------------------- - Hash = 233, - HMerge = 234, - HPerm = 235, - MTreeGet = 236, - MTreeSet = 237, - MTreeMerge = 238, - MTreeVerify = 239, + Hash = 202, + HMerge = 203, + HPerm = 204, + MTreeGet = 205, + MTreeSet = 206, + MTreeMerge = 207, + MTreeVerify = 208, // ----- STARK proof verification ------------------------------------------------------------- - FriExt2Fold4 = 240, + FriExt2Fold4 = 209, // ----- exec / call -------------------------------------------------------------------------- - ExecLocal = 241, - ExecImported = 242, - CallLocal = 243, - CallMastRoot = 244, - CallImported = 245, - SysCall = 246, - DynExec = 247, - DynCall = 248, - ProcRefLocal = 249, - ProcRefImported = 250, + ExecLocal = 210, + ExecImported = 211, + CallLocal = 212, + CallMastRoot = 213, + CallImported = 214, + SysCall = 215, + DynExec = 216, + DynCall = 217, + ProcRefLocal = 218, + ProcRefImported = 219, // ----- debugging ---------------------------------------------------------------------------- - Debug = 251, + Debug = 220, // ----- emit -------------------------------------------------------------------------------- - Emit = 252, + Emit = 221, // ----- control flow ------------------------------------------------------------------------- IfElse = 253, diff --git a/assembly/src/ast/nodes/serde/serialization.rs b/assembly/src/ast/nodes/serde/serialization.rs index 4050ebb205..5f75686ec2 100644 --- a/assembly/src/ast/nodes/serde/serialization.rs +++ b/assembly/src/ast/nodes/serde/serialization.rs @@ -154,11 +154,6 @@ impl Serializable for Instruction { } Self::U32Split => OpCode::U32Split.write_into(target), Self::U32Cast => OpCode::U32Cast.write_into(target), - Self::U32CheckedAdd => OpCode::U32CheckedAdd.write_into(target), - Self::U32CheckedAddImm(v) => { - OpCode::U32CheckedAddImm.write_into(target); - target.write_u32(*v); - } Self::U32WrappingAdd => OpCode::U32WrappingAdd.write_into(target), Self::U32WrappingAddImm(v) => { OpCode::U32WrappingAddImm.write_into(target); @@ -171,11 +166,6 @@ impl Serializable for Instruction { } Self::U32OverflowingAdd3 => OpCode::U32OverflowingAdd3.write_into(target), Self::U32WrappingAdd3 => OpCode::U32WrappingAdd3.write_into(target), - Self::U32CheckedSub => OpCode::U32CheckedSub.write_into(target), - Self::U32CheckedSubImm(v) => { - OpCode::U32CheckedSubImm.write_into(target); - target.write_u32(*v); - } Self::U32WrappingSub => OpCode::U32WrappingSub.write_into(target), Self::U32WrappingSubImm(v) => { OpCode::U32WrappingSubImm.write_into(target); @@ -186,11 +176,6 @@ impl Serializable for Instruction { OpCode::U32OverflowingSubImm.write_into(target); target.write_u32(*v); } - Self::U32CheckedMul => OpCode::U32CheckedMul.write_into(target), - Self::U32CheckedMulImm(v) => { - OpCode::U32CheckedMulImm.write_into(target); - target.write_u32(*v); - } Self::U32WrappingMul => OpCode::U32WrappingMul.write_into(target), Self::U32WrappingMulImm(v) => { OpCode::U32WrappingMulImm.write_into(target); @@ -203,104 +188,52 @@ impl Serializable for Instruction { } Self::U32OverflowingMadd => OpCode::U32OverflowingMadd.write_into(target), Self::U32WrappingMadd => OpCode::U32WrappingMadd.write_into(target), - Self::U32CheckedDiv => OpCode::U32CheckedDiv.write_into(target), - Self::U32CheckedDivImm(v) => { - OpCode::U32CheckedDivImm.write_into(target); - target.write_u32(*v); - } - Self::U32UncheckedDiv => OpCode::U32UncheckedDiv.write_into(target), - Self::U32UncheckedDivImm(v) => { - OpCode::U32UncheckedDivImm.write_into(target); - target.write_u32(*v); - } - Self::U32CheckedMod => OpCode::U32CheckedMod.write_into(target), - Self::U32CheckedModImm(v) => { - OpCode::U32CheckedModImm.write_into(target); - target.write_u32(*v); - } - Self::U32UncheckedMod => OpCode::U32UncheckedMod.write_into(target), - Self::U32UncheckedModImm(v) => { - OpCode::U32UncheckedModImm.write_into(target); + Self::U32Div => OpCode::U32Div.write_into(target), + Self::U32DivImm(v) => { + OpCode::U32DivImm.write_into(target); target.write_u32(*v); } - Self::U32CheckedDivMod => OpCode::U32CheckedDivMod.write_into(target), - Self::U32CheckedDivModImm(v) => { - OpCode::U32CheckedDivModImm.write_into(target); + Self::U32Mod => OpCode::U32Mod.write_into(target), + Self::U32ModImm(v) => { + OpCode::U32ModImm.write_into(target); target.write_u32(*v); } - Self::U32UncheckedDivMod => OpCode::U32UncheckedDivMod.write_into(target), - Self::U32UncheckedDivModImm(v) => { - OpCode::U32UncheckedDivModImm.write_into(target); + Self::U32DivMod => OpCode::U32DivMod.write_into(target), + Self::U32DivModImm(v) => { + OpCode::U32DivModImm.write_into(target); target.write_u32(*v); } - Self::U32CheckedAnd => OpCode::U32CheckedAnd.write_into(target), - Self::U32CheckedOr => OpCode::U32CheckedOr.write_into(target), - Self::U32CheckedXor => OpCode::U32CheckedXor.write_into(target), - Self::U32CheckedNot => OpCode::U32CheckedNot.write_into(target), - Self::U32CheckedShr => OpCode::U32CheckedShr.write_into(target), - Self::U32CheckedShrImm(v) => { - OpCode::U32CheckedShrImm.write_into(target); + Self::U32And => OpCode::U32And.write_into(target), + Self::U32Or => OpCode::U32Or.write_into(target), + Self::U32Xor => OpCode::U32Xor.write_into(target), + Self::U32Not => OpCode::U32Not.write_into(target), + Self::U32Shr => OpCode::U32Shr.write_into(target), + Self::U32ShrImm(v) => { + OpCode::U32ShrImm.write_into(target); target.write_u8(*v); } - Self::U32UncheckedShr => OpCode::U32UncheckedShr.write_into(target), - Self::U32UncheckedShrImm(v) => { - OpCode::U32UncheckedShrImm.write_into(target); + Self::U32Shl => OpCode::U32Shl.write_into(target), + Self::U32ShlImm(v) => { + OpCode::U32ShlImm.write_into(target); target.write_u8(*v); } - Self::U32CheckedShl => OpCode::U32CheckedShl.write_into(target), - Self::U32CheckedShlImm(v) => { - OpCode::U32CheckedShlImm.write_into(target); + Self::U32Rotr => OpCode::U32Rotr.write_into(target), + Self::U32RotrImm(v) => { + OpCode::U32RotrImm.write_into(target); target.write_u8(*v); } - Self::U32UncheckedShl => OpCode::U32UncheckedShl.write_into(target), - Self::U32UncheckedShlImm(v) => { - OpCode::U32UncheckedShlImm.write_into(target); + Self::U32Rotl => OpCode::U32Rotl.write_into(target), + Self::U32RotlImm(v) => { + OpCode::U32RotlImm.write_into(target); target.write_u8(*v); } - Self::U32CheckedRotr => OpCode::U32CheckedRotr.write_into(target), - Self::U32CheckedRotrImm(v) => { - OpCode::U32CheckedRotrImm.write_into(target); - target.write_u8(*v); - } - Self::U32UncheckedRotr => OpCode::U32UncheckedRotr.write_into(target), - Self::U32UncheckedRotrImm(v) => { - OpCode::U32UncheckedRotrImm.write_into(target); - target.write_u8(*v); - } - Self::U32CheckedRotl => OpCode::U32CheckedRotl.write_into(target), - Self::U32CheckedRotlImm(v) => { - OpCode::U32CheckedRotlImm.write_into(target); - target.write_u8(*v); - } - Self::U32UncheckedRotl => OpCode::U32UncheckedRotl.write_into(target), - Self::U32UncheckedRotlImm(v) => { - OpCode::U32UncheckedRotlImm.write_into(target); - target.write_u8(*v); - } - Self::U32CheckedPopcnt => OpCode::U32CheckedPopcnt.write_into(target), - Self::U32UncheckedPopcnt => OpCode::U32UncheckedPopcnt.write_into(target), - Self::U32CheckedEq => OpCode::U32CheckedEq.write_into(target), - Self::U32CheckedEqImm(v) => { - OpCode::U32CheckedEqImm.write_into(target); - target.write_u32(*v); - } - Self::U32CheckedNeq => OpCode::U32CheckedNeq.write_into(target), - Self::U32CheckedNeqImm(v) => { - OpCode::U32CheckedNeqImm.write_into(target); - target.write_u32(*v); - } - Self::U32CheckedLt => OpCode::U32CheckedLt.write_into(target), - Self::U32UncheckedLt => OpCode::U32UncheckedLt.write_into(target), - Self::U32CheckedLte => OpCode::U32CheckedLte.write_into(target), - Self::U32UncheckedLte => OpCode::U32UncheckedLte.write_into(target), - Self::U32CheckedGt => OpCode::U32CheckedGt.write_into(target), - Self::U32UncheckedGt => OpCode::U32UncheckedGt.write_into(target), - Self::U32CheckedGte => OpCode::U32CheckedGte.write_into(target), - Self::U32UncheckedGte => OpCode::U32UncheckedGte.write_into(target), - Self::U32CheckedMin => OpCode::U32CheckedMin.write_into(target), - Self::U32UncheckedMin => OpCode::U32UncheckedMin.write_into(target), - Self::U32CheckedMax => OpCode::U32CheckedMax.write_into(target), - Self::U32UncheckedMax => OpCode::U32UncheckedMax.write_into(target), + Self::U32Popcnt => OpCode::U32Popcnt.write_into(target), + Self::U32Lt => OpCode::U32Lt.write_into(target), + Self::U32Lte => OpCode::U32Lte.write_into(target), + Self::U32Gt => OpCode::U32Gt.write_into(target), + Self::U32Gte => OpCode::U32Gte.write_into(target), + Self::U32Min => OpCode::U32Min.write_into(target), + Self::U32Max => OpCode::U32Max.write_into(target), // ----- stack manipulation --------------------------------------------------------------- Self::Drop => OpCode::Drop.write_into(target), diff --git a/assembly/src/ast/parsers/context.rs b/assembly/src/ast/parsers/context.rs index 800832c5ba..8437e84200 100644 --- a/assembly/src/ast/parsers/context.rs +++ b/assembly/src/ast/parsers/context.rs @@ -509,73 +509,48 @@ impl ParserContext<'_> { "u32cast" => simple_instruction(op, U32Cast), "u32split" => simple_instruction(op, U32Split), - "u32checked_add" => u32_ops::parse_u32checked_add(op), "u32wrapping_add" => u32_ops::parse_u32wrapping_add(op), "u32overflowing_add" => u32_ops::parse_u32overflowing_add(op), "u32overflowing_add3" => simple_instruction(op, U32OverflowingAdd3), "u32wrapping_add3" => simple_instruction(op, U32WrappingAdd3), - "u32checked_sub" => u32_ops::parse_u32checked_sub(op), "u32wrapping_sub" => u32_ops::parse_u32wrapping_sub(op), "u32overflowing_sub" => u32_ops::parse_u32overflowing_sub(op), - "u32checked_mul" => u32_ops::parse_u32checked_mul(op), "u32wrapping_mul" => u32_ops::parse_u32wrapping_mul(op), "u32overflowing_mul" => u32_ops::parse_u32overflowing_mul(op), "u32overflowing_madd" => simple_instruction(op, U32OverflowingMadd), "u32wrapping_madd" => simple_instruction(op, U32WrappingMadd), - "u32checked_div" => u32_ops::parse_u32_div(op, true), - "u32unchecked_div" => u32_ops::parse_u32_div(op, false), + "u32div" => u32_ops::parse_u32_div(op), - "u32checked_mod" => u32_ops::parse_u32_mod(op, true), - "u32unchecked_mod" => u32_ops::parse_u32_mod(op, false), + "u32mod" => u32_ops::parse_u32_mod(op), - "u32checked_divmod" => u32_ops::parse_u32_divmod(op, true), - "u32unchecked_divmod" => u32_ops::parse_u32_divmod(op, false), + "u32divmod" => u32_ops::parse_u32_divmod(op), - "u32checked_and" => simple_instruction(op, U32CheckedAnd), - "u32checked_or" => simple_instruction(op, U32CheckedOr), - "u32checked_xor" => simple_instruction(op, U32CheckedXor), - "u32checked_not" => simple_instruction(op, U32CheckedNot), + "u32and" => simple_instruction(op, U32And), + "u32or" => simple_instruction(op, U32Or), + "u32xor" => simple_instruction(op, U32Xor), + "u32not" => simple_instruction(op, U32Not), - "u32checked_shr" => u32_ops::parse_u32_shr(op, true), - "u32unchecked_shr" => u32_ops::parse_u32_shr(op, false), + "u32shr" => u32_ops::parse_u32_shr(op), + "u32shl" => u32_ops::parse_u32_shl(op), - "u32checked_shl" => u32_ops::parse_u32_shl(op, true), - "u32unchecked_shl" => u32_ops::parse_u32_shl(op, false), + "u32rotr" => u32_ops::parse_u32_rotr(op), + "u32rotl" => u32_ops::parse_u32_rotl(op), - "u32checked_rotr" => u32_ops::parse_u32_rotr(op, true), - "u32unchecked_rotr" => u32_ops::parse_u32_rotr(op, false), + "u32popcnt" => simple_instruction(op, U32Popcnt), - "u32checked_rotl" => u32_ops::parse_u32_rotl(op, true), - "u32unchecked_rotl" => u32_ops::parse_u32_rotl(op, false), + "u32lt" => simple_instruction(op, U32Lt), + "u32lte" => simple_instruction(op, U32Lte), - "u32checked_popcnt" => simple_instruction(op, U32CheckedPopcnt), - "u32unchecked_popcnt" => simple_instruction(op, U32UncheckedPopcnt), + "u32gt" => simple_instruction(op, U32Gt), + "u32gte" => simple_instruction(op, U32Gte), - "u32checked_eq" => u32_ops::parse_u32checked_eq(op), - "u32checked_neq" => u32_ops::parse_u32checked_neq(op), - - "u32checked_lt" => simple_instruction(op, U32CheckedLt), - "u32unchecked_lt" => simple_instruction(op, U32UncheckedLt), - - "u32checked_lte" => simple_instruction(op, U32CheckedLte), - "u32unchecked_lte" => simple_instruction(op, U32UncheckedLte), - - "u32checked_gt" => simple_instruction(op, U32CheckedGt), - "u32unchecked_gt" => simple_instruction(op, U32UncheckedGt), - - "u32checked_gte" => simple_instruction(op, U32CheckedGte), - "u32unchecked_gte" => simple_instruction(op, U32UncheckedGte), - - "u32checked_min" => simple_instruction(op, U32CheckedMin), - "u32unchecked_min" => simple_instruction(op, U32UncheckedMin), - - "u32checked_max" => simple_instruction(op, U32CheckedMax), - "u32unchecked_max" => simple_instruction(op, U32UncheckedMax), + "u32min" => simple_instruction(op, U32Min), + "u32max" => simple_instruction(op, U32Max), // ----- stack manipulation ----------------------------------------------------------- "drop" => simple_instruction(op, Drop), diff --git a/assembly/src/ast/parsers/u32_ops.rs b/assembly/src/ast/parsers/u32_ops.rs index bbce3bfea9..50714b2fc8 100644 --- a/assembly/src/ast/parsers/u32_ops.rs +++ b/assembly/src/ast/parsers/u32_ops.rs @@ -79,25 +79,6 @@ pub fn parse_u32assertw(op: &Token, constants: &LocalConstMap) -> Result Result { - debug_assert_eq!(op.parts()[0], "u32checked_add"); - match op.num_parts() { - 0 => unreachable!(), - 1 => Ok(Instruction(U32CheckedAdd)), - 2 => { - let value = parse_param::(op, 1)?; - Ok(Instruction(U32CheckedAddImm(value))) - } - _ => Err(ParsingError::extra_param(op)), - } -} - /// Returns `U32WrappingAdd` instruction node if no immediate value is provided or /// `U32WrappingAddImm` instruction node otherwise. /// @@ -136,24 +117,6 @@ pub fn parse_u32overflowing_add(op: &Token) -> Result { } } -/// Returns `U32CheckedSub` instruction node if no immediate value is provided or -/// `U32CheckedSubImm` instruction node otherwise. -/// -/// # Errors -/// Returns an error if the instruction token contains wrong number of parameters, or if the -/// provided parameter is not a u32 value. -pub fn parse_u32checked_sub(op: &Token) -> Result { - debug_assert_eq!(op.parts()[0], "u32checked_sub"); - match op.num_parts() { - 1 => Ok(Instruction(U32CheckedSub)), - 2 => { - let value = parse_param::(op, 1)?; - Ok(Instruction(U32CheckedSubImm(value))) - } - _ => Err(ParsingError::extra_param(op)), - } -} - /// Returns `U32WrappingSub` instruction node if no immediate value is provided or /// `U32WrappingSubImm` instruction node otherwise. /// @@ -192,25 +155,6 @@ pub fn parse_u32overflowing_sub(op: &Token) -> Result { } } -/// Returns `U32CheckedMul` instruction node if no immediate value is provided or -/// `U32CheckedMulImm` instruction node otherwise. -/// -/// # Errors -/// Returns an error if the instruction token contains wrong number of parameters, or if the -/// provided parameter is not a u32 value. -pub fn parse_u32checked_mul(op: &Token) -> Result { - debug_assert_eq!(op.parts()[0], "u32checked_mul"); - match op.num_parts() { - 0 => unreachable!(), - 1 => Ok(Instruction(U32CheckedMul)), - 2 => { - let value = parse_param::(op, 1)?; - Ok(Instruction(U32CheckedMulImm(value))) - } - _ => Err(ParsingError::extra_param(op)), - } -} - /// Returns `U32WrappingMul` instruction node if no immediate value is provided or /// `U32WrappingMulImm` instruction node otherwise. /// @@ -249,260 +193,137 @@ pub fn parse_u32overflowing_mul(op: &Token) -> Result { } } -/// Returns one of four possible instructions: -/// - checked without parameter: `U32CheckedDiv` -/// - unchecked without parameter: `U32UncheckedDiv` -/// - checked with parameter: `U32CheckedDivImm` -/// - unchecked with parameter: `U32UncheckedDivImm` +/// Returns one of two possible instructions: +/// - division without parameter: `U32Div` +/// - division with parameter: `U32DivImm` /// /// # Errors /// Returns an error if the instruction token contains wrong number of parameters, or if the /// provided parameter is not a u32 value. -pub fn parse_u32_div(op: &Token, checked: bool) -> Result { - //debug_assert_eq!("u32checked_div", op.parts()[0], "not a u32checked_div"); +pub fn parse_u32_div(op: &Token) -> Result { match op.num_parts() { 0 => unreachable!(), - 1 => { - if checked { - Ok(Instruction(U32CheckedDiv)) - } else { - Ok(Instruction(U32UncheckedDiv)) - } - } + 1 => Ok(Instruction(U32Div)), 2 => { let value = parse_param::(op, 1)?; check_div_by_zero(value.into(), op, 1)?; - if checked { - Ok(Instruction(U32CheckedDivImm(value))) - } else { - Ok(Instruction(U32UncheckedDivImm(value))) - } + Ok(Instruction(U32DivImm(value))) } _ => Err(ParsingError::extra_param(op)), } } -/// Returns one of four possible instructions: -/// - checked without parameter: `U32CheckedMod` -/// - unchecked without parameter: `U32UncheckedMod` -/// - checked with parameter: `U32CheckedModImm` -/// - unchecked with parameter: `U32UncheckedModImm` +/// Returns one of two possible instructions: +/// - module without parameter: `U32Mod` +/// - module with parameter: `U32ModImm` /// /// # Errors /// Returns an error if the instruction token contains wrong number of parameters, or if the /// provided parameter is not a u32 value. -pub fn parse_u32_mod(op: &Token, checked: bool) -> Result { +pub fn parse_u32_mod(op: &Token) -> Result { match op.num_parts() { 0 => unreachable!(), - 1 => { - if checked { - Ok(Instruction(U32CheckedMod)) - } else { - Ok(Instruction(U32UncheckedMod)) - } - } + 1 => Ok(Instruction(U32Mod)), 2 => { let value = parse_param::(op, 1)?; check_div_by_zero(value.into(), op, 1)?; - if checked { - Ok(Instruction(U32CheckedModImm(value))) - } else { - Ok(Instruction(U32UncheckedModImm(value))) - } + Ok(Instruction(U32ModImm(value))) } _ => Err(ParsingError::extra_param(op)), } } -/// Returns one of four possible instructions: -/// - checked without parameter: `U32CheckedDivMod` -/// - unchecked without parameter: `U32UncheckedDivMod` -/// - checked with parameter: `U32CheckedDivModImm` -/// - unchecked with parameter: `U32UncheckedDivModImm` +/// Returns one of two possible instructions: +/// - DivMod without parameter: `U32DivMod` +/// - DivMod with parameter: `U32DivModImm` /// /// # Errors /// Returns an error if the instruction token contains wrong number of parameters, or if the /// provided parameter is not a u32 value. -pub fn parse_u32_divmod(op: &Token, checked: bool) -> Result { +pub fn parse_u32_divmod(op: &Token) -> Result { match op.num_parts() { 0 => unreachable!(), - 1 => { - if checked { - Ok(Instruction(U32CheckedDivMod)) - } else { - Ok(Instruction(U32UncheckedDivMod)) - } - } + 1 => Ok(Instruction(U32DivMod)), 2 => { let value = parse_param::(op, 1)?; check_div_by_zero(value.into(), op, 1)?; - if checked { - Ok(Instruction(U32CheckedDivModImm(value))) - } else { - Ok(Instruction(U32UncheckedDivModImm(value))) - } + Ok(Instruction(U32DivModImm(value))) } _ => Err(ParsingError::extra_param(op)), } } -/// Returns one of four possible instructions: -/// - checked without parameter: `U32CheckedShr` -/// - unchecked without parameter: `U32UncheckedShr` -/// - checked with parameter: `U32CheckedShrImm` -/// - unchecked with parameter: `U32UncheckedShrImm` +/// Returns one of two possible instructions: +/// - shift right without parameter: `U32Shr` +/// - shift right with parameter: `U32ShrImm` /// /// # Errors /// Returns an error if the instruction token contains wrong number of parameters, or if the /// provided parameter is greater than 31. -pub fn parse_u32_shr(op: &Token, checked: bool) -> Result { +pub fn parse_u32_shr(op: &Token) -> Result { match op.num_parts() { 0 => unreachable!(), - 1 => { - if checked { - Ok(Instruction(U32CheckedShr)) - } else { - Ok(Instruction(U32UncheckedShr)) - } - } + 1 => Ok(Instruction(U32Shr)), 2 => { let n = parse_checked_param::(op, 1, 0..=MAX_U32_SHIFT_VALUE)?; - if checked { - Ok(Instruction(U32CheckedShrImm(n))) - } else { - Ok(Instruction(U32UncheckedShrImm(n))) - } + Ok(Instruction(U32ShrImm(n))) } _ => Err(ParsingError::extra_param(op)), } } -/// Returns one of four possible instructions: -/// - checked without parameter: `U32CheckedShl` -/// - unchecked without parameter: `U32UncheckedShl` -/// - checked with parameter: `U32CheckedShlImm` -/// - unchecked with parameter: `U32UncheckedShlImm` +/// Returns one of two possible instructions: +/// - shift left without parameter: `U32Shl` +/// - shift left with parameter: `U32ShlImm` /// /// # Errors /// Returns an error if the instruction token contains wrong number of parameters, or if the /// provided parameter is greater than 31. -pub fn parse_u32_shl(op: &Token, checked: bool) -> Result { +pub fn parse_u32_shl(op: &Token) -> Result { match op.num_parts() { 0 => unreachable!(), - 1 => { - if checked { - Ok(Instruction(U32CheckedShl)) - } else { - Ok(Instruction(U32UncheckedShl)) - } - } + 1 => Ok(Instruction(U32Shl)), 2 => { let n = parse_checked_param::(op, 1, 0..=MAX_U32_SHIFT_VALUE)?; - if checked { - Ok(Instruction(U32CheckedShlImm(n))) - } else { - Ok(Instruction(U32UncheckedShlImm(n))) - } + Ok(Instruction(U32ShlImm(n))) } _ => Err(ParsingError::extra_param(op)), } } -/// Returns one of four possible instructions: -/// - checked without parameter: `U32CheckedRotr` -/// - unchecked without parameter: `U32UncheckedRotr` -/// - checked with parameter: `U32CheckedRotrImm` -/// - unchecked with parameter: `U32UncheckedRotrImm` +/// Returns one of two possible instructions: +/// - rotation right without parameter: `U32Rotr` +/// - rotation right with parameter: `U32RotrImm` /// /// # Errors /// Returns an error if the instruction token contains wrong number of parameters, or if the /// provided parameter is greater than 31. -pub fn parse_u32_rotr(op: &Token, checked: bool) -> Result { +pub fn parse_u32_rotr(op: &Token) -> Result { match op.num_parts() { 0 => unreachable!(), - 1 => { - if checked { - Ok(Instruction(U32CheckedRotr)) - } else { - Ok(Instruction(U32UncheckedRotr)) - } - } + 1 => Ok(Instruction(U32Rotr)), 2 => { let n = parse_checked_param::(op, 1, 0..=MAX_U32_ROTATE_VALUE)?; - if checked { - Ok(Instruction(U32CheckedRotrImm(n))) - } else { - Ok(Instruction(U32UncheckedRotrImm(n))) - } + Ok(Instruction(U32RotrImm(n))) } _ => Err(ParsingError::extra_param(op)), } } -/// Returns one of four possible instructions: -/// - checked without parameter: `U32CheckedRotl` -/// - unchecked without parameter: `U32UncheckedRotl` -/// - checked with parameter: `U32CheckedRotlImm` -/// - unchecked with parameter: `U32UncheckedRotlImm` +/// Returns one of two possible instructions: +/// - rotation left without parameter: `U32Rotl` +/// - rotation left with parameter: `U32RotlImm` /// /// # Errors /// Returns an error if the instruction token contains wrong number of parameters, or if the /// provided parameter is greater than 31. -pub fn parse_u32_rotl(op: &Token, checked: bool) -> Result { +pub fn parse_u32_rotl(op: &Token) -> Result { match op.num_parts() { 0 => unreachable!(), - 1 => { - if checked { - Ok(Instruction(U32CheckedRotl)) - } else { - Ok(Instruction(U32UncheckedRotl)) - } - } + 1 => Ok(Instruction(U32Rotl)), 2 => { let n = parse_checked_param::(op, 1, 0..=MAX_U32_ROTATE_VALUE)?; - if checked { - Ok(Instruction(U32CheckedRotlImm(n))) - } else { - Ok(Instruction(U32UncheckedRotlImm(n))) - } - } - _ => Err(ParsingError::extra_param(op)), - } -} - -/// Returns `U32CheckedEq` instruction node if no immediate value is provided or -/// `U32CheckedEqImm` instruction node otherwise. -/// -/// # Errors -/// Returns an error if the instruction token contains wrong number of parameters, or if the -/// provided parameter is not a u32 value. -pub fn parse_u32checked_eq(op: &Token) -> Result { - debug_assert_eq!(op.parts()[0], "u32checked_eq"); - match op.num_parts() { - 0 => unreachable!(), - 1 => Ok(Instruction(U32CheckedEq)), - 2 => { - let value = parse_param::(op, 1)?; - Ok(Instruction(U32CheckedEqImm(value))) - } - _ => Err(ParsingError::extra_param(op)), - } -} - -/// Returns `U32CheckedNeq` instruction node if no immediate value is provided or -/// `U32CheckedNeqImm` instruction node otherwise. -/// -/// # Errors -/// Returns an error if the instruction token contains wrong number of parameters, or if the -/// provided parameter is not a u32 value. -pub fn parse_u32checked_neq(op: &Token) -> Result { - debug_assert_eq!(op.parts()[0], "u32checked_neq"); - match op.num_parts() { - 0 => unreachable!(), - 1 => Ok(Instruction(U32CheckedNeq)), - 2 => { - let value = parse_param::(op, 1)?; - Ok(Instruction(U32CheckedNeqImm(value))) + Ok(Instruction(U32RotlImm(n))) } _ => Err(ParsingError::extra_param(op)), } diff --git a/assembly/src/ast/tests.rs b/assembly/src/ast/tests.rs index 240040a82e..2b55f25bd0 100644 --- a/assembly/src/ast/tests.rs +++ b/assembly/src/ast/tests.rs @@ -86,28 +86,22 @@ fn test_ast_parsing_program_u32() { begin push.3 - u32checked_add.5 u32wrapping_add.5 u32overflowing_add.5 - u32checked_sub.1 u32wrapping_sub.1 u32overflowing_sub.1 - u32checked_mul.2 u32wrapping_mul.2 u32overflowing_mul.2 end"; let nodes: Vec = vec![ Node::Instruction(Instruction::PushU8(3)), - Node::Instruction(Instruction::U32CheckedAddImm(5)), Node::Instruction(Instruction::U32WrappingAddImm(5)), Node::Instruction(Instruction::U32OverflowingAddImm(5)), - Node::Instruction(Instruction::U32CheckedSubImm(1)), Node::Instruction(Instruction::U32WrappingSubImm(1)), Node::Instruction(Instruction::U32OverflowingSubImm(1)), - Node::Instruction(Instruction::U32CheckedMulImm(2)), Node::Instruction(Instruction::U32WrappingMulImm(2)), Node::Instruction(Instruction::U32OverflowingMulImm(2)), ]; @@ -810,7 +804,7 @@ fn test_ast_program_serde_control_flow() { while.true push.5.7 - u32checked_add + u32wrapping_add loc_store.1 push.0 end @@ -863,7 +857,7 @@ fn assert_parsing_line_invalid_op() { while.true push.5.7 - u32checked_add + u32wrapping_add loc_store.1 push.0 end diff --git a/docs/src/tools/repl.md b/docs/src/tools/repl.md index c6fdb8e69d..1cd272d35c 100644 --- a/docs/src/tools/repl.md +++ b/docs/src/tools/repl.md @@ -47,13 +47,13 @@ The `!program` command prints out the entire Miden program being executed. E.g., ``` >> push.1.2.3.4 >> repeat.16 pow2 end ->> u32checked_add +>> u32wrapping_add >> !program begin push.1.2.3.4 repeat.16 pow2 end - u32checked_add + u32wrapping_add end ``` @@ -64,7 +64,7 @@ The `!stack` command prints out the state of the stack at the last executed inst ``` >> push.1 push.2 push.3 push.4 push.5 >> exp ->> u32checked_mul +>> u32wrapping_mul >> swap >> eq.2 >> assert diff --git a/docs/src/user_docs/assembly/u32_operations.md b/docs/src/user_docs/assembly/u32_operations.md index c776f942b8..ec7ed79658 100644 --- a/docs/src/user_docs/assembly/u32_operations.md +++ b/docs/src/user_docs/assembly/u32_operations.md @@ -1,11 +1,7 @@ ## u32 operations Miden assembly provides a set of instructions which can perform operations on regular two-complement 32-bit integers. These instructions are described in the tables below. -Most instructions have _checked_ variants. These variants ensure that input values are 32-bit integers, and fail if that's not the case. All other variants do not perform these checks, and thus, should be used only if the inputs are known to be 32-bit integers. Supplying inputs which are greater than or equal to $2^{32}$ to unchecked operations results in undefined behavior. - -The primary benefit of using unchecked operations is performance: they can frequently be executed $2$ or $3$ times faster than their checked counterparts. In general, vast majority of the unchecked operations listed below can be executed in a single VM cycle. - -For instructions where one or more operands can be provided as immediate parameters (e.g., `u32checked_add` and `u32checked_add.b`), we provide stack transition diagrams only for the non-immediate version. For the immediate version, it can be assumed that the operand with the specified name is not present on the stack. +For instructions where one or more operands can be provided as immediate parameters (e.g., `u32wrapping_add` and `u32wrapping_add.b`), we provide stack transition diagrams only for the non-immediate version. For the immediate version, it can be assumed that the operand with the specified name is not present on the stack. In all the table below, the number of cycles it takes for the VM to execute each instruction is listed beneath the instruction. @@ -32,60 +28,41 @@ If the error code is omitted, the default value of $0$ is assumed. | Instruction | Stack input | Stack output | Notes | | ----------------------------------------------------------------------------------------- | -------------- | ------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| u32checked_add
- *(4 cycles)*
u32checked_add.*b*
- *(5-6 cycles)* | [b, a, ...] | [c, ...] | $c \leftarrow a + b$
Fails if $max(a, b, c) \ge 2^{32}$ | | u32overflowing_add
- *(1 cycle)*
u32overflowing_add.*b*
- *(2-3 cycles)* | [b, a, ...] | [d, c, ...] | $c \leftarrow (a + b) \mod 2^{32}$
$d \leftarrow \begin{cases} 1, & \text{if}\ (a + b) \ge 2^{32} \\ 0, & \text{otherwise}\ \end{cases}$
Undefined if $max(a, b) \ge 2^{32}$ | | u32wrapping_add
- *(2 cycles)*
u32wrapping_add.*b*
- *(3-4 cycles)* | [b, a, ...] | [c, ...] | $c \leftarrow (a + b) \mod 2^{32}$
Undefined if $max(a, b) \ge 2^{32}$ | | u32overflowing_add3
- *(1 cycle)* | [c, b, a, ...] | [e, d, ...] | $d \leftarrow (a + b + c) \mod 2^{32}$,
$e \leftarrow \lfloor (a + b + c) / 2^{32}\rfloor$
Undefined if $max(a, b, c) \ge 2^{32}$
| | u32wrapping_add3
- *(2 cycles)* | [c, b, a, ...] | [d, ...] | $d \leftarrow (a + b + c) \mod 2^{32}$,
Undefined if $max(a, b, c) \ge 2^{32}$
| -| u32checked_sub
- *(4 cycles)*
u32checked_sub.*b*
- *(5-6 cycles)* | [b, a, ...] | [c, ...] | $c \leftarrow (a - b)$
Fails if $max(a, b) \ge 2^{32}$ or $a < b$ | | u32overflowing_sub
- *(1 cycle)*
u32overflowing_sub.*b*
- *(2-3 cycles)* | [b, a, ...] | [d, c, ...] | $c \leftarrow (a - b) \mod 2^{32}$
$d \leftarrow \begin{cases} 1, & \text{if}\ a < b \\ 0, & \text{otherwise}\ \end{cases}$
Undefined if $max(a, b) \ge 2^{32}$ | | u32wrapping_sub
- *(2 cycles)*
u32wrapping_sub.*b*
- *(3-4 cycles)* | [b, a, ...] | [c, ...] | $c \leftarrow (a - b) \mod 2^{32}$
Undefined if $max(a, b) \ge 2^{32}$ | -| u32checked_mul
- *(4 cycles)*
u32checked_mul.*b*
- *(5-6 cycles)* | [b, a, ...] | [c, ...] | $c \leftarrow a \cdot b$
Fails if $max(a, b, c) \ge 2^{32}$ | | u32overflowing_mul
- *(1 cycle)*
u32overflowing_mul.*b*
- *(2-3 cycles)* | [b, a, ...] | [d, c, ...] | $c \leftarrow (a \cdot b) \mod 2^{32}$
$d \leftarrow \lfloor(a \cdot b) / 2^{32}\rfloor$
Undefined if $max(a, b) \ge 2^{32}$ | | u32wrapping_mul
- *(2 cycles)*
u32wrapping_mul.*b*
- *(3-4 cycles)* | [b, a, ...] | [c, ...] | $c \leftarrow (a \cdot b) \mod 2^{32}$
Undefined if $max(a, b) \ge 2^{32}$ | | u32overflowing_madd
- *(1 cycle)* | [b, a, c, ...] | [e, d, ...] | $d \leftarrow (a \cdot b + c) \mod 2^{32}$
$e \leftarrow \lfloor(a \cdot b + c) / 2^{32}\rfloor$
Undefined if $max(a, b, c) \ge 2^{32}$ | | u32wrapping_madd
- *(2 cycles)* | [b, a, c, ...] | [d, ...] | $d \leftarrow (a \cdot b + c) \mod 2^{32}$
Undefined if $max(a, b, c) \ge 2^{32}$ | -| u32checked_div
- *(3 cycles)*
u32checked_div.*b*
- *(4-5 cycles)* | [b, a, ...] | [c, ...] | $c \leftarrow \lfloor a / b\rfloor$
Fails if $max(a, b) \ge 2^{32}$ or $b = 0$ | -| u32unchecked_div
- *(2 cycles)*
u32unchecked_div.*b*
- *(3-4 cycles)* | [b, a, ...] | [c, ...] | $c \leftarrow \lfloor a / b\rfloor$
Fails if $b = 0$
Undefined if $max(a, b) \ge 2^{32}$ | -| u32checked_mod
- *(4 cycles)*
u32checked_mod.*b*
- *(5-6 cycles)* | [b, a, ...] | [c, ...] | $c \leftarrow a \mod b$
Fails if $max(a, b) \ge 2^{32}$ or $b = 0$ | -| u32unchecked_mod
- *(3 cycles)*
u32unchecked_mod.*b*
- *(4-5 cycles)* | [b, a, ...] | [c, ...] | $c \leftarrow a \mod b$
Fails if $b = 0$
Undefined if $max(a, b) \ge 2^{32}$ | -| u32checked_divmod
- *(2 cycles)*
u32checked_divmod.*b*
- *(3-4 cycles)* | [b, a, ...] | [d, c, ...] | $c \leftarrow \lfloor a / b\rfloor$
$d \leftarrow a \mod b$
Fails if $max(a, b) \ge 2^{32}$ or $b = 0$ | -| u32unchecked_divmod
- *(1 cycle)*
u32unchecked_divmod.*b*
- *(2-3 cycles)* | [b, a, ...] | [d, c, ...] | $c \leftarrow \lfloor a / b\rfloor$
$d \leftarrow a \mod b$
Fails if $b = 0$
Undefined if $max(a, b) \ge 2^{32}$ | +| u32div
- *(2 cycles)*
u32div.*b*
- *(3-4 cycles)* | [b, a, ...] | [c, ...] | $c \leftarrow \lfloor a / b\rfloor$
Fails if $b = 0$
Undefined if $max(a, b) \ge 2^{32}$ | +| u32mod
- *(3 cycles)*
u32mod.*b*
- *(4-5 cycles)* | [b, a, ...] | [c, ...] | $c \leftarrow a \mod b$
Fails if $b = 0$
Undefined if $max(a, b) \ge 2^{32}$ | +| u32divmod
- *(1 cycle)*
u32divmod.*b*
- *(2-3 cycles)* | [b, a, ...] | [d, c, ...] | $c \leftarrow \lfloor a / b\rfloor$
$d \leftarrow a \mod b$
Fails if $b = 0$
Undefined if $max(a, b) \ge 2^{32}$ | ### Bitwise operations | Instruction | Stack input | Stack output | Notes | | ------------------------------------------------------------------------------------- | -------------- | ------------- | ------------------------------------------------------------------------------------------------------------------------------ | -| u32checked_and
- *(1 cycle)* | [b, a, ...] | [c, ...] | Computes $c$ as a bitwise `AND` of binary representations of $a$ and $b$.
Fails if $max(a,b) \ge 2^{32}$ | -| u32checked_or
- *(6 cycle)s* | [b, a, ...] | [c, ...] | Computes $c$ as a bitwise `OR` of binary representations of $a$ and $b$.
Fails if $max(a,b) \ge 2^{32}$ | -| u32checked_xor
- *(1 cycle)* | [b, a, ...] | [c, ...] | Computes $c$ as a bitwise `XOR` of binary representations of $a$ and $b$.
Fails if $max(a,b) \ge 2^{32}$ | -| u32checked_not
- *(5 cycles)* | [a, ...] | [b, ...] | Computes $b$ as a bitwise `NOT` of binary representation of $a$.
Fails if $a \ge 2^{32}$ | -| u32checked_shl
- *(47 cycles)*
u32checked_shl.*b*
- *(4 cycles)* | [b, a, ...] | [c, ...] | $c \leftarrow (a \cdot 2^b) \mod 2^{32}$
Fails if $a \ge 2^{32}$ or $b > 31$ | -| u32unchecked_shl
- *(40 cycles)*
u32unchecked_shl.*b*
- *(3 cycles)* | [b, a, ...] | [c, ...] | $c \leftarrow (a \cdot 2^b) \mod 2^{32}$
Undefined if $a \ge 2^{32}$ or $b > 31$ | -| u32checked_shr
- *(47 cycles)*
u32checked_shr.*b*
- *(4 cycles)* | [b, a, ...] | [c, ...] | $c \leftarrow \lfloor a/2^b \rfloor$
Fails if $a \ge 2^{32}$ or $b > 31$ | -| u32unchecked_shr
- *(40 cycles)*
u32unchecked_shr.*b*
- *(3 cycles)* | [b, a, ...] | [c, ...] | $c \leftarrow \lfloor a/2^b \rfloor$
Undefined if $a \ge 2^{32}$ or $b > 31$ | -| u32checked_rotl
- *(47 cycles)*
u32checked_rotl.*b*
- *(4 cycles)* | [b, a, ...] | [c, ...] | Computes $c$ by rotating a 32-bit representation of $a$ to the left by $b$ bits.
Fails if $a \ge 2^{32}$ or $b > 31$ | -| u32unchecked_rotl
- *(40 cycles)*
u32unchecked_rotl.*b*
- *(3 cycles)* | [b, a, ...] | [c, ...] | Computes $c$ by rotating a 32-bit representation of $a$ to the left by $b$ bits.
Undefined if $a \ge 2^{32}$ or $b > 31$ | -| u32checked_rotr
- *(59 cycles)*
u32checked_rotr.*b*
- *(6 cycles)* | [b, a, ...] | [c, ...] | Computes $c$ by rotating a 32-bit representation of $a$ to the right by $b$ bits.
Fails if $a \ge 2^{32}$ or $b > 31$ | -| u32unchecked_rotr
- *(44 cycles)*
u32unchecked_rotr.*b*
- *(3 cycles)* | [b, a, ...] | [c, ...] | Computes $c$ by rotating a 32-bit representation of $a$ to the right by $b$ bits.
Undefined if $a \ge 2^{32}$ or $b > 31$ | -| u32checked_popcnt
- *(36 cycles)* | [a, ...] | [b, ...] | Computes $b$ by counting the number of set bits in $a$ (hamming weight of $a$).
Fails if $a \ge 2^{32}$ | -| u32unchecked_popcnt
- *(33 cycles)* | [a, ...] | [b, ...] | Computes $b$ by counting the number of set bits in $a$ (hamming weight of $a$).
Undefined if $a \ge 2^{32}$ | +| u32and
- *(1 cycle)* | [b, a, ...] | [c, ...] | Computes $c$ as a bitwise `AND` of binary representations of $a$ and $b$.
Fails if $max(a,b) \ge 2^{32}$ | +| u32or
- *(6 cycle)s* | [b, a, ...] | [c, ...] | Computes $c$ as a bitwise `OR` of binary representations of $a$ and $b$.
Fails if $max(a,b) \ge 2^{32}$ | +| u32xor
- *(1 cycle)* | [b, a, ...] | [c, ...] | Computes $c$ as a bitwise `XOR` of binary representations of $a$ and $b$.
Fails if $max(a,b) \ge 2^{32}$ | +| u32not
- *(5 cycles)* | [a, ...] | [b, ...] | Computes $b$ as a bitwise `NOT` of binary representation of $a$.
Fails if $a \ge 2^{32}$ | +| u32shl
- *(40 cycles)*
u32shl.*b*
- *(3 cycles)* | [b, a, ...] | [c, ...] | $c \leftarrow (a \cdot 2^b) \mod 2^{32}$
Undefined if $a \ge 2^{32}$ or $b > 31$ | +| u32shr
- *(40 cycles)*
u32shr.*b*
- *(3 cycles)* | [b, a, ...] | [c, ...] | $c \leftarrow \lfloor a/2^b \rfloor$
Undefined if $a \ge 2^{32}$ or $b > 31$ | +| u32rotl
- *(40 cycles)*
u32rotl.*b*
- *(3 cycles)* | [b, a, ...] | [c, ...] | Computes $c$ by rotating a 32-bit representation of $a$ to the left by $b$ bits.
Undefined if $a \ge 2^{32}$ or $b > 31$ | +| u32rotr
- *(44 cycles)*
u32rotr.*b*
- *(3 cycles)* | [b, a, ...] | [c, ...] | Computes $c$ by rotating a 32-bit representation of $a$ to the right by $b$ bits.
Undefined if $a \ge 2^{32}$ or $b > 31$ | +| u32popcnt
- *(33 cycles)* | [a, ...] | [b, ...] | Computes $b$ by counting the number of set bits in $a$ (hamming weight of $a$).
Undefined if $a \ge 2^{32}$ | ### Comparison operations | Instruction | Stack input | Stack output | Notes | | -------------------------------------------------------------------------------- | ------------ | --------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| u32checked_eq
- *(2 cycles)*
u32checked_eq.*b*
- *(3-4 cycles)* | [b, a, ...] | [c, ...] | $c \leftarrow \begin{cases} 1, & \text{if}\ a=b \\ 0, & \text{otherwise}\ \end{cases}$
Fails if $max(a, b) \ge 2^{32}$
Note: unchecked version is not provided because it is equivalent to simple `eq`. | -| u32checked_neq
- *(3 cycles)*
u32checked_neq.*b*
- *(4-5 cycles)* | [b, a, ...] | [c, ...] | $c \leftarrow \begin{cases} 1, & \text{if}\ a \ne b \\ 0, & \text{otherwise}\ \end{cases}$
Fails if $max(a, b) \ge 2^{32}$
Note: unchecked version is not provided because it is equivalent to simple `neq`. | -| u32checked_lt
- *(6 cycles)* | [b, a, ...] | [c, ...] | $c \leftarrow \begin{cases} 1, & \text{if}\ a < b \\ 0, & \text{otherwise}\ \end{cases}$
Fails if $max(a, b) \ge 2^{32}$ | -| u32unchecked_lt
- *(5 cycles)* | [b, a, ...] | [c, ...] | $c \leftarrow \begin{cases} 1, & \text{if}\ a < b \\ 0, & \text{otherwise}\ \end{cases}$
Undefined if $max(a, b) \ge 2^{32}$ | -| u32checked_lte
- *(8 cycles)* | [b, a, ...] | [c, ...] | $c \leftarrow \begin{cases} 1, & \text{if}\ a \le b \\ 0, & \text{otherwise}\ \end{cases}$
Fails if $max(a, b) \ge 2^{32}$ | -| u32unchecked_lte
- *(7 cycles)* | [b, a, ...] | [c, ...] | $c \leftarrow \begin{cases} 1, & \text{if}\ a \le b \\ 0, & \text{otherwise}\ \end{cases}$
Undefined if $max(a, b) \ge 2^{32}$ | -| u32checked_gt
- *(7 cycles)* | [b, a, ...] | [c, ...] | $c \leftarrow \begin{cases} 1, & \text{if}\ a > b \\ 0, & \text{otherwise}\ \end{cases}$
Fails if $max(a, b) \ge 2^{32}$ | -| u32unchecked_gt
- *(6 cycles)* | [b, a, ...] | [c, ...] | $c \leftarrow \begin{cases} 1, & \text{if}\ a > b \\ 0, & \text{otherwise}\ \end{cases}$
Undefined if $max(a, b) \ge 2^{32}$ | -| u32checked_gte
- *(7 cycles)* | [b, a, ...] | [c, ...] | $c \leftarrow \begin{cases} 1, & \text{if}\ a \ge b \\ 0, & \text{otherwise}\ \end{cases}$
Fails if $max(a, b) \ge 2^{32}$ | -| u32unchecked_gte
- *(6 cycles)* | [b, a, ...] | [c, ...] | $c \leftarrow \begin{cases} 1, & \text{if}\ a \ge b \\ 0, & \text{otherwise}\ \end{cases}$
Undefined if $max(a, b) \ge 2^{32}$ | -| u32checked_min
- *(9 cycles)* | [b, a, ...] | [c, ...] | $c \leftarrow \begin{cases} a, & \text{if}\ a < b \\ b, & \text{otherwise}\ \end{cases}$
Fails if $max(a, b) \ge 2^{32}$ | -| u32unchecked_min
- *(8 cycles)* | [b, a, ...] | [c, ...] | $c \leftarrow \begin{cases} a, & \text{if}\ a < b \\ b, & \text{otherwise}\ \end{cases}$
Undefined if $max(a, b) \ge 2^{32}$ | -| u32checked_max
- *(10 cycles)* | [b, a, ...] | [c, ...] | $c \leftarrow \begin{cases} a, & \text{if}\ a > b \\ b, & \text{otherwise}\ \end{cases}$
Fails if $max(a, b) \ge 2^{32}$ | -| u32unchecked_max
- *(9 cycles)* | [b, a, ...] | [c, ...] | $c \leftarrow \begin{cases} a, & \text{if}\ a > b \\ b, & \text{otherwise}\ \end{cases}$
Undefined if $max(a, b) \ge 2^{32}$ | +| u32lt
- *(5 cycles)* | [b, a, ...] | [c, ...] | $c \leftarrow \begin{cases} 1, & \text{if}\ a < b \\ 0, & \text{otherwise}\ \end{cases}$
Undefined if $max(a, b) \ge 2^{32}$ | +| u32lte
- *(7 cycles)* | [b, a, ...] | [c, ...] | $c \leftarrow \begin{cases} 1, & \text{if}\ a \le b \\ 0, & \text{otherwise}\ \end{cases}$
Undefined if $max(a, b) \ge 2^{32}$ | +| u32gt
- *(6 cycles)* | [b, a, ...] | [c, ...] | $c \leftarrow \begin{cases} 1, & \text{if}\ a > b \\ 0, & \text{otherwise}\ \end{cases}$
Undefined if $max(a, b) \ge 2^{32}$ | +| u32gte
- *(6 cycles)* | [b, a, ...] | [c, ...] | $c \leftarrow \begin{cases} 1, & \text{if}\ a \ge b \\ 0, & \text{otherwise}\ \end{cases}$
Undefined if $max(a, b) \ge 2^{32}$ | +| u32min
- *(8 cycles)* | [b, a, ...] | [c, ...] | $c \leftarrow \begin{cases} a, & \text{if}\ a < b \\ b, & \text{otherwise}\ \end{cases}$
Undefined if $max(a, b) \ge 2^{32}$ | +| u32max
- *(9 cycles)* | [b, a, ...] | [c, ...] | $c \leftarrow \begin{cases} a, & \text{if}\ a > b \\ b, & \text{otherwise}\ \end{cases}$
Undefined if $max(a, b) \ge 2^{32}$ | diff --git a/miden/examples/nprime/nprime.masm b/miden/examples/nprime/nprime.masm index 5013247c0b..d6af5e2c9d 100644 --- a/miden/examples/nprime/nprime.masm +++ b/miden/examples/nprime/nprime.masm @@ -74,7 +74,7 @@ proc.is_not_prime_should_continue # [remainder, continue loop?, is prime?, prime, j, candidate, i, n, primes..] dup.4 dup.3 - u32checked_mod + u32assert2 u32mod # if remainder is zero, then the number is divisible by prime; hence isn't prime # [continue loop?, is prime?, prime, j, candidate, i, n, primes..] diff --git a/miden/src/repl/mod.rs b/miden/src/repl/mod.rs index 0d84574a8a..94134c78eb 100644 --- a/miden/src/repl/mod.rs +++ b/miden/src/repl/mod.rs @@ -54,7 +54,7 @@ use rustyline::{error::ReadlineError, DefaultEditor}; /// if all of them are zeros). /// >> push.1 push.2 push.3 push.4 push.5 /// >> exp -/// >> u32checked_mul +/// >> u32wrapping_mul /// >> swap /// >> eq.2 /// >> assert diff --git a/miden/tests/integration/air/chiplets/bitwise.rs b/miden/tests/integration/air/chiplets/bitwise.rs index f36323024b..213d00e2a6 100644 --- a/miden/tests/integration/air/chiplets/bitwise.rs +++ b/miden/tests/integration/air/chiplets/bitwise.rs @@ -3,7 +3,7 @@ use test_utils::{build_op_test, build_test}; #[test] fn bitwise_and() { // Test all bit input combinations: (1, 1), (1, 0), (0, 0). Then test larger numbers. - let asm_op = "u32checked_and push.0 u32checked_and push.0 u32checked_and push.65535 push.137 u32checked_and"; + let asm_op = "u32and push.0 u32and push.0 u32and push.65535 push.137 u32and"; let pub_inputs = vec![1, 1]; build_op_test!(&asm_op, &pub_inputs).prove_and_verify(pub_inputs, false); @@ -12,7 +12,7 @@ fn bitwise_and() { #[test] fn bitwise_or() { // Test all bit input combinations: (1, 1), (1, 0), (0, 0). Then test larger numbers. - let asm_op = "u32checked_or push.0 u32checked_or not push.0 u32checked_or push.65535 push.137 u32checked_or"; + let asm_op = "u32or push.0 u32or not push.0 u32or push.65535 push.137 u32or"; let pub_inputs = vec![1, 1]; build_op_test!(&asm_op, &pub_inputs).prove_and_verify(pub_inputs, false); @@ -21,7 +21,7 @@ fn bitwise_or() { #[test] fn bitwise_xor() { // Test all bit input combinations: (1, 1), (0, 0), (1, 0). Then test larger numbers - let asm_op = "u32checked_xor push.0 u32checked_xor push.1 u32checked_xor push.65535 push.137 u32checked_xor"; + let asm_op = "u32xor push.0 u32xor push.1 u32xor push.65535 push.137 u32xor"; let pub_inputs = vec![1, 1]; build_op_test!(&asm_op, &pub_inputs).prove_and_verify(pub_inputs, false); @@ -29,7 +29,7 @@ fn bitwise_xor() { #[test] fn all_operations() { - let source = "begin u32checked_and push.0 u32checked_or push.0 u32checked_xor end"; + let source = "begin u32and push.0 u32or push.0 u32xor end"; let pub_inputs = vec![1, 1]; build_test!(source, &pub_inputs).prove_and_verify(pub_inputs, false); diff --git a/miden/tests/integration/air/chiplets/mod.rs b/miden/tests/integration/air/chiplets/mod.rs index aa59571d73..ca7137832b 100644 --- a/miden/tests/integration/air/chiplets/mod.rs +++ b/miden/tests/integration/air/chiplets/mod.rs @@ -8,9 +8,9 @@ mod memory; fn chiplets() { // Test a program that uses all of the chiplets. let source = "begin - hperm # hasher operation - push.5 push.10 u32checked_or # bitwise operation - mem_load # memory operation + hperm # hasher operation + push.5 push.10 u32or # bitwise operation + mem_load # memory operation end"; let pub_inputs = rand_vector::(8); diff --git a/miden/tests/integration/air/range.rs b/miden/tests/integration/air/range.rs index aa7796b392..9d59cfdfaf 100644 --- a/miden/tests/integration/air/range.rs +++ b/miden/tests/integration/air/range.rs @@ -14,7 +14,8 @@ fn range_check_once() { /// 5 is checked 3 times, 10 is checked twice, and 15 is checked once. #[test] fn range_check_multi() { - let source = "begin u32checked_add u32checked_add end"; + let source = + "begin u32assert2 u32overflowing_add assertz u32assert2 u32overflowing_add assertz end"; let stack = vec![5, 5, 5]; build_test!(source, &stack).prove_and_verify(stack, false); diff --git a/miden/tests/integration/operations/u32_ops/arithmetic_ops.rs b/miden/tests/integration/operations/u32_ops/arithmetic_ops.rs index a7b3bec551..bbafd8bdfd 100644 --- a/miden/tests/integration/operations/u32_ops/arithmetic_ops.rs +++ b/miden/tests/integration/operations/u32_ops/arithmetic_ops.rs @@ -1,97 +1,9 @@ -use super::{test_param_out_of_bounds, test_unchecked_execution}; +use super::test_unchecked_execution; use test_utils::{build_op_test, proptest::prelude::*, rand::rand_value, TestError, U32_BOUND}; // U32 OPERATIONS TESTS - MANUAL - ARITHMETIC OPERATIONS // ================================================================================================ -#[test] -fn u32checked_add() { - let asm_op = "u32checked_add"; - - // --- simple case ---------------------------------------------------------------------------- - let test = build_op_test!(asm_op, &[1, 2]); - test.expect_stack(&[3]); - - // --- random values -------------------------------------------------------------------------- - // test using u16 values to ensure there's no overflow so the result is valid. - let a = rand_value::() as u16; - let b = rand_value::() as u16; - let expected = a as u64 + b as u64; - - let test = build_op_test!(asm_op, &[a as u64, b as u64]); - test.expect_stack(&[expected]); - - // --- test that the rest of the stack isn't affected ----------------------------------------- - let c = rand_value::(); - let test = build_op_test!(asm_op, &[c, a as u64, b as u64]); - test.expect_stack(&[expected, c]); -} - -#[test] -fn u32checked_add_fail() { - let asm_op = "u32checked_add"; - - // should fail if a >= 2^32 - let test = build_op_test!(asm_op, &[U32_BOUND, 0]); - test.expect_error(TestError::ExecutionError("NotU32Value")); - - // should fail if b >= 2^32 - let test = build_op_test!(asm_op, &[0, U32_BOUND]); - test.expect_error(TestError::ExecutionError("NotU32Value")); - - // should fail if a + b >= 2^32 - let a = u32::MAX; - let b = 1_u64; - let test = build_op_test!(asm_op, &[a as u64, b]); - test.expect_error(TestError::ExecutionError("FailedAssertion")); -} - -#[test] -fn u32checked_add_b() { - let build_asm_op = |param: u16| format!("u32checked_add.{param}"); - - // --- simple cases ---------------------------------------------------------------------------- - let test = build_op_test!(build_asm_op(2).as_str(), &[1]); - test.expect_stack(&[3]); - - let test = build_op_test!(build_asm_op(0).as_str(), &[1]); - test.expect_stack(&[1]); - - // --- random values -------------------------------------------------------------------------- - // test using u16 values to ensure there's no overflow so the result is valid. - let a = rand_value::() as u16; - let b = rand_value::() as u16; - let expected = a as u64 + b as u64; - - let test = build_op_test!(build_asm_op(b).as_str(), &[a as u64]); - test.expect_stack(&[expected]); - - // --- test that the rest of the stack isn't affected ----------------------------------------- - let c = rand_value::(); - - let test = build_op_test!(build_asm_op(b).as_str(), &[c, a as u64]); - test.expect_stack(&[expected, c]); -} - -#[test] -fn u32checked_add_b_fail() { - let build_asm_op = |param: u64| format!("u32checked_add.{param}"); - - // should fail during execution if a >= 2^32. - let test = build_op_test!(build_asm_op(0).as_str(), &[U32_BOUND]); - test.expect_error(TestError::ExecutionError("NotU32Value")); - - // should fail during compilation if b >= 2^32. - test_param_out_of_bounds("u32checked_add", U32_BOUND); - - // should fail if a + b >= 2^32. - let a = u32::MAX; - let b = 1_u64; - - let test = build_op_test!(build_asm_op(b).as_str(), &[a as u64]); - test.expect_error(TestError::ExecutionError("FailedAssertion")); -} - #[test] fn u32wrapping_add() { let asm_op = "u32wrapping_add"; @@ -269,99 +181,6 @@ fn u32overflowing_add3() { assert!(test.execute().is_ok()); } -#[test] -fn u32checked_sub() { - let asm_op = "u32checked_sub"; - - // --- simple cases --------------------------------------------------------------------------- - let test = build_op_test!(asm_op, &[1, 1]); - test.expect_stack(&[0]); - - let test = build_op_test!(asm_op, &[2, 1]); - test.expect_stack(&[1]); - - // --- random u32 values ---------------------------------------------------------------------- - let val1 = rand_value::(); - let val2 = rand_value::(); - // assign the larger value to a and the smaller value to b. - let (a, b) = if val1 >= val2 { (val1, val2) } else { (val2, val1) }; - let expected = a - b; - - let test = build_op_test!(asm_op, &[a as u64, b as u64]); - test.expect_stack(&[expected as u64]); - - // --- test that the rest of the stack isn't affected ----------------------------------------- - let c = rand_value::(); - - let test = build_op_test!(asm_op, &[c, a as u64, b as u64]); - test.expect_stack(&[expected as u64, c]); -} - -#[test] -fn u32checked_sub_fail() { - let asm_op = "u32checked_sub"; - - // should fail if a >= 2^32. - let test = build_op_test!(asm_op, &[U32_BOUND, 0]); - test.expect_error(TestError::ExecutionError("NotU32Value")); - - // should fail if b >= 2^32. - let test = build_op_test!(asm_op, &[0, U32_BOUND]); - test.expect_error(TestError::ExecutionError("NotU32Value")); - - // should fail if a < b. - let a = 1_u64; - let b = 2_u64; - let test = build_op_test!(asm_op, &[a, b]); - test.expect_error(TestError::ExecutionError("FailedAssertion")); -} - -#[test] -fn u32checked_sub_b() { - let build_asm_op = |param: u32| format!("u32checked_sub.{param}"); - - // --- simple cases --------------------------------------------------------------------------- - let test = build_op_test!(build_asm_op(1).as_str(), &[2]); - test.expect_stack(&[1]); - - let test = build_op_test!(build_asm_op(1).as_str(), &[1]); - test.expect_stack(&[0]); - - // --- random u32 values ---------------------------------------------------------------------- - let val1 = rand_value::(); - let val2 = rand_value::(); - // assign the larger value to a and the smaller value to b. - let (a, b) = if val1 >= val2 { (val1, val2) } else { (val2, val1) }; - let expected = a - b; - - let test = build_op_test!(build_asm_op(b).as_str(), &[a as u64]); - test.expect_stack(&[expected as u64]); - - // --- test that the rest of the stack isn't affected ----------------------------------------- - let c = rand_value::(); - - let test = build_op_test!(build_asm_op(b).as_str(), &[c, a as u64]); - test.expect_stack(&[expected as u64, c]); -} - -#[test] -fn u32checked_sub_b_fail() { - let build_asm_op = |param: u64| format!("u32checked_sub.{param}"); - - // should fail during execution if a >= 2^32. - let test = build_op_test!(build_asm_op(0).as_str(), &[U32_BOUND]); - test.expect_error(TestError::ExecutionError("NotU32Value")); - - // should fail during compilation if b >= 2^32. - test_param_out_of_bounds("u32checked_sub", U32_BOUND); - - // should fail if a < b. - let a = 1_u64; - let b = 2_u64; - let test = build_op_test!(build_asm_op(b).as_str(), &[a]); - test.expect_error(TestError::ExecutionError("FailedAssertion")); -} - #[test] fn u32wrapping_sub() { let asm_op = "u32wrapping_sub"; @@ -465,101 +284,6 @@ fn u32overflowing_sub() { test_unchecked_execution(asm_op, 2); } -#[test] -fn u32checked_mul() { - let asm_op = "u32checked_mul"; - - // --- simple cases --------------------------------------------------------------------------- - let test = build_op_test!(asm_op, &[1, 0]); - test.expect_stack(&[0]); - - let test = build_op_test!(asm_op, &[5, 1]); - test.expect_stack(&[5]); - - let test = build_op_test!(asm_op, &[2, 5]); - test.expect_stack(&[10]); - - // --- random values -------------------------------------------------------------------------- - // test using u16 values to ensure there's no overflow so the result is valid. - let a = rand_value::(); - let b = rand_value::(); - - let expected: u64 = a as u64 * b as u64; - let test = build_op_test!(asm_op, &[a as u64, b as u64]); - test.expect_stack(&[expected]); - - // --- test that the rest of the stack isn't affected ----------------------------------------- - let c = rand_value::(); - let test = build_op_test!(asm_op, &[c, a as u64, b as u64]); - test.expect_stack(&[expected, c]); -} - -#[test] -fn u32checked_mul_fail() { - let asm_op = "u32checked_mul"; - - // should fail if a >= 2^32. - let test = build_op_test!(asm_op, &[U32_BOUND, 0]); - test.expect_error(TestError::ExecutionError("NotU32Value")); - - // should fail if b >= 2^32. - let test = build_op_test!(asm_op, &[0, U32_BOUND]); - test.expect_error(TestError::ExecutionError("NotU32Value")); - - // should fail if a * b >= 2^32. - let a = u32::MAX as u64; - let b = 2_u64; - let test = build_op_test!(asm_op, &[a, b]); - test.expect_error(TestError::ExecutionError("FailedAssertion")); -} - -#[test] -fn u32checked_mul_b() { - let build_asm_op = |param: u16| format!("u32checked_mul.{param}"); - - // --- simple cases --------------------------------------------------------------------------- - let test = build_op_test!(build_asm_op(0).as_str(), &[1]); - test.expect_stack(&[0]); - - let test = build_op_test!(build_asm_op(1).as_str(), &[5]); - test.expect_stack(&[5]); - - let test = build_op_test!(build_asm_op(5).as_str(), &[2]); - test.expect_stack(&[10]); - - // --- random values -------------------------------------------------------------------------- - // test using u16 values to ensure there's no overflow so the result is valid. - let a = rand_value::(); - let b = rand_value::(); - - let expected: u64 = a as u64 * b as u64; - let test = build_op_test!(build_asm_op(b).as_str(), &[a as u64]); - test.expect_stack(&[expected]); - - // --- test that the rest of the stack isn't affected ----------------------------------------- - let c = rand_value::(); - let test = build_op_test!(build_asm_op(5).as_str(), &[c, 10]); - test.expect_stack(&[50, c]); -} - -#[test] -fn u32checked_mul_b_fail() { - let build_asm_op = |param: u64| format!("u32checked_mul.{param}"); - - // should fail during execution if a >= 2^32. - let test = build_op_test!(build_asm_op(0).as_str(), &[U32_BOUND]); - test.expect_error(TestError::ExecutionError("NotU32Value")); - - // should fail during compilation if b >= 2^32. - test_param_out_of_bounds("u32checked_mul", U32_BOUND); - - // should fail if a * b >= 2^32. - let a = u32::MAX as u64; - let b = u32::MAX as u64; - let test = build_op_test!(build_asm_op(b).as_str(), &[a]); - test.expect_error(TestError::ExecutionError("FailedAssertion")); -} - #[test] fn u32wrapping_mul() { let asm_op = "u32wrapping_mul"; @@ -703,45 +427,20 @@ fn u32overflowing_madd() { } #[test] -fn u32checked_div() { - let asm_op = "u32checked_div"; - - test_div(asm_op); -} - -#[test] -fn u32checked_div_fail() { - let asm_op = "u32checked_div"; - - // should fail if a >= 2^32 - let test = build_op_test!(asm_op, &[U32_BOUND, 1]); - test.expect_error(TestError::ExecutionError("NotU32Value")); - - // should fail if b >= 2^32 - let test = build_op_test!(asm_op, &[1, U32_BOUND]); - test.expect_error(TestError::ExecutionError("NotU32Value")); - - // should fail if b == 0 - let test = build_op_test!(asm_op, &[1, 0]); - test.expect_error(TestError::ExecutionError("DivideByZero")); -} - -#[test] -fn u32checked_div_b() { - let build_asm_op = |param: u32| format!("u32checked_div.{param}"); - +fn u32div() { // --- simple cases --------------------------------------------------------------------------- - let test = build_op_test!(build_asm_op(1).as_str(), &[0]); + let test = build_op_test!("u32div", &[0, 1]); test.expect_stack(&[0]); - // division with no remainder - let test = build_op_test!(build_asm_op(1).as_str(), &[2]); + let test = build_op_test!("u32div", &[2, 1]); test.expect_stack(&[2]); - // division with remainder - let test = build_op_test!(build_asm_op(2).as_str(), &[1]); + let test = build_op_test!("u32div", &[1, 2]); test.expect_stack(&[0]); + let test = build_op_test!("u32div", &[3, 2]); + test.expect_stack(&[1]); + // --- random u32 values ---------------------------------------------------------------------- let a = rand_value::(); let mut b = rand_value::(); @@ -749,47 +448,22 @@ fn u32checked_div_b() { // ensure we're not using a failure case. b += 1; } - let expected = (a / b) as u64; - - let test = build_op_test!(build_asm_op(b).as_str(), &[a as u64]); - test.expect_stack(&[expected]); + let quot = (a / b) as u64; + let test = build_op_test!("u32div", &[a as u64, b as u64]); + test.expect_stack(&[quot]); // --- test that the rest of the stack isn't affected ----------------------------------------- - let c = rand_value::(); - let test = build_op_test!(build_asm_op(b).as_str(), &[c, a as u64]); - test.expect_stack(&[expected, c]); -} - -#[test] -fn u32checked_div_b_fail() { - let build_asm_op = |param: u64| format!("u32checked_div.{param}"); - - // should fail during execution if a >= 2^32. - let test = build_op_test!(build_asm_op(1).as_str(), &[U32_BOUND]); - test.expect_error(TestError::ExecutionError("NotU32Value")); - - // should fail during compilation if b >= 2^32. - test_param_out_of_bounds("u32checked_div", U32_BOUND); - - // should fail during compilation if b = 0. - let test = build_op_test!(build_asm_op(0).as_str()); - test.expect_error(TestError::AssemblyError("division by zero")); -} - -#[test] -fn u32unchecked_div() { - let asm_op = "u32unchecked_div"; - - // should push d = (a * b) / 2^32 onto the stack. - test_div(asm_op); + let e = rand_value::(); + let test = build_op_test!("u32div", &[e, a as u64, b as u64]); + test.expect_stack(&[quot, e]); // should not fail when inputs are out of bounds. - test_unchecked_execution(asm_op, 2); + test_unchecked_execution("u32div", 2); } #[test] -fn u32unchecked_div_fail() { - let asm_op = "u32unchecked_div"; +fn u32div_fail() { + let asm_op = "u32div"; // should fail if b == 0. let test = build_op_test!(asm_op, &[1, 0]); @@ -797,41 +471,15 @@ fn u32unchecked_div_fail() { } #[test] -fn u32checked_mod() { - let asm_op = "u32checked_mod"; - - test_mod(asm_op); -} - -#[test] -fn u32checked_mod_fail() { - let asm_op = "u32checked_mod"; - - // should fail if a >= 2^32 - let test = build_op_test!(asm_op, &[U32_BOUND, 1]); - test.expect_error(TestError::ExecutionError("NotU32Value")); - - // should fail if b >= 2^32 - let test = build_op_test!(asm_op, &[1, U32_BOUND]); - test.expect_error(TestError::ExecutionError("NotU32Value")); - - // should fail if b == 0 - let test = build_op_test!(asm_op, &[1, 0]); - test.expect_error(TestError::ExecutionError("DivideByZero")); -} - -#[test] -fn u32checked_mod_b() { - let build_asm_op = |param: u32| format!("u32checked_mod.{param}"); - +fn u32mod() { // --- simple cases --------------------------------------------------------------------------- - let test = build_op_test!(build_asm_op(5).as_str(), &[10]); + let test = build_op_test!("u32mod", &[10, 5]); test.expect_stack(&[0]); - let test = build_op_test!(build_asm_op(5).as_str(), &[11]); + let test = build_op_test!("u32mod", &[11, 5]); test.expect_stack(&[1]); - let test = build_op_test!(build_asm_op(11).as_str(), &[5]); + let test = build_op_test!("u32mod", &[5, 11]); test.expect_stack(&[5]); // --- random u32 values ---------------------------------------------------------------------- @@ -842,70 +490,21 @@ fn u32checked_mod_b() { b += 1; } let expected = a % b; - - let test = build_op_test!(build_asm_op(b).as_str(), &[a as u64]); + let test = build_op_test!("u32mod", &[a as u64, b as u64]); test.expect_stack(&[expected as u64]); // --- test that the rest of the stack isn't affected ----------------------------------------- let c = rand_value::(); - - let test = build_op_test!(build_asm_op(b).as_str(), &[c, a as u64]); + let test = build_op_test!("u32mod", &[c, a as u64, b as u64]); test.expect_stack(&[expected as u64, c]); -} - -#[test] -fn u32checked_mod_b_fail() { - let build_asm_op = |param: u64| format!("u32checked_mod.{param}"); - - // should fail during execution if a >= 2^32. - let test = build_op_test!(build_asm_op(1).as_str(), &[U32_BOUND]); - test.expect_error(TestError::ExecutionError("NotU32Value")); - - // should fail during compilation if b >= 2^32. - test_param_out_of_bounds("u32checked_mod", U32_BOUND); - - // should fail during compilation if b = 0. - let test = build_op_test!(build_asm_op(0).as_str()); - test.expect_error(TestError::AssemblyError("division by zero")); -} - -#[test] -fn u32unchecked_mod() { - let asm_op = "u32unchecked_mod"; - - test_mod(asm_op); // should not fail when inputs are out of bounds. - test_unchecked_execution(asm_op, 2); + test_unchecked_execution("u32mod", 2); } #[test] -fn u32unchecked_mod_fail() { - let asm_op = "u32unchecked_mod"; - - // should fail if b == 0 - let test = build_op_test!(asm_op, &[1, 0]); - test.expect_error(TestError::ExecutionError("DivideByZero")); -} - -#[test] -fn u32checked_divmod() { - let asm_op = "u32checked_divmod"; - - test_divmod(asm_op); -} - -#[test] -fn u32checked_divmod_fail() { - let asm_op = "u32checked_divmod"; - - // should fail if a >= 2^32 - let test = build_op_test!(asm_op, &[U32_BOUND, 1]); - test.expect_error(TestError::ExecutionError("NotU32Value")); - - // should fail if b >= 2^32 - let test = build_op_test!(asm_op, &[1, U32_BOUND]); - test.expect_error(TestError::ExecutionError("NotU32Value")); +fn u32mod_fail() { + let asm_op = "u32mod"; // should fail if b == 0 let test = build_op_test!(asm_op, &[1, 0]); @@ -913,21 +512,19 @@ fn u32checked_divmod_fail() { } #[test] -fn u32checked_divmod_b() { - let build_asm_op = |param: u32| format!("u32checked_divmod.{param}"); - +fn u32divmod() { // --- simple cases --------------------------------------------------------------------------- - let test = build_op_test!(build_asm_op(1).as_str(), &[0]); + let test = build_op_test!("u32divmod", &[0, 1]); test.expect_stack(&[0, 0]); // division with no remainder - let test = build_op_test!(build_asm_op(1).as_str(), &[2]); + let test = build_op_test!("u32divmod", &[2, 1]); test.expect_stack(&[0, 2]); // division with remainder - let test = build_op_test!(build_asm_op(2).as_str(), &[1]); + let test = build_op_test!("u32divmod", &[1, 2]); test.expect_stack(&[1, 0]); - let test = build_op_test!(build_asm_op(2).as_str(), &[3]); + let test = build_op_test!("u32divmod", &[3, 2]); test.expect_stack(&[1, 1]); // --- random u32 values ---------------------------------------------------------------------- @@ -939,44 +536,21 @@ fn u32checked_divmod_b() { } let quot = (a / b) as u64; let rem = (a % b) as u64; - let test = build_op_test!(build_asm_op(b).as_str(), &[a as u64]); + let test = build_op_test!("u32divmod", &[a as u64, b as u64]); test.expect_stack(&[rem, quot]); // --- test that the rest of the stack isn't affected ----------------------------------------- let e = rand_value::(); - let test = build_op_test!(build_asm_op(b).as_str(), &[e, a as u64]); + let test = build_op_test!("u32divmod", &[e, a as u64, b as u64]); test.expect_stack(&[rem, quot, e]); -} - -#[test] -fn u32checked_divmod_b_fail() { - let build_asm_op = |param: u64| format!("u32checked_divmod.{param}"); - - // should fail during execution if a >= 2^32. - let test = build_op_test!(build_asm_op(1).as_str(), &[U32_BOUND]); - test.expect_error(TestError::ExecutionError("NotU32Value")); - - // should fail during compilation if b >= 2^32. - test_param_out_of_bounds("u32checked_divmod", U32_BOUND); - - // should fail during compilation if b = 0. - let test = build_op_test!(build_asm_op(0).as_str()); - test.expect_error(TestError::AssemblyError("division by zero")); -} - -#[test] -fn u32unchecked_divmod() { - let asm_op = "u32unchecked_divmod"; - - test_divmod(asm_op); // should not fail when inputs are out of bounds. - test_unchecked_execution(asm_op, 2); + test_unchecked_execution("u32divmod", 2); } #[test] -fn u32unchecked_divmod_fail() { - let asm_op = "u32unchecked_divmod"; +fn u32divmod_fail() { + let asm_op = "u32divmod"; // should fail if b == 0. let test = build_op_test!(asm_op, &[1, 0]); @@ -986,22 +560,6 @@ fn u32unchecked_divmod_fail() { // U32 OPERATIONS TESTS - RANDOMIZED - ARITHMETIC OPERATIONS // ================================================================================================ proptest! { - #[test] - fn u32checked_add_proptest(a in any::(), b in any::()) { - let asm_op = "u32checked_add"; - - let expected = a as u64 + b as u64; - - // b provided via the stack. - let test = build_op_test!(asm_op, &[a as u64, b as u64]); - test.prop_expect_stack(&[expected])?; - - // b provided as a parameter. - let asm_op = format!("{asm_op}.{b}"); - let test = build_op_test!(&asm_op, &[a as u64]); - test.prop_expect_stack(&[expected])?; - } - #[test] fn u32unchecked_add_proptest(a in any::(), b in any::()) { let wrapping_asm_op = "u32wrapping_add"; @@ -1029,29 +587,6 @@ proptest! { test.prop_expect_stack(&[hi, lo])?; } - #[test] - fn u32checked_sub_proptest(val1 in any::(), val2 in any::()) { - let asm_op = "u32checked_sub"; - - // assign the larger value to a and the smaller value to b so all parameters are valid. - let (a, b) = if val1 >= val2 { - (val1, val2) - } else { - (val2, val1) - }; - - let expected = a - b; - // b provided via the stack. - let test = build_op_test!(asm_op, &[a as u64, b as u64]); - test.prop_expect_stack(&[expected as u64])?; - - // b provided as a parameter. - let asm_op = format!("{asm_op}.{b}"); - let test = build_op_test!(&asm_op, &[a as u64]); - test.prop_expect_stack(&[expected as u64])?; - - } - #[test] fn u32unchecked_sub_proptest(a in any::(), b in any::()) { let wrapping_asm_op = "u32wrapping_sub"; @@ -1068,22 +603,6 @@ proptest! { test.prop_expect_stack(&[d, c as u64])?; } - #[test] - fn u32checked_mul_proptest(a in any::(), b in any::()) { - let asm_op = "u32checked_mul"; - - let expected = a as u64 * b as u64; - - // b provided via the stack - let test = build_op_test!(asm_op, &[a as u64, b as u64]); - test.prop_expect_stack(&[expected])?; - - // b provided as a parameter - let asm_op = format!("{asm_op}.{b}"); - let test = build_op_test!(&asm_op, &[a as u64]); - test.prop_expect_stack(&[expected])?; - } - #[test] fn u32unchecked_mul_proptest(a in any::(), b in any::()) { let wrapping_asm_op = "u32wrapping_mul"; @@ -1103,38 +622,16 @@ proptest! { test.prop_expect_stack(&[d, c as u64])?; } - #[test] - fn u32overflowing_madd_proptest(a in any::(), b in any::(), c in any::()) { - let asm_op = "u32overflowing_madd"; - - let madd = a as u64 * b as u64 + c as u64; - let d = madd % U32_BOUND; - let e = madd / U32_BOUND; - - let test = build_op_test!(asm_op, &[c as u64, a as u64, b as u64]); - test.prop_expect_stack(&[e, d])?; - } - #[test] fn u32div_proptest(a in any::(), b in 1..u32::MAX) { - let asm_op = "u32checked_div"; - + let asm_op = "u32div"; let expected = (a / b) as u64; // b provided via the stack. - let test = build_op_test!(asm_op, &[a as u64, b as u64]); - test.prop_expect_stack(&[expected])?; - - // b provided as a parameter. - let asm_op = format!("{asm_op}.{b}"); - let test = build_op_test!(&asm_op, &[a as u64]); - test.prop_expect_stack(&[expected])?; - - // unchecked version should produce the same result for valid values. - let asm_op = "u32unchecked_div"; let test = build_op_test!(&asm_op, &[a as u64, b as u64]); test.prop_expect_stack(&[expected])?; + // b provided as a parameter. let asm_op = format!("{asm_op}.{b}"); let test = build_op_test!(&asm_op, &[a as u64]); test.prop_expect_stack(&[expected])?; @@ -1142,157 +639,45 @@ proptest! { #[test] fn u32mod_proptest(a in any::(), b in 1..u32::MAX) { - let base_op = "u32checked_mod"; - - let expected = a % b; - - // b provided via the stack - let test = build_op_test!(base_op, &[a as u64, b as u64]); - test.prop_expect_stack(&[expected as u64])?; + let asm_op = "u32mod"; + let expected = (a % b) as u64; - // b provided as a parameter - let asm_op = format!("{base_op}.{b}"); - let test = build_op_test!(&asm_op, &[a as u64]); - test.prop_expect_stack(&[expected as u64])?; - - // unchecked version should produce the same result for valid values. - let asm_op = "u32unchecked_mod"; + // b provided via the stack. let test = build_op_test!(&asm_op, &[a as u64, b as u64]); - test.prop_expect_stack(&[expected as u64])?; + test.prop_expect_stack(&[expected])?; + // b provided as a parameter. let asm_op = format!("{asm_op}.{b}"); let test = build_op_test!(&asm_op, &[a as u64]); - test.prop_expect_stack(&[expected as u64])?; + test.prop_expect_stack(&[expected])?; } #[test] fn u32divmod_proptest(a in any::(), b in 1..u32::MAX) { - let asm_op = "u32checked_divmod"; + let asm_op = "u32divmod"; let quot = (a / b) as u64; let rem = (a % b) as u64; // b provided via the stack. - let test = build_op_test!(asm_op, &[a as u64, b as u64]); - test.prop_expect_stack(&[rem, quot])?; - - // b provided as a parameter. - let asm_op = format!("{asm_op}.{b}"); - let test = build_op_test!(&asm_op, &[a as u64]); - test.prop_expect_stack(&[rem, quot])?; - - // unchecked version should produce the same result for valid values. - let asm_op = "u32unchecked_divmod"; let test = build_op_test!(&asm_op, &[a as u64, b as u64]); test.prop_expect_stack(&[rem, quot])?; + // b provided as a parameter. let asm_op = format!("{asm_op}.{b}"); let test = build_op_test!(&asm_op, &[a as u64]); test.prop_expect_stack(&[rem, quot])?; } -} - -// HELPER FUNCTIONS -// ================================================================================================ - -/// This helper function tests division without remainder for two u32 inputs for a number of simple -/// cases as well as for random values. It checks that the floor of a / b is pushed to the -/// stack. Finally, it ensures that the rest of the stack was unaffected. -fn test_div(asm_op: &str) { - // --- simple cases --------------------------------------------------------------------------- - let test = build_op_test!(asm_op, &[0, 1]); - test.expect_stack(&[0]); - - let test = build_op_test!(asm_op, &[2, 1]); - test.expect_stack(&[2]); - - let test = build_op_test!(asm_op, &[1, 2]); - test.expect_stack(&[0]); - - let test = build_op_test!(asm_op, &[3, 2]); - test.expect_stack(&[1]); - - // --- random u32 values ---------------------------------------------------------------------- - let a = rand_value::(); - let mut b = rand_value::(); - if b == 0 { - // ensure we're not using a failure case. - b += 1; - } - let quot = (a / b) as u64; - let test = build_op_test!(asm_op, &[a as u64, b as u64]); - test.expect_stack(&[quot]); - // --- test that the rest of the stack isn't affected ----------------------------------------- - let e = rand_value::(); - let test = build_op_test!(asm_op, &[e, a as u64, b as u64]); - test.expect_stack(&[quot, e]); -} - -/// This helper function tests the modulus operation for two u32 inputs for a number of simple -/// cases as well as for random values. It checks that a % b is pushed to the stack. Finally, it -/// ensures that the rest of the stack was unaffected. -fn test_mod(asm_op: &str) { - // --- simple cases --------------------------------------------------------------------------- - let test = build_op_test!(asm_op, &[10, 5]); - test.expect_stack(&[0]); - - let test = build_op_test!(asm_op, &[11, 5]); - test.expect_stack(&[1]); - - let test = build_op_test!(asm_op, &[5, 11]); - test.expect_stack(&[5]); - - // --- random u32 values ---------------------------------------------------------------------- - let a = rand_value::(); - let mut b = rand_value::(); - if b == 0 { - // ensure we're not using a failure case. - b += 1; - } - let expected = a % b; - let test = build_op_test!(asm_op, &[a as u64, b as u64]); - test.expect_stack(&[expected as u64]); - - // --- test that the rest of the stack isn't affected ----------------------------------------- - let c = rand_value::(); - let test = build_op_test!(asm_op, &[c, a as u64, b as u64]); - test.expect_stack(&[expected as u64, c]); -} - -/// This helper function tests division with remainder for two u32 inputs for a number of simple -/// cases as well as for random values. It checks that the floor of a / b is pushed to the -/// stack, along with the remainder a % b. Finally, it ensures that the rest of the stack was -/// unaffected. -fn test_divmod(asm_op: &str) { - // --- simple cases --------------------------------------------------------------------------- - let test = build_op_test!(asm_op, &[0, 1]); - test.expect_stack(&[0, 0]); - - // division with no remainder - let test = build_op_test!(asm_op, &[2, 1]); - test.expect_stack(&[0, 2]); + #[test] + fn u32overflowing_madd_proptest(a in any::(), b in any::(), c in any::()) { + let asm_op = "u32overflowing_madd"; - // division with remainder - let test = build_op_test!(asm_op, &[1, 2]); - test.expect_stack(&[1, 0]); - let test = build_op_test!(asm_op, &[3, 2]); - test.expect_stack(&[1, 1]); + let madd = a as u64 * b as u64 + c as u64; + let d = madd % U32_BOUND; + let e = madd / U32_BOUND; - // --- random u32 values ---------------------------------------------------------------------- - let a = rand_value::(); - let mut b = rand_value::(); - if b == 0 { - // ensure we're not using a failure case. - b += 1; + let test = build_op_test!(asm_op, &[c as u64, a as u64, b as u64]); + test.prop_expect_stack(&[e, d])?; } - let quot = (a / b) as u64; - let rem = (a % b) as u64; - let test = build_op_test!(asm_op, &[a as u64, b as u64]); - test.expect_stack(&[rem, quot]); - - // --- test that the rest of the stack isn't affected ----------------------------------------- - let e = rand_value::(); - let test = build_op_test!(asm_op, &[e, a as u64, b as u64]); - test.expect_stack(&[rem, quot, e]); } diff --git a/miden/tests/integration/operations/u32_ops/bitwise_ops.rs b/miden/tests/integration/operations/u32_ops/bitwise_ops.rs index af9fd1a3a9..e75be1047b 100644 --- a/miden/tests/integration/operations/u32_ops/bitwise_ops.rs +++ b/miden/tests/integration/operations/u32_ops/bitwise_ops.rs @@ -1,12 +1,12 @@ -use super::{test_input_out_of_bounds, test_param_out_of_bounds}; +use super::test_input_out_of_bounds; use test_utils::{build_op_test, proptest::prelude::*, rand::rand_value, TestError, U32_BOUND}; // U32 OPERATIONS TESTS - MANUAL - BITWISE OPERATIONS // ================================================================================================ #[test] -fn u32checked_and() { - let asm_op = "u32checked_and"; +fn u32and() { + let asm_op = "u32and"; // --- simple cases --------------------------------------------------------------------------- let test = build_op_test!(asm_op, &[1, 1]); @@ -37,8 +37,8 @@ fn u32checked_and() { } #[test] -fn u32checked_and_fail() { - let asm_op = "u32checked_and"; +fn u32and_fail() { + let asm_op = "u32and"; let test = build_op_test!(asm_op, &[U32_BOUND, 0]); test.expect_error(TestError::ExecutionError("NotU32Value")); @@ -48,8 +48,8 @@ fn u32checked_and_fail() { } #[test] -fn u32checked_or() { - let asm_op = "u32checked_or"; +fn u32or() { + let asm_op = "u32or"; // --- simple cases --------------------------------------------------------------------------- let test = build_op_test!(asm_op, &[1, 1]); @@ -80,8 +80,8 @@ fn u32checked_or() { } #[test] -fn u32checked_or_fail() { - let asm_op = "u32checked_or"; +fn u32or_fail() { + let asm_op = "u32or"; let test = build_op_test!(asm_op, &[U32_BOUND, 0]); test.expect_error(TestError::ExecutionError("NotU32Value")); @@ -91,8 +91,8 @@ fn u32checked_or_fail() { } #[test] -fn u32checked_xor() { - let asm_op = "u32checked_xor"; +fn u32xor() { + let asm_op = "u32xor"; // --- simple cases --------------------------------------------------------------------------- let test = build_op_test!(asm_op, &[1, 1]); @@ -122,8 +122,8 @@ fn u32checked_xor() { } #[test] -fn u32checked_xor_fail() { - let asm_op = "u32checked_xor"; +fn u32xor_fail() { + let asm_op = "u32xor"; let test = build_op_test!(asm_op, &[U32_BOUND, 0]); test.expect_error(TestError::ExecutionError("NotU32Value")); @@ -133,8 +133,8 @@ fn u32checked_xor_fail() { } #[test] -fn u32checked_not() { - let asm_op = "u32checked_not"; +fn u32not() { + let asm_op = "u32not"; // --- simple cases --------------------------------------------------------------------------- let test = build_op_test!(asm_op, &[U32_BOUND - 1]); @@ -157,104 +157,15 @@ fn u32checked_not() { } #[test] -fn u32checked_not_fail() { - let asm_op = "u32checked_not"; +fn u32not_fail() { + let asm_op = "u32not"; test_input_out_of_bounds(asm_op); } #[test] -fn u32checked_shl() { +fn u32shl() { // left shift: pops a from the stack and pushes (a * 2^b) mod 2^32 for a provided value b - let asm_op = "u32checked_shl"; - - // --- test simple case ----------------------------------------------------------------------- - let a = 1_u32; - let b = 1_u32; - let test = build_op_test!(asm_op, &[5, a as u64, b as u64]); - test.expect_stack(&[2, 5]); - - // --- test max values of a and b ------------------------------------------------------------- - let a = (U32_BOUND - 1) as u32; - let b = 31; - - let test = build_op_test!(asm_op, &[a as u64, b as u64]); - test.expect_stack(&[a.wrapping_shl(b) as u64]); - - // --- test b = 0 ----------------------------------------------------------------------------- - let a = rand_value::(); - let b = 0; - - let test = build_op_test!(asm_op, &[a as u64, b as u64]); - test.expect_stack(&[a.wrapping_shl(b) as u64]); - - // --- test random values --------------------------------------------------------------------- - let a = rand_value::(); - let b = rand_value::() % 32; - - let test = build_op_test!(asm_op, &[a as u64, b as u64]); - test.expect_stack(&[a.wrapping_shl(b) as u64]); -} - -#[test] -fn u32checked_shl_fail() { - let asm_op = "u32checked_shl"; - - // should fail if a >= 2^32 - let test = build_op_test!(asm_op, &[U32_BOUND, 1]); - test.expect_error(TestError::ExecutionError("NotU32Value")); - - // should fail if b >= 32 - let test = build_op_test!(asm_op, &[1, 32]); - // if b >= 32, 2^b >= 2^32 or not a u32 - test.expect_error(TestError::ExecutionError("NotU32Value")); -} - -#[test] -fn u32checked_shl_b() { - // left shift: pops a from the stack and pushes (a * 2^b) mod 2^32 for a provided value b - let op_base = "u32checked_shl"; - let get_asm_op = |b: u32| format!("{op_base}.{b}"); - - // --- test simple case ----------------------------------------------------------------------- - let a = 1_u32; - let b = 1_u32; - let test = build_op_test!(get_asm_op(b).as_str(), &[5, a as u64]); - test.expect_stack(&[2, 5]); - - // --- test max values of a and b ------------------------------------------------------------- - let a = (U32_BOUND - 1) as u32; - let b = 31; - - let test = build_op_test!(get_asm_op(b).as_str(), &[a as u64]); - test.expect_stack(&[a.wrapping_shl(b) as u64]); - - // --- test b = 0 ----------------------------------------------------------------------------- - let a = rand_value::(); - let b = 0; - - let test = build_op_test!(get_asm_op(b).as_str(), &[a as u64]); - test.expect_stack(&[a.wrapping_shl(b) as u64]); - - // --- test random values --------------------------------------------------------------------- - let a = rand_value::(); - let b = rand_value::() % 32; - - let test = build_op_test!(get_asm_op(b).as_str(), &[a as u64]); - test.expect_stack(&[a.wrapping_shl(b) as u64]); -} - -#[test] -fn u32checked_shl_b_fail() { - let op_base = "u32checked_shl"; - - test_input_out_of_bounds(format!("{}.{}", op_base, 1).as_str()); - test_param_out_of_bounds(op_base, 32); -} - -#[test] -fn u32unchecked_shl() { - // left shift: pops a from the stack and pushes (a * 2^b) mod 2^32 for a provided value b - let asm_op = "u32unchecked_shl"; + let asm_op = "u32shl"; // --- test simple case ----------------------------------------------------------------------- let a = 1_u32; @@ -289,9 +200,9 @@ fn u32unchecked_shl() { } #[test] -fn u32unchecked_shl_b() { +fn u32shl_b() { // left shift: pops a from the stack and pushes (a * 2^b) mod 2^32 for a provided value b - let op_base = "u32unchecked_shl"; + let op_base = "u32shl"; let get_asm_op = |b: u32| format!("{op_base}.{b}"); // --- test simple case ----------------------------------------------------------------------- @@ -314,111 +225,23 @@ fn u32unchecked_shl_b() { let test = build_op_test!(get_asm_op(b).as_str(), &[a as u64]); test.expect_stack(&[a.wrapping_shl(b) as u64]); - // --- test random values --------------------------------------------------------------------- - let a = rand_value::(); - let b = rand_value::() % 32; + // // --- test random values --------------------------------------------------------------------- + // let a = rand_value::(); + // let b = rand_value::() % 32; - let test = build_op_test!(get_asm_op(b).as_str(), &[a as u64]); - test.expect_stack(&[a.wrapping_shl(b) as u64]); + // let test = build_op_test!(get_asm_op(b).as_str(), &[a as u64]); + // test.expect_stack(&[a.wrapping_shl(b) as u64]); - // --- test out of bounds input (should not fail) -------------------------------------------- - let b = 1; - let test = build_op_test!(get_asm_op(b).as_str(), &[U32_BOUND]); - assert!(test.execute().is_ok()); + // // --- test out of bounds input (should not fail) -------------------------------------------- + // let b = 1; + // let test = build_op_test!(get_asm_op(b).as_str(), &[U32_BOUND]); + // assert!(test.execute().is_ok()); } #[test] -fn u32checked_shr() { +fn u32shr() { // right shift: pops a from the stack and pushes a / 2^b for a provided value b - let asm_op = "u32checked_shr"; - - // --- test simple case ----------------------------------------------------------------------- - let a = 4_u32; - let b = 2_u32; - let test = build_op_test!(asm_op, &[5, a as u64, b as u64]); - test.expect_stack(&[1, 5]); - - // --- test max values of a and b ------------------------------------------------------------- - let a = (U32_BOUND - 1) as u32; - let b = 31; - - let test = build_op_test!(asm_op, &[a as u64, b as u64]); - test.expect_stack(&[a.wrapping_shr(b) as u64]); - - // --- test b = 0 --------------------------------------------------------------------------- - let a = rand_value::(); - let b = 0; - - let test = build_op_test!(asm_op, &[a as u64, b as u64]); - test.expect_stack(&[a.wrapping_shr(b) as u64]); - - // --- test random values --------------------------------------------------------------------- - let a = rand_value::(); - let b = rand_value::() % 32; - - let test = build_op_test!(asm_op, &[a as u64, b as u64]); - test.expect_stack(&[a.wrapping_shr(b) as u64]); -} - -#[test] -fn u32checked_shr_fail() { - let asm_op = "u32checked_shr"; - - // should fail if a >= 2^32 - let test = build_op_test!(asm_op, &[U32_BOUND, 1]); - test.expect_error(TestError::ExecutionError("NotU32Value")); - - // should fail if b >= 32 - let test = build_op_test!(asm_op, &[1, 32]); - test.expect_error(TestError::ExecutionError("NotU32Value")); -} - -#[test] -fn u32checked_shr_b() { - // right shift: pops a from the stack and pushes a / 2^b for a provided value b - let op_base = "u32checked_shr"; - let get_asm_op = |b: u32| format!("{op_base}.{b}"); - - // --- test simple case ----------------------------------------------------------------------- - let a = 4_u32; - let b = 2_u32; - let test = build_op_test!(get_asm_op(b).as_str(), &[5, a as u64]); - test.expect_stack(&[1, 5]); - - // --- test max values of a and b ------------------------------------------------------------- - let a = (U32_BOUND - 1) as u32; - let b = 31; - - let test = build_op_test!(get_asm_op(b).as_str(), &[a as u64]); - test.expect_stack(&[a.wrapping_shr(b) as u64]); - - // --- test b = 0 --------------------------------------------------------------------------- - let a = rand_value::(); - let b = 0; - - let test = build_op_test!(get_asm_op(b).as_str(), &[a as u64]); - test.expect_stack(&[a.wrapping_shr(b) as u64]); - - // --- test random values --------------------------------------------------------------------- - let a = rand_value::(); - let b = rand_value::() % 32; - - let test = build_op_test!(get_asm_op(b).as_str(), &[a as u64]); - test.expect_stack(&[a.wrapping_shr(b) as u64]); -} - -#[test] -fn u32checked_shr_b_fail() { - let op_base = "u32checked_shr"; - - test_input_out_of_bounds(format!("{}.{}", op_base, 1).as_str()); - test_param_out_of_bounds(op_base, 32); -} - -#[test] -fn u32unchecked_shr() { - // right shift: pops a from the stack and pushes a / 2^b for a provided value b - let asm_op = "u32unchecked_shr"; + let asm_op = "u32shr"; // --- test simple case ----------------------------------------------------------------------- let a = 4_u32; @@ -453,9 +276,9 @@ fn u32unchecked_shr() { } #[test] -fn u32unchecked_shr_b() { +fn u32shr_b() { // right shift: pops a from the stack and pushes a / 2^b for a provided value b - let op_base = "u32unchecked_shr"; + let op_base = "u32shr"; let get_asm_op = |b: u32| format!("{op_base}.{b}"); // --- test simple case ----------------------------------------------------------------------- @@ -492,106 +315,9 @@ fn u32unchecked_shr_b() { } #[test] -fn u32checked_rotl() { +fn u32rotl() { // Computes c by rotating a 32-bit representation of a to the left by b bits. - let asm_op = "u32checked_rotl"; - - // --- test simple case ----------------------------------------------------------------------- - let a = 1_u32; - let b = 1_u32; - let test = build_op_test!(asm_op, &[5, a as u64, b as u64]); - test.expect_stack(&[2, 5]); - - // --- test simple wraparound case with large a ----------------------------------------------- - let a = (1_u64 << 31) as u32; - let b: u32 = 1; - let test = build_op_test!(asm_op, &[a as u64, b as u64]); - test.expect_stack(&[1]); - - // --- test simple case wraparound case with max b -------------------------------------------- - let a = 2_u32; - let b: u32 = 31; - let test = build_op_test!(asm_op, &[a as u64, b as u64]); - test.expect_stack(&[1]); - - // --- no change when a is max value (all 1s) ------------------------------------------------- - let a = (U32_BOUND - 1) as u32; - let b = 2; - let test = build_op_test!(asm_op, &[a as u64, b as u64]); - test.expect_stack(&[a as u64]); - - // --- test b = 0 ----------------------------------------------------------------------------- - let a = rand_value::(); - let b = 0; - - let test = build_op_test!(asm_op, &[a as u64, b as u64]); - test.expect_stack(&[a.rotate_left(b) as u64]); - - // --- test random values --------------------------------------------------------------------- - let a = rand_value::(); - let b = rand_value::() % 32; - - let test = build_op_test!(asm_op, &[a as u64, b as u64]); - test.expect_stack(&[a.rotate_left(b) as u64]); -} - -#[test] -fn u32checked_rotl_b() { - // Computes c by rotating a 32-bit representation of a to the left by b bits. - let op_base = "u32checked_rotl"; - let get_asm_op = |b: u32| format!("{op_base}.{b}"); - - // --- test simple case ----------------------------------------------------------------------- - let a = 1_u32; - let b = 1_u32; - let test = build_op_test!(get_asm_op(b).as_str(), &[5, a as u64]); - test.expect_stack(&[2, 5]); - - // --- test simple wraparound case with large a ----------------------------------------------- - let a = (1_u64 << 31) as u32; - let b: u32 = 1; - let test = build_op_test!(get_asm_op(b).as_str(), &[a as u64]); - test.expect_stack(&[1]); - - // --- test simple case wraparound case with max b -------------------------------------------- - let a = 2_u32; - let b: u32 = 31; - let test = build_op_test!(get_asm_op(b).as_str(), &[a as u64]); - test.expect_stack(&[1]); - - // --- no change when a is max value (all 1s) ------------------------------------------------- - let a = (U32_BOUND - 1) as u32; - let b = 2; - let test = build_op_test!(get_asm_op(b).as_str(), &[a as u64]); - test.expect_stack(&[a as u64]); - - // --- test b = 0 --------------------------------------------------------------------------- - let a = rand_value::(); - let b = 0; - - let test = build_op_test!(get_asm_op(b).as_str(), &[a as u64]); - test.expect_stack(&[a.rotate_left(b) as u64]); - - // --- test random values --------------------------------------------------------------------- - let a = rand_value::(); - let b = rand_value::() % 32; - - let test = build_op_test!(get_asm_op(b).as_str(), &[a as u64]); - test.expect_stack(&[a.rotate_left(b) as u64]); -} - -#[test] -fn u32checked_rotl_fail_b() { - let op_base = "u32checked_rotl"; - - test_input_out_of_bounds(format!("{}.{}", op_base, 1).as_str()); - test_param_out_of_bounds(op_base, 32); -} - -#[test] -fn u32unchecked_rotl() { - // Computes c by rotating a 32-bit representation of a to the left by b bits. - let asm_op = "u32unchecked_rotl"; + let asm_op = "u32rotl"; // --- test simple case ----------------------------------------------------------------------- let a = 1_u32; @@ -637,119 +363,9 @@ fn u32unchecked_rotl() { } #[test] -fn u32checked_rotr() { - // Computes c by rotating a 32-bit representation of a to the right by b bits. - let asm_op = "u32checked_rotr"; - - // --- test simple case ----------------------------------------------------------------------- - let a = 2_u32; - let b = 1_u32; - let test = build_op_test!(asm_op, &[5, a as u64, b as u64]); - test.expect_stack(&[1, 5]); - - // --- test simple wraparound case with small a ----------------------------------------------- - let a = 1_u32; - let b = 1_u32; - let test = build_op_test!(asm_op, &[a as u64, b as u64]); - test.expect_stack(&[U32_BOUND >> 1]); - - // --- test simple case wraparound case with max b -------------------------------------------- - let a = 1_u32; - let b: u32 = 31; - let test = build_op_test!(asm_op, &[a as u64, b as u64]); - test.expect_stack(&[2]); - - // --- no change when a is max value (all 1s) ------------------------------------------------- - let a = (U32_BOUND - 1) as u32; - let b = 2; - let test = build_op_test!(asm_op, &[a as u64, b as u64]); - test.expect_stack(&[a as u64]); - - // --- test b = 0 --------------------------------------------------------------------------- - let a = rand_value::(); - let b = 0; - - let test = build_op_test!(asm_op, &[a as u64, b as u64]); - test.expect_stack(&[a.rotate_right(b) as u64]); - - // --- test random values --------------------------------------------------------------------- - let a = rand_value::(); - let b = rand_value::() % 32; - - let test = build_op_test!(asm_op, &[a as u64, b as u64]); - test.expect_stack(&[a.rotate_right(b) as u64]); -} - -#[test] -fn u32checked_rotr_fail() { - let asm_op = "u32checked_rotr"; - - // should fail if a >= 2^32 - let test = build_op_test!(asm_op, &[U32_BOUND, 1]); - test.expect_error(TestError::ExecutionError("NotU32Value")); - - // should fail if b >= 32 - let test = build_op_test!(asm_op, &[1, 32]); - test.expect_error(TestError::ExecutionError("FailedAssertion")); -} - -#[test] -fn u32checked_rotr_b() { - // Computes c by rotating a 32-bit representation of a to the right by b bits. - let op_base = "u32checked_rotr"; - let get_asm_op = |b: u32| format!("{op_base}.{b}"); - - // --- test simple case ----------------------------------------------------------------------- - let a = 2_u32; - let b = 1_u32; - let test = build_op_test!(get_asm_op(b).as_str(), &[5, a as u64]); - test.expect_stack(&[1, 5]); - - // --- test simple wraparound case with small a ----------------------------------------------- - let a = 1_u32; - let b = 1_u32; - let test = build_op_test!(get_asm_op(b).as_str(), &[a as u64]); - test.expect_stack(&[U32_BOUND >> 1]); - - // --- test simple case wraparound case with max b -------------------------------------------- - let a = 1_u32; - let b: u32 = 31; - let test = build_op_test!(get_asm_op(b).as_str(), &[a as u64]); - test.expect_stack(&[2]); - - // --- no change when a is max value (all 1s) ------------------------------------------------- - let a = (U32_BOUND - 1) as u32; - let b = 2; - let test = build_op_test!(get_asm_op(b).as_str(), &[a as u64]); - test.expect_stack(&[a as u64]); - - // --- test b = 0 --------------------------------------------------------------------------- - let a = rand_value::(); - let b = 0; - - let test = build_op_test!(get_asm_op(b).as_str(), &[a as u64]); - test.expect_stack(&[a.rotate_right(b) as u64]); - - // --- test random values --------------------------------------------------------------------- - let a = rand_value::(); - let b = rand_value::() % 32; - - let test = build_op_test!(get_asm_op(b).as_str(), &[a as u64]); - test.expect_stack(&[a.rotate_right(b) as u64]); -} - -#[test] -fn u32checked_rotr_b_fail() { - let op_base = "u32checked_rotr"; - - test_input_out_of_bounds(format!("{}.{}", op_base, 1).as_str()); - test_param_out_of_bounds(op_base, 32); -} - -#[test] -fn u32unchecked_rotr() { +fn u32rotr() { // Computes c by rotating a 32-bit representation of a to the right by b bits. - let asm_op = "u32unchecked_rotr"; + let asm_op = "u32rotr"; // --- test simple case ----------------------------------------------------------------------- let a = 2_u32; @@ -795,26 +411,8 @@ fn u32unchecked_rotr() { } #[test] -fn u32checked_popcnt() { - let asm_op = "u32checked_popcnt"; - build_op_test!(asm_op, &[0]).expect_stack(&[0]); - build_op_test!(asm_op, &[1]).expect_stack(&[1]); - build_op_test!(asm_op, &[555]).expect_stack(&[5]); - build_op_test!(asm_op, &[65536]).expect_stack(&[1]); - build_op_test!(asm_op, &[4294967295]).expect_stack(&[32]); -} - -#[test] -fn u32checked_popcnt_fail() { - let asm_op = "u32checked_popcnt"; - build_op_test!(asm_op, &[4294967296]).expect_error(TestError::ExecutionError("NotU32Value")); - build_op_test!(asm_op, &[281474976710655]) - .expect_error(TestError::ExecutionError("NotU32Value")); -} - -#[test] -fn u32unchecked_popcnt() { - let asm_op = "u32unchecked_popcnt"; +fn u32popcnt() { + let asm_op = "u32popcnt"; build_op_test!(asm_op, &[0]).expect_stack(&[0]); build_op_test!(asm_op, &[1]).expect_stack(&[1]); build_op_test!(asm_op, &[555]).expect_stack(&[5]); @@ -827,8 +425,8 @@ fn u32unchecked_popcnt() { proptest! { #[test] - fn u32checked_and_proptest(a in any::(), b in any::()) { - let asm_opcode = "u32checked_and"; + fn u32and_proptest(a in any::(), b in any::()) { + let asm_opcode = "u32and"; let values = [a as u64, b as u64]; // should result in bitwise AND let expected = (a & b) as u64; @@ -838,8 +436,8 @@ proptest! { } #[test] - fn u32checked_or_proptest(a in any::(), b in any::()) { - let asm_opcode = "u32checked_or"; + fn u32or_proptest(a in any::(), b in any::()) { + let asm_opcode = "u32or"; let values = [a as u64, b as u64]; // should result in bitwise OR let expected = (a | b) as u64; @@ -849,8 +447,8 @@ proptest! { } #[test] - fn u32checked_xor_proptest(a in any::(), b in any::()) { - let asm_opcode = "u32checked_xor"; + fn u32xor_proptest(a in any::(), b in any::()) { + let asm_opcode = "u32xor"; let values = [a as u64, b as u64]; // should result in bitwise XOR let expected = (a ^ b) as u64; @@ -860,8 +458,8 @@ proptest! { } #[test] - fn u32checked_not_proptest(value in any::()) { - let asm_opcode = "u32checked_not"; + fn u32not_proptest(value in any::()) { + let asm_opcode = "u32not"; // should result in bitwise NOT let test = build_op_test!(asm_opcode, &[value as u64]); @@ -869,28 +467,8 @@ proptest! { } #[test] - fn u32checked_shl_proptest(a in any::(), b in 0_u32..32) { - let asm_opcode = "u32checked_shl"; - - // should execute left shift - let expected = a << b; - let test = build_op_test!(asm_opcode, &[a as u64, b as u64]); - test.prop_expect_stack(&[expected as u64])?; - } - - #[test] - fn u32checked_shl_b_proptest(a in any::(), b in 0_u32..32) { - let asm_opcode = format!("u32checked_shl.{b}"); - - // should execute left shift - let expected = a << b; - let test = build_op_test!(asm_opcode, &[a as u64]); - test.prop_expect_stack(&[expected as u64])?; - } - - #[test] - fn u32unchecked_shl_proptest(a in any::(), b in 0_u32..32) { - let asm_opcode = "u32unchecked_shl"; + fn u32shl_proptest(a in any::(), b in 0_u32..32) { + let asm_opcode = "u32shl"; // should execute left shift let c = a.wrapping_shl(b); @@ -899,8 +477,8 @@ proptest! { } #[test] - fn u32unchecked_shl_b_proptest(a in any::(), b in 0_u32..32) { - let asm_opcode = format!("u32unchecked_shl.{b}"); + fn u32shl_b_proptest(a in any::(), b in 0_u32..32) { + let asm_opcode = format!("u32shl.{b}"); // should execute left shift let c = a.wrapping_shl(b); @@ -909,47 +487,8 @@ proptest! { } #[test] - fn u32checked_shr_proptest(a in any::(), b in 0_u32..32) { - let asm_opcode = "u32checked_shr"; - - // should execute right shift - let expected = a >> b; - let test = build_op_test!(asm_opcode, &[a as u64, b as u64]); - test.prop_expect_stack(&[expected as u64])?; - } - - #[test] - fn u32checked_shr_b_proptest(a in any::(), b in 0_u32..32) { - let asm_opcode = format!("u32checked_shr.{b}"); - - // should execute right shift - let expected = a >> b; - let test = build_op_test!(asm_opcode, &[a as u64]); - test.prop_expect_stack(&[expected as u64])?; - } - - #[test] - fn u32checked_rotl_proptest(a in any::(), b in 0_u32..32) { - let asm_opcode = "u32checked_rotl"; - - // should execute left bit rotation - let test = build_op_test!(asm_opcode, &[a as u64, b as u64]); - test.prop_expect_stack(&[a.rotate_left(b) as u64])?; - } - - #[test] - fn u32checked_rotl_b_proptest(a in any::(), b in 0_u32..32) { - let op_base = "u32checked_rotl"; - let asm_opcode = format!("{op_base}.{b}"); - - // should execute left bit rotation - let test = build_op_test!(asm_opcode, &[a as u64]); - test.prop_expect_stack(&[a.rotate_left(b) as u64])?; - } - - #[test] - fn u32unchecked_rotl_proptest(a in any::(), b in 0_u32..32) { - let asm_opcode = "u32unchecked_rotl"; + fn u32rotl_proptest(a in any::(), b in 0_u32..32) { + let asm_opcode = "u32rotl"; // should execute left bit rotation let test = build_op_test!(asm_opcode, &[a as u64, b as u64]); @@ -957,8 +496,8 @@ proptest! { } #[test] - fn u32unchecked_rotl_b_proptest(a in any::(), b in 0_u32..32) { - let op_base = "u32unchecked_rotl"; + fn u32rotl_b_proptest(a in any::(), b in 0_u32..32) { + let op_base = "u32rotl"; let asm_opcode = format!("{op_base}.{b}"); // should execute left bit rotation @@ -967,27 +506,8 @@ proptest! { } #[test] - fn u32checked_rotr_proptest(a in any::(), b in 0_u32..32) { - let asm_opcode = "u32checked_rotr"; - - // should execute right bit rotation - let test = build_op_test!(asm_opcode, &[a as u64, b as u64]); - test.prop_expect_stack(&[a.rotate_right(b) as u64])?; - } - - #[test] - fn u32checked_rotr_b_proptest(a in any::(), b in 0_u32..32) { - let op_base = "u32checked_rotr"; - let asm_opcode = format!("{op_base}.{b}"); - - // should execute right bit rotation - let test = build_op_test!(asm_opcode, &[a as u64]); - test.prop_expect_stack(&[a.rotate_right(b) as u64])?; - } - - #[test] - fn u32unchecked_rotr_proptest(a in any::(), b in 0_u32..32) { - let asm_opcode = "u32unchecked_rotr"; + fn u32rotr_proptest(a in any::(), b in 0_u32..32) { + let asm_opcode = "u32rotr"; // should execute right bit rotation let test = build_op_test!(asm_opcode, &[a as u64, b as u64]); @@ -995,8 +515,8 @@ proptest! { } #[test] - fn u32unchecked_rotr_b_proptest(a in any::(), b in 0_u32..32) { - let op_base = "u32unchecked_rotr"; + fn u32rotr_b_proptest(a in any::(), b in 0_u32..32) { + let op_base = "u32rotr"; let asm_opcode = format!("{op_base}.{b}"); // should execute right bit rotation @@ -1005,16 +525,8 @@ proptest! { } #[test] - fn u32checked_popcount_proptest(a in any::()) { - let asm_opcode = "u32checked_popcnt"; - let expected = a.count_ones(); - let test = build_op_test!(asm_opcode, &[a as u64]); - test.prop_expect_stack(&[expected as u64])?; - } - - #[test] - fn u32unchecked_popcount_proptest(a in any::()) { - let asm_opcode = "u32unchecked_popcnt"; + fn u32popcount_proptest(a in any::()) { + let asm_opcode = "u32popcnt"; let expected = a.count_ones(); let test = build_op_test!(asm_opcode, &[a as u64]); test.prop_expect_stack(&[expected as u64])?; diff --git a/miden/tests/integration/operations/u32_ops/comparison_ops.rs b/miden/tests/integration/operations/u32_ops/comparison_ops.rs index c8ce7c6c1b..7213d16660 100644 --- a/miden/tests/integration/operations/u32_ops/comparison_ops.rs +++ b/miden/tests/integration/operations/u32_ops/comparison_ops.rs @@ -1,195 +1,13 @@ -use super::{test_inputs_out_of_bounds, test_param_out_of_bounds, test_unchecked_execution}; +use super::test_unchecked_execution; use core::cmp::Ordering; -use test_utils::{build_op_test, proptest::prelude::*, rand::rand_value, TestError, U32_BOUND}; +use test_utils::{build_op_test, proptest::prelude::*, rand::rand_value}; // U32 OPERATIONS TESTS - MANUAL - COMPARISON OPERATIONS // ================================================================================================ #[test] -fn u32checked_eq() { - let asm_op = "u32checked_eq"; - - // --- simple cases --------------------------------------------------------------------------- - let test = build_op_test!(asm_op, &[1, 1]); - test.expect_stack(&[1]); - - let test = build_op_test!(asm_op, &[0, 1]); - test.expect_stack(&[0]); - - // --- random u32: equality ------------------------------------------------------------------- - let a = rand_value::() as u32; - - let test = build_op_test!(asm_op, &[a as u64, a as u64]); - test.expect_stack(&[1]); - - // --- random u32: probable inequality -------------------------------------------------------- - let b = rand_value::() as u32; - let expected = if a == b { 1 } else { 0 }; - - let test = build_op_test!(asm_op, &[a as u64, b as u64]); - test.expect_stack(&[expected]); - - // --- test that the rest of the stack isn't affected ----------------------------------------- - let c = rand_value::(); - - let test = build_op_test!(asm_op, &[c, a as u64, b as u64]); - test.expect_stack(&[expected, c]); -} - -#[test] -fn u32eq_fail() { - let asm_op = "u32checked_eq"; - - // should fail if either one of 2 inputs is out of bounds - test_inputs_out_of_bounds(asm_op, 2); -} - -#[test] -fn u32checked_eq_b() { - let build_asm_op = |param: u32| format!("u32checked_eq.{param}"); - - // --- simple cases --------------------------------------------------------------------------- - let test = build_op_test!(build_asm_op(1).as_str(), &[1]); - test.expect_stack(&[1]); - - let test = build_op_test!(build_asm_op(0).as_str(), &[1]); - test.expect_stack(&[0]); - - // --- random u32: equality ------------------------------------------------------------------- - let a = rand_value::() as u32; - - let test = build_op_test!(build_asm_op(a).as_str(), &[a as u64]); - test.expect_stack(&[1]); - - // --- random u32: probable inequality -------------------------------------------------------- - let b = rand_value::() as u32; - let expected = if a == b { 1 } else { 0 }; - - let test = build_op_test!(build_asm_op(b).as_str(), &[a as u64]); - test.expect_stack(&[expected]); - - // --- test that the rest of the stack isn't affected ----------------------------------------- - let c = rand_value::(); - - let test = build_op_test!(build_asm_op(b).as_str(), &[c, a as u64]); - test.expect_stack(&[expected, c]); -} - -#[test] -fn u32checked_eq_b_fail() { - let asm_op = "u32checked_eq"; - - // should fail when b is out of bounds and provided as a parameter - test_param_out_of_bounds(asm_op, U32_BOUND); - - // should fail when b is a valid parameter but a is out of bounds - let asm_op = format!("{}.{}", asm_op, 1); - let test = build_op_test!(&asm_op, &[U32_BOUND]); - test.expect_error(TestError::ExecutionError("NotU32Value")); -} - -#[test] -fn u32checked_neq() { - let asm_op = "u32checked_neq"; - - // --- simple cases --------------------------------------------------------------------------- - let test = build_op_test!(asm_op, &[1, 1]); - test.expect_stack(&[0]); - - let test = build_op_test!(asm_op, &[0, 1]); - test.expect_stack(&[1]); - - // --- random u32: equality ------------------------------------------------------------------- - let a = rand_value::() as u32; - - let test = build_op_test!(asm_op, &[a as u64, a as u64]); - test.expect_stack(&[0]); - - // --- random u32: probable inequality -------------------------------------------------------- - let b = rand_value::() as u32; - let expected = if a != b { 1 } else { 0 }; - - let test = build_op_test!(asm_op, &[a as u64, b as u64]); - test.expect_stack(&[expected]); - - // --- test that the rest of the stack isn't affected ----------------------------------------- - let c = rand_value::(); - - let test = build_op_test!(asm_op, &[c, a as u64, b as u64]); - test.expect_stack(&[expected, c]); -} - -#[test] -fn u32checked_neq_fail() { - let asm_op = "u32checked_neq"; - - // should fail if either one of 2 inputs is out of bounds - test_inputs_out_of_bounds(asm_op, 2); -} - -#[test] -fn u32checked_neq_b() { - let build_asm_op = |param: u32| format!("u32checked_neq.{param}"); - - // --- simple cases --------------------------------------------------------------------------- - let test = build_op_test!(build_asm_op(1).as_str(), &[1]); - test.expect_stack(&[0]); - - let test = build_op_test!(build_asm_op(0).as_str(), &[1]); - test.expect_stack(&[1]); - - // --- random u32: equality ------------------------------------------------------------------- - let a = rand_value::() as u32; - - let test = build_op_test!(build_asm_op(a).as_str(), &[a as u64]); - test.expect_stack(&[0]); - - // --- random u32: probable inequality -------------------------------------------------------- - let b = rand_value::() as u32; - let expected = if a != b { 1 } else { 0 }; - - let test = build_op_test!(build_asm_op(b).as_str(), &[a as u64]); - test.expect_stack(&[expected]); - - // --- test that the rest of the stack isn't affected ----------------------------------------- - let c = rand_value::(); - - let test = build_op_test!(build_asm_op(b).as_str(), &[c, a as u64]); - test.expect_stack(&[expected, c]); -} - -#[test] -fn u32checked_neq_b_fail() { - let asm_op = "u32checked_neq"; - - // should fail when b is out of bounds and provided as a parameter - test_param_out_of_bounds(asm_op, U32_BOUND); - - // should fail when b is a valid parameter but a is out of bounds - let asm_op = format!("{}.{}", asm_op, 1); - let test = build_op_test!(&asm_op, &[U32_BOUND]); - test.expect_error(TestError::ExecutionError("NotU32Value")); -} - -#[test] -fn u32checked_lt() { - let asm_op = "u32checked_lt"; - - // should push 1 to the stack when a < b and 0 otherwise - test_comparison_op(asm_op, 1, 0, 0); -} - -#[test] -fn u32checked_lt_fail() { - let asm_op = "u32checked_lt"; - - // should fail if either one of 2 inputs is out of bounds - test_inputs_out_of_bounds(asm_op, 2); -} - -#[test] -fn u32unchecked_lt() { - let asm_op = "u32unchecked_lt"; +fn u32lt() { + let asm_op = "u32lt"; // should push 1 to the stack when a < b and 0 otherwise test_comparison_op(asm_op, 1, 0, 0); @@ -199,24 +17,8 @@ fn u32unchecked_lt() { } #[test] -fn u32checked_lte() { - let asm_op = "u32checked_lte"; - - // should push 1 to the stack when a <= b and 0 otherwise - test_comparison_op(asm_op, 1, 1, 0); -} - -#[test] -fn u32checked_lte_fail() { - let asm_op = "u32checked_lte"; - - // should fail if either one of 2 inputs is out of bounds - test_inputs_out_of_bounds(asm_op, 2); -} - -#[test] -fn u32unchecked_lte() { - let asm_op = "u32unchecked_lte"; +fn u32lte() { + let asm_op = "u32lte"; // should push 1 to the stack when a <= b and 0 otherwise test_comparison_op(asm_op, 1, 1, 0); @@ -226,24 +28,8 @@ fn u32unchecked_lte() { } #[test] -fn u32checked_gt() { - let asm_op = "u32checked_gt"; - - // should push 1 to the stack when a > b and 0 otherwise - test_comparison_op(asm_op, 0, 0, 1); -} - -#[test] -fn u32checked_gt_fail() { - let asm_op = "u32checked_gt"; - - // should fail if either one of 2 inputs is out of bounds - test_inputs_out_of_bounds(asm_op, 2); -} - -#[test] -fn u32unchecked_gt() { - let asm_op = "u32unchecked_gt"; +fn u32gt() { + let asm_op = "u32gt"; // should push 1 to the stack when a > b and 0 otherwise test_comparison_op(asm_op, 0, 0, 1); @@ -253,24 +39,8 @@ fn u32unchecked_gt() { } #[test] -fn u32checked_gte() { - let asm_op = "u32checked_gte"; - - // should push 1 to the stack when a >= b and 0 otherwise - test_comparison_op(asm_op, 0, 1, 1); -} - -#[test] -fn u32checked_gte_fail() { - let asm_op = "u32checked_gte"; - - // should fail if either one of 2 inputs is out of bounds - test_inputs_out_of_bounds(asm_op, 2); -} - -#[test] -fn u32unchecked_gte() { - let asm_op = "u32unchecked_gte"; +fn u32gte() { + let asm_op = "u32gte"; // should push 1 to the stack when a >= b and 0 otherwise test_comparison_op(asm_op, 0, 1, 1); @@ -280,24 +50,8 @@ fn u32unchecked_gte() { } #[test] -fn u32checked_min() { - let asm_op = "u32checked_min"; - - // should put the minimum of the 2 inputs on the stack - test_min(asm_op); -} - -#[test] -fn u32checked_min_fail() { - let asm_op = "u32checked_min"; - - // should fail if either one of 2 inputs is out of bounds - test_inputs_out_of_bounds(asm_op, 2); -} - -#[test] -fn u32unchecked_min() { - let asm_op = "u32unchecked_min"; +fn u32min() { + let asm_op = "u32min"; // should put the minimum of the 2 inputs on the stack test_min(asm_op); @@ -307,24 +61,8 @@ fn u32unchecked_min() { } #[test] -fn u32checked_max() { - let asm_op = "u32checked_max"; - - // should put the maximum of the 2 inputs on the stack - test_max(asm_op); -} - -#[test] -fn u32checked_max_fail() { - let asm_op = "u32checked_max"; - - // should fail if either one of 2 inputs is out of bounds - test_inputs_out_of_bounds(asm_op, 2); -} - -#[test] -fn u32unchecked_max() { - let asm_op = "u32unchecked_max"; +fn u32max() { + let asm_op = "u32max"; // should put the maximum of the 2 inputs on the stack test_max(asm_op); @@ -337,136 +75,72 @@ fn u32unchecked_max() { // ================================================================================================ proptest! { - #[test] - fn u32checked_eq_proptest(a in any::(), b in any::()) { - let asm_op = "u32checked_eq"; - let values = [b as u64, a as u64]; - - // should test for equality - let expected = if a == b { 1 } else { 0 }; - // b provided via the stack - let test = build_op_test!(asm_op, &values); - test.prop_expect_stack(&[expected])?; - - // b provided as a parameter - let asm_op = format!("{asm_op}.{b}"); - let test = build_op_test!(&asm_op, &[a as u64]); - test.prop_expect_stack(&[expected])?; - } - - #[test] - fn u32checked_neq_proptest(a in any::(), b in any::()) { - let asm_op = "u32checked_neq"; - let values = [b as u64, a as u64]; - - // should test for inequality - let expected = if a != b { 1 } else { 0 }; - // b provided via the stack - let test = build_op_test!(asm_op, &values); - test.prop_expect_stack(&[expected])?; - - // b provided as a parameter - let asm_op = format!("{asm_op}.{b}"); - let test = build_op_test!(&asm_op, &[a as u64]); - test.prop_expect_stack(&[expected])?; - } - #[test] fn u32lt_proptest(a in any::(), b in any::()) { - let asm_op = "u32checked_lt"; let expected = match a.cmp(&b) { Ordering::Less => 1, Ordering::Equal => 0, Ordering::Greater => 0, }; - // checked and unchecked should produce the same result for valid values - let test = build_op_test!(asm_op, &[a as u64, b as u64]); - test.prop_expect_stack(&[expected])?; - - let asm_op = "u32unchecked_lt"; + let asm_op = "u32lt"; let test = build_op_test!(&asm_op, &[a as u64, b as u64]); test.prop_expect_stack(&[expected])?; } #[test] fn u32lte_proptest(a in any::(), b in any::()) { - let asm_op = "u32checked_lte"; let expected = match a.cmp(&b) { Ordering::Less => 1, Ordering::Equal => 1, Ordering::Greater => 0, }; - // checked and unchecked should produce the same result for valid values - let test = build_op_test!(asm_op, &[a as u64, b as u64]); - test.prop_expect_stack(&[expected])?; - - let asm_op = "u32unchecked_lte"; + let asm_op = "u32lte"; let test = build_op_test!(&asm_op, &[a as u64, b as u64]); test.prop_expect_stack(&[expected])?; } #[test] fn u32gt_proptest(a in any::(), b in any::()) { - let asm_op = "u32checked_gt"; let expected = match a.cmp(&b) { Ordering::Less => 0, Ordering::Equal => 0, Ordering::Greater => 1, }; - // checked and unchecked should produce the same result for valid values - let test = build_op_test!(asm_op, &[a as u64, b as u64]); - test.prop_expect_stack(&[expected])?; - - let asm_op = "u32unchecked_gt"; + let asm_op = "u32gt"; let test = build_op_test!(&asm_op, &[a as u64, b as u64]); test.prop_expect_stack(&[expected])?; } #[test] fn u32gte_proptest(a in any::(), b in any::()) { - let asm_op = "u32checked_gte"; let expected = match a.cmp(&b) { Ordering::Less => 0, Ordering::Equal => 1, Ordering::Greater => 1, }; - // checked and unchecked should produce the same result for valid values - let test = build_op_test!(asm_op, &[a as u64, b as u64]); - test.prop_expect_stack(&[expected])?; - - let asm_op = "u32unchecked_gte"; + let asm_op = "u32gte"; let test = build_op_test!(&asm_op, &[a as u64, b as u64]); test.prop_expect_stack(&[expected])?; } #[test] fn u32min_proptest(a in any::(), b in any::()) { - let asm_op = "u32checked_min"; let expected = if a < b { a } else { b }; - // checked and unchecked should produce the same result for valid values - let test = build_op_test!(asm_op, &[a as u64, b as u64]); - test.prop_expect_stack(&[expected as u64])?; - - let asm_op = "u32unchecked_min"; + let asm_op = "u32min"; let test = build_op_test!(&asm_op, &[a as u64, b as u64]); test.prop_expect_stack(&[expected as u64])?; } #[test] fn u32max_proptest(a in any::(), b in any::()) { - let asm_op = "u32checked_max"; let expected = if a > b { a } else { b }; - // checked and unchecked should produce the same result for valid values - let test = build_op_test!(asm_op, &[a as u64, b as u64]); - test.prop_expect_stack(&[expected as u64])?; - - let asm_op = "u32unchecked_max"; + let asm_op = "u32max"; let test = build_op_test!(&asm_op, &[a as u64, b as u64]); test.prop_expect_stack(&[expected as u64])?; } @@ -510,8 +184,8 @@ fn test_comparison_op(asm_op: &str, expected_lt: u64, expected_eq: u64, expected test.expect_stack(&[expected, c]); } -/// Tests a u32min assembly operation (u32checked_min or u32unchecked_min) against a number of -/// cases to ensure that the operation puts the minimum of 2 input values on the stack. +/// Tests a u32min assembly operation against a number of cases to ensure that the operation puts +/// the minimum of 2 input values on the stack. fn test_min(asm_op: &str) { // --- simple cases --------------------------------------------------------------------------- // a < b should put a on the stack @@ -545,8 +219,8 @@ fn test_min(asm_op: &str) { test.expect_stack(&[expected as u64, c]); } -/// Tests a u32max assembly operation (u32checked_max or u32unchecked_max) against a number of -/// cases to ensure that the operation puts the maximum of 2 input values on the stack. +/// Tests a u32max assembly operation against a number of cases to ensure that the operation puts +/// the maximum of 2 input values on the stack. fn test_max(asm_op: &str) { // --- simple cases --------------------------------------------------------------------------- // a < b should put b on the stack diff --git a/miden/tests/integration/operations/u32_ops/mod.rs b/miden/tests/integration/operations/u32_ops/mod.rs index 397ae1b95b..3d1746f1c2 100644 --- a/miden/tests/integration/operations/u32_ops/mod.rs +++ b/miden/tests/integration/operations/u32_ops/mod.rs @@ -30,14 +30,6 @@ pub fn test_inputs_out_of_bounds(asm_op: &str, input_count: usize) { } } -/// This helper function tests a provided assembly operation which takes a single parameter -/// to ensure that it fails when that parameter is over the maximum allowed value (out of bounds). -pub fn test_param_out_of_bounds(asm_op_base: &str, gt_max_value: u64) { - let asm_op = format!("{asm_op_base}.{gt_max_value}"); - let test = build_op_test!(&asm_op); - test.expect_error(TestError::AssemblyError("parameter")); -} - /// This helper function tests that when the given u32 assembly instruction is executed on /// out-of-bounds inputs it does not fail. Each input is tested independently. pub fn test_unchecked_execution(asm_op: &str, input_count: usize) { diff --git a/stdlib/asm/collections/mmr.masm b/stdlib/asm/collections/mmr.masm index 5a32ce3ef8..06df3a23c2 100644 --- a/stdlib/asm/collections/mmr.masm +++ b/stdlib/asm/collections/mmr.masm @@ -17,11 +17,11 @@ export.u32unchecked_trailing_ones while.true # update the flag (2 cycles) - dup.2 u32checked_and + dup.2 u32and # => [flag, count, number, ...] # update the number (4 cycles) - movup.2 u32unchecked_div.2 + movup.2 u32div.2 # => [number/2, flag, count, ...] # update the counter (3 cycles) @@ -85,12 +85,12 @@ export.ilog2_checked push.0 # bit_pos from the most-signficant, `31-bit_pos` equals to ilog2 # stack: [bit_pos, power_of_two, number, ...] - dup.1 dup.3 u32checked_and eq.0 # (4 cycles) + dup.1 dup.3 u32and eq.0 # (4 cycles) # find the first most-significant true bit (9 * leading_zeros cycles) while.true add.1 swap div.2 swap # (5 cycles) - dup.1 dup.3 u32checked_and eq.0 # (4 cycles) + dup.1 dup.3 u32and eq.0 # (4 cycles) end # compute ilog2 (4 cycles) @@ -117,7 +117,7 @@ export.get # stack: [num_leaves, pos, mmr_ptr, ...] # compute `num_leaves & pos`, this contains all peaks before `pos` (and maybe some after the owning peak) (3 cycles) - dup.1 dup.1 u32checked_and + dup.1 dup.1 u32and # stack: [before_candidates, num_leaves, pos, mmr_ptr, ...] # compute `num_leaves - before_candidates`, this removes every peak before the owner (result may include peaks after owner) (4 cycles) @@ -133,7 +133,7 @@ export.get # stack: [after_mask, owner_peak, depth, num_leaves, pos, mmr_ptr, ...] # compute `num_leaves & after_mask`, uses the mask to compute the actual after peaks (2 cycles) - dup.3 u32checked_and + dup.3 u32and # stack: [after_peaks, owner_peak, depth, num_leaves, pos, mmr_ptr, ...] # compute `num_leaves - (after_peaks + owner_peak)`, this computes the before peaks (5 cycles) @@ -145,7 +145,7 @@ export.get # stack: [relative_pos, peaks_before, depth, mmr_ptr, ...] # compute `popcount(peaks_before)`, the count peaks before the target to be skipped when loading from mem (2 cycles) - swap u32checked_popcnt + swap u32assert u32popcnt # stack: [peak_count, relative_pos, depth, mmr_ptr, ...] # compute `mmr_ptr + peak_count + 1` the target tree index (3 cycles) @@ -184,7 +184,7 @@ end #! Cycles: 69 export.num_leaves_to_num_peaks # count number of peaks (69 cycles) - u32split u32unchecked_popcnt swap u32unchecked_popcnt add + u32split u32popcnt swap u32popcnt add # => [count, ...] end @@ -196,7 +196,7 @@ end #! Cycles: 17 export.num_peaks_to_message_size # the peaks are padded to a minimum length of 16 (10 cycles) - push.16 u32unchecked_max + push.16 u32max # => [count_min, ...] # when the number of peaks is greater than 16, then they are padded to an even number (7 cycles) diff --git a/stdlib/asm/collections/smt.masm b/stdlib/asm/collections/smt.masm index 7ad5565faf..7cd4215c4f 100644 --- a/stdlib/asm/collections/smt.masm +++ b/stdlib/asm/collections/smt.masm @@ -30,7 +30,7 @@ const.EMPTY_48_3=1437907447409278328 proc.get_top_16_bits u32split swap drop - u32unchecked_shr.16 + u32shr.16 end #! Extracts 32 most significant bits from the passed-in value. @@ -52,7 +52,7 @@ end proc.get_top_48_bits u32split swap - u32unchecked_shr.16 + u32shr.16 swap mul.65536 add @@ -69,11 +69,11 @@ end #! Cycles: 20 proc.extract_index_16_16 # extract the top 16 and the next 16 bits from the most significant element of V (6 cycles) - dup.4 u32split swap drop u32unchecked_divmod.65536 + dup.4 u32split swap drop u32divmod.65536 # => [v3_hi_lo, v3_hi_hi, U, V, ...] # extract the top 16 and the next 16 bits from the most significant element of U (4 cycles) - dup.2 u32split u32unchecked_divmod.65536 + dup.2 u32split u32divmod.65536 # => [u3_hi_lo, u3_hi_hi, u3_lo, v3_hi_lo, v3_hi_hi, U, V, ...] # make sure the lower 16 bits are different (5 cycles) @@ -100,16 +100,16 @@ proc.extract_index_16_32 dup.4 u32split dup.2 u32split dup movup.3 assert_eq # => [u3_hi, u3_lo, v3_lo, U, V, ...] - u32unchecked_divmod.65536 mul.65536 + u32divmod.65536 mul.65536 # => [idx_mid, idx_hi, u3_lo, v3_lo, U, V, ...] - movup.3 u32unchecked_shr.16 + movup.3 u32shr.16 # => [v3_lo_hi, idx_mid, idx_hi, u3_lo, U, V, ...] dup dup.2 add # => [idx_lo_v, v3_lo_hi, idx_mid, idx_hi, u3_lo, U, V, ...] - movup.4 u32unchecked_shr.16 + movup.4 u32shr.16 # => [u3_lo_hi, idx_lo_v, v3_lo_hi, idx_mid, idx_hi, U, V, ...] dup movup.3 neq assert @@ -138,7 +138,7 @@ proc.extract_index_32_16 # => [u3_lo, idx_hi, v3_lo, U, V, ...] # drop the least significant 16 bits from the lower 32-bit chunks (8 cycles) - u32unchecked_shr.16 movup.2 u32unchecked_shr.16 swap + u32shr.16 movup.2 u32shr.16 swap # => [idx_lo_u, idx_lo_v, idx_hi, U, V, ...] # make sure the lower 16-bit chunks are different (5 cycles) @@ -583,7 +583,7 @@ proc.insert_32.2 # load k3 from memory, extract upper 32 bits from it and split them into two 16-bit values # such that the top 16-bits are in idx_hi and the next 16 bits are in idx_lo (9 cycles) - loc_load.0 exec.get_top_32_bits u32unchecked_divmod.65536 + loc_load.0 exec.get_top_32_bits u32divmod.65536 # => [idx_lo, idx_hi, P, N, X, X, R, ...] # save idx_hi into loc[0][0] to be used later (5 cycles) @@ -666,7 +666,7 @@ proc.insert_48.2 # load k3 from memory, extract upper 48 bits from it and split them into two values such that # the top 32-bits are in idx_hi and the next 16 bits are in idx_lo (9 cycles) - loc_load.0 u32split swap u32unchecked_divmod.65536 drop + loc_load.0 u32split swap u32divmod.65536 drop # => [idx_lo, idx_hi, P, N, X, X, R, ...] # save idx_hi into loc[0][0] to be used later (5 cycles) diff --git a/stdlib/asm/crypto/dsa/rpo_falcon512.masm b/stdlib/asm/crypto/dsa/rpo_falcon512.masm index 6163ccf7c3..7071c10c1b 100644 --- a/stdlib/asm/crypto/dsa/rpo_falcon512.masm +++ b/stdlib/asm/crypto/dsa/rpo_falcon512.masm @@ -190,19 +190,19 @@ export.load_h_s2_and_product.1 dupw.1 u32assert2 - push.M u32unchecked_lt assert - push.M u32unchecked_lt assert + push.M u32lt assert + push.M u32lt assert u32assert2 - push.M u32unchecked_lt assert - push.M u32unchecked_lt assert + push.M u32lt assert + push.M u32lt assert dupw u32assert2 - push.M u32unchecked_lt assert - push.M u32unchecked_lt assert + push.M u32lt assert + push.M u32lt assert u32assert2 - push.M u32unchecked_lt assert - push.M u32unchecked_lt assert + push.M u32lt assert + push.M u32lt assert hperm end @@ -409,7 +409,7 @@ export.norm_sq dup push.6144 - u32unchecked_gt + u32gt #=> [phi, e, e^2, ...] swap @@ -659,6 +659,6 @@ export.verify.1665 #=> [norm_sq(s1) + norm_sq(s2), ...] push.SQUARE_NORM_BOUND - u32checked_lt assert + u32assert2 u32lt assert #=> [...] (Cycles: 8) end diff --git a/stdlib/asm/crypto/fri/frie2f4.masm b/stdlib/asm/crypto/fri/frie2f4.masm index 9d2b16778f..c9c13fb775 100644 --- a/stdlib/asm/crypto/fri/frie2f4.masm +++ b/stdlib/asm/crypto/fri/frie2f4.masm @@ -109,7 +109,7 @@ export.verify_query_layer.3 swapw.2 # [poe, p, e1, e0, d_size, t_depth, a1, a0, C, layer_ptr, rem_ptr, ...] swap # [p, poe, e1, e0, d_size, t_depth, a1, a0, C, layer_ptr, rem_ptr, ...] movup.4 # [d_size, p, poe, e1, e0, t_depth, a1, a0, C, layer_ptr, rem_ptr, ...] - u32unchecked_divmod # p and d_size must be u32 values + u32divmod # p and d_size must be u32 values movup.5 movupw.2 dup.5 @@ -205,7 +205,7 @@ export.verify_query # of the two elements we should compare against. (7 cycles) movup.3 push.2 - u32unchecked_divmod # f_pos must be a u32 value + u32divmod # f_pos must be a u32 value movdn.4 dup.1 dup.1 diff --git a/stdlib/asm/crypto/hashes/blake3.masm b/stdlib/asm/crypto/hashes/blake3.masm index 33316ddc39..326023d1c6 100644 --- a/stdlib/asm/crypto/hashes/blake3.masm +++ b/stdlib/asm/crypto/hashes/blake3.masm @@ -120,41 +120,41 @@ end #! that's because it doesn't dictate what output of 2-to-1 hash will be. proc.finalize movup.8 - u32checked_xor + u32xor swap movup.8 - u32checked_xor + u32xor swap movup.2 movup.8 - u32checked_xor + u32xor movdn.2 movup.3 movup.8 - u32checked_xor + u32xor movdn.3 movup.4 movup.8 - u32checked_xor + u32xor movdn.4 movup.5 movup.8 - u32checked_xor + u32xor movdn.5 movup.6 movup.8 - u32checked_xor + u32xor movdn.6 movup.7 movup.8 - u32checked_xor + u32xor movdn.7 end @@ -227,25 +227,25 @@ proc.columnar_mixing.1 mem_loadw dup.4 - u32checked_xor - u32unchecked_rotr.16 + u32xor + u32rotr.16 swap dup.5 - u32checked_xor - u32unchecked_rotr.16 + u32xor + u32rotr.16 swap movup.2 dup.6 - u32checked_xor - u32unchecked_rotr.16 + u32xor + u32rotr.16 movdn.2 movup.3 dup.7 - u32checked_xor - u32unchecked_rotr.16 + u32xor + u32rotr.16 movdn.3 movup.12 @@ -274,25 +274,25 @@ proc.columnar_mixing.1 movupw.3 dup.4 - u32checked_xor - u32unchecked_rotr.12 + u32xor + u32rotr.12 swap dup.5 - u32checked_xor - u32unchecked_rotr.12 + u32xor + u32rotr.12 swap movup.2 dup.6 - u32checked_xor - u32unchecked_rotr.12 + u32xor + u32rotr.12 movdn.2 movup.3 dup.7 - u32checked_xor - u32unchecked_rotr.12 + u32xor + u32rotr.12 movdn.3 movupw.3 @@ -329,25 +329,25 @@ proc.columnar_mixing.1 movupw.3 dup.4 - u32checked_xor - u32unchecked_rotr.8 + u32xor + u32rotr.8 swap dup.5 - u32checked_xor - u32unchecked_rotr.8 + u32xor + u32rotr.8 swap movup.2 dup.6 - u32checked_xor - u32unchecked_rotr.8 + u32xor + u32rotr.8 movdn.2 movup.3 dup.7 - u32checked_xor - u32unchecked_rotr.8 + u32xor + u32rotr.8 movdn.3 movupw.3 @@ -373,25 +373,25 @@ proc.columnar_mixing.1 movupw.3 dup.4 - u32checked_xor - u32unchecked_rotr.7 + u32xor + u32rotr.7 swap dup.5 - u32checked_xor - u32unchecked_rotr.7 + u32xor + u32rotr.7 swap movup.2 dup.6 - u32checked_xor - u32unchecked_rotr.7 + u32xor + u32rotr.7 movdn.2 movup.3 dup.7 - u32checked_xor - u32unchecked_rotr.7 + u32xor + u32rotr.7 movdn.3 movupw.3 @@ -467,24 +467,24 @@ proc.diagonal_mixing.1 movup.3 dup.4 - u32checked_xor - u32unchecked_rotr.16 + u32xor + u32rotr.16 movdn.3 dup.5 - u32checked_xor - u32unchecked_rotr.16 + u32xor + u32rotr.16 swap dup.6 - u32checked_xor - u32unchecked_rotr.16 + u32xor + u32rotr.16 swap movup.2 dup.7 - u32checked_xor - u32unchecked_rotr.16 + u32xor + u32rotr.16 movdn.2 movup.12 @@ -514,25 +514,25 @@ proc.diagonal_mixing.1 swap dup.6 - u32checked_xor - u32unchecked_rotr.12 + u32xor + u32rotr.12 swap movup.2 dup.7 - u32checked_xor - u32unchecked_rotr.12 + u32xor + u32rotr.12 movdn.2 movup.3 dup.4 - u32checked_xor - u32unchecked_rotr.12 + u32xor + u32rotr.12 movdn.3 dup.5 - u32checked_xor - u32unchecked_rotr.12 + u32xor + u32rotr.12 movupw.3 push.0.0.0.0 @@ -569,24 +569,24 @@ proc.diagonal_mixing.1 movup.3 dup.4 - u32checked_xor - u32unchecked_rotr.8 + u32xor + u32rotr.8 movdn.3 dup.5 - u32checked_xor - u32unchecked_rotr.8 + u32xor + u32rotr.8 swap dup.6 - u32checked_xor - u32unchecked_rotr.8 + u32xor + u32rotr.8 swap movup.2 dup.7 - u32checked_xor - u32unchecked_rotr.8 + u32xor + u32rotr.8 movdn.2 movupw.3 @@ -613,25 +613,25 @@ proc.diagonal_mixing.1 swap dup.6 - u32checked_xor - u32unchecked_rotr.7 + u32xor + u32rotr.7 swap movup.2 dup.7 - u32checked_xor - u32unchecked_rotr.7 + u32xor + u32rotr.7 movdn.2 movup.3 dup.4 - u32checked_xor - u32unchecked_rotr.7 + u32xor + u32rotr.7 movdn.3 dup.5 - u32checked_xor - u32unchecked_rotr.7 + u32xor + u32rotr.7 movupw.3 end diff --git a/stdlib/asm/crypto/hashes/keccak256.masm b/stdlib/asm/crypto/hashes/keccak256.masm index 07ca58be54..a342ee646d 100644 --- a/stdlib/asm/crypto/hashes/keccak256.masm +++ b/stdlib/asm/crypto/hashes/keccak256.masm @@ -46,12 +46,12 @@ proc.theta.3 drop movup.3 - u32checked_xor + u32xor swap movup.3 - u32checked_xor + u32xor swap @@ -70,12 +70,12 @@ proc.theta.3 drop movup.3 - u32checked_xor + u32xor swap movup.3 - u32checked_xor + u32xor swap @@ -92,12 +92,12 @@ proc.theta.3 drop movup.3 - u32checked_xor + u32xor swap movup.3 - u32checked_xor + u32xor swap @@ -115,12 +115,12 @@ proc.theta.3 drop movup.2 - u32checked_xor + u32xor swap movup.2 - u32checked_xor + u32xor swap @@ -154,12 +154,12 @@ proc.theta.3 drop movup.3 - u32checked_xor + u32xor swap movup.3 - u32checked_xor + u32xor swap @@ -176,12 +176,12 @@ proc.theta.3 drop movup.3 - u32checked_xor + u32xor swap movup.3 - u32checked_xor + u32xor swap @@ -200,12 +200,12 @@ proc.theta.3 drop movup.3 - u32checked_xor + u32xor swap movup.3 - u32checked_xor + u32xor swap @@ -221,12 +221,12 @@ proc.theta.3 drop movup.2 - u32checked_xor + u32xor swap movup.2 - u32checked_xor + u32xor swap @@ -269,12 +269,12 @@ proc.theta.3 drop movup.3 - u32checked_xor + u32xor swap movup.3 - u32checked_xor + u32xor swap @@ -293,12 +293,12 @@ proc.theta.3 drop movup.3 - u32checked_xor + u32xor swap movup.3 - u32checked_xor + u32xor swap @@ -315,12 +315,12 @@ proc.theta.3 drop movup.3 - u32checked_xor + u32xor swap movup.3 - u32checked_xor + u32xor swap @@ -338,12 +338,12 @@ proc.theta.3 drop movup.2 - u32checked_xor + u32xor swap movup.2 - u32checked_xor + u32xor swap @@ -378,12 +378,12 @@ proc.theta.3 drop movup.3 - u32checked_xor + u32xor swap movup.3 - u32checked_xor + u32xor swap @@ -400,12 +400,12 @@ proc.theta.3 drop movup.3 - u32checked_xor + u32xor swap movup.3 - u32checked_xor + u32xor swap @@ -424,12 +424,12 @@ proc.theta.3 drop movup.3 - u32checked_xor + u32xor swap movup.3 - u32checked_xor + u32xor swap @@ -445,12 +445,12 @@ proc.theta.3 drop movup.2 - u32checked_xor + u32xor swap movup.2 - u32checked_xor + u32xor swap @@ -493,12 +493,12 @@ proc.theta.3 drop movup.3 - u32checked_xor + u32xor swap movup.3 - u32checked_xor + u32xor swap @@ -517,12 +517,12 @@ proc.theta.3 drop movup.3 - u32checked_xor + u32xor swap movup.3 - u32checked_xor + u32xor swap @@ -539,12 +539,12 @@ proc.theta.3 drop movup.3 - u32checked_xor + u32xor swap movup.3 - u32checked_xor + u32xor swap @@ -562,12 +562,12 @@ proc.theta.3 drop movup.2 - u32checked_xor + u32xor swap movup.2 - u32checked_xor + u32xor swap @@ -586,48 +586,48 @@ proc.theta.3 dup.8 dup.4 - u32unchecked_rotl.1 - u32checked_xor + u32rotl.1 + u32xor dup.10 dup.4 - u32checked_xor + u32xor dup.2 dup.8 - u32unchecked_rotl.1 - u32checked_xor + u32rotl.1 + u32xor dup.4 dup.8 - u32checked_xor + u32xor movup.6 dup.11 - u32unchecked_rotl.1 - u32checked_xor + u32rotl.1 + u32xor movup.7 dup.10 - u32checked_xor + u32xor movup.8 movup.13 - u32unchecked_rotl.1 - u32checked_xor + u32rotl.1 + u32xor movup.9 movup.12 - u32checked_xor + u32xor movup.10 movup.10 - u32unchecked_rotl.1 - u32checked_xor + u32rotl.1 + u32xor movup.10 movup.10 - u32checked_xor + u32xor # stack = [d9, d8, d7, d6, d5, d4, d3, d2, d1, d0] @@ -654,21 +654,21 @@ proc.theta.3 mem_loadw dup.5 - u32checked_xor + u32xor swap dup.6 - u32checked_xor + u32xor swap movup.2 dup.7 - u32checked_xor + u32xor movdn.2 movup.3 dup.8 - u32checked_xor + u32xor movdn.3 dup.4 @@ -685,21 +685,21 @@ proc.theta.3 mem_loadw dup.9 - u32checked_xor + u32xor swap dup.10 - u32checked_xor + u32xor swap movup.2 dup.11 - u32checked_xor + u32xor movdn.2 movup.3 dup.12 - u32checked_xor + u32xor movdn.3 dup.4 @@ -716,21 +716,21 @@ proc.theta.3 mem_loadw dup.13 - u32checked_xor + u32xor swap dup.14 - u32checked_xor + u32xor swap movup.2 dup.5 - u32checked_xor + u32xor movdn.2 movup.3 dup.6 - u32checked_xor + u32xor movdn.3 dup.4 @@ -747,21 +747,21 @@ proc.theta.3 mem_loadw dup.7 - u32checked_xor + u32xor swap dup.8 - u32checked_xor + u32xor swap movup.2 dup.9 - u32checked_xor + u32xor movdn.2 movup.3 dup.10 - u32checked_xor + u32xor movdn.3 dup.4 @@ -778,21 +778,21 @@ proc.theta.3 mem_loadw dup.11 - u32checked_xor + u32xor swap dup.12 - u32checked_xor + u32xor swap movup.2 dup.13 - u32checked_xor + u32xor movdn.2 movup.3 dup.14 - u32checked_xor + u32xor movdn.3 dup.4 @@ -809,21 +809,21 @@ proc.theta.3 mem_loadw dup.5 - u32checked_xor + u32xor swap dup.6 - u32checked_xor + u32xor swap movup.2 dup.7 - u32checked_xor + u32xor movdn.2 movup.3 dup.8 - u32checked_xor + u32xor movdn.3 dup.4 @@ -840,21 +840,21 @@ proc.theta.3 mem_loadw dup.9 - u32checked_xor + u32xor swap dup.10 - u32checked_xor + u32xor swap movup.2 dup.11 - u32checked_xor + u32xor movdn.2 movup.3 dup.12 - u32checked_xor + u32xor movdn.3 dup.4 @@ -871,21 +871,21 @@ proc.theta.3 mem_loadw dup.13 - u32checked_xor + u32xor swap dup.14 - u32checked_xor + u32xor swap movup.2 dup.5 - u32checked_xor + u32xor movdn.2 movup.3 dup.6 - u32checked_xor + u32xor movdn.3 dup.4 @@ -902,21 +902,21 @@ proc.theta.3 mem_loadw dup.7 - u32checked_xor + u32xor swap dup.8 - u32checked_xor + u32xor swap movup.2 dup.9 - u32checked_xor + u32xor movdn.2 movup.3 dup.10 - u32checked_xor + u32xor movdn.3 dup.4 @@ -933,21 +933,21 @@ proc.theta.3 mem_loadw dup.11 - u32checked_xor + u32xor swap dup.12 - u32checked_xor + u32xor swap movup.2 dup.13 - u32checked_xor + u32xor movdn.2 movup.3 dup.14 - u32checked_xor + u32xor movdn.3 dup.4 @@ -964,21 +964,21 @@ proc.theta.3 mem_loadw movup.5 - u32checked_xor + u32xor swap movup.5 - u32checked_xor + u32xor swap movup.2 movup.5 - u32checked_xor + u32xor movdn.2 movup.3 movup.5 - u32checked_xor + u32xor movdn.3 dup.4 @@ -995,21 +995,21 @@ proc.theta.3 mem_loadw movup.5 - u32checked_xor + u32xor swap movup.5 - u32checked_xor + u32xor swap movup.2 movup.5 - u32checked_xor + u32xor movdn.2 movup.3 movup.5 - u32checked_xor + u32xor movdn.3 dup.4 @@ -1026,11 +1026,11 @@ proc.theta.3 mem_loadw movup.5 - u32checked_xor + u32xor swap movup.5 - u32checked_xor + u32xor swap movup.4 @@ -1066,7 +1066,7 @@ proc.rho.1 mem_loadw movup.3 - u32unchecked_rotl.1 + u32rotl.1 movdn.2 movup.4 @@ -1079,16 +1079,16 @@ proc.rho.1 dup.4 mem_loadw - u32unchecked_rotl.31 + u32rotl.31 swap - u32unchecked_rotl.31 + u32rotl.31 swap movup.2 - u32unchecked_rotl.14 + u32rotl.14 movdn.2 movup.3 - u32unchecked_rotl.14 + u32rotl.14 movdn.3 movup.4 @@ -1101,15 +1101,15 @@ proc.rho.1 dup.4 mem_loadw - u32unchecked_rotl.13 + u32rotl.13 swap - u32unchecked_rotl.14 + u32rotl.14 movup.2 - u32unchecked_rotl.18 + u32rotl.18 movdn.2 movup.3 - u32unchecked_rotl.18 + u32rotl.18 movdn.3 movup.4 @@ -1122,16 +1122,16 @@ proc.rho.1 dup.4 mem_loadw - u32unchecked_rotl.22 + u32rotl.22 swap - u32unchecked_rotl.22 + u32rotl.22 swap movup.2 - u32unchecked_rotl.3 + u32rotl.3 movdn.2 movup.3 - u32unchecked_rotl.3 + u32rotl.3 movdn.3 movup.4 @@ -1144,15 +1144,15 @@ proc.rho.1 dup.4 mem_loadw - u32unchecked_rotl.27 + u32rotl.27 swap - u32unchecked_rotl.28 + u32rotl.28 movup.2 - u32unchecked_rotl.10 + u32rotl.10 movdn.2 movup.3 - u32unchecked_rotl.10 + u32rotl.10 movdn.3 movup.4 @@ -1165,15 +1165,15 @@ proc.rho.1 dup.4 mem_loadw - u32unchecked_rotl.1 + u32rotl.1 swap - u32unchecked_rotl.2 + u32rotl.2 movup.2 - u32unchecked_rotl.5 + u32rotl.5 movdn.2 movup.3 - u32unchecked_rotl.5 + u32rotl.5 movdn.3 movup.4 @@ -1186,15 +1186,15 @@ proc.rho.1 dup.4 mem_loadw - u32unchecked_rotl.21 + u32rotl.21 swap - u32unchecked_rotl.22 + u32rotl.22 movup.2 - u32unchecked_rotl.12 + u32rotl.12 movdn.3 movup.2 - u32unchecked_rotl.13 + u32rotl.13 movdn.2 movup.4 @@ -1207,15 +1207,15 @@ proc.rho.1 dup.4 mem_loadw - u32unchecked_rotl.19 + u32rotl.19 swap - u32unchecked_rotl.20 + u32rotl.20 movup.2 - u32unchecked_rotl.20 + u32rotl.20 movdn.3 movup.2 - u32unchecked_rotl.21 + u32rotl.21 movdn.2 movup.4 @@ -1228,15 +1228,15 @@ proc.rho.1 dup.4 mem_loadw - u32unchecked_rotl.22 + u32rotl.22 swap - u32unchecked_rotl.23 + u32rotl.23 movup.2 - u32unchecked_rotl.7 + u32rotl.7 movdn.3 movup.2 - u32unchecked_rotl.8 + u32rotl.8 movdn.2 movup.4 @@ -1249,15 +1249,15 @@ proc.rho.1 dup.4 mem_loadw - u32unchecked_rotl.10 + u32rotl.10 swap - u32unchecked_rotl.11 + u32rotl.11 movup.2 - u32unchecked_rotl.4 + u32rotl.4 movdn.2 movup.3 - u32unchecked_rotl.4 + u32rotl.4 movdn.3 movup.4 @@ -1270,16 +1270,16 @@ proc.rho.1 dup.4 mem_loadw - u32unchecked_rotl.9 + u32rotl.9 swap - u32unchecked_rotl.9 + u32rotl.9 swap movup.2 - u32unchecked_rotl.1 + u32rotl.1 movdn.2 movup.3 - u32unchecked_rotl.1 + u32rotl.1 movdn.3 movup.4 @@ -1292,15 +1292,15 @@ proc.rho.1 dup.4 mem_loadw - u32unchecked_rotl.30 + u32rotl.30 swap - u32unchecked_rotl.31 + u32rotl.31 movup.2 - u32unchecked_rotl.28 + u32rotl.28 movdn.2 movup.3 - u32unchecked_rotl.28 + u32rotl.28 movdn.3 movup.4 @@ -1313,9 +1313,9 @@ proc.rho.1 dup.4 mem_loadw - u32unchecked_rotl.7 + u32rotl.7 swap - u32unchecked_rotl.7 + u32rotl.7 swap movup.4 @@ -1773,9 +1773,9 @@ proc.chi.4 drop drop - u32checked_not + u32not swap - u32checked_not + u32not swap movup.2 @@ -1791,25 +1791,25 @@ proc.chi.4 dup.1 movup.6 - u32checked_and + u32and swap movup.6 - u32checked_and + u32and swap movup.3 - u32checked_not + u32not movup.3 - u32checked_not + u32not movup.4 - u32checked_and + u32and swap movup.4 - u32checked_and + u32and swap movup.3 @@ -1824,9 +1824,9 @@ proc.chi.4 drop drop - u32checked_not + u32not swap - u32checked_not + u32not swap movup.2 @@ -1847,10 +1847,10 @@ proc.chi.4 dup.1 movup.4 - u32checked_and + u32and swap movup.4 - u32checked_and + u32and swap movup.3 @@ -1863,15 +1863,15 @@ proc.chi.4 mem_loadw movup.5 - u32checked_not + u32not movup.5 - u32checked_not + u32not dup.2 - u32checked_and + u32and swap dup.3 - u32checked_and + u32and swap movup.7 @@ -1881,16 +1881,16 @@ proc.chi.4 mem_storew dropw - u32checked_not + u32not swap - u32checked_not + u32not swap movup.2 - u32checked_and + u32and swap movup.2 - u32checked_and + u32and swap locaddr.0 @@ -1907,21 +1907,21 @@ proc.chi.4 mem_loadw movup.4 - u32checked_xor + u32xor swap movup.4 - u32checked_xor + u32xor swap movup.2 movup.4 - u32checked_xor + u32xor movdn.2 movup.3 movup.4 - u32checked_xor + u32xor movdn.3 dup.4 @@ -1940,21 +1940,21 @@ proc.chi.4 mem_loadw movup.4 - u32checked_xor + u32xor swap movup.4 - u32checked_xor + u32xor swap movup.2 movup.4 - u32checked_xor + u32xor movdn.2 movup.3 movup.4 - u32checked_xor + u32xor movdn.3 dup.4 @@ -1968,10 +1968,10 @@ proc.chi.4 mem_loadw movup.5 - u32checked_xor + u32xor swap movup.5 - u32checked_xor + u32xor swap dup.4 @@ -1985,19 +1985,19 @@ proc.chi.4 dup.4 mem_loadw - u32checked_not + u32not swap - u32checked_not + u32not swap dup.3 dup.3 movup.2 - u32checked_and + u32and swap movup.2 - u32checked_and + u32and swap push.0.0 @@ -2014,31 +2014,31 @@ proc.chi.4 movup.5 movup.5 - u32checked_not + u32not swap - u32checked_not + u32not swap dup.2 - u32checked_and + u32and swap dup.3 - u32checked_and + u32and swap movup.3 movup.3 - u32checked_not + u32not swap - u32checked_not + u32not swap dup.4 - u32checked_and + u32and swap dup.5 - u32checked_and + u32and swap movup.3 @@ -2061,16 +2061,16 @@ proc.chi.4 dup.1 movup.4 - u32checked_not + u32not movup.5 - u32checked_not + u32not swap movup.2 - u32checked_and + u32and swap movup.2 - u32checked_and + u32and swap movup.3 @@ -2090,16 +2090,16 @@ proc.chi.4 movup.3 movup.3 - u32checked_not + u32not swap - u32checked_not + u32not swap movup.2 - u32checked_and + u32and swap movup.2 - u32checked_and + u32and swap movup.3 @@ -2120,21 +2120,21 @@ proc.chi.4 loc_loadw.1 movup.4 - u32checked_xor + u32xor swap movup.4 - u32checked_xor + u32xor swap movup.2 movup.4 - u32checked_xor + u32xor movdn.2 movup.3 movup.4 - u32checked_xor + u32xor movdn.3 dup.4 @@ -2151,21 +2151,21 @@ proc.chi.4 loc_loadw.2 movup.4 - u32checked_xor + u32xor swap movup.4 - u32checked_xor + u32xor swap movup.2 movup.4 - u32checked_xor + u32xor movdn.2 movup.3 movup.4 - u32checked_xor + u32xor movdn.3 dup.4 @@ -2182,21 +2182,21 @@ proc.chi.4 loc_loadw.3 movup.4 - u32checked_xor + u32xor swap movup.4 - u32checked_xor + u32xor swap movup.2 movup.4 - u32checked_xor + u32xor movdn.2 movup.3 movup.4 - u32checked_xor + u32xor movdn.3 dup.4 @@ -2213,9 +2213,9 @@ proc.chi.4 drop drop - u32checked_not + u32not swap - u32checked_not + u32not swap movup.2 @@ -2231,25 +2231,25 @@ proc.chi.4 dup.1 movup.6 - u32checked_and + u32and swap movup.6 - u32checked_and + u32and swap movup.3 movup.3 - u32checked_not + u32not swap - u32checked_not + u32not swap dup.4 - u32checked_and + u32and swap dup.5 - u32checked_and + u32and swap movup.3 @@ -2275,16 +2275,16 @@ proc.chi.4 movup.5 movup.5 - u32checked_not + u32not swap - u32checked_not + u32not swap movup.2 - u32checked_and + u32and swap movup.2 - u32checked_and + u32and swap movup.4 @@ -2299,19 +2299,19 @@ proc.chi.4 movup.7 movup.7 - u32checked_not + u32not swap - u32checked_not + u32not swap dup.3 dup.3 movup.2 - u32checked_and + u32and swap movup.2 - u32checked_and + u32and swap movup.7 @@ -2320,16 +2320,16 @@ proc.chi.4 loc_storew.2 dropw - u32checked_not + u32not swap - u32checked_not + u32not swap movup.2 - u32checked_and + u32and swap movup.2 - u32checked_and + u32and swap push.0.0 @@ -2345,21 +2345,21 @@ proc.chi.4 loc_loadw.1 movup.4 - u32checked_xor + u32xor swap movup.4 - u32checked_xor + u32xor swap movup.2 movup.4 - u32checked_xor + u32xor movdn.2 movup.3 movup.4 - u32checked_xor + u32xor movdn.3 dup.4 @@ -2376,21 +2376,21 @@ proc.chi.4 loc_loadw.2 movup.4 - u32checked_xor + u32xor swap movup.4 - u32checked_xor + u32xor swap movup.2 movup.4 - u32checked_xor + u32xor movdn.2 movup.3 movup.4 - u32checked_xor + u32xor movdn.3 dup.4 @@ -2407,21 +2407,21 @@ proc.chi.4 loc_loadw.3 movup.4 - u32checked_xor + u32xor swap movup.4 - u32checked_xor + u32xor swap movup.2 movup.4 - u32checked_xor + u32xor movdn.2 movup.3 movup.4 - u32checked_xor + u32xor movdn.3 dup.4 @@ -2435,19 +2435,19 @@ proc.chi.4 dup.4 mem_loadw - u32checked_not + u32not swap - u32checked_not + u32not swap dup.3 dup.3 movup.2 - u32checked_and + u32and swap movup.2 - u32checked_and + u32and swap push.0.0 @@ -2463,37 +2463,37 @@ proc.chi.4 movup.5 movup.5 - u32checked_not + u32not swap - u32checked_not + u32not swap dup.3 dup.3 movup.2 - u32checked_and + u32and swap movup.2 - u32checked_and + u32and swap movup.3 movup.3 - u32checked_not + u32not swap - u32checked_not + u32not swap dup.5 dup.5 movup.2 - u32checked_and + u32and swap movup.2 - u32checked_and + u32and swap movup.3 @@ -2514,19 +2514,19 @@ proc.chi.4 movup.3 movup.3 - u32checked_not + u32not swap - u32checked_not + u32not swap dup.3 dup.3 movup.2 - u32checked_and + u32and swap movup.2 - u32checked_and + u32and swap movup.4 @@ -2546,16 +2546,16 @@ proc.chi.4 movup.5 movup.5 - u32checked_not + u32not swap - u32checked_not + u32not swap movup.2 - u32checked_and + u32and swap movup.2 - u32checked_and + u32and swap movup.3 @@ -2574,21 +2574,21 @@ proc.chi.4 loc_loadw.1 movup.4 - u32checked_xor + u32xor swap movup.4 - u32checked_xor + u32xor swap movup.2 movup.4 - u32checked_xor + u32xor movdn.2 movup.3 movup.4 - u32checked_xor + u32xor movdn.3 dup.4 @@ -2605,21 +2605,21 @@ proc.chi.4 loc_loadw.2 movup.4 - u32checked_xor + u32xor swap movup.4 - u32checked_xor + u32xor swap movup.2 movup.4 - u32checked_xor + u32xor movdn.2 movup.3 movup.4 - u32checked_xor + u32xor movdn.3 dup.4 @@ -2636,21 +2636,21 @@ proc.chi.4 loc_loadw.3 movup.4 - u32checked_xor + u32xor swap movup.4 - u32checked_xor + u32xor swap movup.2 movup.4 - u32checked_xor + u32xor movdn.2 movup.3 movup.4 - u32checked_xor + u32xor movdn.3 dup.4 @@ -2679,37 +2679,37 @@ proc.chi.4 movup.5 movup.5 - u32checked_not + u32not swap - u32checked_not + u32not swap dup.3 dup.3 movup.2 - u32checked_and + u32and swap movup.2 - u32checked_and + u32and swap movup.3 movup.3 - u32checked_not + u32not swap - u32checked_not + u32not swap dup.5 dup.5 movup.2 - u32checked_and + u32and swap movup.2 - u32checked_and + u32and swap movup.3 @@ -2732,19 +2732,19 @@ proc.chi.4 movup.3 movup.3 - u32checked_not + u32not swap - u32checked_not + u32not swap dup.3 dup.3 movup.2 - u32checked_and + u32and swap movup.2 - u32checked_and + u32and swap movup.4 @@ -2759,19 +2759,19 @@ proc.chi.4 movup.7 movup.7 - u32checked_not + u32not swap - u32checked_not + u32not swap dup.3 dup.3 movup.2 - u32checked_and + u32and swap movup.2 - u32checked_and + u32and swap movup.7 @@ -2780,16 +2780,16 @@ proc.chi.4 loc_storew.2 dropw - u32checked_not + u32not swap - u32checked_not + u32not swap movup.2 - u32checked_and + u32and swap movup.2 - u32checked_and + u32and swap push.0.0 @@ -2805,21 +2805,21 @@ proc.chi.4 loc_loadw.1 movup.4 - u32checked_xor + u32xor swap movup.4 - u32checked_xor + u32xor swap movup.2 movup.4 - u32checked_xor + u32xor movdn.2 movup.3 movup.4 - u32checked_xor + u32xor movdn.3 dup.4 @@ -2836,21 +2836,21 @@ proc.chi.4 loc_loadw.2 movup.4 - u32checked_xor + u32xor swap movup.4 - u32checked_xor + u32xor swap movup.2 movup.4 - u32checked_xor + u32xor movdn.2 movup.3 movup.4 - u32checked_xor + u32xor movdn.3 dup.4 @@ -2867,21 +2867,21 @@ proc.chi.4 loc_loadw.3 movup.4 - u32checked_xor + u32xor swap movup.4 - u32checked_xor + u32xor swap movup.2 movup.4 - u32checked_xor + u32xor movdn.2 movup.3 movup.4 - u32checked_xor + u32xor movdn.3 dup.4 @@ -2915,12 +2915,12 @@ proc.iota mem_loadw movup.5 - u32checked_xor + u32xor swap movup.5 - u32checked_xor + u32xor swap @@ -3197,9 +3197,9 @@ export.to_bit_interleaved push.0.0 repeat.16 - u32unchecked_shr.1 + u32shr.1 swap - u32unchecked_shr.1 + u32shr.1 swap # --- @@ -3208,19 +3208,19 @@ export.to_bit_interleaved dup.3 push.1 - u32checked_and + u32and swap push.1 - u32checked_and + u32and swap - u32unchecked_shl.31 + u32shl.31 swap - u32unchecked_shl.15 + u32shl.15 swap - u32checked_xor - u32checked_xor + u32xor + u32xor # --- @@ -3228,30 +3228,30 @@ export.to_bit_interleaved dup.3 push.2 - u32checked_and + u32and swap push.2 - u32checked_and + u32and swap - u32unchecked_shl.30 + u32shl.30 swap - u32unchecked_shl.14 + u32shl.14 swap movup.3 - u32checked_xor - u32checked_xor + u32xor + u32xor swap # --- movup.2 - u32unchecked_shr.2 + u32shr.2 movdn.2 movup.3 - u32unchecked_shr.2 + u32shr.2 movdn.3 end @@ -3285,9 +3285,9 @@ export.from_bit_interleaved push.0.0 repeat.16 - u32unchecked_shr.2 + u32shr.2 swap - u32unchecked_shr.2 + u32shr.2 swap # --- @@ -3296,18 +3296,18 @@ export.from_bit_interleaved dup.3 push.1 - u32checked_and + u32and swap push.1 - u32checked_and + u32and - u32unchecked_shl.31 + u32shl.31 swap - u32unchecked_shl.30 - u32checked_xor + u32shl.30 + u32xor movup.2 - u32checked_xor + u32xor swap # --- @@ -3316,26 +3316,26 @@ export.from_bit_interleaved dup.3 push.65536 - u32checked_and + u32and swap push.65536 - u32checked_and + u32and - u32unchecked_shl.15 + u32shl.15 swap - u32unchecked_shl.14 - u32checked_xor + u32shl.14 + u32xor - u32checked_xor + u32xor # --- movup.2 - u32unchecked_shr.1 + u32shr.1 movdn.2 movup.3 - u32unchecked_shr.1 + u32shr.1 movdn.3 end diff --git a/stdlib/asm/crypto/hashes/native.masm b/stdlib/asm/crypto/hashes/native.masm index 4b2ec0d8f0..278a2da2bf 100644 --- a/stdlib/asm/crypto/hashes/native.masm +++ b/stdlib/asm/crypto/hashes/native.masm @@ -46,7 +46,7 @@ end #! odd words: 60 cycles + 3 * words export.hash_memory # enforce `start_addr < end_addr` - dup.1 dup.1 u32checked_gt assert + dup.1 dup.1 u32assert2 u32gt assert # figure out if the range is for an odd number of words (9 cycles) dup.1 dup.1 sub is_odd diff --git a/stdlib/asm/crypto/hashes/sha256.masm b/stdlib/asm/crypto/hashes/sha256.masm index 197d966aee..7b627c1114 100644 --- a/stdlib/asm/crypto/hashes/sha256.masm +++ b/stdlib/asm/crypto/hashes/sha256.masm @@ -7,19 +7,19 @@ #! See https://github.com/itzmeanjan/merklize-sha/blob/8a2c006/include/sha2.hpp#L73-L79 proc.small_sigma_0 dup - u32unchecked_rotr.7 + u32rotr.7 swap dup - u32unchecked_rotr.18 + u32rotr.18 swap - u32unchecked_shr.3 + u32shr.3 - u32checked_xor - u32checked_xor + u32xor + u32xor end #! Computes SHA2 small sigma 1. @@ -31,19 +31,19 @@ end #! See https://github.com/itzmeanjan/merklize-sha/blob/8a2c006/include/sha2.hpp#L81-L87 proc.small_sigma_1 dup - u32unchecked_rotr.17 + u32rotr.17 swap dup - u32unchecked_rotr.19 + u32rotr.19 swap - u32unchecked_shr.10 + u32shr.10 - u32checked_xor - u32checked_xor + u32xor + u32xor end #! Computes SHA2 big sigma 0. @@ -55,19 +55,19 @@ end #! See https://github.com/itzmeanjan/merklize-sha/blob/8a2c006/include/sha2.hpp#L57-L63 proc.cap_sigma_0 dup - u32unchecked_rotr.2 + u32rotr.2 swap dup - u32unchecked_rotr.13 + u32rotr.13 swap - u32unchecked_rotr.22 + u32rotr.22 - u32checked_xor - u32checked_xor + u32xor + u32xor end #! Computes SHA2 big sigma 1. @@ -79,19 +79,19 @@ end #! See https://github.com/itzmeanjan/merklize-sha/blob/8a2c006/include/sha2.hpp#L65-L71 proc.cap_sigma_1 dup - u32unchecked_rotr.6 + u32rotr.6 swap dup - u32unchecked_rotr.11 + u32rotr.11 swap - u32unchecked_rotr.25 + u32rotr.25 - u32checked_xor - u32checked_xor + u32xor + u32xor end #! Computes SHA2 ch. @@ -104,15 +104,15 @@ end proc.ch swap dup.1 - u32checked_and + u32and swap - u32checked_not + u32not movup.2 - u32checked_and + u32and - u32checked_xor + u32xor end #! Computes SHA2 maj. @@ -125,18 +125,18 @@ end proc.maj dup.1 dup.1 - u32checked_and + u32and swap dup.3 - u32checked_and + u32and movup.2 movup.3 - u32checked_and + u32and - u32checked_xor - u32checked_xor + u32xor + u32xor end #! Reverses order of first four elements on stack @@ -1571,23 +1571,23 @@ export.hash_memory.12 loc_store.1 # loc.2 (padded length): input_length + (55 - input_length) % 64 + 9 - push.55 loc_load.1 u32wrapping_sub push.63 u32checked_and - loc_load.1 u32checked_add u32checked_add.9 loc_store.2 + push.55 loc_load.1 u32wrapping_sub push.63 u32and + loc_load.1 u32assert2 u32overflowing_add assertz u32assert u32overflowing_add.9 assertz loc_store.2 # loc.3 (last memory address in padding): input_address + padded_length / 16 - 1 - loc_load.2 u32checked_div.16 loc_load.0 u32wrapping_add u32wrapping_sub.1 loc_store.3 + loc_load.2 u32assert u32div.16 loc_load.0 u32wrapping_add u32wrapping_sub.1 loc_store.3 # loc.4 (u32 aligned padding byte): 0x80000000 >> ((input_length % 4) * 8) - loc_load.1 u32checked_mod.4 u32checked_mul.8 push.0x80000000 swap u32checked_shr loc_store.4 + loc_load.1 u32assert u32mod.4 u32assert u32overflowing_mul.8 assertz push.0x80000000 swap u32shr loc_store.4 # loc.5 (memory offset of first padding byte): (input_length / 4) % 4 - loc_load.1 u32checked_div.4 u32checked_mod.4 loc_store.5 + loc_load.1 u32assert u32div.4 u32mod.4 loc_store.5 # loc.6 (memory address of first padding byte): input_address + (len / 16) - loc_load.0 loc_load.1 u32checked_div.16 u32checked_add loc_store.6 + loc_load.0 loc_load.1 u32assert u32div.16 u32assert2 u32overflowing_add assertz loc_store.6 # loc.7 (number of remaining 512-bit blocks to consume): padded_length / 64 - loc_load.2 u32checked_div.64 loc_store.7 + loc_load.2 u32assert u32div.64 loc_store.7 # Set the first byte after the message to 0x80 padw loc_load.6 mem_loadw loc_store.8 loc_store.9 loc_store.10 loc_store.11 @@ -1596,7 +1596,7 @@ export.hash_memory.12 # Set message length in bits at end of padding padw loc_load.3 mem_loadw - movup.3 drop loc_load.1 u32checked_mul.8 movdn.3 + movup.3 drop loc_load.1 u32assert u32overflowing_mul.8 assertz movdn.3 loc_load.3 mem_storew dropw # Sha256 init @@ -1604,16 +1604,16 @@ export.hash_memory.12 push.0xa54ff53a.0x3c6ef372.0xbb67ae85.0x6a09e667 # Consume sha256 blocks - loc_load.7 u32checked_neq.0 + loc_load.7 u32assert neq.0 while.true - padw loc_load.0 u32checked_add.3 mem_loadw movdnw.2 - padw loc_load.0 u32checked_add.2 mem_loadw movdnw.2 - padw loc_load.0 u32checked_add.1 mem_loadw movdnw.2 - padw loc_load.0 u32checked_add.0 mem_loadw movdnw.2 + padw loc_load.0 u32assert u32overflowing_add.3 assertz mem_loadw movdnw.2 + padw loc_load.0 u32assert u32overflowing_add.2 assertz mem_loadw movdnw.2 + padw loc_load.0 u32assert u32overflowing_add.1 assertz mem_loadw movdnw.2 + padw loc_load.0 u32assert u32overflowing_add.0 assertz mem_loadw movdnw.2 exec.prepare_message_schedule_and_consume - loc_load.0 u32checked_add.4 loc_store.0 - loc_load.7 u32checked_sub.1 dup loc_store.7 - u32checked_neq.0 + loc_load.0 u32assert u32overflowing_add.4 assertz loc_store.0 + loc_load.7 u32assert u32overflowing_sub.1 assertz dup loc_store.7 + u32assert neq.0 end end diff --git a/stdlib/asm/crypto/stark/random_coin.masm b/stdlib/asm/crypto/stark/random_coin.masm index 7bcb997b81..e66b024a40 100644 --- a/stdlib/asm/crypto/stark/random_coin.masm +++ b/stdlib/asm/crypto/stark/random_coin.masm @@ -247,7 +247,7 @@ proc.generate_random_coefficients # If we use field division and num_tuples is not a multiple of 4 then we will enter into # a very large loop with high probability. push.0 dup movup.2 movup.3 - u32checked_divmod.4 + u32assert u32divmod.4 assertz neg #=> [loop_ctr, dest_ptr, x, x, ...] @@ -320,7 +320,7 @@ proc.generate_random_coefficients_pad # If we use field division and num_tuples is not a multiple of 4 then we will enter into # a very large loop with high probability. push.0 dup movup.2 movup.3 - u32checked_divmod.4 + u32assert u32divmod.4 assertz neg #=> [loop_ctr, dest_ptr, x, x, ...] @@ -520,7 +520,7 @@ proc.generate_four_integers dup.3 # [r0, R1, ptr, mask, depth, ...] u32split swap # [r0_lo, r0_hi, R1, ptr, mask, depth, ...] dup.7 # [mask, r0_lo, r0_hi, R1, ptr, mask, depth, ...] - u32checked_and # [r, r0_hi, R1, ptr, mask, depth, ...] + u32and # [r, r0_hi, R1, ptr, mask, depth, ...] dup.8 swap # [r, depth, r0_hi, R1, ptr, mask, depth, ...] push.0 movdn.3 # [r, depth, r0_hi, 0, R1, ptr, mask, depth, ...] @@ -533,7 +533,7 @@ proc.generate_four_integers dup.2 # [r1, R1, ptr, mask, depth, ...] u32split swap # [r1_lo, r1_hi, R1, ptr, mask, depth, ...] dup.7 # [mask, r1_lo, r1_hi, R1, ptr, mask, depth, ...] - u32checked_and # [r, r1_hi, R1, ptr, mask, depth, ...] + u32and # [r, r1_hi, R1, ptr, mask, depth, ...] dup.8 swap # [r, depth, r1_hi, R1, ptr, mask, depth, ...] push.0 movdn.3 # [r, depth, r1_hi, 0, R1, ptr, mask, depth, ...] @@ -546,7 +546,7 @@ proc.generate_four_integers dup.1 u32split swap dup.7 - u32checked_and + u32and dup.8 swap push.0 movdn.3 @@ -559,7 +559,7 @@ proc.generate_four_integers dup u32split swap dup.7 - u32checked_and + u32and dup.8 swap push.0 movdn.3 @@ -585,7 +585,7 @@ proc.generate_three_integers dup.2 # [r0, R1, ptr, mask, depth, ...] u32split swap # [r0_lo, r0_hi, R1, ptr, mask, depth, ...] dup.7 # [mask, r0_lo, r0_hi, R1, ptr, mask, depth, ...] - u32checked_and # [r, r0_hi, R1, ptr, mask, depth, ...] + u32and # [r, r0_hi, R1, ptr, mask, depth, ...] dup.8 swap # [r, depth, r0_hi, R1, ptr, mask, depth, ...] push.0 movdn.3 # [r, depth, r0_hi, 0, R1, ptr, mask, depth, ...] @@ -598,7 +598,7 @@ proc.generate_three_integers dup.1 # [r1, R1, ptr, mask, depth, ...] u32split swap # [r1_lo, r1_hi, R1, ptr, mask, depth, ...] dup.7 # [mask, r1_lo, r1_hi, R1, ptr, mask, depth, ...] - u32checked_and # [r, r1_hi, R1, ptr, mask, depth, ...] + u32and # [r, r1_hi, R1, ptr, mask, depth, ...] dup.8 swap # [r, depth, r1_hi, R1, ptr, mask, depth, ...] push.0 movdn.3 # [r, depth, r1_hi, 0, R1, ptr, mask, depth, ...] @@ -611,7 +611,7 @@ proc.generate_three_integers dup.0 u32split swap dup.7 - u32checked_and + u32and dup.8 swap push.0 movdn.3 @@ -676,7 +676,7 @@ export.generate_list_indices push.7 sub ## Divide by 8 to get the number of iterations - u32checked_divmod.8 + u32assert u32divmod.8 #=> [remainder, quotient, X, query_ptr, mask, depth, ...] ## Save remainder for later use @@ -721,7 +721,7 @@ export.generate_list_indices movup.7 u32split swap # [r0_lo, r0_hi, R2, r3, r2, r1, ptr, mask, depth, ...] dup.10 # [mask, r0_lo, r0_hi, R2, r3, r2, r1, ptr, mask, depth, ...] - u32checked_and # [r, r0_hi, R2, r3, r2, r1, ptr, mask, depth, ...] + u32and # [r, r0_hi, R2, r3, r2, r1, ptr, mask, depth, ...] dup.11 swap # [r, depth, r0_hi, R2, r3, r2, r1, ptr, mask, depth, ...] push.0 movdn.3 # [r, depth, r0_hi, 0, R2, r3, r2, r1, ptr, mask, depth, ...] @@ -750,7 +750,7 @@ export.check_pow # Compute the mask. pow2 - u32checked_sub.1 + u32assert u32overflowing_sub.1 assertz #=> [mask, ...] # Load Capacity portion @@ -783,7 +783,7 @@ export.check_pow # Make sure the PoW is valid u32split drop - u32checked_and + u32and assertz drop #=> [...] diff --git a/stdlib/asm/math/ecgfp5/group.masm b/stdlib/asm/math/ecgfp5/group.masm index a9967baffb..ddecc813cd 100644 --- a/stdlib/asm/math/ecgfp5/group.masm +++ b/stdlib/asm/math/ecgfp5/group.masm @@ -634,7 +634,7 @@ export.mul.10 repeat.32 dup push.1 - u32checked_and + u32and if.true # bring base @@ -697,7 +697,7 @@ export.mul.10 loc_store.4 - u32unchecked_shr.1 + u32shr.1 end drop @@ -1094,10 +1094,10 @@ export.gen_mul.8 dup push.1 - u32checked_and + u32and movdn.4 - u32unchecked_shr.1 + u32shr.1 loc_storew.0 dropw @@ -1159,10 +1159,10 @@ export.gen_mul.8 dup push.1 - u32checked_and + u32and movdn.4 - u32unchecked_shr.1 + u32shr.1 loc_storew.2 dropw diff --git a/stdlib/asm/math/ecgfp5/scalar_field.masm b/stdlib/asm/math/ecgfp5/scalar_field.masm index e9a37da8c8..2572fb3cdd 100644 --- a/stdlib/asm/math/ecgfp5/scalar_field.masm +++ b/stdlib/asm/math/ecgfp5/scalar_field.masm @@ -149,82 +149,82 @@ proc.select dup movup.12 dup.3 - u32checked_xor - u32checked_and + u32xor + u32and movup.2 - u32checked_xor + u32xor dup.1 movup.12 dup.4 - u32checked_xor - u32checked_and + u32xor + u32and movup.3 - u32checked_xor + u32xor dup.2 movup.12 dup.5 - u32checked_xor - u32checked_and + u32xor + u32and movup.4 - u32checked_xor + u32xor dup.3 movup.12 dup.6 - u32checked_xor - u32checked_and + u32xor + u32and movup.5 - u32checked_xor + u32xor dup.4 movup.12 dup.7 - u32checked_xor - u32checked_and + u32xor + u32and movup.6 - u32checked_xor + u32xor dup.5 movup.12 dup.8 - u32checked_xor - u32checked_and + u32xor + u32and movup.7 - u32checked_xor + u32xor dup.6 movup.12 dup.9 - u32checked_xor - u32checked_and + u32xor + u32and movup.8 - u32checked_xor + u32xor dup.7 movup.12 dup.10 - u32checked_xor - u32checked_and + u32xor + u32and movup.9 - u32checked_xor + u32xor dup.8 movup.12 dup.11 - u32checked_xor - u32checked_and + u32xor + u32and movup.10 - u32checked_xor + u32xor movup.9 movup.11 dup.11 - u32checked_xor - u32checked_and + u32xor + u32and movup.10 - u32checked_xor + u32xor swap movup.2 @@ -3857,7 +3857,7 @@ export.inv.6 dropw dup - u32unchecked_shr.31 + u32shr.31 if.true # bring base back to stack push.0.0.0.0.0.0.0.0.0.0.0.0 @@ -3897,7 +3897,7 @@ export.inv.6 dropw end - u32unchecked_shl.1 + u32shl.1 end drop diff --git a/stdlib/asm/math/secp256k1/base_field.masm b/stdlib/asm/math/secp256k1/base_field.masm index 5b5fde8250..66b2d7f76f 100644 --- a/stdlib/asm/math/secp256k1/base_field.masm +++ b/stdlib/asm/math/secp256k1/base_field.masm @@ -608,7 +608,7 @@ export.inv.4 dropw dup - u32unchecked_shr.31 + u32shr.31 if.true push.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0 @@ -630,7 +630,7 @@ export.inv.4 dropw end - u32unchecked_shl.1 + u32shl.1 end drop diff --git a/stdlib/asm/math/secp256k1/group.masm b/stdlib/asm/math/secp256k1/group.masm index 5478223347..d92994f713 100644 --- a/stdlib/asm/math/secp256k1/group.masm +++ b/stdlib/asm/math/secp256k1/group.masm @@ -1029,7 +1029,7 @@ export.mul.18 repeat.32 dup push.1 - u32checked_and + u32and if.true # res = base + res @@ -1135,7 +1135,7 @@ export.mul.18 dropw - u32unchecked_shr.1 + u32shr.1 end drop @@ -3289,9 +3289,9 @@ export.gen_mul.20 loc_loadw.18 dup push.1 - u32checked_and + u32and movdn.4 - u32unchecked_shr.1 + u32shr.1 loc_storew.18 dropw diff --git a/stdlib/asm/math/secp256k1/scalar_field.masm b/stdlib/asm/math/secp256k1/scalar_field.masm index 6347b5816c..4e5a7cc44a 100644 --- a/stdlib/asm/math/secp256k1/scalar_field.masm +++ b/stdlib/asm/math/secp256k1/scalar_field.masm @@ -468,7 +468,7 @@ export.inv.4 dropw dup - u32unchecked_shr.31 + u32shr.31 if.true push.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0 @@ -490,7 +490,7 @@ export.inv.4 dropw end - u32unchecked_shl.1 + u32shl.1 end drop diff --git a/stdlib/asm/math/u256.masm b/stdlib/asm/math/u256.masm index 9dd5c49086..7598009cd3 100644 --- a/stdlib/asm/math/u256.masm +++ b/stdlib/asm/math/u256.masm @@ -93,87 +93,87 @@ export.and swapw.3 movup.3 movup.7 - u32checked_and + u32and movup.3 movup.6 - u32checked_and + u32and movup.3 movup.5 - u32checked_and + u32and movup.3 movup.4 - u32checked_and + u32and swapw.2 movup.3 movup.7 - u32checked_and + u32and movup.3 movup.6 - u32checked_and + u32and movup.3 movup.5 - u32checked_and + u32and movup.3 movup.4 - u32checked_and + u32and end export.or swapw.3 movup.3 movup.7 - u32checked_or + u32or movup.3 movup.6 - u32checked_or + u32or movup.3 movup.5 - u32checked_or + u32or movup.3 movup.4 - u32checked_or + u32or swapw.2 movup.3 movup.7 - u32checked_or + u32or movup.3 movup.6 - u32checked_or + u32or movup.3 movup.5 - u32checked_or + u32or movup.3 movup.4 - u32checked_or + u32or end export.xor swapw.3 movup.3 movup.7 - u32checked_xor + u32xor movup.3 movup.6 - u32checked_xor + u32xor movup.3 movup.5 - u32checked_xor + u32xor movup.3 movup.4 - u32checked_xor + u32xor swapw.2 movup.3 movup.7 - u32checked_xor + u32xor movup.3 movup.6 - u32checked_xor + u32xor movup.3 movup.5 - u32checked_xor + u32xor movup.3 movup.4 - u32checked_xor + u32xor end export.iszero_unsafe diff --git a/stdlib/asm/math/u64.masm b/stdlib/asm/math/u64.masm index 4e6cabf229..19c6d5a3ce 100644 --- a/stdlib/asm/math/u64.masm +++ b/stdlib/asm/math/u64.masm @@ -306,10 +306,10 @@ end #! [b_hi, b_lo, a_hi, a_lo, ...] -> [c, ...], where c = 1 when a == b, and 0 otherwise. export.unchecked_eq movup.2 - u32checked_eq + eq swap movup.2 - u32checked_eq + eq and end @@ -319,10 +319,10 @@ end #! [b_hi, b_lo, a_hi, a_lo, ...] -> [c, ...], where c = 1 when a == b, and 0 otherwise. export.checked_eq movup.2 - u32checked_eq + u32assert2 eq swap movup.2 - u32checked_eq + u32assert2 eq and end @@ -332,10 +332,10 @@ end #! [b_hi, b_lo, a_hi, a_lo, ...] -> [c, ...], where c = 1 when a != b, and 0 otherwise. export.unchecked_neq movup.2 - u32checked_neq + neq swap movup.2 - u32checked_neq + neq or end @@ -624,10 +624,10 @@ end export.checked_and swap movup.3 - u32checked_and + u32and swap movup.2 - u32checked_and + u32and end #! Performs bitwise OR of two unsigned 64 bit integers. @@ -637,10 +637,10 @@ end export.checked_or swap movup.3 - u32checked_or + u32or swap movup.2 - u32checked_or + u32or end #! Performs bitwise XOR of two unsigned 64 bit integers. @@ -650,10 +650,10 @@ end export.checked_xor swap movup.3 - u32checked_xor + u32xor swap movup.2 - u32checked_xor + u32xor end #! Performs left shift of one unsigned 64-bit integer using the pow2 operation. @@ -685,7 +685,7 @@ export.unchecked_shr add movup.2 swap - u32unchecked_divmod + u32divmod movup.3 movup.3 dup @@ -695,7 +695,7 @@ export.unchecked_shr movdn.4 dup movdn.4 - u32unchecked_divmod + u32divmod drop push.4294967296 dup.5 @@ -774,7 +774,7 @@ export.unchecked_rotl # Shift the low limb. push.31 - u32checked_and + u32and pow2 dup movup.3 @@ -812,7 +812,7 @@ export.unchecked_rotr # Shift the low limb left by 32-b. push.31 - u32checked_and + u32and push.32 swap u32overflowing_sub diff --git a/stdlib/tests/crypto/sha256.rs b/stdlib/tests/crypto/sha256.rs index d283167e61..8fe1400281 100644 --- a/stdlib/tests/crypto/sha256.rs +++ b/stdlib/tests/crypto/sha256.rs @@ -19,14 +19,14 @@ fn sha256_hash_memory() { mem_store.1 # mem.2 - length in felts - mem_load.1 u32checked_add.3 u32checked_div.4 mem_store.2 + mem_load.1 u32assert u32overflowing_add.3 assertz u32assert u32div.4 mem_store.2 # Load input data into memory address 10000, 10001, ... - mem_load.2 u32checked_neq.0 + mem_load.2 u32assert neq.0 while.true mem_load.0 mem_storew dropw - mem_load.0 u32checked_add.1 mem_store.0 - mem_load.2 u32checked_sub.1 dup mem_store.2 u32checked_neq.0 + mem_load.0 u32assert u32overflowing_add.1 assertz mem_store.0 + mem_load.2 u32assert u32overflowing_sub.1 assertz dup mem_store.2 u32assert neq.0 end # Compute hash of memory address 10000, 10001, ... diff --git a/stdlib/tests/math/secp256k1/group.rs b/stdlib/tests/math/secp256k1/group.rs index ec926ba7c3..a889a22837 100644 --- a/stdlib/tests/math/secp256k1/group.rs +++ b/stdlib/tests/math/secp256k1/group.rs @@ -64,26 +64,26 @@ fn test_secp256k1_point_doubling(src: Point, dst: Point) { movup.4 mem_loadw - u32checked_eq.{} + u32assert eq.{} assert - u32checked_eq.{} + u32assert eq.{} assert - u32checked_eq.{} + u32assert eq.{} assert - u32checked_eq.{} + u32assert eq.{} assert push.0.0.0.0 movup.4 mem_loadw - u32checked_eq.{} + u32assert eq.{} assert - u32checked_eq.{} + u32assert eq.{} assert - u32checked_eq.{} + u32assert eq.{} assert - u32checked_eq.{} + u32assert eq.{} assert # --- end asserting X3 --- @@ -92,26 +92,26 @@ fn test_secp256k1_point_doubling(src: Point, dst: Point) { movup.4 mem_loadw - u32checked_eq.{} + u32assert eq.{} assert - u32checked_eq.{} + u32assert eq.{} assert - u32checked_eq.{} + u32assert eq.{} assert - u32checked_eq.{} + u32assert eq.{} assert push.0.0.0.0 movup.4 mem_loadw - u32checked_eq.{} + u32assert eq.{} assert - u32checked_eq.{} + u32assert eq.{} assert - u32checked_eq.{} + u32assert eq.{} assert - u32checked_eq.{} + u32assert eq.{} assert # --- end asserting Y3 --- @@ -120,26 +120,26 @@ fn test_secp256k1_point_doubling(src: Point, dst: Point) { movup.4 mem_loadw - u32checked_eq.{} + u32assert eq.{} assert - u32checked_eq.{} + u32assert eq.{} assert - u32checked_eq.{} + u32assert eq.{} assert - u32checked_eq.{} + u32assert eq.{} assert push.0.0.0.0 movup.4 mem_loadw - u32checked_eq.{} + u32assert eq.{} assert - u32checked_eq.{} + u32assert eq.{} assert - u32checked_eq.{} + u32assert eq.{} assert - u32checked_eq.{} + u32assert eq.{} assert # --- end asserting Z3 --- end @@ -291,26 +291,26 @@ fn test_secp256k1_point_addition(src0: Point, src1: Point, dst: Point) { movup.4 mem_loadw - u32checked_eq.{} + u32assert eq.{} assert - u32checked_eq.{} + u32assert eq.{} assert - u32checked_eq.{} + u32assert eq.{} assert - u32checked_eq.{} + u32assert eq.{} assert push.0.0.0.0 movup.4 mem_loadw - u32checked_eq.{} + u32assert eq.{} assert - u32checked_eq.{} + u32assert eq.{} assert - u32checked_eq.{} + u32assert eq.{} assert - u32checked_eq.{} + u32assert eq.{} assert # --- end asserting X3 --- @@ -319,26 +319,26 @@ fn test_secp256k1_point_addition(src0: Point, src1: Point, dst: Point) { movup.4 mem_loadw - u32checked_eq.{} + u32assert eq.{} assert - u32checked_eq.{} + u32assert eq.{} assert - u32checked_eq.{} + u32assert eq.{} assert - u32checked_eq.{} + u32assert eq.{} assert push.0.0.0.0 movup.4 mem_loadw - u32checked_eq.{} + u32assert eq.{} assert - u32checked_eq.{} + u32assert eq.{} assert - u32checked_eq.{} + u32assert eq.{} assert - u32checked_eq.{} + u32assert eq.{} assert # --- end asserting Y3 --- @@ -347,26 +347,26 @@ fn test_secp256k1_point_addition(src0: Point, src1: Point, dst: Point) { movup.4 mem_loadw - u32checked_eq.{} + u32assert eq.{} assert - u32checked_eq.{} + u32assert eq.{} assert - u32checked_eq.{} + u32assert eq.{} assert - u32checked_eq.{} + u32assert eq.{} assert push.0.0.0.0 movup.4 mem_loadw - u32checked_eq.{} + u32assert eq.{} assert - u32checked_eq.{} + u32assert eq.{} assert - u32checked_eq.{} + u32assert eq.{} assert - u32checked_eq.{} + u32assert eq.{} assert # --- end asserting Z3 --- end @@ -517,26 +517,26 @@ fn test_secp256k1_point_multiplication(src_point: Point, scalar: FieldElement, d movup.4 mem_loadw - u32checked_eq.{} + u32assert eq.{} assert - u32checked_eq.{} + u32assert eq.{} assert - u32checked_eq.{} + u32assert eq.{} assert - u32checked_eq.{} + u32assert eq.{} assert push.0.0.0.0 movup.4 mem_loadw - u32checked_eq.{} + u32assert eq.{} assert - u32checked_eq.{} + u32assert eq.{} assert - u32checked_eq.{} + u32assert eq.{} assert - u32checked_eq.{} + u32assert eq.{} assert # --- end asserting X --- @@ -545,26 +545,26 @@ fn test_secp256k1_point_multiplication(src_point: Point, scalar: FieldElement, d movup.4 mem_loadw - u32checked_eq.{} + u32assert eq.{} assert - u32checked_eq.{} + u32assert eq.{} assert - u32checked_eq.{} + u32assert eq.{} assert - u32checked_eq.{} + u32assert eq.{} assert push.0.0.0.0 movup.4 mem_loadw - u32checked_eq.{} + u32assert eq.{} assert - u32checked_eq.{} + u32assert eq.{} assert - u32checked_eq.{} + u32assert eq.{} assert - u32checked_eq.{} + u32assert eq.{} assert # --- end asserting Y --- @@ -573,26 +573,26 @@ fn test_secp256k1_point_multiplication(src_point: Point, scalar: FieldElement, d movup.4 mem_loadw - u32checked_eq.{} + u32assert eq.{} assert - u32checked_eq.{} + u32assert eq.{} assert - u32checked_eq.{} + u32assert eq.{} assert - u32checked_eq.{} + u32assert eq.{} assert push.0.0.0.0 movup.4 mem_loadw - u32checked_eq.{} + u32assert eq.{} assert - u32checked_eq.{} + u32assert eq.{} assert - u32checked_eq.{} + u32assert eq.{} assert - u32checked_eq.{} + u32assert eq.{} assert # --- end asserting Z --- end @@ -693,26 +693,26 @@ fn test_secp256k1_generator_multiplication(scalar: FieldElement, point: Point) { movup.4 mem_loadw - u32checked_eq.{} + u32assert eq.{} assert - u32checked_eq.{} + u32assert eq.{} assert - u32checked_eq.{} + u32assert eq.{} assert - u32checked_eq.{} + u32assert eq.{} assert push.0.0.0.0 movup.4 mem_loadw - u32checked_eq.{} + u32assert eq.{} assert - u32checked_eq.{} + u32assert eq.{} assert - u32checked_eq.{} + u32assert eq.{} assert - u32checked_eq.{} + u32assert eq.{} assert # --- end asserting X --- @@ -721,26 +721,26 @@ fn test_secp256k1_generator_multiplication(scalar: FieldElement, point: Point) { movup.4 mem_loadw - u32checked_eq.{} + u32assert eq.{} assert - u32checked_eq.{} + u32assert eq.{} assert - u32checked_eq.{} + u32assert eq.{} assert - u32checked_eq.{} + u32assert eq.{} assert push.0.0.0.0 movup.4 mem_loadw - u32checked_eq.{} + u32assert eq.{} assert - u32checked_eq.{} + u32assert eq.{} assert - u32checked_eq.{} + u32assert eq.{} assert - u32checked_eq.{} + u32assert eq.{} assert # --- end asserting Y --- @@ -749,26 +749,26 @@ fn test_secp256k1_generator_multiplication(scalar: FieldElement, point: Point) { movup.4 mem_loadw - u32checked_eq.{} + u32assert eq.{} assert - u32checked_eq.{} + u32assert eq.{} assert - u32checked_eq.{} + u32assert eq.{} assert - u32checked_eq.{} + u32assert eq.{} assert push.0.0.0.0 movup.4 mem_loadw - u32checked_eq.{} + u32assert eq.{} assert - u32checked_eq.{} + u32assert eq.{} assert - u32checked_eq.{} + u32assert eq.{} assert - u32checked_eq.{} + u32assert eq.{} assert # --- end asserting Z --- end