Skip to content

Commit

Permalink
Merge pull request #164 from valida-xyz/thealmarty-truncloadu8
Browse files Browse the repository at this point in the history
Add truncated loadu8.
  • Loading branch information
thealmarty authored Apr 30, 2024
2 parents e4c92a9 + 953300c commit 4057c01
Show file tree
Hide file tree
Showing 8 changed files with 85 additions and 6 deletions.
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

0 comments on commit 4057c01

Please sign in to comment.