Skip to content

Commit

Permalink
feat: add U32 comparison ops with immediates variants along with
Browse files Browse the repository at this point in the history
other ops to `hir::MasmOp`
  • Loading branch information
greenhat committed Jun 26, 2024
1 parent 39cfefb commit 13af81c
Show file tree
Hide file tree
Showing 2 changed files with 64 additions and 20 deletions.
10 changes: 8 additions & 2 deletions hir/src/asm/builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1855,7 +1855,7 @@ fn apply_op_stack_effects(
assert!(stack.len() >= 8, "expected at least 8 elements on the stack for mtree_merge");
stack.dropw();
}
MasmOp::MtreeVerify => {
MasmOp::MtreeVerify | MasmOp::MtreeVerifyWithError(_) => {
assert!(
stack.len() >= 10,
"expected at least 10 elements on the stack for mtree_verify"
Expand Down Expand Up @@ -2076,7 +2076,13 @@ fn apply_op_stack_effects(
| MasmOp::U32WrappingAddImm(_)
| MasmOp::U32WrappingSubImm(_)
| MasmOp::U32WrappingMulImm(_)
| MasmOp::U32Not => {
| MasmOp::U32Not
| MasmOp::U32LtImm(_)
| MasmOp::U32LteImm(_)
| MasmOp::U32GtImm(_)
| MasmOp::U32GteImm(_)
| MasmOp::U32MinImm(_)
| MasmOp::U32MaxImm(_) => {
let ty = stack.pop().expect("operand stack is empty");
assert_compatible_u32_operand!(ty, op);
stack.push(ty);
Expand Down
74 changes: 56 additions & 18 deletions hir/src/asm/isa.rs
Original file line number Diff line number Diff line change
Expand Up @@ -385,6 +385,16 @@ pub enum MasmOp {
/// [V, d, i, R] => [V, d, i, R]
/// ```
MtreeVerify,
/// Verifies that a Merkle tree with root `R` opens to node `V` at depth `d` and index `i`.
///
/// The Merkle tree with root `R` must be present in the advice provider or the operation
/// fails.
///
/// ```ignore
/// [V, d, i, R] => [V, d, i, R]
/// ```
/// Raise the given error code if the verification fails
MtreeVerifyWithError(u32),
/// Performs FRI layer folding by a factor of 4 for FRI protocol executed in a degree 2
/// extension of the base field. Additionally, performs several computations which simplify
/// FRI verification procedure.
Expand Down Expand Up @@ -782,26 +792,38 @@ pub enum MasmOp {
///
/// This operation is unchecked, so the result is undefined if the operands are not valid u32
U32Lt,
/// Same as above, but `b` is provided by the immediate
U32LtImm(u32),
/// Pops `b, a` from the stack, and places 1 on the stack if `a <= b`, else 0
///
/// This operation is unchecked, so the result is undefined if the operands are not valid u32
U32Lte,
/// Same as above, but `b` is provided by the immediate
U32LteImm(u32),
/// Pops `b, a` from the stack, and places 1 on the stack if `a > b`, else 0
///
/// This operation is unchecked, so the result is undefined if the operands are not valid u32
U32Gt,
/// Same as above, but `b` is provided by the immediate
U32GtImm(u32),
/// Pops `b, a` from the stack, and places 1 on the stack if `a >= b`, else 0
///
/// This operation is unchecked, so the result is undefined if the operands are not valid u32
U32Gte,
/// Same as above, but `b` is provided by the immediate
U32GteImm(u32),
/// Pops `b, a` from the stack, and places `a` back on the stack if `a < b`, else `b`
///
/// This operation is unchecked, so the result is undefined if the operands are not valid u32
U32Min,
/// Same as above, but `b` is provided by the immediate
U32MinImm(u32),
/// Pops `b, a` from the stack, and places `a` back on the stack if `a > b`, else `b`
///
/// This operation is unchecked, so the result is undefined if the operands are not valid u32
U32Max,
/// Same as above, but `b` is provided by the immediate
U32MaxImm(u32),
/// Trigger a breakpoint when this instruction is reached
Breakpoint,
/// Print out the contents of the stack
Expand Down Expand Up @@ -1013,7 +1035,7 @@ impl MasmOp {
Self::MtreeGet => 9,
Self::MtreeSet => 29,
Self::MtreeMerge => 16,
Self::MtreeVerify => 1,
Self::MtreeVerify | Self::MtreeVerifyWithError(_) => 1,
// This hasn't been measured, just a random guess due to the complexity
Self::FriExt2Fold4 | Self::RCombBase => 50,
Self::Ext2add => 5,
Expand Down Expand Up @@ -1074,11 +1096,17 @@ impl MasmOp {
Self::U32Clo => 36,
Self::U32Cto => 33,
Self::U32Lt => 3,
Self::U32LtImm(_) => 4,
Self::U32Lte => 5,
Self::U32LteImm(_) => 6,
Self::U32Gt => 4,
Self::U32GtImm(_) => 5,
Self::U32Gte => 4,
Self::U32GteImm(_) => 5,
Self::U32Min => 8,
Self::U32MinImm(_) => 9,
Self::U32Max => 9,
Self::U32MaxImm(_) => 10,
// These instructions do not modify the VM state, so we place set their cost at 0 for
// now
Self::Emit(_)
Expand Down Expand Up @@ -1151,9 +1179,13 @@ impl MasmOp {
Instruction::NeqImm(imm) => Self::NeqImm(unwrap_imm!(imm)),
Instruction::Eqw => Self::Eqw,
Instruction::Lt => Self::Lt,
Instruction::LtImm(imm) => Self::LtImm(unwrap_imm!(imm)),
Instruction::Lte => Self::Lte,
Instruction::LteImm(imm) => Self::LteImm(unwrap_imm!(imm)),
Instruction::Gt => Self::Gt,
Instruction::GtImm(imm) => Self::GtImm(unwrap_imm!(imm)),
Instruction::Gte => Self::Gte,
Instruction::GteImm(imm) => Self::GteImm(unwrap_imm!(imm)),
Instruction::IsOdd => Self::IsOdd,
Instruction::Hash => Self::Hash,
Instruction::HMerge => Self::Hmerge,
Expand All @@ -1162,6 +1194,9 @@ impl MasmOp {
Instruction::MTreeSet => Self::MtreeSet,
Instruction::MTreeMerge => Self::MtreeMerge,
Instruction::MTreeVerify => Self::MtreeVerify,
Instruction::MTreeVerifyWithError(code) => {
Self::MtreeVerifyWithError(unwrap_u32!(code))
}
Instruction::Ext2Add => Self::Ext2add,
Instruction::Ext2Sub => Self::Ext2sub,
Instruction::Ext2Mul => Self::Ext2mul,
Expand Down Expand Up @@ -1220,11 +1255,17 @@ impl MasmOp {
Instruction::U32Clo => Self::U32Clo,
Instruction::U32Cto => Self::U32Cto,
Instruction::U32Lt => Self::U32Lt,
Instruction::U32LtImm(imm) => Self::U32LtImm(unwrap_u32!(imm)),
Instruction::U32Lte => Self::U32Lte,
Instruction::U32LteImm(imm) => Self::U32LteImm(unwrap_u32!(imm)),
Instruction::U32Gt => Self::U32Gt,
Instruction::U32GtImm(imm) => Self::U32GtImm(unwrap_u32!(imm)),
Instruction::U32Gte => Self::U32Gte,
Instruction::U32GteImm(imm) => Self::U32GteImm(unwrap_u32!(imm)),
Instruction::U32Min => Self::U32Min,
Instruction::U32MinImm(imm) => Self::U32MinImm(unwrap_u32!(imm)),
Instruction::U32Max => Self::U32Max,
Instruction::U32MaxImm(imm) => Self::U32MaxImm(unwrap_u32!(imm)),
Instruction::Drop => Self::Drop,
Instruction::DropW => Self::Dropw,
Instruction::PadW => Self::Padw,
Expand Down Expand Up @@ -1408,17 +1449,6 @@ impl MasmOp {
Self::DebugFrameRange(unwrap_u16!(start), unwrap_u16!(end))
}
Instruction::Nop => Self::Nop,
Instruction::LtImm(imm) => Self::LtImm(unwrap_imm!(imm)),
Instruction::LteImm(imm) => Self::LteImm(unwrap_imm!(imm)),
Instruction::GtImm(imm) => Self::GtImm(unwrap_imm!(imm)),
Instruction::GteImm(imm) => Self::GteImm(unwrap_imm!(imm)),
Instruction::U32LtImm(_) => todo!(),
Instruction::U32LteImm(_) => todo!(),
Instruction::U32GtImm(_) => todo!(),
Instruction::U32GteImm(_) => todo!(),
Instruction::U32MinImm(_) => todo!(),
Instruction::U32MaxImm(_) => todo!(),
Instruction::MTreeVerifyWithError(_) => todo!(),
};
smallvec![op]
}
Expand Down Expand Up @@ -1677,6 +1707,7 @@ impl MasmOp {
Self::MtreeSet => Instruction::MTreeSet,
Self::MtreeMerge => Instruction::MTreeMerge,
Self::MtreeVerify => Instruction::MTreeVerify,
Self::MtreeVerifyWithError(code) => Instruction::MTreeVerifyWithError(code.into()),
Self::FriExt2Fold4 => Instruction::FriExt2Fold4,
Self::RCombBase => Instruction::RCombBase,
Self::U32Test => Instruction::U32Test,
Expand Down Expand Up @@ -1741,11 +1772,17 @@ impl MasmOp {
Self::U32Clo => Instruction::U32Clo,
Self::U32Cto => Instruction::U32Cto,
Self::U32Lt => Instruction::U32Lt,
Self::U32LtImm(imm) => Instruction::U32LtImm(imm.into()),
Self::U32Lte => Instruction::U32Lte,
Self::U32LteImm(imm) => Instruction::U32LteImm(imm.into()),
Self::U32Gt => Instruction::U32Gt,
Self::U32GtImm(imm) => Instruction::U32GtImm(imm.into()),
Self::U32Gte => Instruction::U32Gte,
Self::U32GteImm(imm) => Instruction::U32GteImm(imm.into()),
Self::U32Min => Instruction::U32Min,
Self::U32MinImm(imm) => Instruction::U32MinImm(imm.into()),
Self::U32Max => Instruction::U32Max,
Self::U32MaxImm(imm) => Instruction::U32MaxImm(imm.into()),
Self::Breakpoint => Instruction::Breakpoint,
Self::DebugStack => Instruction::Debug(DebugOptions::StackAll),
Self::DebugStackN(n) => Instruction::Debug(DebugOptions::StackTop(n.into())),
Expand Down Expand Up @@ -1880,6 +1917,7 @@ impl fmt::Display for MasmOp {
Self::MtreeSet => f.write_str("mtree_set"),
Self::MtreeMerge => f.write_str("mtree_merge"),
Self::MtreeVerify => f.write_str("mtree_verify"),
Self::MtreeVerifyWithError(code) => write!(f, "mtree_verify.err={code}"),
Self::FriExt2Fold4 => f.write_str("fri_ext2fold4"),
Self::RCombBase => f.write_str("rcomb_base"),
Self::U32Test => f.write_str("u32test"),
Expand Down Expand Up @@ -1924,12 +1962,12 @@ impl fmt::Display for MasmOp {
Self::U32Ctz => f.write_str("u32ctz"),
Self::U32Clo => f.write_str("u32clo"),
Self::U32Cto => f.write_str("u32cto"),
Self::U32Lt => f.write_str("u32lt"),
Self::U32Lte => f.write_str("u32lte"),
Self::U32Gt => f.write_str("u32gt"),
Self::U32Gte => f.write_str("u32gte"),
Self::U32Min => f.write_str("u32min"),
Self::U32Max => f.write_str("u32max"),
Self::U32Lt | Self::U32LtImm(_) => f.write_str("u32lt"),
Self::U32Lte | Self::U32LteImm(_) => f.write_str("u32lte"),
Self::U32Gt | Self::U32GtImm(_) => f.write_str("u32gt"),
Self::U32Gte | Self::U32GteImm(_) => f.write_str("u32gte"),
Self::U32Min | Self::U32MinImm(_) => f.write_str("u32min"),
Self::U32Max | Self::U32MaxImm(_) => f.write_str("u32max"),
Self::Breakpoint => f.write_str("breakpoint"),
Self::DebugStack | Self::DebugStackN(_) => f.write_str("debug.stack"),
Self::DebugMemory | Self::DebugMemoryAt(_) | Self::DebugMemoryRange(..) => {
Expand Down

0 comments on commit 13af81c

Please sign in to comment.