mirror of
https://github.com/powdr-labs/powdr.git
synced 2026-01-09 14:48:16 -05:00
split riscv modules in crates so other crates can have minimal deps (#2747)
This commit is contained in:
66
Cargo.toml
66
Cargo.toml
@@ -3,37 +3,39 @@
|
||||
resolver = "2"
|
||||
|
||||
members = [
|
||||
"powdr",
|
||||
"number",
|
||||
"parser",
|
||||
"cargo-powdr",
|
||||
"cli",
|
||||
"cli-rs",
|
||||
"constraint-solver",
|
||||
"executor",
|
||||
"jit-compiler",
|
||||
"riscv",
|
||||
"parser-util",
|
||||
"pil-analyzer",
|
||||
"pipeline",
|
||||
"pilopt",
|
||||
"plonky3",
|
||||
"asm-to-pil",
|
||||
"asmopt",
|
||||
"backend",
|
||||
"ast",
|
||||
"analysis",
|
||||
"linker",
|
||||
"isa-utils",
|
||||
"airgen",
|
||||
"riscv-executor",
|
||||
"syscalls",
|
||||
"schemas",
|
||||
"backend-utils",
|
||||
"executor-utils",
|
||||
"autoprecompiles",
|
||||
"openvm",
|
||||
"cli-openvm",
|
||||
"powdr",
|
||||
"number",
|
||||
"parser",
|
||||
"cargo-powdr",
|
||||
"cli",
|
||||
"cli-rs",
|
||||
"constraint-solver",
|
||||
"executor",
|
||||
"jit-compiler",
|
||||
"riscv",
|
||||
"riscv-elf",
|
||||
"riscv-types",
|
||||
"parser-util",
|
||||
"pil-analyzer",
|
||||
"pipeline",
|
||||
"pilopt",
|
||||
"plonky3",
|
||||
"asm-to-pil",
|
||||
"asmopt",
|
||||
"backend",
|
||||
"ast",
|
||||
"analysis",
|
||||
"linker",
|
||||
"isa-utils",
|
||||
"airgen",
|
||||
"riscv-executor",
|
||||
"syscalls",
|
||||
"schemas",
|
||||
"backend-utils",
|
||||
"executor-utils",
|
||||
"autoprecompiles",
|
||||
"openvm",
|
||||
"cli-openvm",
|
||||
]
|
||||
|
||||
exclude = ["riscv-runtime"]
|
||||
@@ -70,7 +72,9 @@ powdr-pilopt = { path = "./pilopt", version = "0.1.4" }
|
||||
powdr-pipeline = { path = "./pipeline", version = "0.1.4" }
|
||||
powdr-plonky3 = { path = "./plonky3", version = "0.1.4" }
|
||||
powdr-riscv = { path = "./riscv", version = "0.1.4" }
|
||||
powdr-riscv-elf = { path = "./riscv-elf", version = "0.1.4" }
|
||||
powdr-riscv-executor = { path = "./riscv-executor", version = "0.1.4" }
|
||||
powdr-riscv-types = { path = "./riscv-types", version = "0.1.4" }
|
||||
powdr-syscalls = { path = "./syscalls", version = "0.1.4" }
|
||||
powdr-schemas = { path = "./schemas", version = "0.1.4" }
|
||||
powdr-autoprecompiles = { path = "./autoprecompiles", version = "0.1.4" }
|
||||
|
||||
@@ -46,7 +46,7 @@ openvm-stark-backend = { git = "https://github.com/powdr-labs/stark-backend.git"
|
||||
|
||||
powdr-ast.workspace = true
|
||||
powdr-number.workspace = true
|
||||
powdr-riscv.workspace = true
|
||||
powdr-riscv-elf.workspace = true
|
||||
powdr-autoprecompiles.workspace = true
|
||||
powdr-constraint-solver.workspace = true
|
||||
|
||||
|
||||
@@ -215,7 +215,7 @@ pub fn compile_exe(
|
||||
let target_path = path.to_str().unwrap();
|
||||
|
||||
let elf_binary = build_elf_path(guest_opts.clone(), target_path, &Default::default())?;
|
||||
let elf_powdr = powdr_riscv::elf::load_elf(&elf_binary);
|
||||
let elf_powdr = powdr_riscv_elf::load_elf(&elf_binary);
|
||||
|
||||
let airs =
|
||||
instructions_to_airs::<_, powdr_number::BabyBearField>(exe.clone(), sdk_vm_config.clone());
|
||||
|
||||
26
riscv-elf/Cargo.toml
Normal file
26
riscv-elf/Cargo.toml
Normal file
@@ -0,0 +1,26 @@
|
||||
[package]
|
||||
name = "powdr-riscv-elf"
|
||||
description = "powdr RISCV ELF utils"
|
||||
version.workspace = true
|
||||
edition.workspace = true
|
||||
license.workspace = true
|
||||
homepage.workspace = true
|
||||
repository.workspace = true
|
||||
|
||||
[dependencies]
|
||||
powdr-isa-utils.workspace = true
|
||||
powdr-riscv-types.workspace = true
|
||||
powdr-syscalls.workspace = true
|
||||
|
||||
gimli = "0.31"
|
||||
goblin = "0.8"
|
||||
itertools = "0.13"
|
||||
log = "0.4.27"
|
||||
raki = "0.1.4"
|
||||
thiserror = "1.0"
|
||||
|
||||
[lints]
|
||||
workspace = true
|
||||
|
||||
[lib]
|
||||
bench = false # See https://github.com/bheisler/criterion.rs/issues/458
|
||||
@@ -21,25 +21,17 @@ use raki::{
|
||||
Isa,
|
||||
};
|
||||
|
||||
use crate::{
|
||||
code_gen::{self, InstructionArgs, MemEntry, Register, RiscVProgram, Statement},
|
||||
elf::debug_info::SymbolTable,
|
||||
CompilerOptions,
|
||||
use powdr_riscv_types::{
|
||||
self, InstructionArgs, MemEntry, Register, RiscVProgram, SourceFileInfo, Statement,
|
||||
};
|
||||
|
||||
use self::debug_info::DebugInfo;
|
||||
pub mod debug_info;
|
||||
|
||||
mod debug_info;
|
||||
use self::debug_info::{DebugInfo, SymbolTable};
|
||||
|
||||
/// The program header type (p_type) for Powdr prover data segments.
|
||||
pub const PT_POWDR_PROVER_DATA: u32 = 0x600000da;
|
||||
|
||||
/// Generates a Powdr Assembly program from a RISC-V 32 executable ELF file.
|
||||
pub fn translate(file_name: &Path, options: CompilerOptions) -> String {
|
||||
let elf_program = load_elf(file_name);
|
||||
code_gen::translate_program(elf_program, options)
|
||||
}
|
||||
|
||||
pub struct ElfProgram {
|
||||
dbg: DebugInfo,
|
||||
data_map: BTreeMap<u32, Data>,
|
||||
@@ -280,12 +272,12 @@ fn static_relocate_data_sections(
|
||||
}
|
||||
|
||||
impl RiscVProgram for ElfProgram {
|
||||
fn take_source_files_info(&mut self) -> impl Iterator<Item = crate::code_gen::SourceFileInfo> {
|
||||
fn take_source_files_info(&mut self) -> impl Iterator<Item = SourceFileInfo> {
|
||||
self.dbg
|
||||
.file_list
|
||||
.iter()
|
||||
.enumerate()
|
||||
.map(|(id, (dir, file))| crate::code_gen::SourceFileInfo {
|
||||
.map(|(id, (dir, file))| SourceFileInfo {
|
||||
// +1 because files are indexed from 1
|
||||
id: id as u32 + 1,
|
||||
file,
|
||||
@@ -293,7 +285,7 @@ impl RiscVProgram for ElfProgram {
|
||||
})
|
||||
}
|
||||
|
||||
fn take_initial_mem(&mut self) -> impl Iterator<Item = crate::code_gen::MemEntry> {
|
||||
fn take_initial_mem(&mut self) -> impl Iterator<Item = MemEntry> {
|
||||
self.data_map.iter().map(|(addr, data)| {
|
||||
let value = match data {
|
||||
Data::TextLabel(label) => {
|
||||
@@ -320,7 +312,7 @@ impl RiscVProgram for ElfProgram {
|
||||
|
||||
fn take_executable_statements(
|
||||
&mut self,
|
||||
) -> impl Iterator<Item = code_gen::Statement<impl AsRef<str>, impl InstructionArgs>> {
|
||||
) -> impl Iterator<Item = Statement<impl AsRef<str>, impl InstructionArgs>> {
|
||||
// In the output, the precedence is labels, locations, and then instructions.
|
||||
// We merge the 3 iterators with this operations: merge(labels, merge(locs, instructions)), where each is sorted by address.
|
||||
|
||||
@@ -586,7 +578,7 @@ impl InstructionArgs for WrappedArgs<'_> {
|
||||
/// Indexes the program sections by their virtual address.
|
||||
///
|
||||
/// Allows for querying if an address is in a data or text section.
|
||||
struct AddressMap<'a>(BTreeMap<u32, &'a ProgramHeader>);
|
||||
pub struct AddressMap<'a>(BTreeMap<u32, &'a ProgramHeader>);
|
||||
|
||||
impl AddressMap<'_> {
|
||||
fn is_in_data_section(&self, addr: u32) -> bool {
|
||||
17
riscv-types/Cargo.toml
Normal file
17
riscv-types/Cargo.toml
Normal file
@@ -0,0 +1,17 @@
|
||||
[package]
|
||||
name = "powdr-riscv-types"
|
||||
description = "powdr RISCV types and traits"
|
||||
version.workspace = true
|
||||
edition.workspace = true
|
||||
license.workspace = true
|
||||
homepage.workspace = true
|
||||
repository.workspace = true
|
||||
|
||||
[dependencies]
|
||||
powdr-isa-utils.workspace = true
|
||||
|
||||
[lints]
|
||||
workspace = true
|
||||
|
||||
[lib]
|
||||
bench = false # See https://github.com/bheisler/criterion.rs/issues/458
|
||||
138
riscv-types/src/lib.rs
Normal file
138
riscv-types/src/lib.rs
Normal file
@@ -0,0 +1,138 @@
|
||||
use powdr_isa_utils::SingleDataValue;
|
||||
use std::fmt;
|
||||
|
||||
#[derive(Clone, Copy, PartialEq, Eq, Debug)]
|
||||
pub struct Register {
|
||||
value: u8,
|
||||
}
|
||||
|
||||
impl Register {
|
||||
pub fn new(value: u8) -> Self {
|
||||
Self { value }
|
||||
}
|
||||
|
||||
pub fn is_zero(&self) -> bool {
|
||||
self.value == 0
|
||||
}
|
||||
|
||||
pub fn addr(&self) -> u8 {
|
||||
self.value
|
||||
}
|
||||
}
|
||||
|
||||
/// List of machine registers, declared in the asm machine.
|
||||
/// NOTE: the bootloader expects the PC to be the last register in this list.
|
||||
pub const REGISTER_NAMES: [&str; 3] = ["main::query_arg_1", "main::query_arg_2", "main::pc"];
|
||||
|
||||
/// These are the names of the RISCV registers that are stored in memory.
|
||||
pub const REGISTER_MEMORY_NAMES: [&str; 37] = [
|
||||
"x0",
|
||||
"x1",
|
||||
"x2",
|
||||
"x3",
|
||||
"x4",
|
||||
"x5",
|
||||
"x6",
|
||||
"x7",
|
||||
"x8",
|
||||
"x9",
|
||||
"x10",
|
||||
"x11",
|
||||
"x12",
|
||||
"x13",
|
||||
"x14",
|
||||
"x15",
|
||||
"x16",
|
||||
"x17",
|
||||
"x18",
|
||||
"x19",
|
||||
"x20",
|
||||
"x21",
|
||||
"x22",
|
||||
"x23",
|
||||
"x24",
|
||||
"x25",
|
||||
"x26",
|
||||
"x27",
|
||||
"x28",
|
||||
"x29",
|
||||
"x30",
|
||||
"x31",
|
||||
"tmp1",
|
||||
"tmp2",
|
||||
"tmp3",
|
||||
"tmp4",
|
||||
"lr_sc_reservation",
|
||||
];
|
||||
|
||||
impl fmt::Display for Register {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
write!(f, "{}", REGISTER_MEMORY_NAMES[self.value as usize])
|
||||
}
|
||||
}
|
||||
|
||||
impl From<&str> for Register {
|
||||
fn from(s: &str) -> Self {
|
||||
REGISTER_MEMORY_NAMES
|
||||
.iter()
|
||||
.position(|&name| name == s)
|
||||
.map(|value| Self::new(value as u8))
|
||||
.unwrap_or_else(|| panic!("Invalid register"))
|
||||
}
|
||||
}
|
||||
|
||||
pub enum Statement<'a, L: AsRef<str>, A: InstructionArgs> {
|
||||
DebugLoc { file: u64, line: u64, col: u64 },
|
||||
Label(L),
|
||||
Instruction { op: &'a str, args: A },
|
||||
}
|
||||
|
||||
pub struct MemEntry {
|
||||
pub label: Option<String>,
|
||||
pub addr: u32,
|
||||
pub value: SingleDataValue,
|
||||
}
|
||||
|
||||
pub struct SourceFileInfo<'a> {
|
||||
pub id: u32,
|
||||
pub dir: &'a str,
|
||||
pub file: &'a str,
|
||||
}
|
||||
|
||||
/// A RISC-V program that can be translated to POWDR ASM.
|
||||
pub trait RiscVProgram {
|
||||
/// Takes the listing of source files, to be used in the debug statements.
|
||||
fn take_source_files_info(&mut self) -> impl Iterator<Item = SourceFileInfo>;
|
||||
|
||||
/// Takes the initial memory snapshot.
|
||||
fn take_initial_mem(&mut self) -> impl Iterator<Item = MemEntry>;
|
||||
|
||||
/// Takes the executable statements and labels.
|
||||
fn take_executable_statements(
|
||||
&mut self,
|
||||
) -> impl Iterator<Item = Statement<impl AsRef<str>, impl InstructionArgs>>;
|
||||
|
||||
/// Returns the addresses of the start and end of prover data.
|
||||
fn prover_data_bounds(&self) -> (u32, u32);
|
||||
|
||||
/// The name of the function that should be called to start the program.
|
||||
fn start_function(&self) -> impl AsRef<str>;
|
||||
}
|
||||
|
||||
pub trait InstructionArgs {
|
||||
type Error: fmt::Display;
|
||||
|
||||
fn l(&self) -> Result<impl AsRef<str>, Self::Error>;
|
||||
fn r(&self) -> Result<Register, Self::Error>;
|
||||
fn rri(&self) -> Result<(Register, Register, u32), Self::Error>;
|
||||
/// Returns the usual rd, rs1, rs2
|
||||
fn rrr(&self) -> Result<(Register, Register, Register), Self::Error>;
|
||||
/// Special case used in amo* instructions, returning rd, rs2, rs1
|
||||
fn rrr2(&self) -> Result<(Register, Register, Register), Self::Error>;
|
||||
fn ri(&self) -> Result<(Register, u32), Self::Error>;
|
||||
fn rr(&self) -> Result<(Register, Register), Self::Error>;
|
||||
fn rrl(&self) -> Result<(Register, Register, impl AsRef<str>), Self::Error>;
|
||||
fn rl(&self) -> Result<(Register, impl AsRef<str>), Self::Error>;
|
||||
fn rro(&self) -> Result<(Register, Register, u32), Self::Error>;
|
||||
fn empty(&self) -> Result<(), Self::Error>;
|
||||
}
|
||||
@@ -24,6 +24,8 @@ powdr-number.workspace = true
|
||||
powdr-parser.workspace = true
|
||||
powdr-parser-util.workspace = true
|
||||
powdr-pipeline.workspace = true
|
||||
powdr-riscv-elf.workspace = true
|
||||
powdr-riscv-types.workspace = true
|
||||
powdr-riscv-executor.workspace = true
|
||||
powdr-syscalls.workspace = true
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
use ::powdr_pipeline::Pipeline;
|
||||
use powdr_number::GoldilocksField;
|
||||
|
||||
use powdr_riscv::{compile_rust_crate_to_riscv, elf, CompilerOptions};
|
||||
use powdr_riscv::{compile_rust_crate_to_riscv, translate, CompilerOptions};
|
||||
|
||||
use criterion::{criterion_group, criterion_main, Criterion};
|
||||
use mktemp::Temp;
|
||||
@@ -17,7 +17,7 @@ fn executor_benchmark(c: &mut Criterion) {
|
||||
let executable =
|
||||
compile_rust_crate_to_riscv("./tests/riscv_data/keccak/Cargo.toml", &tmp_dir, None);
|
||||
let options = CompilerOptions::new_gl();
|
||||
let contents = elf::translate(&executable, options);
|
||||
let contents = translate(&executable, options);
|
||||
let mut pipeline = Pipeline::<T>::default().from_asm_string(contents, None);
|
||||
pipeline.compute_backend_tuned_pil().unwrap();
|
||||
pipeline.compute_fixed_cols().unwrap();
|
||||
|
||||
@@ -1,131 +1,11 @@
|
||||
use std::fmt;
|
||||
|
||||
use powdr_isa_utils::SingleDataValue;
|
||||
use powdr_number::FieldSize;
|
||||
use powdr_riscv_types::RiscVProgram;
|
||||
|
||||
use crate::CompilerOptions;
|
||||
|
||||
use crate::large_field;
|
||||
use crate::small_field;
|
||||
|
||||
/// These are the names of the RISCV registers that are stored in memory.
|
||||
pub const REGISTER_MEMORY_NAMES: [&str; 37] = [
|
||||
"x0",
|
||||
"x1",
|
||||
"x2",
|
||||
"x3",
|
||||
"x4",
|
||||
"x5",
|
||||
"x6",
|
||||
"x7",
|
||||
"x8",
|
||||
"x9",
|
||||
"x10",
|
||||
"x11",
|
||||
"x12",
|
||||
"x13",
|
||||
"x14",
|
||||
"x15",
|
||||
"x16",
|
||||
"x17",
|
||||
"x18",
|
||||
"x19",
|
||||
"x20",
|
||||
"x21",
|
||||
"x22",
|
||||
"x23",
|
||||
"x24",
|
||||
"x25",
|
||||
"x26",
|
||||
"x27",
|
||||
"x28",
|
||||
"x29",
|
||||
"x30",
|
||||
"x31",
|
||||
"tmp1",
|
||||
"tmp2",
|
||||
"tmp3",
|
||||
"tmp4",
|
||||
"lr_sc_reservation",
|
||||
];
|
||||
|
||||
/// List of machine registers, declared in the asm machine.
|
||||
/// NOTE: the bootloader expects the PC to be the last register in this list.
|
||||
pub const REGISTER_NAMES: [&str; 3] = ["main::query_arg_1", "main::query_arg_2", "main::pc"];
|
||||
|
||||
#[derive(Clone, Copy, PartialEq, Eq, Debug)]
|
||||
pub struct Register {
|
||||
value: u8,
|
||||
}
|
||||
|
||||
impl Register {
|
||||
pub fn new(value: u8) -> Self {
|
||||
Self { value }
|
||||
}
|
||||
|
||||
pub fn is_zero(&self) -> bool {
|
||||
self.value == 0
|
||||
}
|
||||
|
||||
pub fn addr(&self) -> u8 {
|
||||
self.value
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Display for Register {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
write!(f, "{}", REGISTER_MEMORY_NAMES[self.value as usize])
|
||||
}
|
||||
}
|
||||
|
||||
impl From<&str> for Register {
|
||||
fn from(s: &str) -> Self {
|
||||
REGISTER_MEMORY_NAMES
|
||||
.iter()
|
||||
.position(|&name| name == s)
|
||||
.map(|value| Self::new(value as u8))
|
||||
.unwrap_or_else(|| panic!("Invalid register"))
|
||||
}
|
||||
}
|
||||
|
||||
pub enum Statement<'a, L: AsRef<str>, A: InstructionArgs> {
|
||||
DebugLoc { file: u64, line: u64, col: u64 },
|
||||
Label(L),
|
||||
Instruction { op: &'a str, args: A },
|
||||
}
|
||||
|
||||
pub struct MemEntry {
|
||||
pub label: Option<String>,
|
||||
pub addr: u32,
|
||||
pub value: SingleDataValue,
|
||||
}
|
||||
|
||||
pub struct SourceFileInfo<'a> {
|
||||
pub id: u32,
|
||||
pub dir: &'a str,
|
||||
pub file: &'a str,
|
||||
}
|
||||
|
||||
/// A RISC-V program that can be translated to POWDR ASM.
|
||||
pub trait RiscVProgram {
|
||||
/// Takes the listing of source files, to be used in the debug statements.
|
||||
fn take_source_files_info(&mut self) -> impl Iterator<Item = SourceFileInfo>;
|
||||
|
||||
/// Takes the initial memory snapshot.
|
||||
fn take_initial_mem(&mut self) -> impl Iterator<Item = MemEntry>;
|
||||
|
||||
/// Takes the executable statements and labels.
|
||||
fn take_executable_statements(
|
||||
&mut self,
|
||||
) -> impl Iterator<Item = Statement<impl AsRef<str>, impl InstructionArgs>>;
|
||||
|
||||
/// Returns the addresses of the start and end of prover data.
|
||||
fn prover_data_bounds(&self) -> (u32, u32);
|
||||
|
||||
/// The name of the function that should be called to start the program.
|
||||
fn start_function(&self) -> impl AsRef<str>;
|
||||
}
|
||||
|
||||
/// Translates a RISC-V program to POWDR ASM.
|
||||
///
|
||||
/// Will call each of the methods in the `RiscVProgram` just once.
|
||||
@@ -135,21 +15,3 @@ pub fn translate_program(program: impl RiscVProgram, options: CompilerOptions) -
|
||||
FieldSize::Large => large_field::code_gen::translate_program(program, options),
|
||||
}
|
||||
}
|
||||
|
||||
pub trait InstructionArgs {
|
||||
type Error: fmt::Display;
|
||||
|
||||
fn l(&self) -> Result<impl AsRef<str>, Self::Error>;
|
||||
fn r(&self) -> Result<Register, Self::Error>;
|
||||
fn rri(&self) -> Result<(Register, Register, u32), Self::Error>;
|
||||
/// Returns the usual rd, rs1, rs2
|
||||
fn rrr(&self) -> Result<(Register, Register, Register), Self::Error>;
|
||||
/// Special case used in amo* instructions, returning rd, rs2, rs1
|
||||
fn rrr2(&self) -> Result<(Register, Register, Register), Self::Error>;
|
||||
fn ri(&self) -> Result<(Register, u32), Self::Error>;
|
||||
fn rr(&self) -> Result<(Register, Register), Self::Error>;
|
||||
fn rrl(&self) -> Result<(Register, Register, impl AsRef<str>), Self::Error>;
|
||||
fn rl(&self) -> Result<(Register, impl AsRef<str>), Self::Error>;
|
||||
fn rro(&self) -> Result<(Register, Register, u32), Self::Error>;
|
||||
fn empty(&self) -> Result<(), Self::Error>;
|
||||
}
|
||||
|
||||
@@ -12,11 +12,11 @@ use powdr_pipeline::Pipeline;
|
||||
use powdr_riscv_executor::{
|
||||
get_main_machine, hash_map_to_memory_state, MemoryState, ProfilerOptions,
|
||||
};
|
||||
use powdr_riscv_types::{Register, REGISTER_MEMORY_NAMES, REGISTER_NAMES};
|
||||
|
||||
pub mod bootloader;
|
||||
mod memory_merkle_tree;
|
||||
|
||||
use crate::code_gen::{REGISTER_MEMORY_NAMES, REGISTER_NAMES};
|
||||
use bootloader::split_fe;
|
||||
use bootloader::{default_input, PAGE_SIZE_BYTES_LOG, PC_INDEX};
|
||||
use memory_merkle_tree::MerkleTree;
|
||||
@@ -27,8 +27,6 @@ use crate::continuations::bootloader::{
|
||||
MEMORY_HASH_START_INDEX, PAGE_INPUTS_OFFSET, WORDS_PER_PAGE,
|
||||
};
|
||||
|
||||
use crate::code_gen::Register;
|
||||
|
||||
fn render_memory_hash<F: FieldElement>(hash: &[F]) -> String {
|
||||
// Main memory values must fit into u32
|
||||
hash.iter()
|
||||
|
||||
@@ -19,8 +19,8 @@ pub const PAGE_SIZE_BYTES_LOG: usize = 11;
|
||||
/// 32-Bit architecture -> 4 bytes per word
|
||||
pub const BYTES_PER_WORD: usize = 4;
|
||||
|
||||
use crate::code_gen::{REGISTER_MEMORY_NAMES, REGISTER_NAMES};
|
||||
use crate::large_field;
|
||||
use powdr_riscv_types::{REGISTER_MEMORY_NAMES, REGISTER_NAMES};
|
||||
|
||||
// Derived constants
|
||||
pub const WORDS_PER_PAGE: usize = (1 << (PAGE_SIZE_BYTES_LOG)) / BYTES_PER_WORD;
|
||||
|
||||
@@ -1,11 +1,9 @@
|
||||
use crate::code_gen::Register;
|
||||
|
||||
use crate::code_gen::{REGISTER_MEMORY_NAMES, REGISTER_NAMES};
|
||||
use crate::continuations::bootloader::{
|
||||
BOOTLOADER_INPUTS_PER_PAGE, BYTES_PER_WORD, DEFAULT_PC, MEMORY_HASH_START_INDEX,
|
||||
MERKLE_TREE_DEPTH, NUM_PAGES_INDEX, N_LEAVES_LOG, PAGE_INPUTS_OFFSET, PAGE_NUMBER_MASK,
|
||||
PAGE_SIZE_BYTES, PC_INDEX, SHUTDOWN_START, WORDS_PER_HASH, WORDS_PER_PAGE,
|
||||
};
|
||||
use powdr_riscv_types::{Register, REGISTER_MEMORY_NAMES, REGISTER_NAMES};
|
||||
|
||||
pub const BOOTLOADER_SPECIFIC_INSTRUCTION_NAMES: [&str; 2] =
|
||||
["load_bootloader_input", "jump_to_bootloader_input"];
|
||||
|
||||
@@ -1,18 +1,15 @@
|
||||
use std::vec;
|
||||
|
||||
use itertools::Itertools;
|
||||
use powdr_isa_utils::SingleDataValue;
|
||||
use powdr_isa_utils::{escape_label, quote};
|
||||
use powdr_isa_utils::{escape_label, quote, SingleDataValue};
|
||||
use powdr_number::KnownField;
|
||||
|
||||
use crate::continuations::bootloader::{bootloader_and_shutdown_routine, bootloader_preamble};
|
||||
|
||||
use crate::code_gen::{
|
||||
use powdr_riscv_types::{
|
||||
InstructionArgs, MemEntry, Register, RiscVProgram, SourceFileInfo, Statement,
|
||||
};
|
||||
use crate::CompilerOptions;
|
||||
|
||||
use crate::continuations::bootloader::{bootloader_and_shutdown_routine, bootloader_preamble};
|
||||
use crate::large_field::runtime::Runtime;
|
||||
use crate::CompilerOptions;
|
||||
|
||||
/// Translates a RISC-V program to POWDR ASM
|
||||
/// with constraints that work for a field >= the Goldilocks modulus.
|
||||
|
||||
@@ -4,7 +4,7 @@ use powdr_syscalls::Syscall;
|
||||
|
||||
use itertools::Itertools;
|
||||
|
||||
use crate::code_gen::Register;
|
||||
use powdr_riscv_types::Register;
|
||||
|
||||
use crate::runtime::{parse_instruction_declaration, SubMachine, SyscallImpl};
|
||||
use crate::RuntimeLibs;
|
||||
|
||||
@@ -12,7 +12,6 @@ use std::fs;
|
||||
|
||||
mod code_gen;
|
||||
pub mod continuations;
|
||||
pub mod elf;
|
||||
pub mod large_field;
|
||||
pub mod runtime;
|
||||
pub mod small_field;
|
||||
@@ -212,9 +211,14 @@ pub fn compile_riscv_elf(
|
||||
options,
|
||||
output_dir,
|
||||
force_overwrite,
|
||||
elf::translate,
|
||||
translate,
|
||||
)
|
||||
}
|
||||
/// Generates a Powdr Assembly program from a RISC-V 32 executable ELF file.
|
||||
pub fn translate(file_name: &Path, options: CompilerOptions) -> String {
|
||||
let elf_program = powdr_riscv_elf::load_elf(file_name);
|
||||
code_gen::translate_program(elf_program, options)
|
||||
}
|
||||
|
||||
/// Creates an array of references to a given type by calling as_ref on each
|
||||
/// element.
|
||||
|
||||
@@ -1,19 +1,15 @@
|
||||
use std::vec;
|
||||
|
||||
use itertools::Itertools;
|
||||
use powdr_isa_utils::SingleDataValue;
|
||||
use powdr_isa_utils::{escape_label, quote};
|
||||
|
||||
use powdr_isa_utils::{escape_label, quote, SingleDataValue};
|
||||
use powdr_number::KnownField;
|
||||
|
||||
use crate::continuations::bootloader::{bootloader_and_shutdown_routine, bootloader_preamble};
|
||||
|
||||
use crate::code_gen::{
|
||||
use powdr_riscv_types::{
|
||||
InstructionArgs, MemEntry, Register, RiscVProgram, SourceFileInfo, Statement,
|
||||
};
|
||||
use crate::CompilerOptions;
|
||||
|
||||
use crate::continuations::bootloader::{bootloader_and_shutdown_routine, bootloader_preamble};
|
||||
use crate::small_field::runtime::Runtime;
|
||||
use crate::CompilerOptions;
|
||||
|
||||
/// Translates a RISC-V program to POWDR ASM with constraints that work for a field >24 bits.
|
||||
///
|
||||
|
||||
@@ -4,7 +4,7 @@ use powdr_syscalls::Syscall;
|
||||
|
||||
use itertools::Itertools;
|
||||
|
||||
use crate::code_gen::Register;
|
||||
use powdr_riscv_types::Register;
|
||||
|
||||
use crate::runtime::{parse_instruction_declaration, SubMachine, SyscallImpl};
|
||||
use crate::RuntimeLibs;
|
||||
|
||||
@@ -123,7 +123,7 @@ pub fn compile_riscv_asm_file(asm_file: &Path, options: CompilerOptions, use_pie
|
||||
.status()
|
||||
.unwrap();
|
||||
|
||||
powdr_riscv::elf::translate(&executable, options)
|
||||
powdr_riscv::translate(&executable, options)
|
||||
}
|
||||
|
||||
pub fn verify_riscv_asm_file(
|
||||
|
||||
@@ -26,7 +26,7 @@ pub fn test_continuations(case: &str, prover_data: Vec<Vec<u8>>) {
|
||||
|
||||
// Test continuations from ELF file.
|
||||
let powdr_asm =
|
||||
powdr_riscv::elf::translate(&executable, CompilerOptions::new_gl().with_continuations());
|
||||
powdr_riscv::translate(&executable, CompilerOptions::new_gl().with_continuations());
|
||||
run_continuations_test(case, powdr_asm, prover_data);
|
||||
}
|
||||
|
||||
@@ -73,7 +73,7 @@ fn bn254_sanity_check() {
|
||||
|
||||
log::info!("Verifying {case} converted from ELF file");
|
||||
let options = CompilerOptions::new(KnownField::Bn254Field, RuntimeLibs::new(), false);
|
||||
let from_elf = powdr_riscv::elf::translate(&executable, options);
|
||||
let from_elf = powdr_riscv::translate(&executable, options);
|
||||
|
||||
let temp_dir = mktemp::Temp::new_dir().unwrap().release();
|
||||
|
||||
@@ -395,7 +395,7 @@ fn read_slice_with_options<T: FieldElement>(options: CompilerOptions) {
|
||||
&temp_dir,
|
||||
None,
|
||||
);
|
||||
let powdr_asm = powdr_riscv::elf::translate(&executable, options);
|
||||
let powdr_asm = powdr_riscv::translate(&executable, options);
|
||||
|
||||
let data: Vec<u32> = vec![];
|
||||
let answer = data.iter().sum::<u32>();
|
||||
@@ -508,7 +508,7 @@ fn features_with_options<T: FieldElement>(options: CompilerOptions) {
|
||||
);
|
||||
|
||||
log::info!("Verifying {case} converted from ELF file");
|
||||
let from_elf = powdr_riscv::elf::translate(&executable, options);
|
||||
let from_elf = powdr_riscv::translate(&executable, options);
|
||||
verify_riscv_asm_string::<T, usize>(
|
||||
&format!("{case}_from_elf.asm"),
|
||||
&from_elf,
|
||||
@@ -526,7 +526,7 @@ fn features_with_options<T: FieldElement>(options: CompilerOptions) {
|
||||
);
|
||||
|
||||
log::info!("Verifying {case} converted from ELF file");
|
||||
let from_elf = powdr_riscv::elf::translate(&executable, options);
|
||||
let from_elf = powdr_riscv::translate(&executable, options);
|
||||
verify_riscv_asm_string::<T, usize>(
|
||||
&format!("{case}_from_elf.asm"),
|
||||
&from_elf,
|
||||
@@ -544,7 +544,7 @@ fn features_with_options<T: FieldElement>(options: CompilerOptions) {
|
||||
);
|
||||
|
||||
log::info!("Verifying {case} converted from ELF file");
|
||||
let from_elf = powdr_riscv::elf::translate(&executable, options);
|
||||
let from_elf = powdr_riscv::translate(&executable, options);
|
||||
verify_riscv_asm_string::<T, usize>(
|
||||
&format!("{case}_from_elf.asm"),
|
||||
&from_elf,
|
||||
@@ -568,7 +568,7 @@ fn many_chunks_dry() {
|
||||
None,
|
||||
);
|
||||
let powdr_asm =
|
||||
powdr_riscv::elf::translate(&executable, CompilerOptions::new_gl().with_continuations());
|
||||
powdr_riscv::translate(&executable, CompilerOptions::new_gl().with_continuations());
|
||||
|
||||
let mut pipeline = Pipeline::default()
|
||||
.from_asm_string(powdr_asm, Some(PathBuf::from(case)))
|
||||
@@ -599,7 +599,7 @@ fn output_syscall_with_options<T: FieldElement>(options: CompilerOptions) {
|
||||
&temp_dir,
|
||||
None,
|
||||
);
|
||||
let powdr_asm = powdr_riscv::elf::translate(&executable, options);
|
||||
let powdr_asm = powdr_riscv::translate(&executable, options);
|
||||
|
||||
let inputs = vec![1u32, 2, 3].into_iter().map(T::from).collect();
|
||||
let mut pipeline = Pipeline::<T>::default()
|
||||
@@ -695,7 +695,7 @@ fn verify_riscv_crate_impl<T: FieldElement, S: serde::Serialize + Send + Sync +
|
||||
);
|
||||
|
||||
log::info!("Verifying {case}");
|
||||
let from_elf = powdr_riscv::elf::translate(&executable, options);
|
||||
let from_elf = powdr_riscv::translate(&executable, options);
|
||||
verify_riscv_asm_string(
|
||||
&format!("{case}_from_elf.asm"),
|
||||
&from_elf,
|
||||
@@ -717,7 +717,7 @@ fn profiler_sanity_check() {
|
||||
);
|
||||
|
||||
let options = CompilerOptions::new(KnownField::GoldilocksField, RuntimeLibs::new(), false);
|
||||
let asm = powdr_riscv::elf::translate(&executable, options);
|
||||
let asm = powdr_riscv::translate(&executable, options);
|
||||
|
||||
let temp_dir = mktemp::Temp::new_dir().unwrap().release();
|
||||
let file_name = format!("{case}.asm");
|
||||
@@ -769,7 +769,7 @@ fn exported_csv_as_external_witness() {
|
||||
|
||||
// compile
|
||||
let options = CompilerOptions::new(KnownField::GoldilocksField, RuntimeLibs::new(), false);
|
||||
let asm = powdr_riscv::elf::translate(&executable, options);
|
||||
let asm = powdr_riscv::translate(&executable, options);
|
||||
|
||||
// export witness
|
||||
let temp_dir = mktemp::Temp::new_dir().unwrap().release();
|
||||
|
||||
Reference in New Issue
Block a user