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

Add truncated loadu8. #164

Merged
merged 2 commits into from
Apr 30, 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
2 changes: 1 addition & 1 deletion assembler/grammar/assembly.pest
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ comment = { ";" ~ (!"\n" ~ ANY)* ~ "\n" }
label = { (!":" ~ !"\n" ~ ANY)+ ~ ":" ~ "\n" }
instruction = { mnemonic ~ (operand ~ ", "?)+? ~ "\n"? }
mnemonic = {
"lw" | "sw" | "loadu8" | "loads8" | "storeu8" | "jalv" | "jal" | "beqi" | "beq" | "bnei" | "bne" | "imm32" | "stop" |
"lw" | "sw" | "loadu8" | "tloadu8" | "loads8" | "storeu8" | "jalv" | "jal" | "beqi" | "beq" | "bnei" | "bne" | "imm32" | "stop" |
"advread" | "advwrite" |
"addi" | "add" | "subi" | "sub" | "muli" | "mul" | "mulhsi"| "mulhui"| "mulhs"| "mulhu" | "divi" | "div" | "sdiv" | "sdivi" |
"ilte" | "ltei" | "lte" | "ilt" | "lti" | "lt" | "shli" | "shl" | "shri" | "shr" | "srai" | "sra" |
Expand Down
3 changes: 2 additions & 1 deletion assembler/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ pub fn assemble(input: &str) -> Result<Vec<u8>, String> {
// Core CPU
"lw" => LOAD32,
"loadu8" => LOADU8,
"tloadu8" => TLOADU8,
"loads8" => LOADS8,
"sw" => STORE32,
"storeu8" => STOREU8,
Expand Down Expand Up @@ -104,7 +105,7 @@ pub fn assemble(input: &str) -> Result<Vec<u8>, String> {

// Insert zero operands if necessary
match mnemonic {
"lw" | "loadu8" | "loads8" => {
"lw" | "loadu8" | "tloadu8" | "loads8" => {
// (a, 0, c, 0, 0)
operands.insert(1, 0);
operands.extend(vec![0; 2]);
Expand Down
5 changes: 5 additions & 0 deletions basic/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ use valida_cpu::{
BeqInstruction, BneInstruction, Imm32Instruction, JalInstruction, JalvInstruction,
Load32Instruction, LoadFpInstruction, LoadS8Instruction, LoadU8Instruction,
ReadAdviceInstruction, StopInstruction, Store32Instruction, StoreU8Instruction,
TLoadU8Instruction,
};
use valida_cpu::{CpuChip, MachineWithCpuChip};
use valida_machine::__internal::p3_challenger::{CanObserve, FieldChallenger};
Expand All @@ -67,6 +68,7 @@ pub struct BasicMachine<F: PrimeField32 + TwoAdicField> {
// Core instructions
load32: Load32Instruction,
loadu8: LoadU8Instruction,
tloadu8: TLoadU8Instruction,
loads8: LoadS8Instruction,
store32: Store32Instruction,
storeu8: StoreU8Instruction,
Expand Down Expand Up @@ -1081,6 +1083,9 @@ impl<F: PrimeField32 + TwoAdicField> Machine<F> for BasicMachine<F> {
<LoadU8Instruction as Instruction<Self, F>>::OPCODE => {
LoadU8Instruction::execute_with_advice::<Adv>(self, ops, advice)
}
<TLoadU8Instruction as Instruction<Self, F>>::OPCODE => {
TLoadU8Instruction::execute_with_advice::<Adv>(self, ops, advice)
}
<LoadS8Instruction as Instruction<Self, F>>::OPCODE => {
LoadS8Instruction::execute_with_advice::<Adv>(self, ops, advice)
}
Expand Down
1 change: 1 addition & 0 deletions cpu/src/columns.rs
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ pub struct OpcodeFlagCols<T> {
pub is_imm_op: T,
pub is_load: T,
pub is_load_u8: T,
pub is_tload_u8: T,
pub is_load_s8: T,
pub is_store: T,
pub is_store_u8: T,
Expand Down
72 changes: 69 additions & 3 deletions cpu/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ use valida_machine::{
use valida_memory::{MachineWithMemoryChip, Operation as MemoryOperation};
use valida_opcodes::{
BEQ, BNE, BYTES_PER_INSTR, IMM32, JAL, JALV, LOAD32, LOADFP, LOADS8, LOADU8, READ_ADVICE, STOP,
STORE32, STOREU8,
STORE32, STOREU8, TLOADU8,
};

use p3_air::VirtualPairCol;
Expand All @@ -37,6 +37,7 @@ pub enum Operation {
StoreU8,
Load32,
LoadU8,
TLoadU8,
LoadS8,
Jal,
Jalv,
Expand Down Expand Up @@ -187,6 +188,9 @@ impl CpuChip {
Operation::LoadU8 => {
cols.opcode_flags.is_load_u8 = SC::Val::one();
}
Operation::TLoadU8 => {
cols.opcode_flags.is_tload_u8 = SC::Val::one();
}
Operation::LoadS8 => {
cols.opcode_flags.is_load_s8 = SC::Val::one();
}
Expand Down Expand Up @@ -365,6 +369,7 @@ pub trait MachineWithCpuChip<F: Field>: MachineWithMemoryChip<F> {
instructions!(
Load32Instruction,
LoadU8Instruction,
TLoadU8Instruction,
LoadS8Instruction,
Store32Instruction,
StoreU8Instruction,
Expand Down Expand Up @@ -475,6 +480,68 @@ where
}
}

impl<M, F> Instruction<M, F> for TLoadU8Instruction
where
M: MachineWithCpuChip<F>,
F: Field,
{
const OPCODE: u32 = TLOADU8;

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 fp = state.cpu().fp;

let read_addr_loc = (fp as i32 + ops.c()) as u32;

let read_addr = state
.mem_mut()
.read(clk, read_addr_loc, true, pc, opcode, 0, "");
let read_addr_index = addr_of_word(read_addr.into());

// The word from the read address.
let cell = state.mem_mut().read(
clk,
read_addr_index,
true,
pc,
opcode,
1,
&format!(
"fp = {}, c = {}, [fp+c] = {:?}",
fp as i32,
ops.c() as u32,
read_addr_index
),
);

// The array index of the word for the byte to read from
let index_of_read = index_of_byte(read_addr.into());
// The byte from the read cell.
let cell_byte: u8 = cell[index_of_read];

let write_addr = (state.cpu().fp as i32 + ops.a()) as u32;
// The address, converted to a multiple of 4.
let write_addr_index = addr_of_word(write_addr);

// The array index of the word for the byte to write to
let index_of_write = index_of_byte(write_addr);

// The original content of the cell to write to. If the cell is empty, initiate it with a default value.
let cell_write = state.mem_mut().read_or_init(clk, write_addr_index, true);

// The Word to write, with one byte overwritten to the read byte
let cell_to_write = cell_write.update_byte(cell_byte, index_of_write);

state
.mem_mut()
.write(clk, write_addr_index, cell_to_write, true);
state.cpu_mut().pc += 1;
state.cpu_mut().push_op(Operation::TLoadU8, opcode, ops);
}
}

impl<M, F> Instruction<M, F> for LoadU8Instruction
where
M: MachineWithCpuChip<F>,
Expand Down Expand Up @@ -520,7 +587,6 @@ where
// The address, converted to a multiple of 4.
let write_addr_index = addr_of_word(write_addr);

// The Word to write, with one byte overwritten to the read byte
state
.mem_mut()
.write(clk, write_addr_index, Word::from_u8(cell_byte), true);
Expand Down Expand Up @@ -575,7 +641,7 @@ where
// The address, converted to a multiple of 4.
let write_addr_index = addr_of_word(write_addr);

// The Word to write, with one byte overwritten to the read byte
// The Word to write, with the read byte sign extended to 32 bits.
let cell_to_write = Word::sign_extend_byte(cell_byte);

state
Expand Down
3 changes: 2 additions & 1 deletion machine/src/core.rs
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,8 @@ impl Word<u8> {
}
}

// The cell is stored in little endian format in the compiler. But the VM stores it in big endian.
/// Update the cell with one byte overwritten to the input byte.
/// The cell is stored in little endian format in the compiler. But the VM stores it in big endian.
impl Word<u8> {
pub fn update_byte(self, byte: u8, loc: usize) -> Self {
let result_little_end: [u8; MEMORY_CELL_BYTES] = self.0;
Expand Down
3 changes: 3 additions & 0 deletions machine/src/program.rs
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,9 @@ impl InstructionWord<i32> {
valida_opcodes::LOADU8 => {
format!("{}(fp), {}(fp)", self.operands.0[0], self.operands.0[2])
}
valida_opcodes::TLOADU8 => {
format!("{}(fp), {}(fp)", self.operands.0[0], self.operands.0[2])
}
valida_opcodes::LOADS8 => {
format!("{}(fp), {}(fp)", self.operands.0[0], self.operands.0[2])
}
Expand Down
2 changes: 2 additions & 0 deletions opcodes/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ pub enum Opcode {
LOADU8 = 11,
LOADS8 = 12,
STOREU8 = 13,
TLOADU8 = 16,

ADD32 = 100,
SUB32 = 101,
Expand Down Expand Up @@ -65,6 +66,7 @@ declare_opcode!(LOADFP);
declare_opcode!(LOADU8);
declare_opcode!(LOADS8);
declare_opcode!(STOREU8);
declare_opcode!(TLOADU8);

/// NONDETERMINISTIC
declare_opcode!(READ_ADVICE);
Expand Down
Loading