diff --git a/src/asm_compiler/mod.rs b/src/asm_compiler/mod.rs index 3deb8e3f6..24eb148b6 100644 --- a/src/asm_compiler/mod.rs +++ b/src/asm_compiler/mod.rs @@ -7,17 +7,13 @@ use crate::parser::asm_ast::*; use crate::parser::ast::*; use crate::utils::ParseError; -pub fn compile<'a>( - file_name: Option<&str>, - input: &'a str, - row_count: DegreeType, -) -> Result> { - // TODO define the row count / poly degree in the assembly file. - parser::parse_asm(file_name, input).map(|ast| ASMPILConverter::new().convert(ast, row_count)) +pub fn compile<'a>(file_name: Option<&str>, input: &'a str) -> Result> { + parser::parse_asm(file_name, input).map(|ast| ASMPILConverter::new().convert(ast)) } #[derive(Default)] struct ASMPILConverter { + degree_exponent: u32, pil: Vec, pc_name: Option, registers: BTreeMap, @@ -34,11 +30,34 @@ impl ASMPILConverter { Default::default() } - fn convert(&mut self, input: ASMFile, max_steps: DegreeType) -> PILFile { + fn set_degree(&mut self, degree: DegreeType) { + // check the degree is a power of 2 + assert!( + degree.is_power_of_two(), + "Degree should be a power of two, found {}", + degree + ); + self.degree_exponent = degree.ilog2(); + } + + fn degree(&self) -> DegreeType { + 1 << self.degree_exponent + } + + fn convert(&mut self, input: ASMFile) -> PILFile { + self.set_degree(1024); + + let mut statements = input.0.iter().peekable(); + + if let Some(ASMStatement::Degree(_, degree)) = statements.peek() { + self.set_degree(crate::number::abstract_to_degree(degree)); + statements.next(); + } + self.pil.push(Statement::Namespace( 0, "Assembly".to_string(), - Expression::Number(AbstractNumberType::from(max_steps)), + Expression::Number(AbstractNumberType::from(self.degree())), )); self.pil.push(Statement::PolynomialConstantDefinition( 0, @@ -46,8 +65,11 @@ impl ASMPILConverter { FunctionDefinition::Array(vec![build_number(1.into())]), )); - for statement in &input.0 { + for statement in statements { match statement { + ASMStatement::Degree(..) => { + panic!("The degree statement is only supported at the start of the asm source"); + } ASMStatement::RegisterDeclaration(start, name, flags) => { self.handle_register_declaration(flags, name, start); } @@ -850,7 +872,7 @@ pol constant p_reg_write_X_CNT = [1, 0, 0, 0, 0, 0, 0, 0, 0]; "#; let file_name = "tests/asm_data/simple_sum.asm"; let contents = fs::read_to_string(file_name).unwrap(); - let pil = compile(Some(file_name), &contents, 1024).unwrap(); + let pil = compile(Some(file_name), &contents).unwrap(); assert_eq!(format!("{pil}").trim(), expectation.trim()); } } diff --git a/src/bin/compiler.rs b/src/bin/compiler.rs index 2c0891872..421a3f26f 100644 --- a/src/bin/compiler.rs +++ b/src/bin/compiler.rs @@ -24,11 +24,6 @@ enum Commands { #[arg(default_value_t = String::new())] inputs: String, - /// Number of rows (degree of the polynomials). - #[arg(short, long)] - #[arg(default_value_t = 1024)] - rows: u64, - /// Directory for output files. #[arg(short, long)] #[arg(default_value_t = String::from("."))] @@ -56,11 +51,6 @@ enum Commands { #[arg(default_value_t = String::new())] inputs: String, - /// Number of rows (degree of the polynomials). - #[arg(short, long)] - #[arg(default_value_t = 1024)] - rows: u64, - /// Directory for output files. #[arg(short, long)] #[arg(default_value_t = String::from("."))] @@ -87,11 +77,6 @@ enum Commands { #[arg(default_value_t = String::new())] inputs: String, - /// Number of rows (degree of the polynomials). - #[arg(short, long)] - #[arg(default_value_t = 1024)] - rows: u64, - /// Output directory for PIL file, json file and fixed and witness column data. #[arg(short, long)] #[arg(default_value_t = String::from("."))] @@ -140,7 +125,6 @@ fn main() { Commands::Rust { file, inputs, - rows, output_directory, force, verbose, @@ -148,7 +132,6 @@ fn main() { powdr::riscv::compile_rust( &file, split_inputs(&inputs), - rows, Path::new(&output_directory), force, verbose, @@ -157,7 +140,6 @@ fn main() { Commands::RiscvAsm { file, inputs, - rows, output_directory, force, verbose, @@ -166,7 +148,6 @@ fn main() { &file, &file, split_inputs(&inputs), - rows, Path::new(&output_directory), force, verbose, @@ -175,7 +156,6 @@ fn main() { Commands::Asm { file, inputs, - rows, output_directory, force, verbose, @@ -183,7 +163,6 @@ fn main() { powdr::compiler::compile_asm( &file, split_inputs(&inputs), - rows, Path::new(&output_directory), force, verbose, diff --git a/src/compiler.rs b/src/compiler.rs index 9c99b05dd..ad2e1114c 100644 --- a/src/compiler.rs +++ b/src/compiler.rs @@ -54,7 +54,6 @@ pub fn compile_pil_ast( pub fn compile_asm( file_name: &str, inputs: Vec, - rows: u64, output_dir: &Path, force_overwrite: bool, verbose: bool, @@ -64,7 +63,6 @@ pub fn compile_asm( file_name, &contents, inputs, - rows, output_dir, force_overwrite, verbose, @@ -77,12 +75,11 @@ pub fn compile_asm_string( file_name: &str, contents: &str, inputs: Vec, - rows: u64, output_dir: &Path, force_overwrite: bool, verbose: bool, ) { - let pil = asm_compiler::compile(Some(file_name), contents, rows).unwrap_or_else(|err| { + let pil = asm_compiler::compile(Some(file_name), contents).unwrap_or_else(|err| { eprintln!("Error parsing .asm file:"); err.output_to_stderr(); panic!(); diff --git a/src/parser/asm_ast.rs b/src/parser/asm_ast.rs index d58fddf5d..db7d394a9 100644 --- a/src/parser/asm_ast.rs +++ b/src/parser/asm_ast.rs @@ -1,3 +1,5 @@ +use crate::number::AbstractNumberType; + use super::ast::{Expression, SelectedExpressions, Statement}; #[derive(Debug, PartialEq, Eq)] @@ -5,6 +7,7 @@ pub struct ASMFile(pub Vec); #[derive(Debug, PartialEq, Eq, Clone)] pub enum ASMStatement { + Degree(usize, AbstractNumberType), RegisterDeclaration(usize, String, Option), InstructionDeclaration( usize, diff --git a/src/parser/powdr.lalrpop b/src/parser/powdr.lalrpop index 127ad5f3d..bf8fde9ea 100644 --- a/src/parser/powdr.lalrpop +++ b/src/parser/powdr.lalrpop @@ -138,6 +138,7 @@ ConstantFixed = { ASMStatement: ASMStatement = { + Degree, RegisterDeclaration, InstructionDeclaration, InlinePil, @@ -146,6 +147,10 @@ ASMStatement: ASMStatement = { Label, } +Degree: ASMStatement = { + <@L> "degree" ";" => ASMStatement::Degree(<>) +} + RegisterDeclaration: ASMStatement = { // TODO default update <@L> "reg" <( "[" "]" )?> ";" => ASMStatement::RegisterDeclaration(<>) diff --git a/src/riscv/mod.rs b/src/riscv/mod.rs index 367aab837..108d9f1d4 100644 --- a/src/riscv/mod.rs +++ b/src/riscv/mod.rs @@ -13,7 +13,6 @@ pub mod parser; pub fn compile_rust( file_name: &str, inputs: Vec, - rows: u64, output_dir: &Path, force_overwrite: bool, verbose: bool, @@ -37,7 +36,6 @@ pub fn compile_rust( file_name, riscv_asm_file_name.to_str().unwrap(), inputs, - rows, output_dir, force_overwrite, verbose, @@ -51,7 +49,6 @@ pub fn compile_riscv_asm( original_file_name: &str, file_name: &str, inputs: Vec, - rows: u64, output_dir: &Path, force_overwrite: bool, verbose: bool, @@ -80,7 +77,6 @@ pub fn compile_riscv_asm( powdr_asm_file_name.to_str().unwrap(), &powdr_asm, inputs, - rows, output_dir, force_overwrite, verbose, diff --git a/tests/asm.rs b/tests/asm.rs index 9dd37782c..430d78164 100644 --- a/tests/asm.rs +++ b/tests/asm.rs @@ -1,12 +1,12 @@ use common::verify_asm_string; -use powdr::number::{AbstractNumberType, DegreeType}; +use powdr::number::AbstractNumberType; use std::fs; mod common; -fn verify_asm(file_name: &str, inputs: Vec, row_count: Option) { +fn verify_asm(file_name: &str, inputs: Vec) { let contents = fs::read_to_string(format!("./tests/asm_data/{file_name}")).unwrap(); - verify_asm_string(file_name, &contents, inputs, row_count) + verify_asm_string(file_name, &contents, inputs) } #[test] @@ -14,7 +14,6 @@ fn simple_sum_asm() { verify_asm( "simple_sum.asm", [16, 4, 1, 2, 8, 5].iter().map(|&x| x.into()).collect(), - None, ); } @@ -23,31 +22,22 @@ fn palindrome() { verify_asm( "palindrome.asm", [7, 1, 7, 3, 9, 3, 7, 1].iter().map(|&x| x.into()).collect(), - None, ); } #[test] fn test_mem_read_write() { - verify_asm("mem_read_write.asm", Default::default(), None); + verify_asm("mem_read_write.asm", Default::default()); } #[test] fn test_multi_assign() { - verify_asm( - "multi_assign.asm", - [7].iter().map(|&x| x.into()).collect(), - None, - ); + verify_asm("multi_assign.asm", [7].iter().map(|&x| x.into()).collect()); } #[test] fn test_bit_access() { - verify_asm( - "bit_access.asm", - [20].iter().map(|&x| x.into()).collect(), - None, - ); + verify_asm("bit_access.asm", [20].iter().map(|&x| x.into()).collect()); } #[test] @@ -55,6 +45,5 @@ fn functional_instructions() { verify_asm( "functional_instructions.asm", [20].iter().map(|&x| x.into()).collect(), - None, ); } diff --git a/tests/asm_data/palindrome.asm b/tests/asm_data/palindrome.asm index aeea7a676..35958c6a6 100644 --- a/tests/asm_data/palindrome.asm +++ b/tests/asm_data/palindrome.asm @@ -1,6 +1,8 @@ // Verfies that the input is a palindrome. // Input: length, x_1, x_2, ..., x_length +degree 1024; + reg pc[@pc]; reg X[<=]; reg A; diff --git a/tests/common/mod.rs b/tests/common/mod.rs index 00f97c6f1..d568a0871 100644 --- a/tests/common/mod.rs +++ b/tests/common/mod.rs @@ -2,17 +2,11 @@ use std::{fs, path::Path, process::Command}; use itertools::Itertools; use powdr::compiler; -use powdr::number::{AbstractNumberType, DegreeType}; +use powdr::number::AbstractNumberType; #[allow(unused)] -pub fn verify_asm_string( - file_name: &str, - contents: &str, - inputs: Vec, - row_count: Option, -) { - let pil = - powdr::asm_compiler::compile(Some(file_name), contents, row_count.unwrap_or(1024)).unwrap(); +pub fn verify_asm_string(file_name: &str, contents: &str, inputs: Vec) { + let pil = powdr::asm_compiler::compile(Some(file_name), contents).unwrap(); let pil_file_name = "asm.pil"; let temp_dir = mktemp::Temp::new_dir().unwrap(); assert!(compiler::compile_pil_ast( diff --git a/tests/riscv.rs b/tests/riscv.rs index 7a04566eb..b74214217 100644 --- a/tests/riscv.rs +++ b/tests/riscv.rs @@ -1,5 +1,5 @@ use common::verify_asm_string; -use powdr::number::{AbstractNumberType, DegreeType}; +use powdr::number::AbstractNumberType; mod common; @@ -9,13 +9,12 @@ fn test_sum() { verify( case, [16, 4, 1, 2, 8, 5].iter().map(|&x| x.into()).collect(), - None, ); } -fn verify(case: &str, inputs: Vec, row_count: Option) { +fn verify(case: &str, inputs: Vec) { let riscv_asm = powdr::riscv::compile_rust_to_riscv_asm(&format!("tests/riscv_data/{case}")); let powdr_asm = powdr::riscv::compiler::compile_riscv_asm(&riscv_asm); - verify_asm_string(&format!("{case}.asm"), &powdr_asm, inputs, row_count); + verify_asm_string(&format!("{case}.asm"), &powdr_asm, inputs); }