Skip to content

Commit

Permalink
issue/159: signed inequality comparison instructions (#162)
Browse files Browse the repository at this point in the history
  • Loading branch information
morganthomas authored Apr 26, 2024
1 parent 132ccf9 commit fdf0ddf
Show file tree
Hide file tree
Showing 4 changed files with 142 additions and 3 deletions.
123 changes: 121 additions & 2 deletions alu_u32/src/lt/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ use valida_cpu::MachineWithCpuChip;
use valida_machine::{
instructions, Chip, Instruction, Interaction, Operands, Word, MEMORY_CELL_BYTES,
};
use valida_opcodes::{LT32, LTE32};
use valida_opcodes::{LT32, LTE32, SLE32, SLT32};

use p3_air::VirtualPairCol;
use p3_field::{AbstractField, Field, PrimeField};
Expand All @@ -26,6 +26,8 @@ pub mod stark;
pub enum Operation {
Lt32(Word<u8>, Word<u8>, Word<u8>), // (dst, src1, src2)
Lte32(Word<u8>, Word<u8>, Word<u8>), // (dst, src1, src2)
Slt32(Word<u8>, Word<u8>, Word<u8>), // (dst, src1, src2)
Sle32(Word<u8>, Word<u8>, Word<u8>), // (dst, src1, src2)
}

#[derive(Default)]
Expand Down Expand Up @@ -98,6 +100,16 @@ impl Lt32Chip {
cols.is_lte = F::one();
self.set_cols(cols, a, b, c);
}
Operation::Slt32(a, b, c) => {
// TODO: this is just a placeholder
cols.is_lt = F::one();
self.set_cols(cols, a, b, c);
}
Operation::Sle32(a, b, c) => {
// TODO: this is just a placeholder
cols.is_lte = F::one();
self.set_cols(cols, a, b, c);
}
}
row
}
Expand Down Expand Up @@ -134,7 +146,12 @@ pub trait MachineWithLt32Chip<F: Field>: MachineWithCpuChip<F> {
fn lt_u32_mut(&mut self) -> &mut Lt32Chip;
}

instructions!(Lt32Instruction, Lte32Instruction);
instructions!(
Lt32Instruction,
Lte32Instruction,
Slt32Instruction,
Sle32Instruction
);

impl<M, F> Instruction<M, F> for Lt32Instruction
where
Expand Down Expand Up @@ -233,3 +250,105 @@ where
state.cpu_mut().push_bus_op(imm, opcode, ops);
}
}

impl<M, F> Instruction<M, F> for Slt32Instruction
where
M: MachineWithLt32Chip<F>,
F: Field,
{
const OPCODE: u32 = SLT32;

fn execute(state: &mut M, ops: Operands<i32>) {
let opcode = <Self as Instruction<M, F>>::OPCODE;
let clk = state.cpu().clock;
let pc = state.cpu().pc;
let mut imm: Option<Word<u8>> = None;
let read_addr_1 = (state.cpu().fp as i32 + ops.b()) as u32;
let write_addr = (state.cpu().fp as i32 + ops.a()) as u32;
let src1: Word<u8> = if ops.d() == 1 {
let b = (ops.b() as u32).into();
imm = Some(b);
b
} else {
state
.mem_mut()
.read(clk, read_addr_1, true, pc, opcode, 0, "")
};
let src2: Word<u8> = if ops.is_imm() == 1 {
let c = (ops.c() as u32).into();
imm = Some(c);
c
} else {
let read_addr_2 = (state.cpu().fp as i32 + ops.c()) as u32;
state
.mem_mut()
.read(clk, read_addr_2, true, pc, opcode, 1, "")
};

let src1_i: i32 = src1.into();
let src2_i: i32 = src2.into();
let dst = if src1_i < src2_i {
Word::from(1)
} else {
Word::from(0)
};
state.mem_mut().write(clk, write_addr, dst, true);

state
.lt_u32_mut()
.operations
.push(Operation::Slt32(dst, src1, src2));
state.cpu_mut().push_bus_op(imm, opcode, ops);
}
}

impl<M, F> Instruction<M, F> for Sle32Instruction
where
M: MachineWithLt32Chip<F>,
F: Field,
{
const OPCODE: u32 = SLE32;

fn execute(state: &mut M, ops: Operands<i32>) {
let opcode = <Self as Instruction<M, F>>::OPCODE;
let clk = state.cpu().clock;
let pc = state.cpu().pc;
let mut imm: Option<Word<u8>> = None;
let read_addr_1 = (state.cpu().fp as i32 + ops.b()) as u32;
let write_addr = (state.cpu().fp as i32 + ops.a()) as u32;
let src1: Word<u8> = if ops.d() == 1 {
let b = (ops.b() as u32).into();
imm = Some(b);
b
} else {
state
.mem_mut()
.read(clk, read_addr_1, true, pc, opcode, 0, "")
};
let src2: Word<u8> = if ops.is_imm() == 1 {
let c = (ops.c() as u32).into();
imm = Some(c);
c
} else {
let read_addr_2 = (state.cpu().fp as i32 + ops.c()) as u32;
state
.mem_mut()
.read(clk, read_addr_2, true, pc, opcode, 1, "")
};

let src1_i: i32 = src1.into();
let src2_i: i32 = src2.into();
let dst = if src1_i <= src2_i {
Word::from(1)
} else {
Word::from(0)
};
state.mem_mut().write(clk, write_addr, dst, true);

state
.lt_u32_mut()
.operations
.push(Operation::Sle32(dst, src1, src2));
state.cpu_mut().push_bus_op(imm, opcode, ops);
}
}
11 changes: 10 additions & 1 deletion basic/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,10 @@ use valida_alu_u32::{
},
com::{Com32Chip, Eq32Instruction, MachineWithCom32Chip, Ne32Instruction},
div::{Div32Chip, Div32Instruction, MachineWithDiv32Chip, SDiv32Instruction},
lt::{Lt32Chip, Lt32Instruction, Lte32Instruction, MachineWithLt32Chip},
lt::{
Lt32Chip, Lt32Instruction, Lte32Instruction, MachineWithLt32Chip, Sle32Instruction,
Slt32Instruction,
},
mul::{
MachineWithMul32Chip, Mul32Chip, Mul32Instruction, Mulhs32Instruction, Mulhu32Instruction,
},
Expand Down Expand Up @@ -1144,6 +1147,12 @@ impl<F: PrimeField32 + TwoAdicField> Machine<F> for BasicMachine<F> {
<Lte32Instruction as Instruction<Self, F>>::OPCODE => {
Lte32Instruction::execute_with_advice::<Adv>(self, ops, advice)
}
<Slt32Instruction as Instruction<Self, F>>::OPCODE => {
Slt32Instruction::execute_with_advice::<Adv>(self, ops, advice)
}
<Sle32Instruction as Instruction<Self, F>>::OPCODE => {
Sle32Instruction::execute_with_advice::<Adv>(self, ops, advice)
}
<And32Instruction as Instruction<Self, F>>::OPCODE => {
And32Instruction::execute_with_advice::<Adv>(self, ops, advice)
}
Expand Down
7 changes: 7 additions & 0 deletions machine/src/core.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
use super::MEMORY_CELL_BYTES;
use core::cmp::Ordering;
use core::mem::transmute;
use core::ops::{Add, BitAnd, BitOr, BitXor, Div, Index, IndexMut, Mul, Shl, Shr, Sub};
use p3_field::{Field, PrimeField};

Expand Down Expand Up @@ -82,6 +83,12 @@ impl Into<u32> for Word<u8> {
}
}

impl Into<i32> for Word<u8> {
fn into(self) -> i32 {
unsafe { transmute::<u32, i32>(self.into()) }
}
}

impl From<u32> for Word<u8> {
fn from(value: u32) -> Self {
let mut result = Word::<u8>::default();
Expand Down
4 changes: 4 additions & 0 deletions opcodes/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,8 @@ pub enum Opcode {
MULHS32 = 114,
LTE32 = 115,
EQ32 = 116,
SLT32 = 117,
SLE32 = 118,
ADD = 200,
SUB = 201,
MUL = 202,
Expand Down Expand Up @@ -85,6 +87,8 @@ declare_opcode!(SRA32);
declare_opcode!(MULHS32);
declare_opcode!(LTE32);
declare_opcode!(EQ32);
declare_opcode!(SLT32);
declare_opcode!(SLE32);

/// NATIVE FIELD
declare_opcode!(ADD);
Expand Down

0 comments on commit fdf0ddf

Please sign in to comment.