Skip to content

Commit

Permalink
Merge pull request #450 from quangvdao/quang/add-64-bits-instructions
Browse files Browse the repository at this point in the history
Add 64-bit version to all instructions
  • Loading branch information
moodlezoup authored Sep 10, 2024
2 parents 5eb4883 + 18cacef commit 40b8b4c
Show file tree
Hide file tree
Showing 38 changed files with 1,792 additions and 398 deletions.
57 changes: 44 additions & 13 deletions jolt-core/src/jolt/instruction/add.rs
Original file line number Diff line number Diff line change
Expand Up @@ -59,12 +59,18 @@ impl<const WORD_SIZE: usize> JoltInstruction for ADDInstruction<WORD_SIZE> {
} else if WORD_SIZE == 64 {
self.0.overflowing_add(self.1).0
} else {
panic!("only implemented for u32 / u64")
panic!("ADD is only implemented for 32-bit or 64-bit word sizes")
}
}

fn random(&self, rng: &mut StdRng) -> Self {
Self(rng.next_u32() as u64, rng.next_u32() as u64)
if WORD_SIZE == 32 {
Self(rng.next_u32() as u64, rng.next_u32() as u64)
} else if WORD_SIZE == 64 {
Self(rng.next_u64(), rng.next_u64())
} else {
panic!("Only 32-bit and 64-bit word sizes are supported")
}
}
}

Expand All @@ -82,23 +88,26 @@ mod test {
let mut rng = test_rng();
const C: usize = 4;
const M: usize = 1 << 16;
const WORD_SIZE: usize = 32;

// Random
for _ in 0..256 {
let (x, y) = (rng.next_u32() as u64, rng.next_u32() as u64);
let instruction = ADDInstruction::<32>(x, y);
let instruction = ADDInstruction::<WORD_SIZE>(x, y);
jolt_instruction_test!(instruction);
}

// Edge cases
let u32_max: u64 = u32::MAX as u64;
let instructions = vec![
ADDInstruction::<32>(100, 0),
ADDInstruction::<32>(0, 100),
ADDInstruction::<32>(1, 0),
ADDInstruction::<32>(0, u32_max),
ADDInstruction::<32>(u32_max, 0),
ADDInstruction::<32>(u32_max, u32_max),
ADDInstruction::<32>(u32_max, 1 << 8),
ADDInstruction::<32>(1 << 8, u32_max),
ADDInstruction::<WORD_SIZE>(100, 0),
ADDInstruction::<WORD_SIZE>(0, 100),
ADDInstruction::<WORD_SIZE>(1, 0),
ADDInstruction::<WORD_SIZE>(0, u32_max),
ADDInstruction::<WORD_SIZE>(u32_max, 0),
ADDInstruction::<WORD_SIZE>(u32_max, u32_max),
ADDInstruction::<WORD_SIZE>(u32_max, 1 << 8),
ADDInstruction::<WORD_SIZE>(1 << 8, u32_max),
];
for instruction in instructions {
jolt_instruction_test!(instruction);
Expand All @@ -110,10 +119,32 @@ mod test {
let mut rng = test_rng();
const C: usize = 8;
const M: usize = 1 << 16;
const WORD_SIZE: usize = 64;

// Random
for _ in 0..256 {
let (x, y) = (rng.next_u32() as u64, rng.next_u32() as u64);
let instruction = ADDInstruction::<64>(x, y);
let (x, y) = (rng.next_u64(), rng.next_u64());
let instruction = ADDInstruction::<WORD_SIZE>(x, y);
jolt_instruction_test!(instruction);
}

// Edge cases
let u64_max: u64 = u64::MAX;
let instructions = vec![
ADDInstruction::<WORD_SIZE>(100, 0),
ADDInstruction::<WORD_SIZE>(0, 100),
ADDInstruction::<WORD_SIZE>(1, 0),
ADDInstruction::<WORD_SIZE>(0, u64_max),
ADDInstruction::<WORD_SIZE>(u64_max, 0),
ADDInstruction::<WORD_SIZE>(u64_max, u64_max),
ADDInstruction::<WORD_SIZE>(u64_max, 1 << 32),
ADDInstruction::<WORD_SIZE>(1 << 32, u64_max),
ADDInstruction::<WORD_SIZE>(1 << 63, 1),
ADDInstruction::<WORD_SIZE>(1, 1 << 63),
ADDInstruction::<WORD_SIZE>(u64_max - 1, 1),
ADDInstruction::<WORD_SIZE>(1, u64_max - 1),
];
for instruction in instructions {
jolt_instruction_test!(instruction);
}
}
Expand Down
60 changes: 45 additions & 15 deletions jolt-core/src/jolt/instruction/and.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,9 @@ use crate::jolt::subtable::{and::AndSubtable, LassoSubtable};
use crate::utils::instruction_utils::{chunk_and_concatenate_operands, concatenate_lookups};

#[derive(Copy, Clone, Default, Debug, Serialize, Deserialize)]
pub struct ANDInstruction(pub u64, pub u64);
pub struct ANDInstruction<const WORD_SIZE: usize>(pub u64, pub u64);

impl JoltInstruction for ANDInstruction {
impl<const WORD_SIZE: usize> JoltInstruction for ANDInstruction<WORD_SIZE> {
fn operands(&self) -> (u64, u64) {
(self.0, self.1)
}
Expand All @@ -37,11 +37,18 @@ impl JoltInstruction for ANDInstruction {
}

fn lookup_entry(&self) -> u64 {
// This is the same for 32-bit and 64-bit word sizes
self.0 & self.1
}

fn random(&self, rng: &mut StdRng) -> Self {
Self(rng.next_u32() as u64, rng.next_u32() as u64)
if WORD_SIZE == 32 {
Self(rng.next_u32() as u64, rng.next_u32() as u64)
} else if WORD_SIZE == 64 {
Self(rng.next_u64(), rng.next_u64())
} else {
panic!("Only 32-bit and 64-bit word sizes are supported")
}
}
}

Expand All @@ -60,10 +67,28 @@ mod test {
let mut rng = test_rng();
const C: usize = 4;
const M: usize = 1 << 16;
const WORD_SIZE: usize = 32;

// Random
for _ in 0..256 {
let (x, y) = (rng.next_u32() as u64, rng.next_u32() as u64);
let instruction = ANDInstruction(x, y);
let instruction = ANDInstruction::<WORD_SIZE>(x, y);
jolt_instruction_test!(instruction);
}

// Edge cases
let u32_max: u64 = u32::MAX as u64;
let instructions = vec![
ANDInstruction::<WORD_SIZE>(100, 0),
ANDInstruction::<WORD_SIZE>(0, 100),
ANDInstruction::<WORD_SIZE>(1, 0),
ANDInstruction::<WORD_SIZE>(0, u32_max),
ANDInstruction::<WORD_SIZE>(u32_max, 0),
ANDInstruction::<WORD_SIZE>(u32_max, u32_max),
ANDInstruction::<WORD_SIZE>(u32_max, 1 << 8),
ANDInstruction::<WORD_SIZE>(1 << 8, u32_max),
];
for instruction in instructions {
jolt_instruction_test!(instruction);
}
}
Expand All @@ -73,25 +98,30 @@ mod test {
let mut rng = test_rng();
const C: usize = 8;
const M: usize = 1 << 16;
const WORD_SIZE: usize = 64;

// Random
for _ in 0..256 {
let (x, y) = (rng.next_u64(), rng.next_u64());
let instruction = ANDInstruction(x, y);
let instruction = ANDInstruction::<WORD_SIZE>(x, y);
jolt_instruction_test!(instruction);
}

// Test edge-cases
let u32_max: u64 = u32::MAX as u64;
// Edge cases
let u64_max: u64 = u64::MAX;
let instructions = vec![
ANDInstruction(100, 0),
ANDInstruction(0, 100),
ANDInstruction(1, 0),
ANDInstruction(0, u32_max),
ANDInstruction(u32_max, 0),
ANDInstruction(u32_max, u32_max),
ANDInstruction(u32_max, 1 << 8),
ANDInstruction(1 << 8, u32_max),
ANDInstruction::<WORD_SIZE>(100, 0),
ANDInstruction::<WORD_SIZE>(0, 100),
ANDInstruction::<WORD_SIZE>(1, 0),
ANDInstruction::<WORD_SIZE>(0, u64_max),
ANDInstruction::<WORD_SIZE>(u64_max, 0),
ANDInstruction::<WORD_SIZE>(u64_max, u64_max),
ANDInstruction::<WORD_SIZE>(u64_max, 1 << 32),
ANDInstruction::<WORD_SIZE>(1 << 32, u64_max),
ANDInstruction::<WORD_SIZE>(1 << 63, 1),
ANDInstruction::<WORD_SIZE>(1, 1 << 63),
ANDInstruction::<WORD_SIZE>(u64_max - 1, 1),
ANDInstruction::<WORD_SIZE>(1, u64_max - 1),
];
for instruction in instructions {
jolt_instruction_test!(instruction);
Expand Down
56 changes: 43 additions & 13 deletions jolt-core/src/jolt/instruction/beq.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,9 @@ use crate::{
};

#[derive(Copy, Clone, Default, Debug, Serialize, Deserialize)]
pub struct BEQInstruction(pub u64, pub u64);
pub struct BEQInstruction<const WORD_SIZE: usize>(pub u64, pub u64);

impl JoltInstruction for BEQInstruction {
impl<const WORD_SIZE: usize> JoltInstruction for BEQInstruction<WORD_SIZE> {
fn operands(&self) -> (u64, u64) {
(self.0, self.1)
}
Expand All @@ -41,11 +41,18 @@ impl JoltInstruction for BEQInstruction {
}

fn lookup_entry(&self) -> u64 {
// This is the same for both 32-bit and 64-bit
(self.0 == self.1).into()
}

fn random(&self, rng: &mut StdRng) -> Self {
Self(rng.next_u32() as u64, rng.next_u32() as u64)
if WORD_SIZE == 32 {
Self(rng.next_u32() as u64, rng.next_u32() as u64)
} else if WORD_SIZE == 64 {
Self(rng.next_u64(), rng.next_u64())
} else {
panic!("Only 32-bit and 64-bit word sizes are supported")
}
}
}

Expand All @@ -64,25 +71,26 @@ mod test {
let mut rng = test_rng();
const C: usize = 4;
const M: usize = 1 << 16;
const WORD_SIZE: usize = 32;

// Random
for _ in 0..256 {
let (x, y) = (rng.next_u32() as u64, rng.next_u32() as u64);
let instruction = BEQInstruction(x, y);
let instruction = BEQInstruction::<WORD_SIZE>(x, y);
jolt_instruction_test!(instruction);
}

// Test edge-cases
let u32_max: u64 = u32::MAX as u64;
let instructions = vec![
BEQInstruction(100, 0),
BEQInstruction(0, 100),
BEQInstruction(1, 0),
BEQInstruction(0, u32_max),
BEQInstruction(u32_max, 0),
BEQInstruction(u32_max, u32_max),
BEQInstruction(u32_max, 1 << 8),
BEQInstruction(1 << 8, u32_max),
BEQInstruction::<WORD_SIZE>(100, 0),
BEQInstruction::<WORD_SIZE>(0, 100),
BEQInstruction::<WORD_SIZE>(1, 0),
BEQInstruction::<WORD_SIZE>(0, u32_max),
BEQInstruction::<WORD_SIZE>(u32_max, 0),
BEQInstruction::<WORD_SIZE>(u32_max, u32_max),
BEQInstruction::<WORD_SIZE>(u32_max, 1 << 8),
BEQInstruction::<WORD_SIZE>(1 << 8, u32_max),
];
for instruction in instructions {
jolt_instruction_test!(instruction);
Expand All @@ -94,10 +102,32 @@ mod test {
let mut rng = test_rng();
const C: usize = 8;
const M: usize = 1 << 16;
const WORD_SIZE: usize = 64;

// Random
for _ in 0..256 {
let (x, y) = (rng.next_u64(), rng.next_u64());
let instruction = BEQInstruction(x, y);
let instruction = BEQInstruction::<WORD_SIZE>(x, y);
jolt_instruction_test!(instruction);
}

// Test edge-cases
let u64_max: u64 = u64::MAX;
let instructions = vec![
BEQInstruction::<WORD_SIZE>(100, 0),
BEQInstruction::<WORD_SIZE>(0, 100),
BEQInstruction::<WORD_SIZE>(1, 0),
BEQInstruction::<WORD_SIZE>(0, u64_max),
BEQInstruction::<WORD_SIZE>(u64_max, 0),
BEQInstruction::<WORD_SIZE>(u64_max, u64_max),
BEQInstruction::<WORD_SIZE>(u64_max, 1 << 32),
BEQInstruction::<WORD_SIZE>(1 << 32, u64_max),
BEQInstruction::<WORD_SIZE>(1 << 63, 1),
BEQInstruction::<WORD_SIZE>(1, 1 << 63),
BEQInstruction::<WORD_SIZE>(u64_max - 1, u64_max),
BEQInstruction::<WORD_SIZE>(u64_max, u64_max - 1),
];
for instruction in instructions {
jolt_instruction_test!(instruction);
}
}
Expand Down
Loading

0 comments on commit 40b8b4c

Please sign in to comment.