From 4a6c8cd349f9d1f09255f86eae4290469ea8d3dc Mon Sep 17 00:00:00 2001 From: Andrey Date: Wed, 3 Jul 2024 18:53:57 +0300 Subject: [PATCH] refactor: add imm value emulation, remove excess instructions --- .../src/assembler/instruction/field_ops.rs | 42 ----------- assembly/src/assembler/instruction/mod.rs | 22 ++---- assembly/src/assembler/instruction/u32_ops.rs | 36 ++-------- assembly/src/ast/instruction/deserialize.rs | 10 --- assembly/src/ast/instruction/mod.rs | 10 --- assembly/src/ast/instruction/opcode.rs | 10 --- assembly/src/ast/instruction/print.rs | 10 --- assembly/src/ast/instruction/serialize.rs | 40 ----------- assembly/src/ast/visit.rs | 18 +---- assembly/src/parser/grammar.lalrpop | 70 ++++++++++++++++--- 10 files changed, 74 insertions(+), 194 deletions(-) diff --git a/assembly/src/assembler/instruction/field_ops.rs b/assembly/src/assembler/instruction/field_ops.rs index 8c7fabc90e..5833f735d8 100644 --- a/assembly/src/assembler/instruction/field_ops.rs +++ b/assembly/src/assembler/instruction/field_ops.rs @@ -353,16 +353,6 @@ pub fn lt(span_builder: &mut BasicBlockBuilder) { set_result(span_builder); } -/// Appends a sequence of operations to pop the top element off the stack and do a "less than" -/// comparison with a provided immediate value. The stack is expected to be arranged as [a, ...] -/// (from the top). A value of 1 is pushed onto the stack if a < imm. Otherwise, 0 is pushed. -/// -/// This operation takes 15 VM cycles. -pub fn lt_imm(basic_block_builder: &mut BasicBlockBuilder, imm: Felt) { - basic_block_builder.push_op(Push(imm)); - lt(basic_block_builder); -} - /// Appends a sequence of operations to pop the top 2 elements off the stack and do a "less /// than or equal" 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. @@ -387,17 +377,6 @@ pub fn lte(span_builder: &mut BasicBlockBuilder) { set_result(span_builder); } -/// Appends a sequence of operations to pop the top element off the stack and do a "less than or -/// equal" comparison with a provided immediate value. The stack is expected to be arranged as -/// [a, ...] (from the top). A value of 1 is pushed onto the stack if a <= imm. Otherwise, 0 is -/// pushed. -/// -/// This operation takes 16 VM cycles. -pub fn lte_imm(span_builder: &mut BasicBlockBuilder, imm: Felt) { - span_builder.push_op(Push(imm)); - lte(span_builder); -} - /// Appends a sequence of operations to pop the top 2 elements off the stack and do a "greater /// 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. @@ -422,16 +401,6 @@ pub fn gt(span_builder: &mut BasicBlockBuilder) { set_result(span_builder); } -/// Appends a sequence of operations to pop the top element off the stack and do a "greater than" -/// comparison with a provided immediate value. The stack is expected to be arranged as [a, ...] -/// (from the top). A value of 1 is pushed onto the stack if a > imm. Otherwise, 0 is pushed. -/// -/// This operation takes 16 VM cycles. -pub fn gt_imm(span_builder: &mut BasicBlockBuilder, imm: Felt) { - span_builder.push_op(Push(imm)); - gt(span_builder); -} - /// Appends a sequence of operations to pop the top 2 elements off the stack and do a "greater /// than or equal" 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. @@ -456,17 +425,6 @@ pub fn gte(span_builder: &mut BasicBlockBuilder) { set_result(span_builder); } -/// Appends a sequence of operations to pop the top element off the stack and do a "greater than -/// or equal" comparison with a provided immediate value. The stack is expected to be arranged as -/// [a, ...] (from the top). A value of 1 is pushed onto the stack if a >= imm. Otherwise, 0 is -/// pushed. -/// -/// This operation takes 17 VM cycles. -pub fn gte_imm(span_builder: &mut BasicBlockBuilder, imm: Felt) { - span_builder.push_op(Push(imm)); - gte(span_builder); -} - /// Checks if the top element in the stack is an odd number or not. /// /// Vm cycles: 5 diff --git a/assembly/src/assembler/instruction/mod.rs b/assembly/src/assembler/instruction/mod.rs index 48f01ce203..531323225f 100644 --- a/assembly/src/assembler/instruction/mod.rs +++ b/assembly/src/assembler/instruction/mod.rs @@ -103,13 +103,9 @@ impl Assembler { Instruction::Neq => span_builder.push_ops([Eq, Not]), Instruction::NeqImm(imm) => field_ops::neq_imm(span_builder, imm.expect_value()), Instruction::Lt => field_ops::lt(span_builder), - Instruction::LtImm(imm) => field_ops::lt_imm(span_builder, imm.expect_value()), Instruction::Lte => field_ops::lte(span_builder), - Instruction::LteImm(imm) => field_ops::lte_imm(span_builder, imm.expect_value()), Instruction::Gt => field_ops::gt(span_builder), - Instruction::GtImm(imm) => field_ops::gt_imm(span_builder, imm.expect_value()), Instruction::Gte => field_ops::gte(span_builder), - Instruction::GteImm(imm) => field_ops::gte_imm(span_builder, imm.expect_value()), Instruction::IsOdd => field_ops::is_odd(span_builder), // ----- ext2 instructions ------------------------------------------------------------ @@ -199,18 +195,12 @@ impl Assembler { Instruction::U32Ctz => u32_ops::u32ctz(span_builder), Instruction::U32Clo => u32_ops::u32clo(span_builder), Instruction::U32Cto => u32_ops::u32cto(span_builder), - Instruction::U32Lt => u32_ops::u32lt(span_builder, None), - Instruction::U32LtImm(v) => u32_ops::u32lt(span_builder, Some(v.expect_value())), - Instruction::U32Lte => u32_ops::u32lte(span_builder, None), - Instruction::U32LteImm(v) => u32_ops::u32lte(span_builder, Some(v.expect_value())), - Instruction::U32Gt => u32_ops::u32gt(span_builder, None), - Instruction::U32GtImm(v) => u32_ops::u32gt(span_builder, Some(v.expect_value())), - Instruction::U32Gte => u32_ops::u32gte(span_builder, None), - Instruction::U32GteImm(v) => u32_ops::u32gte(span_builder, Some(v.expect_value())), - Instruction::U32Min => u32_ops::u32min(span_builder, None), - Instruction::U32MinImm(v) => u32_ops::u32min(span_builder, Some(v.expect_value())), - Instruction::U32Max => u32_ops::u32max(span_builder, None), - Instruction::U32MaxImm(v) => u32_ops::u32max(span_builder, Some(v.expect_value())), + Instruction::U32Lt => u32_ops::u32lt(span_builder), + Instruction::U32Lte => u32_ops::u32lte(span_builder), + Instruction::U32Gt => u32_ops::u32gt(span_builder), + Instruction::U32Gte => u32_ops::u32gte(span_builder), + Instruction::U32Min => u32_ops::u32min(span_builder), + Instruction::U32Max => u32_ops::u32max(span_builder), // ----- stack manipulation ----------------------------------------------------------- Instruction::Drop => span_builder.push_op(Drop), diff --git a/assembly/src/assembler/instruction/u32_ops.rs b/assembly/src/assembler/instruction/u32_ops.rs index e5b5575728..e3e3f355e1 100644 --- a/assembly/src/assembler/instruction/u32_ops.rs +++ b/assembly/src/assembler/instruction/u32_ops.rs @@ -719,11 +719,7 @@ fn calculate_cto(span: &mut BasicBlockBuilder) { /// This operation takes: /// - 3 cycles without immediate value. /// - 4 cycles with immediate value. -pub fn u32lt(span_builder: &mut BasicBlockBuilder, imm: Option) { - if let Some(imm) = imm { - span_builder.push_op(Push(Felt::from(imm))); - } - +pub fn u32lt(span_builder: &mut BasicBlockBuilder) { compute_lt(span_builder); } @@ -732,11 +728,7 @@ pub fn u32lt(span_builder: &mut BasicBlockBuilder, imm: Option) { /// This operation takes: /// - 5 cycles without immediate value. /// - 6 cycles with immediate value. -pub fn u32lte(span_builder: &mut BasicBlockBuilder, imm: Option) { - if let Some(imm) = imm { - span_builder.push_op(Push(Felt::from(imm))); - } - +pub fn u32lte(span_builder: &mut BasicBlockBuilder) { // Compute the lt with reversed number to get a gt check span_builder.push_op(Swap); compute_lt(span_builder); @@ -750,11 +742,7 @@ pub fn u32lte(span_builder: &mut BasicBlockBuilder, imm: Option) { /// This operation takes: /// - 4 cycles without immediate value. /// - 5 cycles with immediate value. -pub fn u32gt(span_builder: &mut BasicBlockBuilder, imm: Option) { - if let Some(imm) = imm { - span_builder.push_op(Push(Felt::from(imm))); - } - +pub fn u32gt(span_builder: &mut BasicBlockBuilder) { // Reverse the numbers so we can get a gt check. span_builder.push_op(Swap); @@ -766,11 +754,7 @@ pub fn u32gt(span_builder: &mut BasicBlockBuilder, imm: Option) { /// This operation takes: /// - 4 cycles without immediate value. /// - 5 cycles with immediate value. -pub fn u32gte(span_builder: &mut BasicBlockBuilder, imm: Option) { - if let Some(imm) = imm { - span_builder.push_op(Push(Felt::from(imm))); - } - +pub fn u32gte(span_builder: &mut BasicBlockBuilder) { compute_lt(span_builder); // Flip the final results to get the gte results. @@ -786,11 +770,7 @@ pub fn u32gte(span_builder: &mut BasicBlockBuilder, imm: Option) { /// This operation takes: /// - 8 cycles without immediate value. /// - 9 cycles with immediate value. -pub fn u32min(span_builder: &mut BasicBlockBuilder, imm: Option) { - if let Some(imm) = imm { - span_builder.push_op(Push(Felt::from(imm))); - } - +pub fn u32min(span_builder: &mut BasicBlockBuilder) { compute_max_and_min(span_builder); // Drop the max and keep the min @@ -806,11 +786,7 @@ pub fn u32min(span_builder: &mut BasicBlockBuilder, imm: Option) { /// This operation takes: /// - 9 cycles without immediate value. /// - 10 cycles with immediate value. -pub fn u32max(span_builder: &mut BasicBlockBuilder, imm: Option) { - if let Some(imm) = imm { - span_builder.push_op(Push(Felt::from(imm))); - } - +pub fn u32max(span_builder: &mut BasicBlockBuilder) { compute_max_and_min(span_builder); // Drop the min and keep the max diff --git a/assembly/src/ast/instruction/deserialize.rs b/assembly/src/ast/instruction/deserialize.rs index abdbefa7a4..3c86c914d7 100644 --- a/assembly/src/ast/instruction/deserialize.rs +++ b/assembly/src/ast/instruction/deserialize.rs @@ -43,13 +43,9 @@ impl Deserializable for Instruction { OpCode::NeqImm => Ok(Self::NeqImm(Felt::read_from(source)?.into())), OpCode::Eqw => Ok(Self::Eqw), OpCode::Lt => Ok(Self::Lt), - OpCode::LtImm => Ok(Self::LtImm(Felt::read_from(source)?.into())), OpCode::Lte => Ok(Self::Lte), - OpCode::LteImm => Ok(Self::LteImm(Felt::read_from(source)?.into())), OpCode::Gt => Ok(Self::Gt), - OpCode::GtImm => Ok(Self::GtImm(Felt::read_from(source)?.into())), OpCode::Gte => Ok(Self::Gte), - OpCode::GteImm => Ok(Self::GteImm(Felt::read_from(source)?.into())), OpCode::IsOdd => Ok(Self::IsOdd), // ----- ext2 operations -------------------------------------------------------------- @@ -117,17 +113,11 @@ impl Deserializable for Instruction { OpCode::U32Clo => Ok(Self::U32Clo), OpCode::U32Cto => Ok(Self::U32Cto), OpCode::U32Lt => Ok(Self::U32Lt), - OpCode::U32LtImm => Ok(Self::U32LtImm(source.read_u32()?.into())), OpCode::U32Lte => Ok(Self::U32Lte), - OpCode::U32LteImm => Ok(Self::U32LteImm(source.read_u32()?.into())), OpCode::U32Gt => Ok(Self::U32Gt), - OpCode::U32GtImm => Ok(Self::U32GtImm(source.read_u32()?.into())), OpCode::U32Gte => Ok(Self::U32Gte), - OpCode::U32GteImm => Ok(Self::U32GteImm(source.read_u32()?.into())), OpCode::U32Min => Ok(Self::U32Min), - OpCode::U32MinImm => Ok(Self::U32MinImm(source.read_u32()?.into())), OpCode::U32Max => Ok(Self::U32Max), - OpCode::U32MaxImm => Ok(Self::U32MaxImm(source.read_u32()?.into())), // ----- stack manipulation ----------------------------------------------------------- OpCode::Drop => Ok(Self::Drop), diff --git a/assembly/src/ast/instruction/mod.rs b/assembly/src/ast/instruction/mod.rs index 9cb7fda2eb..2589f9b3d6 100644 --- a/assembly/src/ast/instruction/mod.rs +++ b/assembly/src/ast/instruction/mod.rs @@ -56,13 +56,9 @@ pub enum Instruction { NeqImm(ImmFelt), Eqw, Lt, - LtImm(ImmFelt), Lte, - LteImm(ImmFelt), Gt, - GtImm(ImmFelt), Gte, - GteImm(ImmFelt), IsOdd, // ----- ext2 operations --------------------------------------------------------------------- @@ -124,17 +120,11 @@ pub enum Instruction { U32Clo, U32Cto, U32Lt, - U32LtImm(ImmU32), U32Lte, - U32LteImm(ImmU32), U32Gt, - U32GtImm(ImmU32), U32Gte, - U32GteImm(ImmU32), U32Min, - U32MinImm(ImmU32), U32Max, - U32MaxImm(ImmU32), // ----- stack manipulation ------------------------------------------------------------------ Drop, diff --git a/assembly/src/ast/instruction/opcode.rs b/assembly/src/ast/instruction/opcode.rs index 4698997f7b..94aa729d3b 100644 --- a/assembly/src/ast/instruction/opcode.rs +++ b/assembly/src/ast/instruction/opcode.rs @@ -47,13 +47,9 @@ pub enum OpCode { NeqImm, Eqw, Lt, - LtImm, Lte, - LteImm, Gt, - GtImm, Gte, - GteImm, IsOdd, // ----- ext2 operations --------------------------------------------------------------------- @@ -115,17 +111,11 @@ pub enum OpCode { U32Clo, U32Cto, U32Lt, - U32LtImm, U32Lte, - U32LteImm, U32Gt, - U32GtImm, U32Gte, - U32GteImm, U32Min, - U32MinImm, U32Max, - U32MaxImm, // ----- stack manipulation ------------------------------------------------------------------ Drop, diff --git a/assembly/src/ast/instruction/print.rs b/assembly/src/ast/instruction/print.rs index d35ff06bb8..71a297a6b4 100644 --- a/assembly/src/ast/instruction/print.rs +++ b/assembly/src/ast/instruction/print.rs @@ -54,13 +54,9 @@ impl PrettyPrint for Instruction { Self::NeqImm(value) => inst_with_felt_imm("neq", value), Self::Eqw => const_text("eqw"), Self::Lt => const_text("lt"), - Self::LtImm(value) => inst_with_felt_imm("lt", value), Self::Lte => const_text("lte"), - Self::LteImm(value) => inst_with_felt_imm("lte", value), Self::Gt => const_text("gt"), - Self::GtImm(value) => inst_with_felt_imm("gt", value), Self::Gte => const_text("gte"), - Self::GteImm(value) => inst_with_felt_imm("gte", value), Self::IsOdd => const_text("is_odd"), // ----- ext2 operations -------------------------------------------------------------- @@ -128,17 +124,11 @@ impl PrettyPrint for Instruction { Self::U32Clo => const_text("u32clo"), Self::U32Cto => const_text("u32cto"), Self::U32Lt => const_text("u32lt"), - Self::U32LtImm(value) => inst_with_imm("u32lt", value), Self::U32Lte => const_text("u32lte"), - Self::U32LteImm(value) => inst_with_imm("u32lte", value), Self::U32Gt => const_text("u32gt"), - Self::U32GtImm(value) => inst_with_imm("u32gt", value), Self::U32Gte => const_text("u32gte"), - Self::U32GteImm(value) => inst_with_imm("u32gte", value), Self::U32Min => const_text("u32min"), - Self::U32MinImm(value) => inst_with_imm("u32min", value), Self::U32Max => const_text("u32max"), - Self::U32MaxImm(value) => inst_with_imm("u32min", value), // ----- stack manipulation ----------------------------------------------------------- Self::Drop => const_text("drop"), diff --git a/assembly/src/ast/instruction/serialize.rs b/assembly/src/ast/instruction/serialize.rs index 4f3b14adb0..a00cd509cc 100644 --- a/assembly/src/ast/instruction/serialize.rs +++ b/assembly/src/ast/instruction/serialize.rs @@ -77,25 +77,9 @@ impl Serializable for Instruction { } Self::Eqw => OpCode::Eqw.write_into(target), Self::Lt => OpCode::Lt.write_into(target), - Self::LtImm(v) => { - OpCode::LtImm.write_into(target); - v.expect_value().write_into(target); - } Self::Lte => OpCode::Lte.write_into(target), - Self::LteImm(v) => { - OpCode::LteImm.write_into(target); - v.expect_value().write_into(target); - } Self::Gt => OpCode::Gt.write_into(target), - Self::GtImm(v) => { - OpCode::GtImm.write_into(target); - v.expect_value().write_into(target); - } Self::Gte => OpCode::Gte.write_into(target), - Self::GteImm(v) => { - OpCode::GteImm.write_into(target); - v.expect_value().write_into(target); - } Self::IsOdd => OpCode::IsOdd.write_into(target), // ----- ext2 operations -------------------------------------------------------------- @@ -205,35 +189,11 @@ impl Serializable for Instruction { Self::U32Clo => OpCode::U32Clo.write_into(target), Self::U32Cto => OpCode::U32Cto.write_into(target), Self::U32Lt => OpCode::U32Lt.write_into(target), - Self::U32LtImm(v) => { - OpCode::U32LtImm.write_into(target); - target.write_u32(v.expect_value()); - } Self::U32Lte => OpCode::U32Lte.write_into(target), - Self::U32LteImm(v) => { - OpCode::U32LteImm.write_into(target); - target.write_u32(v.expect_value()); - } Self::U32Gt => OpCode::U32Gt.write_into(target), - Self::U32GtImm(v) => { - OpCode::U32GtImm.write_into(target); - target.write_u32(v.expect_value()); - } Self::U32Gte => OpCode::U32Gte.write_into(target), - Self::U32GteImm(v) => { - OpCode::U32GteImm.write_into(target); - target.write_u32(v.expect_value()); - } Self::U32Min => OpCode::U32Min.write_into(target), - Self::U32MinImm(v) => { - OpCode::U32MinImm.write_into(target); - target.write_u32(v.expect_value()); - } Self::U32Max => OpCode::U32Max.write_into(target), - Self::U32MaxImm(v) => { - OpCode::U32MaxImm.write_into(target); - target.write_u32(v.expect_value()); - } // ----- stack manipulation ----------------------------------------------------------- Self::Drop => OpCode::Drop.write_into(target), diff --git a/assembly/src/ast/visit.rs b/assembly/src/ast/visit.rs index 12b6245249..4f07a7527b 100644 --- a/assembly/src/ast/visit.rs +++ b/assembly/src/ast/visit.rs @@ -297,8 +297,7 @@ where | U32AssertWWithError(ref code) | MTreeVerifyWithError(ref code) => visitor.visit_immediate_error_code(code), AddImm(ref imm) | SubImm(ref imm) | MulImm(ref imm) | DivImm(ref imm) | ExpImm(ref imm) - | EqImm(ref imm) | NeqImm(ref imm) | LtImm(ref imm) | LteImm(ref imm) | GtImm(ref imm) - | GteImm(ref imm) | Push(ref imm) => visitor.visit_immediate_felt(imm), + | EqImm(ref imm) | NeqImm(ref imm) | Push(ref imm) => visitor.visit_immediate_felt(imm), U32WrappingAddImm(ref imm) | U32OverflowingAddImm(ref imm) | U32WrappingSubImm(ref imm) @@ -308,12 +307,6 @@ where | U32DivImm(ref imm) | U32ModImm(ref imm) | U32DivModImm(ref imm) - | U32LtImm(ref imm) - | U32LteImm(ref imm) - | U32GtImm(ref imm) - | U32GteImm(ref imm) - | U32MinImm(ref imm) - | U32MaxImm(ref imm) | MemLoadImm(ref imm) | MemLoadWImm(ref imm) | MemStoreImm(ref imm) @@ -744,8 +737,7 @@ where | U32AssertWWithError(ref mut code) | MTreeVerifyWithError(ref mut code) => visitor.visit_mut_immediate_error_code(code), AddImm(ref mut imm) | SubImm(ref mut imm) | MulImm(ref mut imm) | DivImm(ref mut imm) - | ExpImm(ref mut imm) | EqImm(ref mut imm) | NeqImm(ref mut imm) | LtImm(ref mut imm) - | LteImm(ref mut imm) | GtImm(ref mut imm) | GteImm(ref mut imm) | Push(ref mut imm) => { + | ExpImm(ref mut imm) | EqImm(ref mut imm) | NeqImm(ref mut imm) | Push(ref mut imm) => { visitor.visit_mut_immediate_felt(imm) } U32WrappingAddImm(ref mut imm) @@ -757,12 +749,6 @@ where | U32DivImm(ref mut imm) | U32ModImm(ref mut imm) | U32DivModImm(ref mut imm) - | U32LtImm(ref mut imm) - | U32LteImm(ref mut imm) - | U32GtImm(ref mut imm) - | U32GteImm(ref mut imm) - | U32MinImm(ref mut imm) - | U32MaxImm(ref mut imm) | MemLoadImm(ref mut imm) | MemLoadWImm(ref mut imm) | MemStoreImm(ref mut imm) diff --git a/assembly/src/parser/grammar.lalrpop b/assembly/src/parser/grammar.lalrpop index 03933299d1..77b2aefd8f 100644 --- a/assembly/src/parser/grammar.lalrpop +++ b/assembly/src/parser/grammar.lalrpop @@ -626,28 +626,48 @@ FoldableInstWithFeltImmediate: SmallOpsVec = { "lt" > => { let span = span!(l, r); match imm { - Some(imm) => smallvec![Op::Inst(Span::new(span, Instruction::LtImm(imm)))], + Some(imm) => { + match imm { + Immediate::Constant(name) => smallvec![Op::Inst(Span::new(span, Instruction::Push(Immediate::Constant(name)))), Op::Inst(Span::new(span, Instruction::Lt))], + Immediate::Value(value) => smallvec![Op::Inst(Span::new(span, Instruction::PushFelt(value.into_inner()))), Op::Inst(Span::new(span, Instruction::Lt))], + } + } None => smallvec![Op::Inst(Span::new(span, Instruction::Lt))], } }, "lte" > => { let span = span!(l, r); match imm { - Some(imm) => smallvec![Op::Inst(Span::new(span, Instruction::LteImm(imm)))], + Some(imm) => { + match imm { + Immediate::Constant(name) => smallvec![Op::Inst(Span::new(span, Instruction::Push(Immediate::Constant(name)))), Op::Inst(Span::new(span, Instruction::Lte))], + Immediate::Value(value) => smallvec![Op::Inst(Span::new(span, Instruction::PushFelt(value.into_inner()))), Op::Inst(Span::new(span, Instruction::Lte))], + } + } None => smallvec![Op::Inst(Span::new(span, Instruction::Lte))], } }, "gt" > => { let span = span!(l, r); match imm { - Some(imm) => smallvec![Op::Inst(Span::new(span, Instruction::GtImm(imm)))], + Some(imm) => { + match imm { + Immediate::Constant(name) => smallvec![Op::Inst(Span::new(span, Instruction::Push(Immediate::Constant(name)))), Op::Inst(Span::new(span, Instruction::Gt))], + Immediate::Value(value) => smallvec![Op::Inst(Span::new(span, Instruction::PushFelt(value.into_inner()))), Op::Inst(Span::new(span, Instruction::Gt))], + } + } None => smallvec![Op::Inst(Span::new(span, Instruction::Gt))], } }, "gte" > => { let span = span!(l, r); match imm { - Some(imm) => smallvec![Op::Inst(Span::new(span, Instruction::GteImm(imm)))], + Some(imm) => { + match imm { + Immediate::Constant(name) => smallvec![Op::Inst(Span::new(span, Instruction::Push(Immediate::Constant(name)))), Op::Inst(Span::new(span, Instruction::Gte))], + Immediate::Value(value) => smallvec![Op::Inst(Span::new(span, Instruction::PushFelt(value.into_inner()))), Op::Inst(Span::new(span, Instruction::Gte))], + } + } None => smallvec![Op::Inst(Span::new(span, Instruction::Gte))], } }, @@ -847,42 +867,72 @@ FoldableInstWithU32Immediate: SmallOpsVec = { "u32lt" > => { let span = span!(l, r); match imm { - Some(imm) => smallvec![Op::Inst(Span::new(span, Instruction::U32LtImm(imm)))], + Some(imm) => { + match imm { + Immediate::Constant(name) => smallvec![Op::Inst(Span::new(span, Instruction::Push(Immediate::Constant(name)))), Op::Inst(Span::new(span, Instruction::U32Lt))], + Immediate::Value(value) => smallvec![Op::Inst(Span::new(span, Instruction::PushU32(value.into_inner()))), Op::Inst(Span::new(span, Instruction::U32Lt))], + } + } None => smallvec![Op::Inst(Span::new(span, Instruction::U32Lt))], } }, "u32lte" > => { let span = span!(l, r); match imm { - Some(imm) => smallvec![Op::Inst(Span::new(span, Instruction::U32LteImm(imm)))], + Some(imm) => { + match imm { + Immediate::Constant(name) => smallvec![Op::Inst(Span::new(span, Instruction::Push(Immediate::Constant(name)))), Op::Inst(Span::new(span, Instruction::U32Lte))], + Immediate::Value(value) => smallvec![Op::Inst(Span::new(span, Instruction::PushU32(value.into_inner()))), Op::Inst(Span::new(span, Instruction::U32Lte))], + } + } None => smallvec![Op::Inst(Span::new(span, Instruction::U32Lte))], } }, "u32gt" > => { let span = span!(l, r); match imm { - Some(imm) => smallvec![Op::Inst(Span::new(span, Instruction::U32GtImm(imm)))], + Some(imm) => { + match imm { + Immediate::Constant(name) => smallvec![Op::Inst(Span::new(span, Instruction::Push(Immediate::Constant(name)))), Op::Inst(Span::new(span, Instruction::U32Gt))], + Immediate::Value(value) => smallvec![Op::Inst(Span::new(span, Instruction::PushU32(value.into_inner()))), Op::Inst(Span::new(span, Instruction::U32Gt))], + } + } None => smallvec![Op::Inst(Span::new(span, Instruction::U32Gt))], } }, "u32gte" > => { let span = span!(l, r); match imm { - Some(imm) => smallvec![Op::Inst(Span::new(span, Instruction::U32GteImm(imm)))], + Some(imm) => { + match imm { + Immediate::Constant(name) => smallvec![Op::Inst(Span::new(span, Instruction::Push(Immediate::Constant(name)))), Op::Inst(Span::new(span, Instruction::U32Gte))], + Immediate::Value(value) => smallvec![Op::Inst(Span::new(span, Instruction::PushU32(value.into_inner()))), Op::Inst(Span::new(span, Instruction::U32Gte))], + } + } None => smallvec![Op::Inst(Span::new(span, Instruction::U32Gte))], } }, "u32min" > => { let span = span!(l, r); match imm { - Some(imm) => smallvec![Op::Inst(Span::new(span, Instruction::U32MinImm(imm)))], + Some(imm) => { + match imm { + Immediate::Constant(name) => smallvec![Op::Inst(Span::new(span, Instruction::Push(Immediate::Constant(name)))), Op::Inst(Span::new(span, Instruction::U32Min))], + Immediate::Value(value) => smallvec![Op::Inst(Span::new(span, Instruction::PushU32(value.into_inner()))), Op::Inst(Span::new(span, Instruction::U32Min))], + } + } None => smallvec![Op::Inst(Span::new(span, Instruction::U32Min))], } }, "u32max" > => { let span = span!(l, r); match imm { - Some(imm) => smallvec![Op::Inst(Span::new(span, Instruction::U32MaxImm(imm)))], + Some(imm) => { + match imm { + Immediate::Constant(name) => smallvec![Op::Inst(Span::new(span, Instruction::Push(Immediate::Constant(name)))), Op::Inst(Span::new(span, Instruction::U32Max))], + Immediate::Value(value) => smallvec![Op::Inst(Span::new(span, Instruction::PushU32(value.into_inner()))), Op::Inst(Span::new(span, Instruction::U32Max))], + } + } None => smallvec![Op::Inst(Span::new(span, Instruction::U32Max))], } },