Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Rework field and u32 comparison instructions #1380

Merged
merged 1 commit into from
Jul 10, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
42 changes: 0 additions & 42 deletions assembly/src/assembler/instruction/field_ops.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand All @@ -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.
Expand All @@ -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.
Expand All @@ -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
Expand Down
22 changes: 6 additions & 16 deletions assembly/src/assembler/instruction/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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 ------------------------------------------------------------
Expand Down Expand Up @@ -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),
Expand Down
36 changes: 6 additions & 30 deletions assembly/src/assembler/instruction/u32_ops.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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<u32>) {
if let Some(imm) = imm {
span_builder.push_op(Push(Felt::from(imm)));
}

pub fn u32lt(span_builder: &mut BasicBlockBuilder) {
compute_lt(span_builder);
}

Expand All @@ -732,11 +728,7 @@ pub fn u32lt(span_builder: &mut BasicBlockBuilder, imm: Option<u32>) {
/// This operation takes:
/// - 5 cycles without immediate value.
/// - 6 cycles with immediate value.
pub fn u32lte(span_builder: &mut BasicBlockBuilder, imm: Option<u32>) {
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);
Expand All @@ -750,11 +742,7 @@ pub fn u32lte(span_builder: &mut BasicBlockBuilder, imm: Option<u32>) {
/// This operation takes:
/// - 4 cycles without immediate value.
/// - 5 cycles with immediate value.
pub fn u32gt(span_builder: &mut BasicBlockBuilder, imm: Option<u32>) {
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);

Expand All @@ -766,11 +754,7 @@ pub fn u32gt(span_builder: &mut BasicBlockBuilder, imm: Option<u32>) {
/// This operation takes:
/// - 4 cycles without immediate value.
/// - 5 cycles with immediate value.
pub fn u32gte(span_builder: &mut BasicBlockBuilder, imm: Option<u32>) {
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.
Expand All @@ -786,11 +770,7 @@ pub fn u32gte(span_builder: &mut BasicBlockBuilder, imm: Option<u32>) {
/// This operation takes:
/// - 8 cycles without immediate value.
/// - 9 cycles with immediate value.
pub fn u32min(span_builder: &mut BasicBlockBuilder, imm: Option<u32>) {
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
Expand All @@ -806,11 +786,7 @@ pub fn u32min(span_builder: &mut BasicBlockBuilder, imm: Option<u32>) {
/// This operation takes:
/// - 9 cycles without immediate value.
/// - 10 cycles with immediate value.
pub fn u32max(span_builder: &mut BasicBlockBuilder, imm: Option<u32>) {
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
Expand Down
10 changes: 0 additions & 10 deletions assembly/src/ast/instruction/deserialize.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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 --------------------------------------------------------------
Expand Down Expand Up @@ -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),
Expand Down
10 changes: 0 additions & 10 deletions assembly/src/ast/instruction/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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 ---------------------------------------------------------------------
Expand Down Expand Up @@ -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,
Expand Down
10 changes: 0 additions & 10 deletions assembly/src/ast/instruction/opcode.rs
Original file line number Diff line number Diff line change
Expand Up @@ -47,13 +47,9 @@ pub enum OpCode {
NeqImm,
Eqw,
Lt,
LtImm,
Lte,
LteImm,
Gt,
GtImm,
Gte,
GteImm,
IsOdd,

// ----- ext2 operations ---------------------------------------------------------------------
Expand Down Expand Up @@ -115,17 +111,11 @@ pub enum OpCode {
U32Clo,
U32Cto,
U32Lt,
U32LtImm,
U32Lte,
U32LteImm,
U32Gt,
U32GtImm,
U32Gte,
U32GteImm,
U32Min,
U32MinImm,
U32Max,
U32MaxImm,

// ----- stack manipulation ------------------------------------------------------------------
Drop,
Expand Down
10 changes: 0 additions & 10 deletions assembly/src/ast/instruction/print.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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 --------------------------------------------------------------
Expand Down Expand Up @@ -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"),
Expand Down
40 changes: 0 additions & 40 deletions assembly/src/ast/instruction/serialize.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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 --------------------------------------------------------------
Expand Down Expand Up @@ -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),
Expand Down
Loading
Loading