├── .github └── workflows │ └── ci.yaml ├── .gitignore ├── .gitmodules ├── Cargo.lock ├── Cargo.toml ├── LICENSE.md ├── README.md ├── assets └── banner.png ├── bin ├── Cargo.toml ├── README.md └── src │ ├── cannon.rs │ └── subcommands │ ├── load_elf.rs │ ├── mod.rs │ ├── run.rs │ └── witness.rs ├── crates ├── cannon │ ├── Cargo.toml │ ├── README.md │ └── src │ │ ├── builder.rs │ │ ├── gz.rs │ │ ├── kernel.rs │ │ ├── lib.rs │ │ ├── proc_oracle.rs │ │ ├── traces.rs │ │ └── types.rs ├── mipsevm │ ├── Cargo.toml │ ├── README.md │ ├── benches │ │ ├── execution.rs │ │ └── memory.rs │ ├── bindings │ │ ├── README.md │ │ ├── bindings.sh │ │ ├── mips_creation.bin │ │ └── preimage_oracle_deployed.bin │ ├── open_mips_tests │ │ ├── LICENSE │ │ ├── README.md │ │ ├── maketests.py │ │ └── test │ │ │ ├── add.asm │ │ │ ├── addi.asm │ │ │ ├── addiu.asm │ │ │ ├── addu.asm │ │ │ ├── and.asm │ │ │ ├── andi.asm │ │ │ ├── beq.asm │ │ │ ├── bgez.asm │ │ │ ├── bgtz.asm │ │ │ ├── bin │ │ │ ├── add.bin │ │ │ ├── addi.bin │ │ │ ├── addiu.bin │ │ │ ├── addu.bin │ │ │ ├── and.bin │ │ │ ├── andi.bin │ │ │ ├── beq.bin │ │ │ ├── bgez.bin │ │ │ ├── bgtz.bin │ │ │ ├── blez.bin │ │ │ ├── bltz.bin │ │ │ ├── bne.bin │ │ │ ├── brk.bin │ │ │ ├── clo.bin │ │ │ ├── clone.bin │ │ │ ├── clz.bin │ │ │ ├── div.bin │ │ │ ├── divu.bin │ │ │ ├── exit_group.bin │ │ │ ├── fcntl.bin │ │ │ ├── j.bin │ │ │ ├── jal.bin │ │ │ ├── jalr.bin │ │ │ ├── jr.bin │ │ │ ├── lb.bin │ │ │ ├── lbu.bin │ │ │ ├── lh.bin │ │ │ ├── lhu.bin │ │ │ ├── lui.bin │ │ │ ├── lw.bin │ │ │ ├── lwl.bin │ │ │ ├── lwr.bin │ │ │ ├── mfthi.bin │ │ │ ├── mftlo.bin │ │ │ ├── mmap.bin │ │ │ ├── movn.bin │ │ │ ├── movz.bin │ │ │ ├── mul.bin │ │ │ ├── mult.bin │ │ │ ├── multu.bin │ │ │ ├── nor.bin │ │ │ ├── oracle.bin │ │ │ ├── oracle_unaligned_read.bin │ │ │ ├── oracle_unaligned_write.bin │ │ │ ├── ori.bin │ │ │ ├── sb.bin │ │ │ ├── sh.bin │ │ │ ├── sll.bin │ │ │ ├── sllv.bin │ │ │ ├── slt.bin │ │ │ ├── slti.bin │ │ │ ├── sltiu.bin │ │ │ ├── sltu.bin │ │ │ ├── sra.bin │ │ │ ├── srav.bin │ │ │ ├── srl.bin │ │ │ ├── srlv.bin │ │ │ ├── sub.bin │ │ │ ├── subu.bin │ │ │ ├── swl.bin │ │ │ ├── swr.bin │ │ │ ├── xor.bin │ │ │ └── xori.bin │ │ │ ├── blez.asm │ │ │ ├── bltz.asm │ │ │ ├── bne.asm │ │ │ ├── brk.asm │ │ │ ├── clo.asm │ │ │ ├── clone.asm │ │ │ ├── clz.asm │ │ │ ├── div.asm │ │ │ ├── divu.asm │ │ │ ├── exit_group.asm │ │ │ ├── fcntl.asm │ │ │ ├── j.asm │ │ │ ├── jal.asm │ │ │ ├── jalr.asm │ │ │ ├── jr.asm │ │ │ ├── lb.asm │ │ │ ├── lbu.asm │ │ │ ├── lh.asm │ │ │ ├── lhu.asm │ │ │ ├── lui.asm │ │ │ ├── lw.asm │ │ │ ├── lwl.asm │ │ │ ├── lwr.asm │ │ │ ├── mfthi.asm │ │ │ ├── mftlo.asm │ │ │ ├── mmap.asm │ │ │ ├── movn.asm │ │ │ ├── movz.asm │ │ │ ├── mul.asm │ │ │ ├── mult.asm │ │ │ ├── multu.asm │ │ │ ├── nor.asm │ │ │ ├── oracle.asm │ │ │ ├── oracle_unaligned_read.asm │ │ │ ├── oracle_unaligned_write.asm │ │ │ ├── ori.asm │ │ │ ├── sb.asm │ │ │ ├── sh.asm │ │ │ ├── sll.asm │ │ │ ├── sllv.asm │ │ │ ├── slt.asm │ │ │ ├── slti.asm │ │ │ ├── sltiu.asm │ │ │ ├── sltu.asm │ │ │ ├── sra.asm │ │ │ ├── srav.asm │ │ │ ├── srl.asm │ │ │ ├── srlv.asm │ │ │ ├── sub.asm │ │ │ ├── subu.asm │ │ │ ├── swl.asm │ │ │ ├── swr.asm │ │ │ ├── xor.asm │ │ │ └── xori.asm │ └── src │ │ ├── lib.rs │ │ ├── memory.rs │ │ ├── mips │ │ ├── instrumented.rs │ │ ├── mips_vm.rs │ │ └── mod.rs │ │ ├── page.rs │ │ ├── patch.rs │ │ ├── ser.rs │ │ ├── state.rs │ │ ├── test_utils │ │ ├── evm.rs │ │ └── mod.rs │ │ ├── traces.rs │ │ ├── traits.rs │ │ ├── types.rs │ │ ├── utils.rs │ │ └── witness.rs └── preimage │ ├── Cargo.toml │ ├── README.md │ └── src │ ├── file_chan.rs │ ├── hints.rs │ ├── lib.rs │ ├── oracle.rs │ ├── traces.rs │ ├── traits.rs │ └── types.rs ├── docker ├── README.md ├── build.sh └── cannon-rs.dockerfile └── example ├── Makefile ├── bin ├── claim.elf └── hello.elf ├── claim ├── go.mod ├── go.sum └── main.go └── hello ├── go.mod └── main.go /.github/workflows/ci.yaml: -------------------------------------------------------------------------------- 1 | name: Rust CI 2 | on: [push] 3 | 4 | env: 5 | CARGO_TERM_COLOR: always 6 | 7 | jobs: 8 | cargo-tests: 9 | runs-on: ubuntu-latest 10 | timeout-minutes: 20 11 | steps: 12 | - name: Checkout sources 13 | uses: actions/checkout@v4 14 | - name: Install Rust nightly toolchain 15 | uses: dtolnay/rust-toolchain@nightly 16 | - uses: Swatinem/rust-cache@v2 17 | with: 18 | cache-on-failure: true 19 | - name: Install xsltproc 20 | run: sudo apt-get install xsltproc 21 | - uses: taiki-e/install-action@nextest 22 | - name: cargo test 23 | run: cargo nextest run --release --workspace --all --locked 24 | cargo-lint: 25 | runs-on: ubuntu-latest 26 | timeout-minutes: 20 27 | steps: 28 | - name: Checkout sources 29 | uses: actions/checkout@v4 30 | - name: Install Rust nightly toolchain 31 | uses: dtolnay/rust-toolchain@nightly 32 | with: 33 | components: rustfmt, clippy 34 | - uses: Swatinem/rust-cache@v2 35 | with: 36 | cache-on-failure: true 37 | - name: Install xsltproc 38 | run: sudo apt-get install xsltproc 39 | - name: cargo fmt 40 | run: cargo fmt --all -- --check 41 | - name: cargo clippy 42 | run: cargo clippy --workspace --all --locked -- -D warnings 43 | cargo-build: 44 | runs-on: ubuntu-latest 45 | timeout-minutes: 20 46 | continue-on-error: true 47 | steps: 48 | - name: Checkout sources 49 | uses: actions/checkout@v4 50 | - name: Install Rust nightly toolchain 51 | uses: dtolnay/rust-toolchain@nightly 52 | - uses: Swatinem/rust-cache@v2 53 | with: 54 | cache-on-failure: true 55 | - name: Install xsltproc 56 | run: sudo apt-get install xsltproc 57 | - name: build 58 | id: build 59 | run: cargo build --workspace --all --locked 60 | cargo-doc: 61 | runs-on: ubuntu-latest 62 | timeout-minutes: 20 63 | continue-on-error: true 64 | steps: 65 | - name: Checkout sources 66 | uses: actions/checkout@v4 67 | - name: Install Rust nightly toolchain 68 | uses: dtolnay/rust-toolchain@nightly 69 | - uses: Swatinem/rust-cache@v2 70 | with: 71 | cache-on-failure: true 72 | - name: Install xsltproc 73 | run: sudo apt-get install xsltproc 74 | - name: doclint 75 | id: build 76 | continue-on-error: true 77 | run: RUSTDOCFLAGS="-D warnings" cargo doc --all --no-deps --document-private-items 78 | - name: doctest 79 | run: cargo test --doc --all --locked 80 | 81 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # MacOS 2 | .DS_Store 3 | 4 | # Rust 5 | /target 6 | -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "crates/mipsevm/bindings/optimism"] 2 | path = crates/mipsevm/bindings/optimism 3 | url = https://github.com/ethereum-optimism/optimism 4 | -------------------------------------------------------------------------------- /Cargo.toml: -------------------------------------------------------------------------------- 1 | [workspace] 2 | members = ["bin", "crates/*"] 3 | resolver = "2" 4 | 5 | [workspace.package] 6 | version = "0.1.0" 7 | authors = ["clabby"] 8 | 9 | [workspace.dependencies] 10 | # types 11 | alloy-primitives = "0.6.2" 12 | 13 | # ser 14 | serde = { version = "1.0.196", features = ["derive"] } 15 | serde_json = "1.0.113" 16 | 17 | # runtime 18 | tokio = { version = "1.36.0", features = ["full"] } 19 | 20 | # misc 21 | anyhow = "1.0.79" 22 | 23 | [profile.release] 24 | opt-level = 3 25 | lto = true 26 | codegen-units = 1 27 | 28 | [profile.dev] 29 | overflow-checks = false 30 | 31 | [profile.bench] 32 | debug = true 33 | -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | ===================== 3 | 4 | Copyright © `2023` `cannon-rs contributors` 5 | 6 | Permission is hereby granted, free of charge, to any person 7 | obtaining a copy of this software and associated documentation 8 | files (the “Software”), to deal in the Software without 9 | restriction, including without limitation the rights to use, 10 | copy, modify, merge, publish, distribute, sublicense, and/or sell 11 | copies of the Software, and to permit persons to whom the 12 | Software is furnished to do so, subject to the following 13 | conditions: 14 | 15 | The above copyright notice and this permission notice shall be 16 | included in all copies or substantial portions of the Software. 17 | 18 | THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, 19 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES 20 | OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 21 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 22 | HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 23 | WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 24 | FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 25 | OTHER DEALINGS IN THE SOFTWARE. 26 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 |

2 | Cannon 3 |

4 | 5 |

6 | An alternative implementation of the OP Stack's Cannon in Rust. 7 |

8 | 9 |

10 | 11 | Ci 12 | 13 | License 14 | OP Stack 15 | 16 |

17 | 18 |

19 | What's a Cannon? • 20 | Overview • 21 | Credits • 22 | Benchmarks • 23 | Contributing • 24 | Documentation • 25 | Docker 26 |

27 | 28 | ## What's a Cannon? 29 | 30 | Cannon is an emulator designed to simulate a single MIPS thread context on the EVM. Its primary use is to execute the [`op-program`][op-program] 31 | (also known as the fault-proof program) for the [OP Stack][monorepo]'s interactive dispute protocol. The `op-program` consists 32 | of a stripped down version of `op-geth`'s state transition code in addition to the derivation pipeline, and produces deterministic results. 33 | Subsequently, it is compiled to MIPS to be ran on top of Cannon on-chain to prove fault in claims about the state of L2 on L1. Cannon also has a 34 | native implementation of the MIPS thread context that mirrors the on-chain version, which enables the [op-challenger][op-challenger] to generate 35 | state commitments for an `op-program` execution trace and participate in dispute games. 36 | 37 | *TL;DR:* 38 | * It's Rust code 39 | * ...that was [originally Go code][cannon] 40 | * ...that runs an EVM 41 | * ...emulating a MIPS machine 42 | * ...running [compiled Go code][op-program] 43 | * ...that runs an EVM 44 | 45 | ## Overview 46 | * [`cannon-mipsevm`](./crates/mipsevm) - Contains the native implementation of the MIPS thread context emulator. 47 | * [`preimage-oracle`](./crates/preimage) - Rust bindings for interacting as client or sever over the Pre-image Oracle ABI. 48 | * [`cannon-contracts`](https://github.com/ethereum-optimism/optimism/tree/develop/packages/contracts-bedrock/src/cannon) - [*in OP monorepo*] Contains the Solidity implementation of the MIPS thread context and the Preimage Oracle. 49 | 50 | ## Credits 51 | 52 | This repository is heavily inspired by the original [Cannon][cannon], built by [George Hotz][geohot] and members of the [OP Labs][op-labs] team. The original implementation is written in Go, and can be found [in the Optimism monorepo][cannon]. All 53 | credits for the original idea and reference implementation of this concept go to these folks. 54 | 55 | ## Benchmarks 56 | 57 | ### `cannon-mipsevm` benchmarks 58 | 59 | The below benchmark was ran on a 2021 Macbook Pro with an M1 Max and 32 GB of unified memory 60 | on commit [`71b68d5`](https://github.com/anton-rs/cannon-rs/pull/17/commits/71b68d52fb858cfc544c1430b482aeaef460552e). 61 | 62 | | Benchmark Name | `cannon` mean (Reference) | `cannon-rs` mean | 63 | |----------------------------|---------------------------|---------------------| 64 | | Memory Merkle Root (25MB) | 736.94 ms | 29.58 µs (-99%) | 65 | | Memory Merkle Root (50MB) | 1.54s | 7.25 ms (-99%) | 66 | | Memory Merkle Root (100MB) | 3.34s | 273.76 ms (-91.8%) | 67 | | Memory Merkle Root (200MB) | 6.30s | 1.65s (-73.81%) | 68 | 69 | *todo - execution benchmarks* 70 | 71 | ## Contributing 72 | 73 | To get started, a few dependencies are required: 74 | * [Rust toolchain][rustup] 75 | * Recommended: [`cargo-nextest`][nextest] 76 | * [Go toolchain][golang] 77 | * [binutils][binutils] 78 | 79 | ### Testing 80 | 81 | ```sh 82 | # With `cargo-nextest` 83 | cargo +nightly nextest run --release --all --all-features 84 | # Without `cargo-nextest` 85 | cargo +nightly t --release --all --all-features 86 | ``` 87 | 88 | ### Linting and Formatting 89 | 90 | ```sh 91 | cargo +nightly fmt --all -- && cargo +nightly clippy --all --all-features -- -D warnings 92 | ``` 93 | 94 | ### Running Benchmarks 95 | 96 | ```sh 97 | cargo +nightly bench --all --all-features 98 | ``` 99 | 100 | ## Documentation 101 | 102 | Rustdocs are available by running `cargo doc --open` after cloning the repo. 103 | 104 | ### Specification 105 | 106 | The specification for both Cannon and the preimage oracle can be found in the [Optimism monorepo][monorepo]. 107 | * [Cannon specification][cannon-specs] 108 | * [Preimage oracle specification][fpp-specs] 109 | 110 | ## Docker 111 | 112 | The docker image for `cannon-rs` is located in the [docker](./docker) directory, and can be built using the 113 | script provided. 114 | 115 | [geohot]: https://github.com/geohot 116 | [op-labs]: https://oplabs.co 117 | [monorepo]: https://github.com/ethereum-optimism/optimism 118 | [cannon]: https://github.com/ethereum-optimism/optimism/tree/develop/cannon 119 | [op-program]: https://github.com/ethereum-optimism/optimism/tree/develop/op-program 120 | [op-challenger]: https://github.com/ethereum-optimism/optimism/tree/develop/op-challenger 121 | [rustup]: https://rustup.rs/ 122 | [golang]: https://go.dev/doc/install 123 | [binutils]: https://www.gnu.org/software/binutils/ 124 | [nextest]: https://nexte.st/ 125 | [fpp-specs]: https://github.com/ethereum-optimism/optimism/blob/develop/specs/fault-proof.md 126 | [cannon-specs]: https://github.com/ethereum-optimism/optimism/blob/develop/specs/cannon-fault-proof-vm.md 127 | -------------------------------------------------------------------------------- /assets/banner.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/op-rs/cannon-rs/5ab846ae9d4cc0d2cf26c4a7af88f86f5339644b/assets/banner.png -------------------------------------------------------------------------------- /bin/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "cannon-rs" 3 | description = "Binary crate for cannon-rs" 4 | edition = "2021" 5 | 6 | version.workspace = true 7 | authors.workspace = true 8 | 9 | [dependencies] 10 | # External 11 | anyhow = "1.0.75" 12 | clap = { version = "4.4.3", features = ["derive"] } 13 | alloy-primitives = "0.4.0" 14 | tracing = "0.1.37" 15 | tracing-subscriber = "0.3.17" 16 | serde = { version = "1.0.188", features = ["derive"] } 17 | serde_json = "1.0.107" 18 | 19 | # Local 20 | cannon = { path = "../crates/cannon" } 21 | cannon-mipsevm = { path = "../crates/mipsevm" } 22 | 23 | [[bin]] 24 | name = "cannon" 25 | path = "src/cannon.rs" 26 | -------------------------------------------------------------------------------- /bin/README.md: -------------------------------------------------------------------------------- 1 | # `cannon` 2 | 3 | > **Note** 4 | > Not started yet; Blocked by preimage oracle ABI bindings. 5 | 6 | This crate contains the implementation of the Cannon binary for `cannon-rs`. 7 | -------------------------------------------------------------------------------- /bin/src/cannon.rs: -------------------------------------------------------------------------------- 1 | use crate::subcommands::CannonSubcommandDispatcher; 2 | use anyhow::{anyhow, Result}; 3 | use clap::{ArgAction, ColorChoice, Parser}; 4 | use tracing::Level; 5 | 6 | mod subcommands; 7 | 8 | /// Comand line arguments for `cannon` binary 9 | #[derive(Parser, Debug)] 10 | #[command(author, version, about, color = ColorChoice::Always)] 11 | struct Args { 12 | /// Verbosity level (0-4) 13 | #[arg(long, short, action = ArgAction::Count, default_value = "2")] 14 | v: u8, 15 | 16 | /// The subcommand to run 17 | #[command(subcommand)] 18 | subcommand: subcommands::CannonSubcommand, 19 | } 20 | 21 | fn main() -> Result<()> { 22 | // Parse the command arguments 23 | let Args { v, subcommand } = Args::parse(); 24 | 25 | // Initialize the tracing subscriber 26 | init_tracing_subscriber(v)?; 27 | 28 | tracing::debug!(target: "cannon-cli", "Dispatching subcommand"); 29 | subcommand.dispatch()?; 30 | 31 | Ok(()) 32 | } 33 | 34 | /// Initializes the tracing subscriber 35 | /// 36 | /// # Arguments 37 | /// * `verbosity_level` - The verbosity level (0-4) 38 | /// 39 | /// # Returns 40 | /// * `Result<()>` - Ok if successful, Err otherwise. 41 | fn init_tracing_subscriber(verbosity_level: u8) -> Result<()> { 42 | let subscriber = tracing_subscriber::fmt() 43 | .with_max_level(match verbosity_level { 44 | 0 => Level::ERROR, 45 | 1 => Level::WARN, 46 | 2 => Level::INFO, 47 | 3 => Level::DEBUG, 48 | _ => Level::TRACE, 49 | }) 50 | .finish(); 51 | tracing::subscriber::set_global_default(subscriber).map_err(|e| anyhow!(e)) 52 | } 53 | -------------------------------------------------------------------------------- /bin/src/subcommands/load_elf.rs: -------------------------------------------------------------------------------- 1 | //! The `load-elf` subcommand for the cannon binary 2 | 3 | use super::CannonSubcommandDispatcher; 4 | use alloy_primitives::B256; 5 | use anyhow::Result; 6 | use cannon::gz::compress_bytes; 7 | use cannon_mipsevm::{load_elf, patch_go, patch_stack, StateWitnessHasher}; 8 | use clap::Args; 9 | use std::{ 10 | fmt::Display, 11 | fs::File, 12 | io::{BufReader, BufWriter, Read, Write}, 13 | path::PathBuf, 14 | str::FromStr, 15 | }; 16 | 17 | /// Command line arguments for `cannon load-elf` 18 | #[derive(Args, Debug)] 19 | #[command(author, version, about)] 20 | pub(crate) struct LoadElfArgs { 21 | /// The path to the input 32-bit big-endian MIPS ELF file. 22 | #[arg(long)] 23 | path: PathBuf, 24 | 25 | /// The type of patch to perform on the ELF file. 26 | #[arg(long, default_values = ["go", "stack"])] 27 | patch_kind: Vec, 28 | 29 | /// The output path to write the JSON state to. State will be dumped to stdout if set to `-`. 30 | /// Not written if not provided. 31 | #[arg(long)] 32 | output: Option, 33 | } 34 | 35 | #[derive(Clone, Debug)] 36 | enum PatchKind { 37 | Go, 38 | Stack, 39 | } 40 | 41 | impl FromStr for PatchKind { 42 | type Err = anyhow::Error; 43 | 44 | fn from_str(s: &str) -> Result { 45 | match s { 46 | "go" => Ok(PatchKind::Go), 47 | "stack" => Ok(PatchKind::Stack), 48 | _ => Err(anyhow::anyhow!("Invalid patch kind: {}", s)), 49 | } 50 | } 51 | } 52 | 53 | impl Display for PatchKind { 54 | fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { 55 | match self { 56 | PatchKind::Go => write!(f, "Go"), 57 | PatchKind::Stack => write!(f, "Stack"), 58 | } 59 | } 60 | } 61 | 62 | impl CannonSubcommandDispatcher for LoadElfArgs { 63 | fn dispatch(self) -> Result<()> { 64 | tracing::info!(target: "cannon-cli::load-elf", "Loading ELF file @ {}", self.path.display()); 65 | let file = File::open(&self.path)?; 66 | let file_sz = file.metadata()?.len(); 67 | let mut reader = BufReader::new(file); 68 | let mut elf_raw = Vec::with_capacity(file_sz as usize); 69 | reader.read_to_end(&mut elf_raw)?; 70 | let mut state = load_elf(&elf_raw)?; 71 | tracing::info!(target: "cannon-cli::load-elf", "Loaded ELF file and constructed the State"); 72 | 73 | for p in self.patch_kind { 74 | tracing::info!(target: "cannon-cli::load-elf", "Patching the ELF file with patch type = {p}..."); 75 | match p { 76 | PatchKind::Go => patch_go(&elf_raw, &mut state), 77 | PatchKind::Stack => patch_stack(&mut state), 78 | }?; 79 | } 80 | 81 | if let Some(ref path_str) = self.output { 82 | if path_str == "-" { 83 | println!("{}", serde_json::to_string(&state)?); 84 | } else { 85 | let mut writer = BufWriter::new(File::create(path_str)?); 86 | let ser_state = serde_json::to_vec(&state)?; 87 | let gz_state = compress_bytes(&ser_state)?; 88 | writer.write_all(&gz_state)?; 89 | } 90 | } 91 | 92 | tracing::info!(target: "cannon-cli::load-elf", "Patched the ELF file and dumped the State successfully. state hash: {} mem size: {} pages: {}", B256::from(state.encode_witness()?.state_hash()), state.memory.usage(), state.memory.page_count()); 93 | 94 | Ok(()) 95 | } 96 | } 97 | -------------------------------------------------------------------------------- /bin/src/subcommands/mod.rs: -------------------------------------------------------------------------------- 1 | //! Subcommands for the `cannon` binary 2 | 3 | use anyhow::Result; 4 | use clap::Subcommand; 5 | 6 | mod load_elf; 7 | mod run; 8 | mod witness; 9 | 10 | pub(crate) trait CannonSubcommandDispatcher { 11 | /// Dispatches the subcommand 12 | fn dispatch(self) -> Result<()>; 13 | } 14 | 15 | /// The subcommands for the `cannon` binary 16 | #[derive(Subcommand, Debug)] 17 | pub(crate) enum CannonSubcommand { 18 | Run(run::RunArgs), 19 | Witness(witness::WitnessArgs), 20 | LoadElf(load_elf::LoadElfArgs), 21 | } 22 | 23 | impl CannonSubcommandDispatcher for CannonSubcommand { 24 | fn dispatch(self) -> Result<()> { 25 | match self { 26 | CannonSubcommand::Run(args) => args.dispatch(), 27 | CannonSubcommand::Witness(args) => args.dispatch(), 28 | CannonSubcommand::LoadElf(args) => args.dispatch(), 29 | } 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /bin/src/subcommands/run.rs: -------------------------------------------------------------------------------- 1 | //! The `run` subcommand for the cannon binary 2 | 3 | use super::CannonSubcommandDispatcher; 4 | use anyhow::Result; 5 | use cannon::KernelBuilder; 6 | use clap::Args; 7 | 8 | /// Command line arguments for `cannon run` 9 | #[derive(Args, Debug)] 10 | #[command(author, version, about)] 11 | pub(crate) struct RunArgs { 12 | /// The preimage oracle command 13 | #[arg(long)] 14 | preimage_server: String, 15 | 16 | /// The path to the input JSON state. 17 | #[arg(long)] 18 | input: String, 19 | 20 | /// The path to the output JSON state. 21 | #[arg(long)] 22 | output: Option, 23 | 24 | /// The step to generate an output proof at. 25 | #[arg(long)] 26 | proof_at: Option, 27 | 28 | /// Format for proof data output file names. Proof data is written to stdout 29 | /// if this is not specified. 30 | #[arg(long, aliases = ["proof-fmt"])] 31 | proof_format: Option, 32 | 33 | /// The step pattern to generate state snapshots at. 34 | #[arg(long)] 35 | snapshot_at: Option, 36 | 37 | /// Format for snapshot data output file names. 38 | #[arg(long, aliases = ["snapshot-fmt"])] 39 | snapshot_format: Option, 40 | 41 | /// The instruction step to stop running at. 42 | #[arg(long)] 43 | stop_at: Option, 44 | 45 | /// The pattern to print information at. 46 | #[arg(long)] 47 | info_at: Option, 48 | } 49 | 50 | impl CannonSubcommandDispatcher for RunArgs { 51 | fn dispatch(self) -> Result<()> { 52 | let kernel = KernelBuilder::default() 53 | .with_preimage_server(self.preimage_server.replace('"', "")) 54 | .with_input(self.input) 55 | .with_output(self.output) 56 | .with_proof_at(self.proof_at) 57 | .with_proof_format(self.proof_format) 58 | .with_snapshot_at(self.snapshot_at) 59 | .with_snapshot_format(self.snapshot_format) 60 | .with_stop_at(self.stop_at) 61 | .with_info_at(self.info_at) 62 | .build()?; 63 | kernel.run() 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /bin/src/subcommands/witness.rs: -------------------------------------------------------------------------------- 1 | //! The `witness` subcommand for the cannon binary 2 | 3 | use super::CannonSubcommandDispatcher; 4 | use alloy_primitives::B256; 5 | use anyhow::Result; 6 | use cannon::gz::decompress_bytes; 7 | use cannon_mipsevm::{State, StateWitnessHasher}; 8 | use clap::Args; 9 | use std::{fs, path::PathBuf}; 10 | 11 | /// Command line arguments for `cannon witness` 12 | #[derive(Args, Debug)] 13 | #[command(author, version, about)] 14 | pub(crate) struct WitnessArgs { 15 | /// The path to the input JSON state. 16 | #[arg(long)] 17 | input: PathBuf, 18 | 19 | /// The path to the output JSON state. 20 | #[arg(long)] 21 | output: Option, 22 | } 23 | 24 | impl CannonSubcommandDispatcher for WitnessArgs { 25 | fn dispatch(self) -> Result<()> { 26 | tracing::info!(target: "cannon-cli::witness", "Loading state JSON dump from {}", self.input.display()); 27 | 28 | let state_raw = fs::read(&self.input)?; 29 | let mut state: State = serde_json::from_slice(&decompress_bytes(&state_raw)?)?; 30 | 31 | tracing::info!(target: "cannon-cli::witness", "Loaded state JSON dump and deserialized the State"); 32 | 33 | let witness = state.encode_witness()?; 34 | let witness_hash = witness.state_hash(); 35 | 36 | tracing::info!(target: "cannon-cli::witness", "Encoded witness and computed witness hash: {}", B256::from(witness_hash)); 37 | 38 | match self.output { 39 | Some(ref output_path) => fs::write(output_path, witness).map_err(|_| { 40 | anyhow::anyhow!("Failed to write witness to {}", output_path.display()) 41 | }), 42 | None => { 43 | println!("{}", B256::from(witness_hash)); 44 | Ok(()) 45 | } 46 | }?; 47 | 48 | tracing::info!(target: "cannon-cli::witness", "Wrote witness to {}", self.output.as_ref().map_or("stdout".to_string(), |p| p.display().to_string())); 49 | Ok(()) 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /crates/cannon/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "cannon" 3 | description = "An implementation of the OP Stack's native BE MIPS32 VM in Rust" 4 | edition = "2021" 5 | 6 | version.workspace = true 7 | authors.workspace = true 8 | 9 | [dependencies] 10 | # workspace 11 | alloy-primitives.workspace = true 12 | anyhow.workspace = true 13 | serde.workspace = true 14 | serde_json.workspace = true 15 | tokio.workspace = true 16 | 17 | # local 18 | cannon-mipsevm = { path = "../mipsevm" } 19 | preimage-oracle = { path = "../preimage" } 20 | 21 | # misc 22 | flate2 = "1.0.28" 23 | command-fds = "0.2.3" 24 | tracing = { version = "0.1.40", optional = true } 25 | 26 | [dev-dependencies] 27 | proptest = "1.4.0" 28 | 29 | [features] 30 | tracing = ["dep:tracing"] 31 | -------------------------------------------------------------------------------- /crates/cannon/README.md: -------------------------------------------------------------------------------- 1 | # `cannon` 2 | 3 | The cannon crate provides a high-level interface to run the Cannon kernel, which consists of the [MIPS32 emulator][mipsevm] 4 | as well as the [preimage oracle server][preimage-oracle]. 5 | 6 | The interaction between these two processes is fully synchronous. While the emulator is running, the preimage oracle 7 | server is blocked on waiting for hints and preimage requests from the emulator. During the time that the preimage oracle server 8 | is working, the emulator is blocked on waiting for the preimage oracle server to respond. 9 | 10 | ```text 11 | ┌───────┐ ┌───────────────┐ 12 | │mipsevm│ │preimage-server│ 13 | └───┬───┘ └───────┬───────┘ 14 | │ │ 15 | │ Hint │ 16 | │──────────────>│ 17 | │ │ 18 | │ Ack hint │ 19 | │<──────────────│ 20 | │ │ 21 | │ Get Preimage │ 22 | │──────────────>│ 23 | │ │ 24 | │Return preimage│ 25 | │<──────────────│ 26 | ┌───┴───┐ ┌───────┴───────┐ 27 | │mipsevm│ │preimage-server│ 28 | └───────┘ └───────────────┘ 29 | ``` 30 | 31 | [mipsevm]: ../mipsevm 32 | [preimage-oracle]: ../preimage-oracle 33 | -------------------------------------------------------------------------------- /crates/cannon/src/builder.rs: -------------------------------------------------------------------------------- 1 | //! The [KernelBuilder] struct is a helper for building a [Kernel] struct. 2 | 3 | use crate::{gz, ChildWithFds, Kernel, ProcessPreimageOracle}; 4 | use anyhow::{anyhow, Result}; 5 | use cannon_mipsevm::{InstrumentedState, State}; 6 | use std::{ 7 | fs::{self, File}, 8 | io::{self, BufReader, Read, Stderr, Stdout}, 9 | path::PathBuf, 10 | }; 11 | 12 | /// The [KernelBuilder] struct is a helper for building a [Kernel] struct. 13 | #[derive(Default, Debug)] 14 | pub struct KernelBuilder { 15 | /// The full command to run the preimage server 16 | preimage_server: String, 17 | /// The path to the input JSON state. 18 | input: String, 19 | /// The path to the output JSON state. 20 | output: Option, 21 | /// The step to generate an output proof at. 22 | proof_at: Option, 23 | /// Format for proof data output file names. Proof data is written to stdout 24 | /// if this is not specified. 25 | proof_format: Option, 26 | /// The step pattern to generate state snapshots at. 27 | snapshot_at: Option, 28 | /// Format for snapshot data output file names. 29 | snapshot_format: Option, 30 | /// The instruction step to stop running at. 31 | stop_at: Option, 32 | /// The pattern to print information at. 33 | info_at: Option, 34 | } 35 | 36 | impl KernelBuilder { 37 | /// Builds the [Kernel] struct from the information contained within the [KernelBuilder]. 38 | /// 39 | /// TODO(clabby): Make the i/o streams + the preimage oracle configurable. 40 | pub fn build(self) -> Result> { 41 | // Read the compressed state dump from the input file, decompress it, and deserialize it. 42 | let f = File::open(&self.input)?; 43 | let f_sz = f.metadata()?.len(); 44 | let mut reader = BufReader::new(f); 45 | // Give a reasonable capacity to the vector to avoid too many reallocations. The size of the file 46 | // is the size of the compressed state dump, so we will still reallocate. 47 | let mut raw_state = Vec::with_capacity(f_sz as usize); 48 | reader.read_to_end(&mut raw_state)?; 49 | let raw_state = fs::read(&self.input)?; 50 | let state: State = serde_json::from_slice(&gz::decompress_bytes(&raw_state)?)?; 51 | 52 | let (hint_cl_rw, hint_oracle_rw) = preimage_oracle::create_bidirectional_channel()?; 53 | let (pre_cl_rw, pre_oracle_rw) = preimage_oracle::create_bidirectional_channel()?; 54 | 55 | let server_io = [hint_oracle_rw, pre_oracle_rw]; 56 | 57 | // TODO(clabby): Allow for the preimage server to be configurable. 58 | let cmd = self 59 | .preimage_server 60 | .split(' ') 61 | .map(String::from) 62 | .collect::>(); 63 | let (oracle, server_proc) = ProcessPreimageOracle::start( 64 | PathBuf::from( 65 | cmd.first() 66 | .ok_or(anyhow!("Missing preimage server binary path"))?, 67 | ), 68 | &cmd[1..], 69 | (hint_cl_rw, pre_cl_rw), 70 | &server_io, 71 | )?; 72 | 73 | let server_proc = server_proc.map(|p| ChildWithFds { 74 | inner: p, 75 | fds: server_io, 76 | }); 77 | 78 | // TODO(clabby): Allow for the stdout / stderr to be configurable. 79 | let instrumented = InstrumentedState::new(state, oracle, io::stdout(), io::stderr()); 80 | 81 | Ok(Kernel::new( 82 | instrumented, 83 | server_proc, 84 | self.input, 85 | self.output, 86 | self.proof_at, 87 | self.proof_format, 88 | self.snapshot_at, 89 | self.snapshot_format, 90 | self.stop_at, 91 | self.info_at, 92 | )) 93 | } 94 | 95 | pub fn with_preimage_server(mut self, preimage_server: String) -> Self { 96 | self.preimage_server = preimage_server; 97 | self 98 | } 99 | 100 | pub fn with_input(mut self, input: String) -> Self { 101 | self.input = input; 102 | self 103 | } 104 | 105 | pub fn with_output(mut self, output: Option) -> Self { 106 | self.output = output; 107 | self 108 | } 109 | 110 | pub fn with_proof_at(mut self, proof_at: Option) -> Self { 111 | self.proof_at = proof_at; 112 | self 113 | } 114 | 115 | pub fn with_proof_format(mut self, proof_format: Option) -> Self { 116 | self.proof_format = proof_format; 117 | self 118 | } 119 | 120 | pub fn with_snapshot_at(mut self, snapshot_at: Option) -> Self { 121 | self.snapshot_at = snapshot_at; 122 | self 123 | } 124 | 125 | pub fn with_snapshot_format(mut self, snapshot_format: Option) -> Self { 126 | self.snapshot_format = snapshot_format; 127 | self 128 | } 129 | 130 | pub fn with_stop_at(mut self, stop_at: Option) -> Self { 131 | self.stop_at = stop_at; 132 | self 133 | } 134 | 135 | pub fn with_info_at(mut self, info_at: Option) -> Self { 136 | self.info_at = info_at; 137 | self 138 | } 139 | } 140 | -------------------------------------------------------------------------------- /crates/cannon/src/gz.rs: -------------------------------------------------------------------------------- 1 | //! This module contains utilities for compressing and decompressing serialized bytes using gzip. 2 | 3 | use anyhow::Result; 4 | use flate2::{bufread::GzDecoder, write::GzEncoder, Compression}; 5 | use std::io::{Read, Write}; 6 | 7 | /// Compresses a byte slice using gzip. 8 | #[inline(always)] 9 | pub fn compress_bytes(bytes: &[u8]) -> Result> { 10 | let mut encoder = GzEncoder::new(Vec::with_capacity(bytes.len()), Compression::default()); 11 | encoder.write_all(bytes)?; 12 | Ok(encoder.finish()?) 13 | } 14 | 15 | /// Decompresses a byte slice using gzip. 16 | pub fn decompress_bytes(compressed_bytes: &[u8]) -> Result> { 17 | let mut decoder = GzDecoder::new(compressed_bytes); 18 | 19 | // Give our decompressed buffer the same capacity as the compressed buffer to reduce 20 | // reallocations up to the compressed buffer's size. 21 | let mut decompressed_bytes = Vec::with_capacity(compressed_bytes.len()); 22 | decoder.read_to_end(&mut decompressed_bytes)?; 23 | 24 | Ok(decompressed_bytes) 25 | } 26 | 27 | #[cfg(test)] 28 | mod test { 29 | use proptest::proptest; 30 | 31 | proptest! { 32 | #[test] 33 | fn test_compress_decompress(bytes: Vec) { 34 | let compressed = super::compress_bytes(&bytes).unwrap(); 35 | let decompressed = super::decompress_bytes(&compressed).unwrap(); 36 | assert_eq!(bytes, decompressed); 37 | } 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /crates/cannon/src/lib.rs: -------------------------------------------------------------------------------- 1 | #![doc = include_str!("../README.md")] 2 | 3 | mod builder; 4 | pub use builder::KernelBuilder; 5 | 6 | pub mod gz; 7 | pub use gz::{compress_bytes, decompress_bytes}; 8 | 9 | mod kernel; 10 | pub use kernel::Kernel; 11 | 12 | mod proc_oracle; 13 | pub use proc_oracle::ProcessPreimageOracle; 14 | 15 | mod types; 16 | pub use types::{ChildWithFds, Proof}; 17 | 18 | mod traces; 19 | -------------------------------------------------------------------------------- /crates/cannon/src/proc_oracle.rs: -------------------------------------------------------------------------------- 1 | //! This module contains the [PreimageServer] struct and its associated methods. 2 | 3 | use anyhow::Result; 4 | use cannon_mipsevm::PreimageOracle; 5 | use command_fds::{CommandFdExt, FdMapping}; 6 | use preimage_oracle::{Hint, HintWriter, Hinter, Oracle, OracleClient, RawKey, ReadWritePair}; 7 | use std::{ 8 | io, 9 | os::fd::AsRawFd, 10 | path::PathBuf, 11 | process::{Child, Command}, 12 | }; 13 | 14 | /// The [ProcessPreimageOracle] struct represents a preimage oracle process that communicates with 15 | /// the mipsevm via a few special file descriptors. This process is responsible for preparing and 16 | /// sending the results of preimage requests to the mipsevm process. 17 | pub struct ProcessPreimageOracle { 18 | /// The preimage oracle client 19 | pub preimage_client: OracleClient, 20 | /// The hint writer client 21 | pub hint_writer_client: HintWriter, 22 | } 23 | 24 | impl ProcessPreimageOracle { 25 | /// Creates a new [PreimageServer] from the given [OracleClient] and [HintWriter] and starts 26 | /// the server process. 27 | pub fn start( 28 | cmd: PathBuf, 29 | args: &[String], 30 | client_io: (ReadWritePair, ReadWritePair), 31 | server_io: &[ReadWritePair; 2], 32 | ) -> Result<(Self, Option)> { 33 | let cmd_str = cmd.display().to_string(); 34 | let child = (!cmd_str.is_empty()).then(|| { 35 | crate::info!( 36 | "Starting preimage server process: {} {:?}", 37 | cmd.display(), 38 | args 39 | ); 40 | 41 | let mut command = Command::new(cmd); 42 | let command = { 43 | // Grab the file descriptors for the hint and preimage channels 44 | // that the server will use to communicate with the mipsevm 45 | let fds = [ 46 | server_io[0].reader().as_raw_fd(), 47 | server_io[0].writer().as_raw_fd(), 48 | server_io[1].reader().as_raw_fd(), 49 | server_io[1].writer().as_raw_fd(), 50 | ]; 51 | 52 | crate::traces::info!(target: "cannon::preimage::server", "Starting preimage server process: {:?} with fds {:?}", args, fds); 53 | 54 | command 55 | .args(args) 56 | .stdout(io::stdout()) 57 | .stderr(io::stderr()) 58 | .fd_mappings( 59 | fds.iter().enumerate() 60 | .map(|(i, fd)| FdMapping { 61 | parent_fd: *fd, 62 | child_fd: 3 + i as i32, 63 | }) 64 | .collect(), 65 | )? 66 | }; 67 | 68 | command.spawn().map_err(|e| anyhow::anyhow!("Failed to start preimage server process: {}", e)) 69 | }); 70 | 71 | Ok(( 72 | Self { 73 | hint_writer_client: HintWriter::new(client_io.0), 74 | preimage_client: OracleClient::new(client_io.1), 75 | }, 76 | child.transpose()?, 77 | )) 78 | } 79 | } 80 | 81 | impl PreimageOracle for ProcessPreimageOracle { 82 | fn hint(&mut self, value: impl Hint) -> Result<()> { 83 | self.hint_writer_client.hint(value) 84 | } 85 | 86 | fn get(&mut self, key: [u8; 32]) -> anyhow::Result> { 87 | let key = RawKey(key); 88 | self.preimage_client.get(key) 89 | } 90 | } 91 | -------------------------------------------------------------------------------- /crates/cannon/src/traces.rs: -------------------------------------------------------------------------------- 1 | #![allow(unused_imports)] 2 | 3 | /// Performs a tracing debug if the `tracing` feature is enabled. 4 | #[macro_export] 5 | macro_rules! debug { 6 | ($($arg:tt)*) => { 7 | #[cfg(feature = "tracing")] 8 | tracing::debug!($($arg)*); 9 | }; 10 | } 11 | pub use debug; 12 | 13 | /// Performs a tracing info if the `tracing` feature is enabled. 14 | #[macro_export] 15 | macro_rules! info { 16 | ($($arg:tt)*) => { 17 | #[cfg(feature = "tracing")] 18 | tracing::info!($($arg)*); 19 | }; 20 | } 21 | pub use info; 22 | 23 | /// Performs a tracing error if the `tracing` feature is enabled. 24 | #[macro_export] 25 | macro_rules! error { 26 | ($($arg:tt)*) => { 27 | #[cfg(feature = "tracing")] 28 | tracing::error!($($arg)*); 29 | }; 30 | } 31 | pub use error; 32 | 33 | /// Performs a tracing warn if the `tracing` feature is enabled. 34 | #[macro_export] 35 | macro_rules! warn { 36 | ($($arg:tt)*) => { 37 | #[cfg(feature = "tracing")] 38 | tracing::warn!($($arg)*); 39 | }; 40 | } 41 | pub use crate::warn; 42 | 43 | #[cfg(test)] 44 | mod tests { 45 | use super::*; 46 | 47 | #[test] 48 | fn test_debug() { 49 | debug!("test"); 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /crates/cannon/src/types.rs: -------------------------------------------------------------------------------- 1 | //! This module contains the types for the `cannon` interface. 2 | 3 | use cannon_mipsevm::StateWitness; 4 | use preimage_oracle::ReadWritePair; 5 | use serde::{Deserialize, Serialize}; 6 | use std::process::Child; 7 | 8 | /// The [Proof] struct contains the data for a Cannon proof at a given instruction. 9 | #[derive(Clone, PartialEq, Eq, Serialize, Deserialize)] 10 | #[serde(rename_all = "camelCase")] 11 | pub struct Proof { 12 | pub step: u64, 13 | pub pre: [u8; 32], 14 | pub post: [u8; 32], 15 | #[serde(with = "cannon_mipsevm::ser::state_witness_hex")] 16 | pub state_data: StateWitness, 17 | pub proof_data: Vec, 18 | pub step_input: Vec, 19 | pub oracle_key: Option>, 20 | pub oracle_value: Option>, 21 | pub oracle_offset: Option, 22 | pub oracle_input: Option>, 23 | } 24 | 25 | /// A [Child] process that was given file descriptors. This struct couples 26 | /// the two together so that when the [Child] is dropped, the file descriptors 27 | /// are as well, preventing a resource leak. 28 | pub struct ChildWithFds { 29 | pub inner: Child, 30 | pub fds: [ReadWritePair; 2], 31 | } 32 | -------------------------------------------------------------------------------- /crates/mipsevm/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "cannon-mipsevm" 3 | description = "An implementation of the MIPSEVM for Cannon" 4 | edition = "2021" 5 | 6 | version.workspace = true 7 | authors.workspace = true 8 | 9 | [dependencies] 10 | # workspace 11 | alloy-primitives.workspace = true 12 | serde.workspace = true 13 | serde_json.workspace = true 14 | anyhow.workspace = true 15 | 16 | # local 17 | preimage-oracle = { path = "../preimage" } 18 | 19 | # types 20 | alloy-sol-types = "0.6.2" 21 | 22 | # misc 23 | once_cell = "1.19.0" 24 | elf = "0.7.4" 25 | revm = { version = "3.5.0", features = ["no_gas_measuring"] } 26 | tracing = { version = "0.1.40", optional = true } 27 | 28 | # hashing 29 | rustc-hash = "1.1.0" 30 | xkcp-rs = { git = "https://github.com/DaniPopes/xkcp-rs", rev = "40447a5" } 31 | keccak256-aarch64-simd = { git = "https://github.com/clabby/keccak256-aarch64", rev = "5c4c8f8", optional = true } 32 | 33 | [dev-dependencies] 34 | rand = "0.8.5" 35 | criterion = { version = "0.5.1", features = ["html_reports"] } 36 | pprof = { version = "0.13.0", features = ["criterion", "flamegraph", "frame-pointer"] } 37 | proptest = "1.4.0" 38 | 39 | [features] 40 | tracing = ["dep:tracing"] 41 | simd-keccak = ["dep:keccak256-aarch64-simd"] 42 | 43 | [[bench]] 44 | name = "memory" 45 | harness = false 46 | 47 | [[bench]] 48 | name = "execution" 49 | harness = false 50 | -------------------------------------------------------------------------------- /crates/mipsevm/benches/execution.rs: -------------------------------------------------------------------------------- 1 | use cannon_mipsevm::{ 2 | load_elf, patch_go, patch_stack, 3 | test_utils::{ClaimTestOracle, StaticOracle}, 4 | InstrumentedState, PreimageOracle, 5 | }; 6 | use criterion::{criterion_group, criterion_main, Bencher, Criterion}; 7 | use pprof::criterion::{Output, PProfProfiler}; 8 | use std::io::BufWriter; 9 | 10 | #[inline(always)] 11 | fn bench_exec( 12 | elf_bytes: &[u8], 13 | oracle: impl PreimageOracle, 14 | compute_witness: bool, 15 | b: &mut Bencher, 16 | ) { 17 | let mut state = load_elf(elf_bytes).unwrap(); 18 | patch_go(elf_bytes, &mut state).unwrap(); 19 | patch_stack(&mut state).unwrap(); 20 | 21 | let out = BufWriter::new(Vec::default()); 22 | let err = BufWriter::new(Vec::default()); 23 | let mut ins = InstrumentedState::new(state, oracle, out, err); 24 | 25 | b.iter(|| loop { 26 | if ins.state.exited { 27 | break; 28 | } 29 | ins.step(compute_witness).unwrap(); 30 | }) 31 | } 32 | 33 | fn execution(c: &mut Criterion) { 34 | let mut g = c.benchmark_group("execution"); 35 | g.sample_size(10); 36 | 37 | g.bench_function("[No Witness] Execution (hello.elf)", |b| { 38 | let elf_bytes = include_bytes!("../../../example/bin/hello.elf"); 39 | bench_exec(elf_bytes, StaticOracle::default(), false, b); 40 | }); 41 | 42 | g.bench_function("[Witness] Execution (hello.elf)", |b| { 43 | let elf_bytes = include_bytes!("../../../example/bin/hello.elf"); 44 | bench_exec(elf_bytes, StaticOracle::default(), true, b); 45 | }); 46 | 47 | g.bench_function("[No Witness] Execution (claim.elf)", |b| { 48 | let elf_bytes = include_bytes!("../../../example/bin/claim.elf"); 49 | bench_exec(elf_bytes, ClaimTestOracle::default(), false, b); 50 | }); 51 | 52 | g.bench_function("[Witness] Execution (claim.elf)", |b| { 53 | let elf_bytes = include_bytes!("../../../example/bin/claim.elf"); 54 | bench_exec(elf_bytes, ClaimTestOracle::default(), true, b); 55 | }); 56 | } 57 | 58 | criterion_group! { 59 | name = benches; 60 | config = Criterion::default().with_profiler(PProfProfiler::new(100, Output::Flamegraph(None))); 61 | targets = execution 62 | } 63 | criterion_main!(benches); 64 | -------------------------------------------------------------------------------- /crates/mipsevm/benches/memory.rs: -------------------------------------------------------------------------------- 1 | use cannon_mipsevm::Memory; 2 | use criterion::{criterion_group, criterion_main, Criterion}; 3 | use pprof::criterion::{Output, PProfProfiler}; 4 | use rand::RngCore; 5 | 6 | fn merkle_root(c: &mut Criterion) { 7 | let mut g = c.benchmark_group("memory"); 8 | g.sample_size(10); 9 | 10 | g.bench_function("Merkle Root (memory size = 25 MB)", |b| { 11 | let mut memory = Memory::default(); 12 | let mut data = vec![0u8; 25_000_000]; 13 | rand::thread_rng().fill_bytes(&mut data[..]); 14 | memory 15 | .set_memory_range(0, &data[..]) 16 | .expect("Should not error"); 17 | b.iter(|| { 18 | memory.merkle_root().unwrap(); 19 | }); 20 | }); 21 | 22 | g.bench_function("Merkle Root (memory size = 50 MB)", |b| { 23 | let mut memory = Memory::default(); 24 | let mut data = vec![0u8; 50_000_000]; 25 | rand::thread_rng().fill_bytes(&mut data[..]); 26 | memory 27 | .set_memory_range(0, &data[..]) 28 | .expect("Should not error"); 29 | b.iter(|| { 30 | memory.merkle_root().unwrap(); 31 | }); 32 | }); 33 | 34 | g.bench_function("Merkle Root (memory size = 100 MB)", |b| { 35 | let mut memory = Memory::default(); 36 | let mut data = vec![0u8; 100_000_000]; 37 | rand::thread_rng().fill_bytes(&mut data[..]); 38 | memory 39 | .set_memory_range(0, &data[..]) 40 | .expect("Should not error"); 41 | b.iter(|| { 42 | memory.merkle_root().unwrap(); 43 | }); 44 | }); 45 | 46 | g.bench_function("Merkle Root (memory size = 200 MB)", |b| { 47 | let mut memory = Memory::default(); 48 | let mut data = vec![0u8; 200_000_000]; 49 | rand::thread_rng().fill_bytes(&mut data[..]); 50 | memory 51 | .set_memory_range(0, &data[..]) 52 | .expect("Should not error"); 53 | b.iter(|| { 54 | memory.merkle_root().unwrap(); 55 | }); 56 | }); 57 | } 58 | 59 | criterion_group! { 60 | name = benches; 61 | config = Criterion::default().with_profiler(PProfProfiler::new(100, Output::Flamegraph(None))); 62 | targets = merkle_root 63 | } 64 | criterion_main!(benches); 65 | -------------------------------------------------------------------------------- /crates/mipsevm/bindings/README.md: -------------------------------------------------------------------------------- 1 | # `cannon-contract-bindings` 2 | 3 | This folder contains the compiled bytecode of the Cannon contracts for deployment on the MIPSEVM. 4 | 5 | ## Regenerating Bindings 6 | 7 | Dependencies: 8 | * [`forge`][foundry] 9 | * [`jq`][jq] 10 | 11 | ```sh 12 | ./bindings.sh 13 | ``` 14 | 15 | [foundry]: https://github.com/foundry-rs/foundry 16 | [jq]: https://github.com/jqlang/jq 17 | -------------------------------------------------------------------------------- /crates/mipsevm/bindings/bindings.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # This script is used to generate the bindings for the MIPS contracts in the 4 | # Optimism monorepo. 5 | 6 | # The current directory relative to the script. 7 | DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )" 8 | 9 | # Check if a folder with relative path `../optimism` exists and is not empty. 10 | # If it doesn't exist, install the submodules. 11 | if [ ! -d "$DIR/optimism" ] || [ -z "$(ls -A $DIR/optimism)" ]; then 12 | echo "Error: Optimism monorepo not present. Initializing submodules..." 13 | git submodule update --init --recursive 14 | fi 15 | 16 | # Check if `forge` is installed 17 | if ! command -v forge &> /dev/null 18 | then 19 | echo "Error: forge not found. Please install forge and try again." 20 | exit 21 | fi 22 | 23 | CTB="$DIR/optimism/packages/contracts-bedrock" 24 | 25 | cd $CTB && \ 26 | forge install && \ 27 | forge build 28 | 29 | MIPS_ARTIFACT="$CTB/forge-artifacts/MIPS.sol/MIPS.json" 30 | PREIMAGE_ARTIFACT="$CTB/forge-artifacts/PreimageOracle.sol/PreimageOracle.json" 31 | 32 | MIPS_BIN=$(cat $MIPS_ARTIFACT | jq -r '.bytecode.object') 33 | PREIMAGE_DEPLOYED_BIN=$(cat $PREIMAGE_ARTIFACT | jq -r '.deployedBytecode.object') 34 | 35 | echo "Removing old bindings..." 36 | rm $DIR/*.bin 37 | echo "Old bindings removed." 38 | 39 | echo -n "${MIPS_BIN:2}" > $DIR/mips_creation.bin 40 | echo -n "${PREIMAGE_DEPLOYED_BIN:2}" >> $DIR/preimage_oracle_deployed.bin 41 | 42 | echo "Bindings generated successfully." 43 | -------------------------------------------------------------------------------- /crates/mipsevm/bindings/preimage_oracle_deployed.bin: -------------------------------------------------------------------------------- 1 | 608060405234801561001057600080fd5b506004361061007d5760003560e01c8063e03110e11161005b578063e03110e114610111578063e159261114610139578063fe4ac08e1461014e578063fef2b4ed146101c357600080fd5b806361238bde146100825780638542cf50146100c05780639a1f5e7f146100fe575b600080fd5b6100ad610090366004610551565b600160209081526000928352604080842090915290825290205481565b6040519081526020015b60405180910390f35b6100ee6100ce366004610551565b600260209081526000928352604080842090915290825290205460ff1681565b60405190151581526020016100b7565b6100ad61010c366004610573565b6101e3565b61012461011f366004610551565b6102b6565b604080519283526020830191909152016100b7565b61014c6101473660046105a5565b6103a7565b005b61014c61015c366004610573565b6000838152600260209081526040808320878452825280832080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660019081179091558684528252808320968352958152858220939093559283529082905291902055565b6100ad6101d1366004610621565b60006020819052908152604090205481565b60006101ee856104b0565b90506101fb836008610669565b8211806102085750602083115b1561023f576040517ffe25498700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000602081815260c085901b82526008959095528251828252600286526040808320858452875280832080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016600190811790915584845287528083209483529386528382205581815293849052922055919050565b6000828152600260209081526040808320848452909152812054819060ff1661033f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601460248201527f7072652d696d616765206d757374206578697374000000000000000000000000604482015260640160405180910390fd5b506000838152602081815260409091205461035b816008610669565b610366856020610669565b106103845783610377826008610669565b6103819190610681565b91505b506000938452600160209081526040808620948652939052919092205492909150565b604435600080600883018611156103c65763fe2549876000526004601cfd5b60c083901b6080526088838682378087017ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff80151908490207effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f02000000000000000000000000000000000000000000000000000000000000001760008181526002602090815260408083208b8452825280832080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016600190811790915584845282528083209a83529981528982209390935590815290819052959095209190915550505050565b7f01000000000000000000000000000000000000000000000000000000000000007effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82161761054b81600090815233602052604090207effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f01000000000000000000000000000000000000000000000000000000000000001790565b92915050565b6000806040838503121561056457600080fd5b50508035926020909101359150565b6000806000806080858703121561058957600080fd5b5050823594602084013594506040840135936060013592509050565b6000806000604084860312156105ba57600080fd5b83359250602084013567ffffffffffffffff808211156105d957600080fd5b818601915086601f8301126105ed57600080fd5b8135818111156105fc57600080fd5b87602082850101111561060e57600080fd5b6020830194508093505050509250925092565b60006020828403121561063357600080fd5b5035919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000821982111561067c5761067c61063a565b500190565b6000828210156106935761069361063a565b50039056fea164736f6c634300080f000a -------------------------------------------------------------------------------- /crates/mipsevm/open_mips_tests/README.md: -------------------------------------------------------------------------------- 1 | # OpenMIPS test vectors 2 | 3 | Tests from https://github.com/grantae/OpenMIPS/tree/d606b35e9d5260aef20de2a58660c8303a681e9c/software/test/macro/tests 4 | 5 | OpenMIPS is licensed LGPLv3 (as seen in the root of the repository), see [`LICENSE`](./LICENSE) file. 6 | Note that some build-system files from 2014/2015 in that repository by the same author are marked as BSD licensed, 7 | but the build-system is not used here. 8 | 9 | Requires https://github.com/sergev/LiteBSD/releases/download/tools/gcc-4.8.1-mips-macosx.tgz to build 10 | 11 | -------------------------------------------------------------------------------- /crates/mipsevm/open_mips_tests/maketests.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | import os 3 | import sys 4 | import tempfile 5 | from capstone import * 6 | from elftools.elf.elffile import ELFFile 7 | md = Cs(CS_ARCH_MIPS, CS_MODE_32 + CS_MODE_BIG_ENDIAN) 8 | 9 | def maketest(d, out): 10 | with tempfile.NamedTemporaryFile() as nf: 11 | print("building", d, "->", out) 12 | # which mips is go 13 | ret = os.system("mips-linux-gnu-as -defsym big_endian=1 -march=mips32r2 -o %s %s" % (nf.name, d)) 14 | assert(ret == 0) 15 | nf.seek(0) 16 | elffile = ELFFile(nf) 17 | #print(elffile) 18 | for sec in elffile.iter_sections(): 19 | #print(sec, sec.name, sec.data()) 20 | if sec.name == ".test": 21 | with open(out, "wb") as f: 22 | # jump to 0xdead0000 when done 23 | #data = b"\x24\x1f\xde\xad\x00\x1f\xfc\x00" + sec.data() 24 | data = sec.data() 25 | for dd in md.disasm(data, 0): 26 | print(dd) 27 | f.write(data) 28 | 29 | if __name__ == "__main__": 30 | os.makedirs("/tmp/mips", exist_ok=True) 31 | if len(sys.argv) > 2: 32 | maketest(sys.argv[1], sys.argv[2]) 33 | else: 34 | for d in os.listdir("test/"): 35 | if not d.endswith(".asm"): 36 | continue 37 | maketest("test/"+d, "test/bin/"+(d.replace(".asm", ".bin"))) 38 | -------------------------------------------------------------------------------- /crates/mipsevm/open_mips_tests/test/add.asm: -------------------------------------------------------------------------------- 1 | ############################################################################### 2 | # File : add.asm 3 | # Project : MIPS32 MUX 4 | # Author: : Grant Ayers (ayers@cs.stanford.edu) 5 | # 6 | # Standards/Formatting: 7 | # MIPS gas, soft tab, 80 column 8 | # 9 | # Description: 10 | # Test the functionality of the 'add' instruction. 11 | # 12 | ############################################################################### 13 | 14 | 15 | .section .test, "x" 16 | .balign 4 17 | .set noreorder 18 | .global test 19 | .ent test 20 | test: 21 | lui $s0, 0xbfff # Load the base address 0xbffffff0 22 | ori $s0, 0xfff0 23 | ori $s1, $0, 1 # Prepare the 'done' status 24 | 25 | #### Test code start #### 26 | 27 | lui $t0, 0xffff # A = 0xfffffffd (-3) 28 | ori $t0, 0xfffd 29 | ori $t1, $0, 0x3 # B = 0x3 30 | add $t2, $t0, $t1 # C = A + B = 0 31 | sltiu $v0, $t2, 1 # D = 1 if C == 0 32 | 33 | #### Test code end #### 34 | 35 | sw $v0, 8($s0) # Set the test result 36 | sw $s1, 4($s0) # Set 'done' 37 | 38 | $done: 39 | jr $ra 40 | nop 41 | 42 | .end test 43 | -------------------------------------------------------------------------------- /crates/mipsevm/open_mips_tests/test/addi.asm: -------------------------------------------------------------------------------- 1 | ############################################################################### 2 | # File : addi.asm 3 | # Project : MIPS32 MUX 4 | # Author : Grant Ayers (ayers@cs.stanford.edu) 5 | # 6 | # Standards/Formatting: 7 | # MIPS gas, soft tab, 80 column 8 | # 9 | # Description: 10 | # Test the functionality of the 'addi' instruction. 11 | # 12 | ############################################################################### 13 | 14 | 15 | .section .test, "x" 16 | .balign 4 17 | .set noreorder 18 | .global test 19 | .ent test 20 | test: 21 | lui $s0, 0xbfff # Load the base address 0xbffffff0 22 | ori $s0, 0xfff0 23 | ori $s1, $0, 1 # Prepare the 'done' status 24 | 25 | #### Test code start #### 26 | 27 | lui $t0, 0xffff # A = 0xfffffffd (-3) 28 | ori $t0, 0xfffd 29 | addi $t1, $t0, 5 # B = A + 5 = 2 30 | addi $t2, $t1, 0xfffe # C = B + -2 = 0 31 | sltiu $v0, $t2, 1 # D = 1 if C == 0 32 | 33 | #### Test code end #### 34 | 35 | sw $v0, 8($s0) # Set the test result 36 | sw $s1, 4($s0) # Set 'done' 37 | 38 | $done: 39 | jr $ra 40 | nop 41 | 42 | .end test 43 | -------------------------------------------------------------------------------- /crates/mipsevm/open_mips_tests/test/addiu.asm: -------------------------------------------------------------------------------- 1 | ############################################################################### 2 | # File : addiu.asm 3 | # Project : MIPS32 MUX 4 | # Author : Grant Ayers (ayers@cs.stanford.edu) 5 | # 6 | # Standards/Formatting: 7 | # MIPS gas, soft tab, 80 column 8 | # 9 | # Description: 10 | # Test the functionality of the 'addiu' instruction. 11 | # 12 | ############################################################################### 13 | 14 | 15 | .section .test, "x" 16 | .balign 4 17 | .set noreorder 18 | .global test 19 | .ent test 20 | test: 21 | lui $s0, 0xbfff # Load the base address 0xbffffff0 22 | ori $s0, 0xfff0 23 | ori $s1, $0, 1 # Prepare the 'done' status 24 | 25 | #### Test code start #### 26 | 27 | lui $t0, 0xffff # A = 0xfffffffd (-3) 28 | ori $t0, 0xfffd 29 | addiu $t1, $t0, 5 # B = A + 5 = 2 30 | addiu $t2, $t1, 0xfffe # C = B + -2 = 0 31 | sltiu $v0, $t2, 1 # D = 1 if C == 0 32 | 33 | #### Test code end #### 34 | 35 | sw $v0, 8($s0) # Set the test result 36 | sw $s1, 4($s0) # Set 'done' 37 | 38 | $done: 39 | jr $ra 40 | nop 41 | 42 | .end test 43 | -------------------------------------------------------------------------------- /crates/mipsevm/open_mips_tests/test/addu.asm: -------------------------------------------------------------------------------- 1 | ############################################################################### 2 | # File : addu.asm 3 | # Project : MIPS32 MUX 4 | # Author : Grant Ayers (ayers@cs.stanford.edu) 5 | # 6 | # Standards/Formatting: 7 | # MIPS gas, soft tab, 80 column 8 | # 9 | # Description: 10 | # Test the functionality of the 'addu' instruction. 11 | # 12 | ############################################################################### 13 | 14 | 15 | .section .test, "x" 16 | .balign 4 17 | .set noreorder 18 | .global test 19 | .ent test 20 | test: 21 | lui $s0, 0xbfff # Load the base address 0xbffffff0 22 | ori $s0, 0xfff0 23 | ori $s1, $0, 1 # Prepare the 'done' status 24 | 25 | #### Test code start #### 26 | 27 | lui $t0, 0xffff # A = 0xfffffffd (-3) 28 | ori $t0, 0xfffd 29 | ori $t1, $0, 0x3 # B = 0x3 30 | addu $t2, $t0, $t1 # C = A + B = 0 31 | sltiu $v0, $t2, 1 # D = 1 if C == 0 32 | 33 | #### Test code end #### 34 | 35 | sw $v0, 8($s0) # Set the test result 36 | sw $s1, 4($s0) # Set 'done' 37 | 38 | $done: 39 | jr $ra 40 | nop 41 | 42 | .end test 43 | -------------------------------------------------------------------------------- /crates/mipsevm/open_mips_tests/test/and.asm: -------------------------------------------------------------------------------- 1 | ############################################################################### 2 | # File : and.asm 3 | # Project : MIPS32 MUX 4 | # Author: : Grant Ayers (ayers@cs.stanford.edu) 5 | # 6 | # Standards/Formatting: 7 | # MIPS gas, soft tab, 80 column 8 | # 9 | # Description: 10 | # Test the functionality of the 'and' instruction. 11 | # 12 | ############################################################################### 13 | 14 | 15 | .section .test, "x" 16 | .balign 4 17 | .set noreorder 18 | .global test 19 | .ent test 20 | test: 21 | lui $s0, 0xbfff # Load the base address 0xbffffff0 22 | ori $s0, 0xfff0 23 | ori $s1, $0, 1 # Prepare the 'done' status 24 | 25 | #### Test code start #### 26 | 27 | lui $t0, 0xdeaf # A = 0xdeafbeef 28 | lui $t1, 0xaaaa # B = 0xaaaaaaaa 29 | lui $t2, 0x5555 # C = 0x55555555 30 | ori $t0, 0xbeef 31 | ori $t1, 0xaaaa 32 | ori $t2, 0x5555 33 | and $t3, $t0, $t1 # D = A & B = 0x8aaaaaaa 34 | and $t4, $t2, $t3 # E = B & D = 0 35 | sltiu $v0, $t4, 1 36 | 37 | #### Test code end #### 38 | 39 | sw $v0, 8($s0) # Set the test result 40 | sw $s1, 4($s0) # Set 'done' 41 | 42 | $done: 43 | jr $ra 44 | nop 45 | 46 | .end test 47 | -------------------------------------------------------------------------------- /crates/mipsevm/open_mips_tests/test/andi.asm: -------------------------------------------------------------------------------- 1 | ############################################################################### 2 | # File : andi.asm 3 | # Project : MIPS32 MUX 4 | # Author: : Grant Ayers (ayers@cs.stanford.edu) 5 | # 6 | # Standards/Formatting: 7 | # MIPS gas, soft tab, 80 column 8 | # 9 | # Description: 10 | # Test the functionality of the 'andi' instruction. 11 | # 12 | ############################################################################### 13 | 14 | 15 | .section .test, "x" 16 | .balign 4 17 | .set noreorder 18 | .global test 19 | .ent test 20 | test: 21 | lui $s0, 0xbfff # Load the base address 0xbffffff0 22 | ori $s0, 0xfff0 23 | ori $s1, $0, 1 # Prepare the 'done' status 24 | 25 | #### Test code start #### 26 | 27 | ori $t0, $0, 0xcafe # A = 0xcafe 28 | andi $t1, $t0, 0xaaaa # B = A & 0xaaaa = 0x8aaa 29 | andi $t2, $t1, 0x5555 # C = B & 0x5555 = 0 30 | sltiu $v0, $t2, 1 31 | 32 | #### Test code end #### 33 | 34 | sw $v0, 8($s0) # Set the test result 35 | sw $s1, 4($s0) # Set 'done' 36 | 37 | $done: 38 | jr $ra 39 | nop 40 | 41 | .end test 42 | -------------------------------------------------------------------------------- /crates/mipsevm/open_mips_tests/test/beq.asm: -------------------------------------------------------------------------------- 1 | ############################################################################### 2 | # File : beq.asm 3 | # Project : MIPS32 MUX 4 | # Author: : Grant Ayers (ayers@cs.stanford.edu) 5 | # 6 | # Standards/Formatting: 7 | # MIPS gas, soft tab, 80 column 8 | # 9 | # Description: 10 | # Test the functionality of the 'beq' instruction. 11 | # 12 | ############################################################################### 13 | 14 | 15 | .section .test, "x" 16 | .balign 4 17 | .set noreorder 18 | .global test 19 | .ent test 20 | test: 21 | lui $s0, 0xbfff # Load the base address 0xbffffff0 22 | ori $s0, 0xfff0 23 | ori $s1, $0, 1 # Prepare the 'done' status 24 | 25 | #### Test code start #### 26 | 27 | ori $t0, $0, 0xcafe 28 | ori $t1, $0, 0xcafe 29 | ori $v0, $0, 0 # The test result starts as a failure 30 | beq $t0, $v0, $finish # No branch 31 | nop 32 | beq $t0, $t1, $target 33 | nop 34 | 35 | $finish: 36 | sw $v0, 8($s0) 37 | sw $s1, 4($s0) 38 | 39 | $done: 40 | jr $ra 41 | nop 42 | j $finish # Early-by-1 branch detection 43 | 44 | $target: 45 | nop 46 | ori $v0, $0, 1 # Set the result to pass 47 | beq $0, $0, $finish # Late-by-1 branch detection (result not stored) 48 | nop 49 | j $finish 50 | nop 51 | 52 | #### Test code end #### 53 | 54 | .end test 55 | -------------------------------------------------------------------------------- /crates/mipsevm/open_mips_tests/test/bgez.asm: -------------------------------------------------------------------------------- 1 | ############################################################################### 2 | # File : bgez.asm 3 | # Project : MIPS32 MUX 4 | # Author: : Grant Ayers (ayers@cs.stanford.edu) 5 | # 6 | # Standards/Formatting: 7 | # MIPS gas, soft tab, 80 column 8 | # 9 | # Description: 10 | # Test the functionality of the 'bgez' instruction. 11 | # 12 | ############################################################################### 13 | 14 | 15 | .section .test, "x" 16 | .balign 4 17 | .set noreorder 18 | .global test 19 | .ent test 20 | test: 21 | lui $s0, 0xbfff # Load the base address 0xbffffff0 22 | ori $s0, 0xfff0 23 | ori $s1, $0, 1 # Prepare the 'done' status 24 | 25 | #### Test code start #### 26 | 27 | lui $t0, 0xffff 28 | bgez $t0, $finish # No branch 29 | nop 30 | bgez $s1, $target 31 | nop 32 | 33 | $finish: 34 | sw $v0, 8($s0) 35 | sw $s1, 4($s0) 36 | 37 | $done: 38 | jr $ra 39 | nop 40 | j $finish # Early-by-1 branch detection 41 | 42 | $target: 43 | nop 44 | ori $v0, $0, 1 # Set the result to pass 45 | bgez $0, $finish # Late-by-1 branch detection (result not stored) 46 | nop 47 | j $finish # Broken branch recovery 48 | nop 49 | 50 | #### Test code end #### 51 | 52 | .end test 53 | -------------------------------------------------------------------------------- /crates/mipsevm/open_mips_tests/test/bgtz.asm: -------------------------------------------------------------------------------- 1 | ############################################################################### 2 | # File : bgtz.asm 3 | # Project : MIPS32 MUX 4 | # Author: : Grant Ayers (ayers@cs.stanford.edu) 5 | # 6 | # Standards/Formatting: 7 | # MIPS gas, soft tab, 80 column 8 | # 9 | # Description: 10 | # Test the functionality of the 'bgtz' instruction. 11 | # 12 | ############################################################################### 13 | 14 | 15 | .section .test, "x" 16 | .balign 4 17 | .set noreorder 18 | .global test 19 | .ent test 20 | test: 21 | lui $s0, 0xbfff # Load the base address 0xbffffff0 22 | ori $s0, 0xfff0 23 | ori $s1, $0, 1 # Prepare the 'done' status 24 | 25 | #### Test code start #### 26 | 27 | ori $v0, $0, 0 # The test result starts as a failure 28 | lui $t0, 0xffff 29 | bgtz $t0, $finish # No branch 30 | nop 31 | bgtz $s1, $target 32 | nop 33 | 34 | $finish: 35 | sw $v0, 8($s0) 36 | sw $s1, 4($s0) 37 | 38 | $done: 39 | jr $ra 40 | nop 41 | j $finish # Early-by-1 branch detection 42 | 43 | $target: 44 | nop 45 | ori $v0, $0, 1 # Set the result to pass 46 | bgtz $s1, $finish # Late-by-1 branch detection (result not stored) 47 | nop 48 | j $finish # Broken branch recovery 49 | nop 50 | 51 | #### Test code end #### 52 | 53 | .end test 54 | -------------------------------------------------------------------------------- /crates/mipsevm/open_mips_tests/test/bin/add.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/op-rs/cannon-rs/5ab846ae9d4cc0d2cf26c4a7af88f86f5339644b/crates/mipsevm/open_mips_tests/test/bin/add.bin -------------------------------------------------------------------------------- /crates/mipsevm/open_mips_tests/test/bin/addi.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/op-rs/cannon-rs/5ab846ae9d4cc0d2cf26c4a7af88f86f5339644b/crates/mipsevm/open_mips_tests/test/bin/addi.bin -------------------------------------------------------------------------------- /crates/mipsevm/open_mips_tests/test/bin/addiu.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/op-rs/cannon-rs/5ab846ae9d4cc0d2cf26c4a7af88f86f5339644b/crates/mipsevm/open_mips_tests/test/bin/addiu.bin -------------------------------------------------------------------------------- /crates/mipsevm/open_mips_tests/test/bin/addu.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/op-rs/cannon-rs/5ab846ae9d4cc0d2cf26c4a7af88f86f5339644b/crates/mipsevm/open_mips_tests/test/bin/addu.bin -------------------------------------------------------------------------------- /crates/mipsevm/open_mips_tests/test/bin/and.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/op-rs/cannon-rs/5ab846ae9d4cc0d2cf26c4a7af88f86f5339644b/crates/mipsevm/open_mips_tests/test/bin/and.bin -------------------------------------------------------------------------------- /crates/mipsevm/open_mips_tests/test/bin/andi.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/op-rs/cannon-rs/5ab846ae9d4cc0d2cf26c4a7af88f86f5339644b/crates/mipsevm/open_mips_tests/test/bin/andi.bin -------------------------------------------------------------------------------- /crates/mipsevm/open_mips_tests/test/bin/beq.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/op-rs/cannon-rs/5ab846ae9d4cc0d2cf26c4a7af88f86f5339644b/crates/mipsevm/open_mips_tests/test/bin/beq.bin -------------------------------------------------------------------------------- /crates/mipsevm/open_mips_tests/test/bin/bgez.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/op-rs/cannon-rs/5ab846ae9d4cc0d2cf26c4a7af88f86f5339644b/crates/mipsevm/open_mips_tests/test/bin/bgez.bin -------------------------------------------------------------------------------- /crates/mipsevm/open_mips_tests/test/bin/bgtz.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/op-rs/cannon-rs/5ab846ae9d4cc0d2cf26c4a7af88f86f5339644b/crates/mipsevm/open_mips_tests/test/bin/bgtz.bin -------------------------------------------------------------------------------- /crates/mipsevm/open_mips_tests/test/bin/blez.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/op-rs/cannon-rs/5ab846ae9d4cc0d2cf26c4a7af88f86f5339644b/crates/mipsevm/open_mips_tests/test/bin/blez.bin -------------------------------------------------------------------------------- /crates/mipsevm/open_mips_tests/test/bin/bltz.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/op-rs/cannon-rs/5ab846ae9d4cc0d2cf26c4a7af88f86f5339644b/crates/mipsevm/open_mips_tests/test/bin/bltz.bin -------------------------------------------------------------------------------- /crates/mipsevm/open_mips_tests/test/bin/bne.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/op-rs/cannon-rs/5ab846ae9d4cc0d2cf26c4a7af88f86f5339644b/crates/mipsevm/open_mips_tests/test/bin/bne.bin -------------------------------------------------------------------------------- /crates/mipsevm/open_mips_tests/test/bin/brk.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/op-rs/cannon-rs/5ab846ae9d4cc0d2cf26c4a7af88f86f5339644b/crates/mipsevm/open_mips_tests/test/bin/brk.bin -------------------------------------------------------------------------------- /crates/mipsevm/open_mips_tests/test/bin/clo.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/op-rs/cannon-rs/5ab846ae9d4cc0d2cf26c4a7af88f86f5339644b/crates/mipsevm/open_mips_tests/test/bin/clo.bin -------------------------------------------------------------------------------- /crates/mipsevm/open_mips_tests/test/bin/clone.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/op-rs/cannon-rs/5ab846ae9d4cc0d2cf26c4a7af88f86f5339644b/crates/mipsevm/open_mips_tests/test/bin/clone.bin -------------------------------------------------------------------------------- /crates/mipsevm/open_mips_tests/test/bin/clz.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/op-rs/cannon-rs/5ab846ae9d4cc0d2cf26c4a7af88f86f5339644b/crates/mipsevm/open_mips_tests/test/bin/clz.bin -------------------------------------------------------------------------------- /crates/mipsevm/open_mips_tests/test/bin/div.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/op-rs/cannon-rs/5ab846ae9d4cc0d2cf26c4a7af88f86f5339644b/crates/mipsevm/open_mips_tests/test/bin/div.bin -------------------------------------------------------------------------------- /crates/mipsevm/open_mips_tests/test/bin/divu.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/op-rs/cannon-rs/5ab846ae9d4cc0d2cf26c4a7af88f86f5339644b/crates/mipsevm/open_mips_tests/test/bin/divu.bin -------------------------------------------------------------------------------- /crates/mipsevm/open_mips_tests/test/bin/exit_group.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/op-rs/cannon-rs/5ab846ae9d4cc0d2cf26c4a7af88f86f5339644b/crates/mipsevm/open_mips_tests/test/bin/exit_group.bin -------------------------------------------------------------------------------- /crates/mipsevm/open_mips_tests/test/bin/fcntl.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/op-rs/cannon-rs/5ab846ae9d4cc0d2cf26c4a7af88f86f5339644b/crates/mipsevm/open_mips_tests/test/bin/fcntl.bin -------------------------------------------------------------------------------- /crates/mipsevm/open_mips_tests/test/bin/j.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/op-rs/cannon-rs/5ab846ae9d4cc0d2cf26c4a7af88f86f5339644b/crates/mipsevm/open_mips_tests/test/bin/j.bin -------------------------------------------------------------------------------- /crates/mipsevm/open_mips_tests/test/bin/jal.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/op-rs/cannon-rs/5ab846ae9d4cc0d2cf26c4a7af88f86f5339644b/crates/mipsevm/open_mips_tests/test/bin/jal.bin -------------------------------------------------------------------------------- /crates/mipsevm/open_mips_tests/test/bin/jalr.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/op-rs/cannon-rs/5ab846ae9d4cc0d2cf26c4a7af88f86f5339644b/crates/mipsevm/open_mips_tests/test/bin/jalr.bin -------------------------------------------------------------------------------- /crates/mipsevm/open_mips_tests/test/bin/jr.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/op-rs/cannon-rs/5ab846ae9d4cc0d2cf26c4a7af88f86f5339644b/crates/mipsevm/open_mips_tests/test/bin/jr.bin -------------------------------------------------------------------------------- /crates/mipsevm/open_mips_tests/test/bin/lb.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/op-rs/cannon-rs/5ab846ae9d4cc0d2cf26c4a7af88f86f5339644b/crates/mipsevm/open_mips_tests/test/bin/lb.bin -------------------------------------------------------------------------------- /crates/mipsevm/open_mips_tests/test/bin/lbu.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/op-rs/cannon-rs/5ab846ae9d4cc0d2cf26c4a7af88f86f5339644b/crates/mipsevm/open_mips_tests/test/bin/lbu.bin -------------------------------------------------------------------------------- /crates/mipsevm/open_mips_tests/test/bin/lh.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/op-rs/cannon-rs/5ab846ae9d4cc0d2cf26c4a7af88f86f5339644b/crates/mipsevm/open_mips_tests/test/bin/lh.bin -------------------------------------------------------------------------------- /crates/mipsevm/open_mips_tests/test/bin/lhu.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/op-rs/cannon-rs/5ab846ae9d4cc0d2cf26c4a7af88f86f5339644b/crates/mipsevm/open_mips_tests/test/bin/lhu.bin -------------------------------------------------------------------------------- /crates/mipsevm/open_mips_tests/test/bin/lui.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/op-rs/cannon-rs/5ab846ae9d4cc0d2cf26c4a7af88f86f5339644b/crates/mipsevm/open_mips_tests/test/bin/lui.bin -------------------------------------------------------------------------------- /crates/mipsevm/open_mips_tests/test/bin/lw.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/op-rs/cannon-rs/5ab846ae9d4cc0d2cf26c4a7af88f86f5339644b/crates/mipsevm/open_mips_tests/test/bin/lw.bin -------------------------------------------------------------------------------- /crates/mipsevm/open_mips_tests/test/bin/lwl.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/op-rs/cannon-rs/5ab846ae9d4cc0d2cf26c4a7af88f86f5339644b/crates/mipsevm/open_mips_tests/test/bin/lwl.bin -------------------------------------------------------------------------------- /crates/mipsevm/open_mips_tests/test/bin/lwr.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/op-rs/cannon-rs/5ab846ae9d4cc0d2cf26c4a7af88f86f5339644b/crates/mipsevm/open_mips_tests/test/bin/lwr.bin -------------------------------------------------------------------------------- /crates/mipsevm/open_mips_tests/test/bin/mfthi.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/op-rs/cannon-rs/5ab846ae9d4cc0d2cf26c4a7af88f86f5339644b/crates/mipsevm/open_mips_tests/test/bin/mfthi.bin -------------------------------------------------------------------------------- /crates/mipsevm/open_mips_tests/test/bin/mftlo.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/op-rs/cannon-rs/5ab846ae9d4cc0d2cf26c4a7af88f86f5339644b/crates/mipsevm/open_mips_tests/test/bin/mftlo.bin -------------------------------------------------------------------------------- /crates/mipsevm/open_mips_tests/test/bin/mmap.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/op-rs/cannon-rs/5ab846ae9d4cc0d2cf26c4a7af88f86f5339644b/crates/mipsevm/open_mips_tests/test/bin/mmap.bin -------------------------------------------------------------------------------- /crates/mipsevm/open_mips_tests/test/bin/movn.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/op-rs/cannon-rs/5ab846ae9d4cc0d2cf26c4a7af88f86f5339644b/crates/mipsevm/open_mips_tests/test/bin/movn.bin -------------------------------------------------------------------------------- /crates/mipsevm/open_mips_tests/test/bin/movz.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/op-rs/cannon-rs/5ab846ae9d4cc0d2cf26c4a7af88f86f5339644b/crates/mipsevm/open_mips_tests/test/bin/movz.bin -------------------------------------------------------------------------------- /crates/mipsevm/open_mips_tests/test/bin/mul.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/op-rs/cannon-rs/5ab846ae9d4cc0d2cf26c4a7af88f86f5339644b/crates/mipsevm/open_mips_tests/test/bin/mul.bin -------------------------------------------------------------------------------- /crates/mipsevm/open_mips_tests/test/bin/mult.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/op-rs/cannon-rs/5ab846ae9d4cc0d2cf26c4a7af88f86f5339644b/crates/mipsevm/open_mips_tests/test/bin/mult.bin -------------------------------------------------------------------------------- /crates/mipsevm/open_mips_tests/test/bin/multu.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/op-rs/cannon-rs/5ab846ae9d4cc0d2cf26c4a7af88f86f5339644b/crates/mipsevm/open_mips_tests/test/bin/multu.bin -------------------------------------------------------------------------------- /crates/mipsevm/open_mips_tests/test/bin/nor.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/op-rs/cannon-rs/5ab846ae9d4cc0d2cf26c4a7af88f86f5339644b/crates/mipsevm/open_mips_tests/test/bin/nor.bin -------------------------------------------------------------------------------- /crates/mipsevm/open_mips_tests/test/bin/oracle.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/op-rs/cannon-rs/5ab846ae9d4cc0d2cf26c4a7af88f86f5339644b/crates/mipsevm/open_mips_tests/test/bin/oracle.bin -------------------------------------------------------------------------------- /crates/mipsevm/open_mips_tests/test/bin/oracle_unaligned_read.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/op-rs/cannon-rs/5ab846ae9d4cc0d2cf26c4a7af88f86f5339644b/crates/mipsevm/open_mips_tests/test/bin/oracle_unaligned_read.bin -------------------------------------------------------------------------------- /crates/mipsevm/open_mips_tests/test/bin/oracle_unaligned_write.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/op-rs/cannon-rs/5ab846ae9d4cc0d2cf26c4a7af88f86f5339644b/crates/mipsevm/open_mips_tests/test/bin/oracle_unaligned_write.bin -------------------------------------------------------------------------------- /crates/mipsevm/open_mips_tests/test/bin/ori.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/op-rs/cannon-rs/5ab846ae9d4cc0d2cf26c4a7af88f86f5339644b/crates/mipsevm/open_mips_tests/test/bin/ori.bin -------------------------------------------------------------------------------- /crates/mipsevm/open_mips_tests/test/bin/sb.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/op-rs/cannon-rs/5ab846ae9d4cc0d2cf26c4a7af88f86f5339644b/crates/mipsevm/open_mips_tests/test/bin/sb.bin -------------------------------------------------------------------------------- /crates/mipsevm/open_mips_tests/test/bin/sh.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/op-rs/cannon-rs/5ab846ae9d4cc0d2cf26c4a7af88f86f5339644b/crates/mipsevm/open_mips_tests/test/bin/sh.bin -------------------------------------------------------------------------------- /crates/mipsevm/open_mips_tests/test/bin/sll.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/op-rs/cannon-rs/5ab846ae9d4cc0d2cf26c4a7af88f86f5339644b/crates/mipsevm/open_mips_tests/test/bin/sll.bin -------------------------------------------------------------------------------- /crates/mipsevm/open_mips_tests/test/bin/sllv.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/op-rs/cannon-rs/5ab846ae9d4cc0d2cf26c4a7af88f86f5339644b/crates/mipsevm/open_mips_tests/test/bin/sllv.bin -------------------------------------------------------------------------------- /crates/mipsevm/open_mips_tests/test/bin/slt.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/op-rs/cannon-rs/5ab846ae9d4cc0d2cf26c4a7af88f86f5339644b/crates/mipsevm/open_mips_tests/test/bin/slt.bin -------------------------------------------------------------------------------- /crates/mipsevm/open_mips_tests/test/bin/slti.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/op-rs/cannon-rs/5ab846ae9d4cc0d2cf26c4a7af88f86f5339644b/crates/mipsevm/open_mips_tests/test/bin/slti.bin -------------------------------------------------------------------------------- /crates/mipsevm/open_mips_tests/test/bin/sltiu.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/op-rs/cannon-rs/5ab846ae9d4cc0d2cf26c4a7af88f86f5339644b/crates/mipsevm/open_mips_tests/test/bin/sltiu.bin -------------------------------------------------------------------------------- /crates/mipsevm/open_mips_tests/test/bin/sltu.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/op-rs/cannon-rs/5ab846ae9d4cc0d2cf26c4a7af88f86f5339644b/crates/mipsevm/open_mips_tests/test/bin/sltu.bin -------------------------------------------------------------------------------- /crates/mipsevm/open_mips_tests/test/bin/sra.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/op-rs/cannon-rs/5ab846ae9d4cc0d2cf26c4a7af88f86f5339644b/crates/mipsevm/open_mips_tests/test/bin/sra.bin -------------------------------------------------------------------------------- /crates/mipsevm/open_mips_tests/test/bin/srav.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/op-rs/cannon-rs/5ab846ae9d4cc0d2cf26c4a7af88f86f5339644b/crates/mipsevm/open_mips_tests/test/bin/srav.bin -------------------------------------------------------------------------------- /crates/mipsevm/open_mips_tests/test/bin/srl.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/op-rs/cannon-rs/5ab846ae9d4cc0d2cf26c4a7af88f86f5339644b/crates/mipsevm/open_mips_tests/test/bin/srl.bin -------------------------------------------------------------------------------- /crates/mipsevm/open_mips_tests/test/bin/srlv.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/op-rs/cannon-rs/5ab846ae9d4cc0d2cf26c4a7af88f86f5339644b/crates/mipsevm/open_mips_tests/test/bin/srlv.bin -------------------------------------------------------------------------------- /crates/mipsevm/open_mips_tests/test/bin/sub.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/op-rs/cannon-rs/5ab846ae9d4cc0d2cf26c4a7af88f86f5339644b/crates/mipsevm/open_mips_tests/test/bin/sub.bin -------------------------------------------------------------------------------- /crates/mipsevm/open_mips_tests/test/bin/subu.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/op-rs/cannon-rs/5ab846ae9d4cc0d2cf26c4a7af88f86f5339644b/crates/mipsevm/open_mips_tests/test/bin/subu.bin -------------------------------------------------------------------------------- /crates/mipsevm/open_mips_tests/test/bin/swl.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/op-rs/cannon-rs/5ab846ae9d4cc0d2cf26c4a7af88f86f5339644b/crates/mipsevm/open_mips_tests/test/bin/swl.bin -------------------------------------------------------------------------------- /crates/mipsevm/open_mips_tests/test/bin/swr.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/op-rs/cannon-rs/5ab846ae9d4cc0d2cf26c4a7af88f86f5339644b/crates/mipsevm/open_mips_tests/test/bin/swr.bin -------------------------------------------------------------------------------- /crates/mipsevm/open_mips_tests/test/bin/xor.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/op-rs/cannon-rs/5ab846ae9d4cc0d2cf26c4a7af88f86f5339644b/crates/mipsevm/open_mips_tests/test/bin/xor.bin -------------------------------------------------------------------------------- /crates/mipsevm/open_mips_tests/test/bin/xori.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/op-rs/cannon-rs/5ab846ae9d4cc0d2cf26c4a7af88f86f5339644b/crates/mipsevm/open_mips_tests/test/bin/xori.bin -------------------------------------------------------------------------------- /crates/mipsevm/open_mips_tests/test/blez.asm: -------------------------------------------------------------------------------- 1 | ############################################################################### 2 | # File : blez.asm 3 | # Project : MIPS32 MUX 4 | # Author: : Grant Ayers (ayers@cs.stanford.edu) 5 | # 6 | # Standards/Formatting: 7 | # MIPS gas, soft tab, 80 column 8 | # 9 | # Description: 10 | # Test the functionality of the 'blez' instruction. 11 | # 12 | ############################################################################### 13 | 14 | 15 | .section .test, "x" 16 | .balign 4 17 | .set noreorder 18 | .global test 19 | .ent test 20 | test: 21 | lui $s0, 0xbfff # Load the base address 0xbffffff0 22 | ori $s0, 0xfff0 23 | ori $s1, $0, 1 # Prepare the 'done' status 24 | 25 | #### Test code start #### 26 | 27 | ori $v0, $0, 0 # The test result starts as a failure 28 | blez $s1, $finish # No branch 29 | lui $t0, 0xffff 30 | blez $t0, $target 31 | nop 32 | 33 | $finish: 34 | sw $v0, 8($s0) 35 | sw $s1, 4($s0) 36 | 37 | $done: 38 | jr $ra 39 | nop 40 | j $finish # Early-by-1 branch detection 41 | 42 | $target: 43 | nop 44 | ori $v0, $0, 1 # Set the result to pass 45 | blez $0, $finish # Late-by-1 branch detection (result not stored) 46 | nop 47 | j $finish 48 | nop 49 | 50 | #### Test code end #### 51 | 52 | .end test 53 | -------------------------------------------------------------------------------- /crates/mipsevm/open_mips_tests/test/bltz.asm: -------------------------------------------------------------------------------- 1 | ############################################################################### 2 | # File : bltz.asm 3 | # Project : MIPS32 MUX 4 | # Author: : Grant Ayers (ayers@cs.stanford.edu) 5 | # 6 | # Standards/Formatting: 7 | # MIPS gas, soft tab, 80 column 8 | # 9 | # Description: 10 | # Test the functionality of the 'bltz' instruction. 11 | # 12 | ############################################################################### 13 | 14 | 15 | .section .test, "x" 16 | .balign 4 17 | .set noreorder 18 | .global test 19 | .ent test 20 | test: 21 | lui $s0, 0xbfff # Load the base address 0xbffffff0 22 | ori $s0, 0xfff0 23 | ori $s1, $0, 1 # Prepare the 'done' status 24 | 25 | #### Test code start #### 26 | 27 | ori $v0, $0, 0 # The test result starts as a failure 28 | bltz $0, $finish # No branch 29 | nop 30 | bltz $s1, $finish # No branch 31 | lui $t0, 0xffff 32 | bltz $t0, $target 33 | nop 34 | 35 | $finish: 36 | sw $v0, 8($s0) 37 | sw $s1, 4($s0) 38 | 39 | $done: 40 | jr $ra 41 | nop 42 | j $finish # Early-by-1 branch detection 43 | 44 | $target: 45 | nop 46 | ori $v0, $0, 1 # Set the result to pass 47 | bltz $t0, $finish # Late-by-1 branch detection (result not stored) 48 | nop 49 | j $finish # Broken branch recovery 50 | nop 51 | 52 | #### Test code end #### 53 | 54 | .end test 55 | -------------------------------------------------------------------------------- /crates/mipsevm/open_mips_tests/test/bne.asm: -------------------------------------------------------------------------------- 1 | ############################################################################### 2 | # File : bne.asm 3 | # Project : MIPS32 MUX 4 | # Author: : Grant Ayers (ayers@cs.stanford.edu) 5 | # 6 | # Standards/Formatting: 7 | # MIPS gas, soft tab, 80 column 8 | # 9 | # Description: 10 | # Test the functionality of the 'bne' instruction. 11 | # 12 | ############################################################################### 13 | 14 | 15 | .section .test, "x" 16 | .balign 4 17 | .set noreorder 18 | .global test 19 | .ent test 20 | test: 21 | lui $s0, 0xbfff # Load the base address 0xbffffff0 22 | ori $s0, 0xfff0 23 | ori $s1, $0, 1 # Prepare the 'done' status 24 | 25 | #### Test code start #### 26 | 27 | ori $t0, $0, 0xcafe 28 | ori $t1, $0, 0xcafe 29 | ori $v0, $0, 0 # The test result starts as a failure 30 | bne $t0, $t1, $finish # No branch 31 | nop 32 | bne $t0, $v0, $target 33 | nop 34 | 35 | $finish: 36 | sw $v0, 8($s0) 37 | sw $s1, 4($s0) 38 | 39 | $done: 40 | jr $ra 41 | nop 42 | j $finish # Early-by-1 branch detection 43 | 44 | $target: 45 | nop 46 | ori $v0, $0, 1 # Set the result to pass 47 | bne $t0, $0, $finish # Late-by-1 branch detection (result not stored) 48 | nop 49 | j $finish 50 | nop 51 | 52 | #### Test code end #### 53 | 54 | .end test 55 | -------------------------------------------------------------------------------- /crates/mipsevm/open_mips_tests/test/brk.asm: -------------------------------------------------------------------------------- 1 | .section .test, "x" 2 | .balign 4 3 | .set noreorder 4 | .global test 5 | .ent test 6 | 7 | test: 8 | li $v0, 4045 9 | syscall 10 | lui $t0, 0x4000 11 | subu $v0, $v0, $t0 12 | sltiu $v0, $v0, 1 13 | 14 | # save results 15 | lui $s0, 0xbfff # Load the base address 0xbffffff0 16 | ori $s0, 0xfff0 17 | ori $s1, $0, 1 # Prepare the 'done' status 18 | 19 | sw $v0, 8($s0) # Set the test result 20 | sw $s1, 4($s0) # Set 'done' 21 | 22 | $done: 23 | jr $ra 24 | nop 25 | 26 | .end test 27 | -------------------------------------------------------------------------------- /crates/mipsevm/open_mips_tests/test/clo.asm: -------------------------------------------------------------------------------- 1 | ############################################################################### 2 | # File : clo.asm 3 | # Project : MIPS32 MUX 4 | # Author: : Grant Ayers (ayers@cs.stanford.edu) 5 | # 6 | # Standards/Formatting: 7 | # MIPS gas, soft tab, 80 column 8 | # 9 | # Description: 10 | # Test the functionality of the 'clo' instruction. 11 | # 12 | ############################################################################### 13 | 14 | 15 | .section .test, "x" 16 | .balign 4 17 | .set noreorder 18 | .global test 19 | .ent test 20 | test: 21 | lui $s0, 0xbfff # Load the base address 0xbffffff0 22 | ori $s0, 0xfff0 23 | ori $s1, $0, 1 # Prepare the 'done' status 24 | 25 | #### Test code start #### 26 | 27 | lui $t2, 0xffff # 32 28 | ori $t2, 0xffff 29 | lui $t3, 0xffff # 18 30 | ori $t3, 0xc000 31 | lui $t4, 0xf800 # 5 32 | lui $t5, 0xf000 # 4 33 | lui $t6, 0x7fff # 0 34 | ori $t7, $0, 0 # 0 35 | clo $s2, $t2 36 | clo $s3, $t3 37 | clo $s4, $t4 38 | clo $s5, $t5 39 | clo $s6, $t6 40 | clo $s7, $t7 41 | addiu $s2, -32 42 | addiu $s3, -18 43 | addiu $s4, -5 44 | addiu $s5, -4 45 | addiu $s6, 0 46 | addiu $s7, 0 47 | or $v1, $s2, $s3 48 | or $v1, $v1, $s4 49 | or $v1, $v1, $s5 50 | or $v1, $v1, $s6 51 | or $v1, $v1, $s7 52 | sltiu $v0, $v1, 1 53 | 54 | #### Test code end #### 55 | 56 | sw $v0, 8($s0) # Set the test result 57 | sw $s1, 4($s0) # Set 'done' 58 | 59 | $done: 60 | jr $ra 61 | nop 62 | 63 | .end test 64 | -------------------------------------------------------------------------------- /crates/mipsevm/open_mips_tests/test/clone.asm: -------------------------------------------------------------------------------- 1 | .section .test, "x" 2 | .balign 4 3 | .set noreorder 4 | .global test 5 | .ent test 6 | 7 | test: 8 | li $v0, 4120 9 | syscall 10 | li $t0, 0x1 11 | subu $v0, $v0, $t0 12 | sltiu $v0, $v0, 1 13 | 14 | # save results 15 | lui $s0, 0xbfff # Load the base address 0xbffffff0 16 | ori $s0, 0xfff0 17 | ori $s1, $0, 1 # Prepare the 'done' status 18 | 19 | sw $v0, 8($s0) # Set the test result 20 | sw $s1, 4($s0) # Set 'done' 21 | 22 | $done: 23 | jr $ra 24 | nop 25 | 26 | .end test 27 | -------------------------------------------------------------------------------- /crates/mipsevm/open_mips_tests/test/clz.asm: -------------------------------------------------------------------------------- 1 | ############################################################################### 2 | # File : clz.asm 3 | # Project : MIPS32 MUX 4 | # Author: : Grant Ayers (ayers@cs.stanford.edu) 5 | # 6 | # Standards/Formatting: 7 | # MIPS gas, soft tab, 80 column 8 | # 9 | # Description: 10 | # Test the functionality of the 'clz' instruction. 11 | # 12 | ############################################################################### 13 | 14 | 15 | .section .test, "x" 16 | .balign 4 17 | .set noreorder 18 | .global test 19 | .ent test 20 | test: 21 | lui $s0, 0xbfff # Load the base address 0xbffffff0 22 | ori $s0, 0xfff0 23 | ori $s1, $0, 1 # Prepare the 'done' status 24 | 25 | #### Test code start #### 26 | 27 | lui $t2, 0xffff # 0 28 | ori $t2, 0xffff 29 | ori $t3, $0, 0x0100 # 23 30 | lui $t4, 0x0700 # 5 31 | lui $t5, 0x0f00 # 4 32 | lui $t6, 0x7fff # 1 33 | ori $t7, $0, 0 # 32 34 | clz $s2, $t2 35 | clz $s3, $t3 36 | clz $s4, $t4 37 | clz $s5, $t5 38 | clz $s6, $t6 39 | clz $s7, $t7 40 | addiu $s2, 0 41 | addiu $s3, -23 42 | addiu $s4, -5 43 | addiu $s5, -4 44 | addiu $s6, -1 45 | addiu $s7, -32 46 | or $v1, $s2, $s3 47 | or $v1, $v1, $s4 48 | or $v1, $v1, $s5 49 | or $v1, $v1, $s6 50 | or $v1, $v1, $s7 51 | sltiu $v0, $v1, 1 52 | 53 | #### Test code end #### 54 | 55 | sw $v0, 8($s0) # Set the test result 56 | sw $s1, 4($s0) # Set 'done' 57 | 58 | $done: 59 | jr $ra 60 | nop 61 | 62 | .end test 63 | -------------------------------------------------------------------------------- /crates/mipsevm/open_mips_tests/test/div.asm: -------------------------------------------------------------------------------- 1 | ############################################################################### 2 | # File : div.asm 3 | # Project : MIPS32 MUX 4 | # Author: : Grant Ayers (ayers@cs.stanford.edu) 5 | # 6 | # Standards/Formatting: 7 | # MIPS gas, soft tab, 80 column 8 | # 9 | # Description: 10 | # Test the functionality of the 'div' instruction. 11 | # 12 | ############################################################################### 13 | 14 | 15 | .section .test, "x" 16 | .balign 4 17 | .set noreorder 18 | .global test 19 | .ent test 20 | test: 21 | lui $s0, 0xbfff # Load the base address 0xbffffff0 22 | ori $s0, 0xfff0 23 | ori $s1, $0, 1 # Prepare the 'done' status 24 | 25 | #### Test code start #### 26 | 27 | lui $t0, 0x1234 28 | ori $t0, 0x5678 29 | lui $t1, 0xc001 30 | ori $t1, 0xcafe 31 | div $t1, $t0 # 0xfffffffd (q), 0xf69ece66 (r) 32 | mfhi $t2 33 | mflo $t3 34 | lui $t4, 0xf69e 35 | ori $t4, 0xce66 36 | lui $t5, 0xffff 37 | ori $t5, 0xfffd 38 | subu $t6, $t2, $t4 39 | subu $t7, $t3, $t5 40 | sltiu $v0, $t6, 1 41 | sltiu $v1, $t7, 1 42 | and $v0, $v0, $v1 43 | 44 | #### Test code end #### 45 | 46 | sw $v0, 8($s0) # Set the test result 47 | sw $s1, 4($s0) # Set 'done' 48 | 49 | $done: 50 | jr $ra 51 | nop 52 | 53 | .end test 54 | -------------------------------------------------------------------------------- /crates/mipsevm/open_mips_tests/test/divu.asm: -------------------------------------------------------------------------------- 1 | ############################################################################### 2 | # File : divu.asm 3 | # Project : MIPS32 MUX 4 | # Author: : Grant Ayers (ayers@cs.stanford.edu) 5 | # 6 | # Standards/Formatting: 7 | # MIPS gas, soft tab, 80 column 8 | # 9 | # Description: 10 | # Test the functionality of the 'divu' instruction. 11 | # 12 | ############################################################################### 13 | 14 | 15 | .section .test, "x" 16 | .balign 4 17 | .set noreorder 18 | .global test 19 | .ent test 20 | test: 21 | lui $s0, 0xbfff # Load the base address 0xbffffff0 22 | ori $s0, 0xfff0 23 | ori $s1, $0, 1 # Prepare the 'done' status 24 | 25 | #### Test code start #### 26 | 27 | lui $t0, 0x1234 28 | ori $t0, 0x5678 29 | lui $t1, 0xc001 30 | ori $t1, 0xcafe 31 | divu $t1, $t0 # 0xa (q), 0x09f66a4e (r) 32 | mfhi $t2 33 | mflo $t3 34 | lui $t4, 0x09f6 35 | ori $t4, 0x6a4e 36 | lui $t5, 0x0000 37 | ori $t5, 0x000a 38 | subu $t6, $t2, $t4 39 | subu $t7, $t3, $t5 40 | sltiu $v0, $t6, 1 41 | sltiu $v1, $t7, 1 42 | and $v0, $v0, $v1 43 | 44 | #### Test code end #### 45 | 46 | sw $v0, 8($s0) # Set the test result 47 | sw $s1, 4($s0) # Set 'done' 48 | 49 | $done: 50 | jr $ra 51 | nop 52 | 53 | .end test 54 | -------------------------------------------------------------------------------- /crates/mipsevm/open_mips_tests/test/exit_group.asm: -------------------------------------------------------------------------------- 1 | .section .test, "x" 2 | .balign 4 3 | .set noreorder 4 | .global test 5 | .ent test 6 | 7 | test: 8 | li $a0, 1 9 | li $v0, 4246 10 | syscall 11 | 12 | # Unreachable .... 13 | # set test result to fail. 14 | # Test runner should short-circuit before reaching this point. 15 | li $v0, 0 16 | 17 | # save results 18 | lui $s0, 0xbfff # Load the base address 0xbffffff0 19 | ori $s0, 0xfff0 20 | ori $s1, $0, 1 # Prepare the 'done' status 21 | 22 | sw $v0, 8($s0) # Set the test result 23 | sw $s1, 4($s0) # Set 'done' 24 | 25 | $done: 26 | jr $ra 27 | nop 28 | 29 | .end test 30 | -------------------------------------------------------------------------------- /crates/mipsevm/open_mips_tests/test/fcntl.asm: -------------------------------------------------------------------------------- 1 | .section .test, "x" 2 | .balign 4 3 | .set noreorder 4 | .global test 5 | .ent test 6 | 7 | test: 8 | # fnctl(0, 3) 9 | li $v0, 4055 10 | li $a0, 0x0 11 | li $a1, 0x3 12 | syscall 13 | sltiu $v0, $v0, 1 14 | 15 | # save results 16 | lui $s0, 0xbfff # Load the base address 0xbffffff0 17 | ori $s0, 0xfff0 18 | ori $s1, $0, 1 # Prepare the 'done' status 19 | 20 | sw $v0, 8($s0) # Set the test result 21 | sw $s1, 4($s0) # Set 'done' 22 | 23 | $done: 24 | jr $ra 25 | nop 26 | 27 | .end test 28 | -------------------------------------------------------------------------------- /crates/mipsevm/open_mips_tests/test/j.asm: -------------------------------------------------------------------------------- 1 | ############################################################################### 2 | # File : j.asm 3 | # Project : MIPS32 MUX 4 | # Author: : Grant Ayers (ayers@cs.stanford.edu) 5 | # 6 | # Standards/Formatting: 7 | # MIPS gas, soft tab, 80 column 8 | # 9 | # Description: 10 | # Test the functionality of the 'j' instruction. 11 | # 12 | ############################################################################### 13 | 14 | 15 | .section .test, "x" 16 | .balign 4 17 | .set noreorder 18 | .global test 19 | .ent test 20 | test: 21 | lui $s0, 0xbfff # Load the base address 0xbffffff0 22 | ori $s0, 0xfff0 23 | ori $s1, $0, 1 # Prepare the 'done' status 24 | 25 | #### Test code start #### 26 | 27 | j $target 28 | ori $v0, $0, 0 # The test result starts as a failure 29 | 30 | $finish: 31 | sw $v0, 8($s0) 32 | sw $s1, 4($s0) 33 | jr $ra 34 | nop 35 | j $finish # Early-by-1 detection 36 | 37 | $target: 38 | nop 39 | ori $v0, $0, 1 # Set the result to pass 40 | j $finish # Late-by 1 detection (result not written) 41 | nop 42 | 43 | #### Test code end #### 44 | 45 | .end test 46 | -------------------------------------------------------------------------------- /crates/mipsevm/open_mips_tests/test/jal.asm: -------------------------------------------------------------------------------- 1 | ############################################################################### 2 | # File : jal.asm 3 | # Project : MIPS32 MUX 4 | # Author: : Grant Ayers (ayers@cs.stanford.edu) 5 | # 6 | # Standards/Formatting: 7 | # MIPS gas, soft tab, 80 column 8 | # 9 | # Description: 10 | # Test the functionality of the 'jal' instruction. 11 | # 12 | ############################################################################### 13 | 14 | 15 | .section .test, "x" 16 | .balign 4 17 | .set noreorder 18 | .global test 19 | .ent test 20 | test: 21 | lui $s0, 0xbfff # Load the base address 0xbffffff0 22 | ori $s0, 0xfff0 23 | ori $s1, $0, 1 # Prepare the 'done' status 24 | 25 | #### Test code start #### 26 | 27 | ori $v1, $ra, 0 # Save $ra 28 | jal $target 29 | ori $v0, $0, 0 # The test result starts as a failure 30 | 31 | $finish: 32 | sw $v0, 8($s0) 33 | ori $ra, $v1, 0 # Restore $ra 34 | sw $s1, 4($s0) 35 | jr $ra 36 | nop 37 | j $finish # Early-by-1 detection 38 | 39 | $target: 40 | nop 41 | ori $v0, $0, 1 # Set the result to pass 42 | jr $ra 43 | nop 44 | 45 | #### Test code end #### 46 | 47 | .end test 48 | -------------------------------------------------------------------------------- /crates/mipsevm/open_mips_tests/test/jalr.asm: -------------------------------------------------------------------------------- 1 | ############################################################################### 2 | # File : jalr.asm 3 | # Project : MIPS32 MUX 4 | # Author: : Grant Ayers (ayers@cs.stanford.edu) 5 | # 6 | # Standards/Formatting: 7 | # MIPS gas, soft tab, 80 column 8 | # 9 | # Description: 10 | # Test the functionality of the 'jalr' instruction. 11 | # 12 | ############################################################################### 13 | 14 | 15 | .section .test, "x" 16 | .balign 4 17 | .set noreorder 18 | .global test 19 | .ent test 20 | test: 21 | lui $s0, 0xbfff # Load the base address 0xbffffff0 22 | ori $s0, 0xfff0 23 | ori $s1, $0, 1 # Prepare the 'done' status 24 | 25 | #### Test code start #### 26 | 27 | ori $v1, $ra, 0 # Save $ra 28 | la $t0, $target 29 | jalr $t0 30 | ori $v0, $0, 0 # The test result starts as a failure 31 | 32 | $finish: 33 | sw $v0, 8($s0) 34 | ori $ra, $v1, 0 # Restore $ra 35 | sw $s1, 4($s0) 36 | jr $ra 37 | nop 38 | j $finish # Early-by-1 detection 39 | 40 | $target: 41 | nop 42 | ori $v0, $0, 1 # Set the result to pass 43 | jr $ra 44 | nop 45 | 46 | #### Test code end #### 47 | 48 | .end test 49 | -------------------------------------------------------------------------------- /crates/mipsevm/open_mips_tests/test/jr.asm: -------------------------------------------------------------------------------- 1 | ############################################################################### 2 | # File : jr.asm 3 | # Project : MIPS32 MUX 4 | # Author: : Grant Ayers (ayers@cs.stanford.edu) 5 | # 6 | # Standards/Formatting: 7 | # MIPS gas, soft tab, 80 column 8 | # 9 | # Description: 10 | # Test the functionality of the 'jr' instruction. 11 | # 12 | ############################################################################### 13 | 14 | 15 | .section .test, "x" 16 | .balign 4 17 | .set noreorder 18 | .global test 19 | .ent test 20 | test: 21 | lui $s0, 0xbfff # Load the base address 0xbffffff0 22 | ori $s0, 0xfff0 23 | ori $s1, $0, 1 # Prepare the 'done' status 24 | 25 | #### Test code start #### 26 | 27 | la $t0, $target 28 | jr $t0 29 | ori $v0, $0, 0 # The test result starts as a failure 30 | 31 | $finish: 32 | sw $v0, 8($s0) 33 | sw $s1, 4($s0) 34 | jr $ra 35 | nop 36 | j $finish # Early-by-1 detection 37 | 38 | $target: 39 | nop 40 | ori $v0, $0, 1 # Set the result to pass 41 | j $finish 42 | nop 43 | 44 | #### Test code end #### 45 | 46 | .end test 47 | -------------------------------------------------------------------------------- /crates/mipsevm/open_mips_tests/test/lb.asm: -------------------------------------------------------------------------------- 1 | ############################################################################### 2 | # File : lb.asm 3 | # Project : MIPS32 MUX 4 | # Author: : Grant Ayers (ayers@cs.stanford.edu) 5 | # 6 | # Standards/Formatting: 7 | # MIPS gas, soft tab, 80 column 8 | # 9 | # Description: 10 | # Test the functionality of the 'lb' instruction. 11 | # 12 | ############################################################################### 13 | 14 | 15 | .section .test, "x" 16 | .balign 4 17 | .set noreorder 18 | .global test 19 | .ent test 20 | test: 21 | lui $s0, 0xbfff # Load the base address 0xbffffff0 22 | ori $s0, 0xfff0 23 | ori $s1, $0, 1 # Prepare the 'done' status 24 | 25 | #### Test code start #### 26 | 27 | lui $t0, 0xbfc0 # Load address 0xbfc007fc (last word in 2KB starting 28 | ori $t0, 0x07fc # from 0xbfc00000) 29 | lui $t1, 0xc001 30 | ori $t1, 0x7afe 31 | sw $t1, 0($t0) 32 | lb $t2, 0($t0) 33 | lb $t3, 1($t0) 34 | lb $t4, 2($t0) 35 | lb $t5, 3($t0) 36 | .ifdef big_endian 37 | lui $t6, 0xffff 38 | ori $t6, 0xffc0 39 | lui $t7, 0x0000 40 | ori $t7, 0x0001 41 | lui $t8, 0x0000 42 | ori $t8, 0x007a 43 | lui $t9, 0xffff 44 | ori $t9, 0xfffe 45 | .else 46 | lui $t6, 0xffff 47 | ori $t6, 0xfffe 48 | lui $t7, 0x0000 49 | ori $t7, 0x007a 50 | lui $t8, 0x0000 51 | ori $t8, 0x0001 52 | lui $t9, 0xffff 53 | ori $t9, 0xffc0 54 | .endif 55 | subu $v1, $t2, $t6 56 | sltiu $v0, $v1, 1 57 | subu $v1, $t3, $t7 58 | sltiu $v1, $v1, 1 59 | and $v0, $v0, $v1 60 | subu $v1, $t4, $t8 61 | sltiu $v1, $v1, 1 62 | and $v0, $v0, $v1 63 | subu $v1, $t5, $t9 64 | sltiu $v1, $v1, 1 65 | and $v0, $v0, $v1 66 | 67 | # Repeat with halves swapped (sign extension corner cases) 68 | lui $t1, 0x7afe 69 | ori $t1, 0xc001 70 | sw $t1, 0($t0) 71 | lb $t2, 0($t0) 72 | lb $t3, 1($t0) 73 | lb $t4, 2($t0) 74 | lb $t5, 3($t0) 75 | .ifdef big_endian 76 | lui $t6, 0x0000 77 | ori $t6, 0x007a 78 | lui $t7, 0xffff 79 | ori $t7, 0xfffe 80 | lui $t8, 0xffff 81 | ori $t8, 0xffc0 82 | lui $t9, 0x0000 83 | ori $t9, 0x0001 84 | .else 85 | lui $t6, 0x0000 86 | ori $t6, 0x0001 87 | lui $t7, 0xffff 88 | ori $t7, 0xffc0 89 | lui $t8, 0xffff 90 | ori $t8, 0xfffe 91 | lui $t9, 0x0000 92 | ori $t9, 0x007a 93 | .endif 94 | subu $v1, $t2, $t6 95 | sltiu $v1, $v1, 1 96 | and $v0, $v0, $v1 97 | subu $v1, $t3, $t7 98 | sltiu $v1, $v1, 1 99 | and $v0, $v0, $v1 100 | subu $v1, $t4, $t8 101 | sltiu $v1, $v1, 1 102 | and $v0, $v0, $v1 103 | subu $v1, $t5, $t9 104 | sltiu $v1, $v1, 1 105 | and $v0, $v0, $v1 106 | 107 | #### Test code end #### 108 | 109 | sw $v0, 8($s0) # Set the test result 110 | sw $s1, 4($s0) # Set 'done' 111 | 112 | $done: 113 | jr $ra 114 | nop 115 | 116 | .end test 117 | -------------------------------------------------------------------------------- /crates/mipsevm/open_mips_tests/test/lbu.asm: -------------------------------------------------------------------------------- 1 | ############################################################################### 2 | # File : lbu.asm 3 | # Project : MIPS32 MUX 4 | # Author: : Grant Ayers (ayers@cs.stanford.edu) 5 | # 6 | # Standards/Formatting: 7 | # MIPS gas, soft tab, 80 column 8 | # 9 | # Description: 10 | # Test the functionality of the 'lbu' instruction. 11 | # 12 | ############################################################################### 13 | 14 | 15 | .section .test, "x" 16 | .balign 4 17 | .set noreorder 18 | .global test 19 | .ent test 20 | test: 21 | lui $s0, 0xbfff # Load the base address 0xbffffff0 22 | ori $s0, 0xfff0 23 | ori $s1, $0, 1 # Prepare the 'done' status 24 | 25 | #### Test code start #### 26 | 27 | lui $t0, 0xbfc0 # Load address 0xbfc007fc (last word in 2KB starting 28 | ori $t0, 0x07fc # from 0xbfc00000) 29 | lui $t1, 0xc001 30 | ori $t1, 0x7afe 31 | sw $t1, 0($t0) 32 | lbu $t2, 0($t0) 33 | lbu $t3, 1($t0) 34 | lbu $t4, 2($t0) 35 | lbu $t5, 3($t0) 36 | .ifdef big_endian 37 | ori $t6, $0, 0x00c0 38 | ori $t7, $0, 0x0001 39 | ori $t8, $0, 0x007a 40 | ori $t9, $0, 0x00fe 41 | .else 42 | ori $t6, $0, 0x00fe 43 | ori $t7, $0, 0x007a 44 | ori $t8, $0, 0x0001 45 | ori $t9, $0, 0x00c0 46 | .endif 47 | subu $v1, $t2, $t6 48 | sltiu $v0, $v1, 1 49 | subu $v1, $t3, $t7 50 | sltiu $v1, $v1, 1 51 | and $v0, $v0, $v1 52 | subu $v1, $t4, $t8 53 | sltiu $v1, $v1, 1 54 | and $v0, $v0, $v1 55 | subu $v1, $t5, $t9 56 | sltiu $v1, $v1, 1 57 | and $v0, $v0, $v1 58 | 59 | #### Test code end #### 60 | 61 | sw $v0, 8($s0) # Set the test result 62 | sw $s1, 4($s0) # Set 'done' 63 | 64 | $done: 65 | jr $ra 66 | nop 67 | 68 | .end test 69 | -------------------------------------------------------------------------------- /crates/mipsevm/open_mips_tests/test/lh.asm: -------------------------------------------------------------------------------- 1 | ############################################################################### 2 | # File : lh.asm 3 | # Project : MIPS32 MUX 4 | # Author: : Grant Ayers (ayers@cs.stanford.edu) 5 | # 6 | # Standards/Formatting: 7 | # MIPS gas, soft tab, 80 column 8 | # 9 | # Description: 10 | # Test the functionality of the 'lh' instruction. 11 | # 12 | ############################################################################### 13 | 14 | 15 | .section .test, "x" 16 | .balign 4 17 | .set noreorder 18 | .global test 19 | .ent test 20 | test: 21 | lui $s0, 0xbfff # Load the base address 0xbffffff0 22 | ori $s0, 0xfff0 23 | ori $s1, $0, 1 # Prepare the 'done' status 24 | 25 | #### Test code start #### 26 | 27 | lui $t0, 0xbfc0 # Load address 0xbfc007fc (last word in 2KB starting 28 | ori $t0, 0x07fc # from 0xbfc00000) 29 | lui $t1, 0x7001 30 | ori $t1, 0xcafe 31 | sw $t1, 0($t0) 32 | lh $t2, 0($t0) 33 | lh $t3, 2($t0) 34 | .ifdef big_endian 35 | lui $t4, 0x0000 36 | ori $t4, 0x7001 37 | lui $t5, 0xffff 38 | ori $t5, 0xcafe 39 | .else 40 | lui $t4, 0xffff 41 | ori $t4, 0xcafe 42 | lui $t5, 0x0000 43 | ori $t5, 0x7001 44 | .endif 45 | subu $v1, $t2, $t4 46 | sltiu $v0, $v1, 1 47 | subu $v1, $t3, $t5 48 | sltiu $v1, $v1, 1 49 | and $v0, $v0, $v1 50 | 51 | # Repeat with halves swapped (sign extension corner cases) 52 | lui $t1, 0xcafe 53 | ori $t1, 0x7001 54 | sw $t1, 0($t0) 55 | lh $t2, 0($t0) 56 | lh $t3, 2($t0) 57 | .ifdef big_endian 58 | lui $t4, 0xffff 59 | ori $t4, 0xcafe 60 | lui $t5, 0x0000 61 | ori $t5, 0x7001 62 | .else 63 | lui $t4, 0x0000 64 | ori $t4, 0x7001 65 | lui $t5, 0xffff 66 | ori $t5, 0xcafe 67 | .endif 68 | subu $v1, $t2, $t4 69 | sltiu $v1, $v1, 1 70 | and $v0, $v0, $v1 71 | subu $v1, $t3, $t5 72 | sltiu $v1, $v1, 1 73 | and $v0, $v0, $v1 74 | 75 | #### Test code end #### 76 | 77 | sw $v0, 8($s0) # Set the test result 78 | sw $s1, 4($s0) # Set 'done' 79 | 80 | $done: 81 | jr $ra 82 | nop 83 | 84 | .end test 85 | -------------------------------------------------------------------------------- /crates/mipsevm/open_mips_tests/test/lhu.asm: -------------------------------------------------------------------------------- 1 | ############################################################################### 2 | # File : lhu.asm 3 | # Project : MIPS32 MUX 4 | # Author: : Grant Ayers (ayers@cs.stanford.edu) 5 | # 6 | # Standards/Formatting: 7 | # MIPS gas, soft tab, 80 column 8 | # 9 | # Description: 10 | # Test the functionality of the 'lhu' instruction. 11 | # 12 | ############################################################################### 13 | 14 | 15 | .section .test, "x" 16 | .balign 4 17 | .set noreorder 18 | .global test 19 | .ent test 20 | test: 21 | lui $s0, 0xbfff # Load the base address 0xbffffff0 22 | ori $s0, 0xfff0 23 | ori $s1, $0, 1 # Prepare the 'done' status 24 | 25 | #### Test code start #### 26 | 27 | lui $t0, 0xbfc0 # Load address 0xbfc007fc (last word in 2KB starting 28 | ori $t0, 0x07fc # from 0xbfc00000) 29 | lui $t1, 0x7001 30 | ori $t1, 0xcafe 31 | sw $t1, 0($t0) 32 | lhu $t2, 0($t0) 33 | lhu $t3, 2($t0) 34 | .ifdef big_endian 35 | ori $t4, $0, 0x7001 36 | ori $t5, $0, 0xcafe 37 | .else 38 | ori $t4, $0, 0xcafe 39 | ori $t5, $0, 0x7001 40 | .endif 41 | subu $v1, $t2, $t4 42 | sltiu $v0, $v1, 1 43 | subu $v1, $t3, $t5 44 | sltiu $v1, $v1, 1 45 | and $v0, $v0, $v1 46 | 47 | # Repeat with halves swapped (sign extension corner cases) 48 | lui $t1, 0xcafe 49 | ori $t1, 0x7001 50 | sw $t1, 0($t0) 51 | lhu $t2, 0($t0) 52 | lhu $t3, 2($t0) 53 | .ifdef big_endian 54 | ori $t4, $0, 0xcafe 55 | ori $t5, $0, 0x7001 56 | .else 57 | ori $t4, $0, 0x7001 58 | ori $t5, $0, 0xcafe 59 | .endif 60 | subu $v1, $t2, $t4 61 | sltiu $v1, $v1, 1 62 | and $v0, $v0, $v1 63 | subu $v1, $t3, $t5 64 | sltiu $v1, $v1, 1 65 | and $v0, $v0, $v1 66 | 67 | #### Test code end #### 68 | 69 | sw $v0, 8($s0) # Set the test result 70 | sw $s1, 4($s0) # Set 'done' 71 | 72 | $done: 73 | jr $ra 74 | nop 75 | 76 | .end test 77 | -------------------------------------------------------------------------------- /crates/mipsevm/open_mips_tests/test/lui.asm: -------------------------------------------------------------------------------- 1 | ############################################################################### 2 | # File : lui.asm 3 | # Project : MIPS32 MUX 4 | # Author: : Grant Ayers (ayers@cs.stanford.edu) 5 | # 6 | # Standards/Formatting: 7 | # MIPS gas, soft tab, 80 column 8 | # 9 | # Description: 10 | # Test the functionality of the 'lui' instruction. 11 | # 12 | ############################################################################### 13 | 14 | 15 | .section .test, "x" 16 | .balign 4 17 | .set noreorder 18 | .global test 19 | .ent test 20 | test: 21 | lui $s0, 0xbfff # Load the base address 0xbffffff0 22 | ori $s0, 0xfff0 23 | ori $s1, $0, 1 # Prepare the 'done' status 24 | 25 | #### Test code start #### 26 | 27 | ori $v0, $0, 1 28 | 29 | #### Test code end #### 30 | 31 | sw $v0, 8($s0) # Set the test result 32 | sw $s1, 4($s0) # Set 'done' 33 | 34 | $done: 35 | jr $ra 36 | nop 37 | 38 | .end test 39 | -------------------------------------------------------------------------------- /crates/mipsevm/open_mips_tests/test/lw.asm: -------------------------------------------------------------------------------- 1 | ############################################################################### 2 | # File : lw.asm 3 | # Project : MIPS32 MUX 4 | # Author: : Grant Ayers (ayers@cs.stanford.edu) 5 | # 6 | # Standards/Formatting: 7 | # MIPS gas, soft tab, 80 column 8 | # 9 | # Description: 10 | # Test the functionality of the 'lw' instruction. 11 | # 12 | ############################################################################### 13 | 14 | 15 | .section .test, "x" 16 | .balign 4 17 | .set noreorder 18 | .global test 19 | .ent test 20 | test: 21 | lui $s0, 0xbfff # Load the base address 0xbffffff0 22 | ori $s0, 0xfff0 23 | ori $s1, $0, 1 # Prepare the 'done' status 24 | 25 | #### Test code start #### 26 | 27 | lui $t0, 0xbfc0 # Load a valid address (last word in 2KB starting 28 | ori $t0, 0x07fc # from 0xbfc00000) 29 | sw $0, 0($t0) 30 | ori $t1, $0, 1 31 | sw $t1, 0($t0) 32 | lw $v0, 0($t0) 33 | 34 | #### Test code end #### 35 | 36 | sw $v0, 8($s0) # Set the test result 37 | sw $s1, 4($s0) # Set 'done' 38 | 39 | $done: 40 | jr $ra 41 | nop 42 | 43 | .end test 44 | -------------------------------------------------------------------------------- /crates/mipsevm/open_mips_tests/test/lwl.asm: -------------------------------------------------------------------------------- 1 | ############################################################################### 2 | # File : lwl.asm 3 | # Project : MIPS32 MUX 4 | # Author: : Grant Ayers (ayers@cs.stanford.edu) 5 | # 6 | # Standards/Formatting: 7 | # MIPS gas, soft tab, 80 column 8 | # 9 | # Description: 10 | # Test the functionality of the 'lwl' instruction. 11 | # 12 | ############################################################################### 13 | 14 | 15 | .section .test, "x" 16 | .balign 4 17 | .set noreorder 18 | .global test 19 | .ent test 20 | test: 21 | lui $s0, 0xbfff # Load the base address 0xbffffff0 22 | ori $s0, 0xfff0 23 | ori $s1, $0, 1 # Prepare the 'done' status 24 | 25 | #### Test code start #### 26 | 27 | lui $t0, 0xbfc0 # Load address 0xbfc007fc (last word in 2KB starting 28 | ori $t0, 0x07fc # from 0xbfc00000) 29 | lui $t1, 0xc001 # Memory word is 0xc001cafe 30 | ori $t1, 0xcafe 31 | sw $t1, 0($t0) 32 | lui $t2, 0xdeaf # Register word is 0xdeafbeef 33 | ori $t2, 0xbeef 34 | or $t3, $0, $t2 35 | or $t4, $0, $t2 36 | or $t5, $0, $t2 37 | or $t6, $0, $t2 38 | lwl $t3, 0($t0) 39 | lwl $t4, 1($t0) 40 | lwl $t5, 2($t0) 41 | lwl $t6, 3($t0) 42 | .ifdef big_endian 43 | lui $s3, 0xc001 # 0xc001cafe 44 | ori $s3, 0xcafe 45 | lui $s4, 0x01ca # 0x01cafeef 46 | ori $s4, 0xfeef 47 | lui $s5, 0xcafe # 0xcafebeef 48 | ori $s5, 0xbeef 49 | lui $s6, 0xfeaf # 0xfeafbeef 50 | ori $s6, 0xbeef 51 | .else 52 | lui $s3, 0xfeaf # 0xfeafbeef 53 | ori $s3, 0xbeef 54 | lui $s4, 0xcafe # 0xcafebeef 55 | ori $s4, 0xbeef 56 | lui $s5, 0x01ca # 0x01cafeef 57 | ori $s5, 0xfeef 58 | lui $s6, 0xc001 # 0xc001cafe 59 | ori $s6, 0xcafe 60 | .endif 61 | subu $s2, $t3, $s3 62 | sltiu $v0, $s2, 1 63 | subu $s2, $t4, $s4 64 | sltiu $v1, $s2, 1 65 | and $v0, $v0, $v1 66 | subu $s2, $t5, $s5 67 | sltiu $v1, $s2, 1 68 | and $v0, $v0, $v1 69 | subu $s2, $t6, $s6 70 | sltiu $v1, $s2, 1 71 | and $v0, $v0, $v1 72 | 73 | #### Test code end #### 74 | 75 | sw $v0, 8($s0) # Set the test result 76 | sw $s1, 4($s0) # Set 'done' 77 | 78 | $done: 79 | jr $ra 80 | nop 81 | 82 | .end test 83 | -------------------------------------------------------------------------------- /crates/mipsevm/open_mips_tests/test/lwr.asm: -------------------------------------------------------------------------------- 1 | ############################################################################### 2 | # File : lwr.asm 3 | # Project : MIPS32 MUX 4 | # Author: : Grant Ayers (ayers@cs.stanford.edu) 5 | # 6 | # Standards/Formatting: 7 | # MIPS gas, soft tab, 80 column 8 | # 9 | # Description: 10 | # Test the functionality of the 'lwr' instruction. 11 | # 12 | ############################################################################### 13 | 14 | 15 | .section .test, "x" 16 | .balign 4 17 | .set noreorder 18 | .global test 19 | .ent test 20 | test: 21 | lui $s0, 0xbfff # Load the base address 0xbffffff0 22 | ori $s0, 0xfff0 23 | ori $s1, $0, 1 # Prepare the 'done' status 24 | 25 | #### Test code start #### 26 | 27 | lui $t0, 0xbfc0 # Load address 0xbfc007fc (last word in 2KB starting 28 | ori $t0, 0x07fc # from 0xbfc00000) 29 | lui $t1, 0xc001 # Memory word is 0xc001cafe 30 | ori $t1, 0xcafe 31 | sw $t1, 0($t0) 32 | lui $t2, 0xdeaf # Register word is 0xdeafbeef 33 | ori $t2, 0xbeef 34 | or $t3, $0, $t2 35 | or $t4, $0, $t2 36 | or $t5, $0, $t2 37 | or $t6, $0, $t2 38 | lwr $t3, 0($t0) 39 | lwr $t4, 1($t0) 40 | lwr $t5, 2($t0) 41 | lwr $t6, 3($t0) 42 | .ifdef big_endian 43 | lui $s3, 0xdeaf # 0xdeafbec0 44 | ori $s3, 0xbec0 45 | lui $s4, 0xdeaf # 0xdeafc001 46 | ori $s4, 0xc001 47 | lui $s5, 0xdec0 # 0xdec001ca 48 | ori $s5, 0x01ca 49 | lui $s6, 0xc001 # 0xc001cafe 50 | ori $s6, 0xcafe 51 | .else 52 | lui $s3, 0xc001 # 0xc001cafe 53 | ori $s3, 0xcafe 54 | lui $s4, 0xdec0 # 0xdec001ca 55 | ori $s4, 0x01ca 56 | lui $s5, 0xdeaf # 0xdeafc001 57 | ori $s5, 0xc001 58 | lui $s6, 0xdeaf # 0xdeafbec0 59 | ori $s6, 0xbec0 60 | .endif 61 | subu $s2, $t3, $s3 62 | sltiu $v0, $s2, 1 63 | subu $s2, $t4, $s4 64 | sltiu $v1, $s2, 1 65 | and $v0, $v0, $v1 66 | subu $s2, $t5, $s5 67 | sltiu $v1, $s2, 1 68 | and $v0, $v0, $v1 69 | subu $s2, $t6, $s6 70 | sltiu $v1, $s2, 1 71 | and $v0, $v0, $v1 72 | 73 | #### Test code end #### 74 | 75 | sw $v0, 8($s0) # Set the test result 76 | sw $s1, 4($s0) # Set 'done' 77 | 78 | $done: 79 | jr $ra 80 | nop 81 | 82 | .end test 83 | -------------------------------------------------------------------------------- /crates/mipsevm/open_mips_tests/test/mfthi.asm: -------------------------------------------------------------------------------- 1 | ############################################################################### 2 | # File : mfthi.asm 3 | # Project : MIPS32 MUX 4 | # Author: : Grant Ayers (ayers@cs.stanford.edu) 5 | # 6 | # Standards/Formatting: 7 | # MIPS gas, soft tab, 80 column 8 | # 9 | # Description: 10 | # Test the functionality of the 'mthi' and 'mfhi' instructions. 11 | # 12 | ############################################################################### 13 | 14 | 15 | .section .test, "x" 16 | .balign 4 17 | .set noreorder 18 | .global test 19 | .ent test 20 | test: 21 | lui $s0, 0xbfff # Load the base address 0xbffffff0 22 | ori $s0, 0xfff0 23 | ori $s1, $0, 1 # Prepare the 'done' status 24 | 25 | #### Test code start #### 26 | 27 | lui $t0, 0xdeaf 28 | ori $t0, 0xbeef 29 | mthi $t0 30 | mfhi $t1 31 | subu $v1, $t0, $t1 32 | sltiu $v0, $v1, 1 33 | 34 | #### Test code end #### 35 | 36 | sw $v0, 8($s0) # Set the test result 37 | sw $s1, 4($s0) # Set 'done' 38 | 39 | $done: 40 | jr $ra 41 | nop 42 | 43 | .end test 44 | -------------------------------------------------------------------------------- /crates/mipsevm/open_mips_tests/test/mftlo.asm: -------------------------------------------------------------------------------- 1 | ############################################################################### 2 | # File : mftlo.asm 3 | # Project : MIPS32 MUX 4 | # Author: : Grant Ayers (ayers@cs.stanford.edu) 5 | # 6 | # Standards/Formatting: 7 | # MIPS gas, soft tab, 80 column 8 | # 9 | # Description: 10 | # Test the functionality of the 'mtlo' and 'mflo' instructions. 11 | # 12 | ############################################################################### 13 | 14 | 15 | .section .test, "x" 16 | .balign 4 17 | .set noreorder 18 | .global test 19 | .ent test 20 | test: 21 | lui $s0, 0xbfff # Load the base address 0xbffffff0 22 | ori $s0, 0xfff0 23 | ori $s1, $0, 1 # Prepare the 'done' status 24 | 25 | #### Test code start #### 26 | 27 | lui $t0, 0xdeaf 28 | ori $t0, 0xbeef 29 | mtlo $t0 30 | mflo $t1 31 | subu $v1, $t0, $t1 32 | sltiu $v0, $v1, 1 33 | 34 | #### Test code end #### 35 | 36 | sw $v0, 8($s0) # Set the test result 37 | sw $s1, 4($s0) # Set 'done' 38 | 39 | $done: 40 | jr $ra 41 | nop 42 | 43 | .end test 44 | -------------------------------------------------------------------------------- /crates/mipsevm/open_mips_tests/test/mmap.asm: -------------------------------------------------------------------------------- 1 | .section .test, "x" 2 | .balign 4 3 | .set noreorder 4 | .global test 5 | .ent test 6 | 7 | test: 8 | li $v0, 4090 9 | lui $a0, 0x3000 10 | li $a1, 4096 11 | syscall 12 | lui $t0, 0x3000 13 | subu $v0, $v0, $t0 14 | sltiu $v0, $v0, 1 15 | 16 | # save results 17 | lui $s0, 0xbfff # Load the base address 0xbffffff0 18 | ori $s0, 0xfff0 19 | ori $s1, $0, 1 # Prepare the 'done' status 20 | 21 | sw $v0, 8($s0) # Set the test result 22 | sw $s1, 4($s0) # Set 'done' 23 | 24 | $done: 25 | jr $ra 26 | nop 27 | 28 | .end test 29 | -------------------------------------------------------------------------------- /crates/mipsevm/open_mips_tests/test/movn.asm: -------------------------------------------------------------------------------- 1 | ############################################################################### 2 | # File : movn.asm 3 | # Project : MIPS32 MUX 4 | # Author: : Grant Ayers (ayers@cs.stanford.edu) 5 | # 6 | # Standards/Formatting: 7 | # MIPS gas, soft tab, 80 column 8 | # 9 | # Description: 10 | # Test the functionality of the 'movn' instruction. 11 | # 12 | ############################################################################### 13 | 14 | 15 | .section .test, "x" 16 | .balign 4 17 | .set noreorder 18 | .global test 19 | .ent test 20 | test: 21 | lui $s0, 0xbfff # Load the base address 0xbffffff0 22 | ori $s0, 0xfff0 23 | ori $s1, $0, 1 # Prepare the 'done' status 24 | 25 | #### Test code start #### 26 | 27 | lui $t0, 0xdeaf 28 | ori $t0, $t0, 0xbeef 29 | ori $t1, $0, 0 30 | movn $t2, $t0, $s1 # $t2 gets 0xdeafbeef 31 | movn $t1, $t0, $0 # $t1 remains 0 32 | subu $t3, $t2, $t0 33 | sltiu $v0, $t3, 1 34 | sltiu $v1, $t1, 1 35 | and $v0, $v0, $v1 36 | 37 | #### Test code end #### 38 | 39 | sw $v0, 8($s0) # Set the test result 40 | sw $s1, 4($s0) # Set 'done' 41 | 42 | $done: 43 | jr $ra 44 | nop 45 | 46 | .end test 47 | -------------------------------------------------------------------------------- /crates/mipsevm/open_mips_tests/test/movz.asm: -------------------------------------------------------------------------------- 1 | ############################################################################### 2 | # File : movz.asm 3 | # Project : MIPS32 MUX 4 | # Author: : Grant Ayers (ayers@cs.stanford.edu) 5 | # 6 | # Standards/Formatting: 7 | # MIPS gas, soft tab, 80 column 8 | # 9 | # Description: 10 | # Test the functionality of the 'movz' instruction. 11 | # 12 | ############################################################################### 13 | 14 | 15 | .section .test, "x" 16 | .balign 4 17 | .set noreorder 18 | .global test 19 | .ent test 20 | test: 21 | lui $s0, 0xbfff # Load the base address 0xbffffff0 22 | ori $s0, 0xfff0 23 | ori $s1, $0, 1 # Prepare the 'done' status 24 | 25 | #### Test code start #### 26 | 27 | lui $t0, 0xdeaf 28 | ori $t0, $t0, 0xbeef 29 | ori $t2, $0, 0 30 | movz $t2, $t0, $s0 # $t2 remains 0 31 | movz $t1, $t0, $0 # $t1 gets 0xdeafbeef 32 | subu $t3, $t1, $t0 33 | sltiu $v0, $t3, 1 34 | sltiu $v1, $t2, 1 35 | and $v0, $v0, $v1 36 | 37 | #### Test code end #### 38 | 39 | sw $v0, 8($s0) # Set the test result 40 | sw $s1, 4($s0) # Set 'done' 41 | 42 | $done: 43 | jr $ra 44 | nop 45 | 46 | .end test 47 | -------------------------------------------------------------------------------- /crates/mipsevm/open_mips_tests/test/mul.asm: -------------------------------------------------------------------------------- 1 | ############################################################################### 2 | # File : mul.asm 3 | # Project : MIPS32 MUX 4 | # Author: : Grant Ayers (ayers@cs.stanford.edu) 5 | # 6 | # Standards/Formatting: 7 | # MIPS gas, soft tab, 80 column 8 | # 9 | # Description: 10 | # Test the functionality of the 'mul' instruction. 11 | # 12 | ############################################################################### 13 | 14 | 15 | .section .test, "x" 16 | .balign 4 17 | .set noreorder 18 | .global test 19 | .ent test 20 | test: 21 | lui $s0, 0xbfff # Load the base address 0xbffffff0 22 | ori $s0, 0xfff0 23 | ori $s1, $0, 1 # Prepare the 'done' status 24 | 25 | #### Test code start #### 26 | 27 | lui $t0, 0x1234 28 | ori $t0, 0x5678 29 | lui $t1, 0xc001 30 | ori $t1, 0xcafe 31 | mul $t2, $t0, $t1 # 0xb2a07b10 32 | lui $t3, 0xb2a0 33 | ori $t3, 0x7b10 34 | subu $t4, $t2, $t3 35 | sltiu $v0, $t4, 1 36 | 37 | #### Test code end #### 38 | 39 | sw $v0, 8($s0) # Set the test result 40 | sw $s1, 4($s0) # Set 'done' 41 | 42 | $done: 43 | jr $ra 44 | nop 45 | 46 | .end test 47 | -------------------------------------------------------------------------------- /crates/mipsevm/open_mips_tests/test/mult.asm: -------------------------------------------------------------------------------- 1 | ############################################################################### 2 | # File : mult.asm 3 | # Project : MIPS32 MUX 4 | # Author: : Grant Ayers (ayers@cs.stanford.edu) 5 | # 6 | # Standards/Formatting: 7 | # MIPS gas, soft tab, 80 column 8 | # 9 | # Description: 10 | # Test the functionality of the 'mult' instruction. 11 | # 12 | ############################################################################### 13 | 14 | 15 | .section .test, "x" 16 | .balign 4 17 | .set noreorder 18 | .global test 19 | .ent test 20 | test: 21 | lui $s0, 0xbfff # Load the base address 0xbffffff0 22 | ori $s0, 0xfff0 23 | ori $s1, $0, 1 # Prepare the 'done' status 24 | 25 | #### Test code start #### 26 | 27 | lui $t0, 0x1234 28 | ori $t0, 0x5678 29 | lui $t1, 0xc001 30 | ori $t1, 0xcafe 31 | mult $t0, $t1 # 0xfb730b05b2a07b10 32 | mfhi $t2 33 | mflo $t3 34 | lui $t4, 0xfb73 35 | ori $t4, 0x0b05 36 | lui $t5, 0xb2a0 37 | ori $t5, 0x7b10 38 | subu $t6, $t2, $t4 39 | subu $t7, $t3, $t5 40 | sltiu $v0, $t6, 1 41 | sltiu $v1, $t7, 1 42 | and $v0, $v0, $v1 43 | 44 | #### Test code end #### 45 | 46 | sw $v0, 8($s0) # Set the test result 47 | sw $s1, 4($s0) # Set 'done' 48 | 49 | $done: 50 | jr $ra 51 | nop 52 | 53 | .end test 54 | -------------------------------------------------------------------------------- /crates/mipsevm/open_mips_tests/test/multu.asm: -------------------------------------------------------------------------------- 1 | ############################################################################### 2 | # File : multu.asm 3 | # Project : MIPS32 MUX 4 | # Author: : Grant Ayers (ayers@cs.stanford.edu) 5 | # 6 | # Standards/Formatting: 7 | # MIPS gas, soft tab, 80 column 8 | # 9 | # Description: 10 | # Test the functionality of the 'multu' instruction. 11 | # 12 | ############################################################################### 13 | 14 | 15 | .section .test, "x" 16 | .balign 4 17 | .set noreorder 18 | .global test 19 | .ent test 20 | test: 21 | lui $s0, 0xbfff # Load the base address 0xbffffff0 22 | ori $s0, 0xfff0 23 | ori $s1, $0, 1 # Prepare the 'done' status 24 | 25 | #### Test code start #### 26 | 27 | lui $t0, 0x1234 28 | ori $t0, 0x5678 29 | lui $t1, 0xc001 30 | ori $t1, 0xcafe 31 | multu $t0, $t1 # 0x0da7617db2a07b10 32 | mfhi $t2 33 | mflo $t3 34 | lui $t4, 0x0da7 35 | ori $t4, 0x617d 36 | lui $t5, 0xb2a0 37 | ori $t5, 0x7b10 38 | subu $t6, $t2, $t4 39 | subu $t7, $t3, $t5 40 | sltiu $v0, $t6, 1 41 | sltiu $v1, $t7, 1 42 | and $v0, $v0, $v1 43 | 44 | #### Test code end #### 45 | 46 | sw $v0, 8($s0) # Set the test result 47 | sw $s1, 4($s0) # Set 'done' 48 | 49 | $done: 50 | jr $ra 51 | nop 52 | 53 | .end test 54 | -------------------------------------------------------------------------------- /crates/mipsevm/open_mips_tests/test/nor.asm: -------------------------------------------------------------------------------- 1 | ############################################################################### 2 | # File : nor.asm 3 | # Project : MIPS32 MUX 4 | # Author: : Grant Ayers (ayers@cs.stanford.edu) 5 | # 6 | # Standards/Formatting: 7 | # MIPS gas, soft tab, 80 column 8 | # 9 | # Description: 10 | # Test the functionality of the 'nor' instruction. 11 | # 12 | ############################################################################### 13 | 14 | 15 | .section .test, "x" 16 | .balign 4 17 | .set noreorder 18 | .global test 19 | .ent test 20 | test: 21 | lui $s0, 0xbfff # Load the base address 0xbffffff0 22 | ori $s0, 0xfff0 23 | ori $s1, $0, 1 # Prepare the 'done' status 24 | 25 | #### Test code start #### 26 | 27 | lui $t0, 0xdeaf # A = 0xdeafbeef 28 | ori $t0, $t0, 0xbeef 29 | lui $t1, 0x3141 # B = 0x31415926 30 | ori $t1, $t1, 0x5926 31 | lui $t2, 0xffff # C = 0xfffffffe 32 | ori $t2, $t2, 0xfffe 33 | nor $t3, $t0, $t1 # D = nor(A,B) = 0x00100010 34 | nor $v0, $t2, $t3 # E = nor(C,D) = 0x1 35 | 36 | #### Test code end #### 37 | 38 | sw $v0, 8($s0) # Set the test result 39 | sw $s1, 4($s0) # Set 'done' 40 | 41 | $done: 42 | jr $ra 43 | nop 44 | 45 | .end test 46 | -------------------------------------------------------------------------------- /crates/mipsevm/open_mips_tests/test/oracle.asm: -------------------------------------------------------------------------------- 1 | .section .test, "x" 2 | .balign 4 3 | .set noreorder 4 | .global test 5 | .ent test 6 | 7 | # load hash at 0x30001000 8 | # 0x47173285 a8d7341e 5e972fc6 77286384 f802f8ef 42a5ec5f 03bbfa25 4cb01fad = keccak("hello world") 9 | # 0x02173285 a8d7341e 5e972fc6 77286384 f802f8ef 42a5ec5f 03bbfa25 4cb01fad = keccak("hello world").key 10 | test: 11 | lui $s0, 0x3000 12 | ori $s0, 0x1000 13 | 14 | lui $t0, 0x0217 15 | ori $t0, 0x3285 16 | sw $t0, 0($s0) 17 | lui $t0, 0xa8d7 18 | ori $t0, 0x341e 19 | sw $t0, 4($s0) 20 | lui $t0, 0x5e97 21 | ori $t0, 0x2fc6 22 | sw $t0, 8($s0) 23 | lui $t0, 0x7728 24 | ori $t0, 0x6384 25 | sw $t0, 0xc($s0) 26 | lui $t0, 0xf802 27 | ori $t0, 0xf8ef 28 | sw $t0, 0x10($s0) 29 | lui $t0, 0x42a5 30 | ori $t0, 0xec5f 31 | sw $t0, 0x14($s0) 32 | lui $t0, 0x03bb 33 | ori $t0, 0xfa25 34 | sw $t0, 0x18($s0) 35 | lui $t0, 0x4cb0 36 | ori $t0, 0x1fad 37 | sw $t0, 0x1c($s0) 38 | 39 | # preimage request - write(fdPreimageWrite, preimageData, 32) 40 | li $a0, 6 41 | li $a1, 0x30001000 42 | li $t0, 8 43 | li $a2, 4 44 | $writeloop: 45 | li $v0, 4004 46 | syscall 47 | addiu $a1, $a1, 4 48 | addiu $t0, $t0, -1 49 | bnez $t0, $writeloop 50 | nop 51 | 52 | # preimage response to 0x30002000 - read(fdPreimageRead, addr, count) 53 | # read preimage length 54 | li $a0, 5 55 | li $a1, 0x31000000 56 | li $a2, 4 57 | li $v0, 4003 58 | syscall 59 | li $a1, 0x31000004 60 | li $v0, 4003 61 | syscall 62 | # read the preimage data 63 | li $a1, 0x31000008 64 | li $t0, 3 65 | $readloop: 66 | li $v0, 4003 67 | syscall 68 | addiu $a1, $a1, 4 69 | addiu $t0, $t0, -1 70 | bnez $t0, $readloop 71 | nop 72 | # reading the pre-image stream at EOF should have no effect 73 | li $a1, 0x31000008 74 | li $v0, 4003 75 | syscall 76 | 77 | # length at 0x31000000. We also check that the lower 32 bits are zero 78 | lui $s1, 0x3100 79 | lw $t0, 0($s1) 80 | sltiu $t6, $t0, 1 81 | li $s1, 0x31000004 82 | lw $t0, 0($s1) 83 | # should be len("hello world") == 11 84 | li $t4, 11 85 | subu $t5, $t0, $t4 86 | sltiu $v0, $t5, 1 87 | and $v0, $v0, $t6 88 | 89 | # data at 0x31000008 90 | lw $t0, 4($s1) 91 | lui $t4, 0x6865 92 | ori $t4, 0x6c6c 93 | subu $t5, $t0, $t4 94 | sltiu $v1, $t5, 1 95 | 96 | and $v0, $v0, $v1 97 | 98 | # save results 99 | lui $s0, 0xbfff # Load the base address 0xbffffff0 100 | ori $s0, 0xfff0 101 | ori $s1, $0, 1 # Prepare the 'done' status 102 | 103 | sw $v0, 8($s0) # Set the test result 104 | sw $s1, 4($s0) # Set 'done' 105 | 106 | $done: 107 | jr $ra 108 | nop 109 | 110 | .end test 111 | -------------------------------------------------------------------------------- /crates/mipsevm/open_mips_tests/test/oracle_unaligned_read.asm: -------------------------------------------------------------------------------- 1 | .section .test, "x" 2 | .balign 4 3 | .set noreorder 4 | .global test 5 | .ent test 6 | 7 | # load hash at 0x30001000 8 | # 0x47173285 a8d7341e 5e972fc6 77286384 f802f8ef 42a5ec5f 03bbfa25 4cb01fad = keccak("hello world") 9 | # 0x02173285 a8d7341e 5e972fc6 77286384 f802f8ef 42a5ec5f 03bbfa25 4cb01fad = keccak("hello world").key 10 | test: 11 | lui $s0, 0x3000 12 | ori $s0, 0x1000 13 | 14 | lui $t0, 0x0217 15 | ori $t0, 0x3285 16 | sw $t0, 0($s0) 17 | lui $t0, 0xa8d7 18 | ori $t0, 0x341e 19 | sw $t0, 4($s0) 20 | lui $t0, 0x5e97 21 | ori $t0, 0x2fc6 22 | sw $t0, 8($s0) 23 | lui $t0, 0x7728 24 | ori $t0, 0x6384 25 | sw $t0, 0xc($s0) 26 | lui $t0, 0xf802 27 | ori $t0, 0xf8ef 28 | sw $t0, 0x10($s0) 29 | lui $t0, 0x42a5 30 | ori $t0, 0xec5f 31 | sw $t0, 0x14($s0) 32 | lui $t0, 0x03bb 33 | ori $t0, 0xfa25 34 | sw $t0, 0x18($s0) 35 | lui $t0, 0x4cb0 36 | ori $t0, 0x1fad 37 | sw $t0, 0x1c($s0) 38 | 39 | # preimage request - write(fdPreimageWrite, preimageData, 32) 40 | li $a0, 6 41 | li $a1, 0x30001000 42 | li $t0, 8 43 | li $a2, 4 44 | $writeloop: 45 | li $v0, 4004 46 | syscall 47 | addiu $a1, $a1, 4 48 | addiu $t0, $t0, -1 49 | bnez $t0, $writeloop 50 | nop 51 | 52 | # preimage response to 0x30002000 - read(fdPreimageRead, addr, count) 53 | # read preimage length to unaligned addr. This will read only up to the nearest aligned byte so we have to read again. 54 | li $a0, 5 55 | li $a1, 0x31000001 56 | li $a2, 4 57 | li $v0, 4003 58 | syscall 59 | li $a1, 0x31000004 60 | li $v0, 4003 61 | syscall 62 | li $a1, 0x31000008 63 | li $a2, 1 64 | li $v0, 4003 65 | syscall 66 | # read the preimage data 67 | li $a1, 0x31000009 68 | li $t0, 11 69 | $readloop: 70 | li $v0, 4003 71 | li $a2, 4 72 | syscall 73 | addu $a1, $a1, $v0 74 | subu $t0, $t0, $v0 75 | bnez $t0, $readloop 76 | nop 77 | 78 | # length at 0x31000001. We also check that the lower 32 bits are zero 79 | li $s1, 0x31000001 80 | lb $t0, 0($s1) 81 | lb $t2, 1($s1) 82 | sll $t2, $t2, 8 83 | or $t0, $t0, $t2 84 | lb $t2, 2($s1) 85 | sll $t2, $t2, 16 86 | or $t0, $t0, $t2 87 | # assert len[0:3] == 0 88 | sltiu $v0, $t0, 1 89 | 90 | # assert len[4:8] == 0 91 | addiu $s1, $s1, 3 92 | lw $t1, 0($s1) 93 | sltiu $v1, $t1, 1 94 | and $v0, $v0, $v1 95 | 96 | # assert len[8:9] == 11 97 | addiu $s1, $s1, 4 98 | lb $t2, 0($s1) 99 | li $t4, 11 100 | subu $t5, $t2, $t4 101 | sltiu $v1, $t5, 1 102 | and $v0, $v0, $v1 103 | 104 | # data at 0x31000009 105 | addiu $s1, $s1, 1 106 | lb $t0, 0($s1) 107 | lb $t2, 1($s1) 108 | sll $t0, $t0, 8 109 | or $t0, $t0, $t2 110 | lb $t2, 2($s1) 111 | sll $t0, $t0, 8 112 | or $t0, $t0, $t2 113 | lb $t2, 3($s1) 114 | sll $t0, $t0, 8 115 | or $t0, $t0, $t2 116 | 117 | #lw $t0, 0($s1) 118 | lui $t4, 0x6865 119 | ori $t4, 0x6c6c 120 | subu $t5, $t0, $t4 121 | sltiu $v1, $t5, 1 122 | 123 | and $v0, $v0, $v1 124 | 125 | # save results 126 | lui $s0, 0xbfff # Load the base address 0xbffffff0 127 | ori $s0, 0xfff0 128 | ori $s1, $0, 1 # Prepare the 'done' status 129 | 130 | sw $v0, 8($s0) # Set the test result 131 | sw $s1, 4($s0) # Set 'done' 132 | 133 | $done: 134 | jr $ra 135 | nop 136 | 137 | .end test 138 | -------------------------------------------------------------------------------- /crates/mipsevm/open_mips_tests/test/oracle_unaligned_write.asm: -------------------------------------------------------------------------------- 1 | .section .test, "x" 2 | .balign 4 3 | .set noreorder 4 | .global test 5 | .ent test 6 | 7 | # load hash at 0x30001000 8 | # 0x47173285 a8d7341e 5e972fc6 77286384 f802f8ef 42a5ec5f 03bbfa25 4cb01fad = keccak("hello world") 9 | # 0x02173285 a8d7341e 5e972fc6 77286384 f802f8ef 42a5ec5f 03bbfa25 4cb01fad = keccak("hello world").key 10 | test: 11 | lui $s0, 0x3000 12 | ori $s0, 0x1000 13 | 14 | lui $t0, 0x0217 15 | ori $t0, 0x3285 16 | sw $t0, 0($s0) 17 | lui $t0, 0xa8d7 18 | ori $t0, 0x341e 19 | sw $t0, 4($s0) 20 | lui $t0, 0x5e97 21 | ori $t0, 0x2fc6 22 | sw $t0, 8($s0) 23 | lui $t0, 0x7728 24 | ori $t0, 0x6384 25 | sw $t0, 0xc($s0) 26 | lui $t0, 0xf802 27 | ori $t0, 0xf8ef 28 | sw $t0, 0x10($s0) 29 | lui $t0, 0x42a5 30 | ori $t0, 0xec5f 31 | sw $t0, 0x14($s0) 32 | lui $t0, 0x03bb 33 | ori $t0, 0xfa25 34 | sw $t0, 0x18($s0) 35 | lui $t0, 0x4cb0 36 | ori $t0, 0x1fad 37 | sw $t0, 0x1c($s0) 38 | 39 | # preimage request - write(fdPreimageWrite, preimageData, 32) 40 | # create stuffed buffer containing the first byte of the hash - [garbage, hash[0], garbage] 41 | lui $s1, 0x3200 42 | ori $s1, 0x0000 43 | lui $t0, 0xFFFF 44 | ori $t0, 0x02FF 45 | sw $t0, 0($s1) 46 | 47 | # initial unaligned write for stuffed buffer 48 | li $a0, 6 49 | li $a1, 0x32000002 50 | li $a2, 1 51 | li $v0, 4004 52 | syscall 53 | 54 | # write 3 bytes for realignment 55 | li $a0, 6 56 | li $a1, 0x30001001 57 | li $a2, 3 58 | li $v0, 4004 59 | syscall 60 | 61 | li $a0, 6 62 | li $a1, 0x30001004 63 | li $t0, 7 64 | li $a2, 4 65 | $writeloop: 66 | li $v0, 4004 67 | syscall 68 | addiu $a1, $a1, 4 69 | addiu $t0, $t0, -1 70 | bnez $t0, $writeloop 71 | nop 72 | 73 | # preimage response to 0x30002000 - read(fdPreimageRead, addr, count) 74 | # read preimage length 75 | li $a0, 5 76 | li $a1, 0x31000000 77 | li $a2, 4 78 | li $v0, 4003 79 | syscall 80 | li $a1, 0x31000004 81 | li $v0, 4003 82 | syscall 83 | # read the preimage data 84 | li $a1, 0x31000008 85 | li $t0, 3 86 | $readloop: 87 | li $v0, 4003 88 | syscall 89 | addiu $a1, $a1, 4 90 | addiu $t0, $t0, -1 91 | bnez $t0, $readloop 92 | nop 93 | 94 | # length at 0x31000000. We also check that the lower 32 bits are zero 95 | lui $s1, 0x3100 96 | lw $t0, 0($s1) 97 | sltiu $t6, $t0, 1 98 | li $s1, 0x31000004 99 | lw $t0, 0($s1) 100 | # should be len("hello world") == 11 101 | li $t4, 11 102 | subu $t5, $t0, $t4 103 | sltiu $v0, $t5, 1 104 | and $v0, $v0, $t6 105 | 106 | # data at 0x31000008 107 | lw $t0, 4($s1) 108 | lui $t4, 0x6865 109 | ori $t4, 0x6c6c 110 | subu $t5, $t0, $t4 111 | sltiu $v1, $t5, 1 112 | 113 | and $v0, $v0, $v1 114 | 115 | # save results 116 | lui $s0, 0xbfff # Load the base address 0xbffffff0 117 | ori $s0, 0xfff0 118 | ori $s1, $0, 1 # Prepare the 'done' status 119 | 120 | sw $v0, 8($s0) # Set the test result 121 | sw $s1, 4($s0) # Set 'done' 122 | 123 | $done: 124 | jr $ra 125 | nop 126 | 127 | .end test 128 | -------------------------------------------------------------------------------- /crates/mipsevm/open_mips_tests/test/ori.asm: -------------------------------------------------------------------------------- 1 | ############################################################################### 2 | # File : ori.asm 3 | # Project : MIPS32 MUX 4 | # Author: : Grant Ayers (ayers@cs.stanford.edu) 5 | # 6 | # Standards/Formatting: 7 | # MIPS gas, soft tab, 80 column 8 | # 9 | # Description: 10 | # Test the functionality of the 'ori' instruction. 11 | # 12 | ############################################################################### 13 | 14 | 15 | .section .test, "x" 16 | .balign 4 17 | .set noreorder 18 | .global test 19 | .ent test 20 | test: 21 | lui $s0, 0xbfff # Load the base address 0xbffffff0 22 | ori $s0, 0xfff0 23 | ori $s1, $0, 1 # Prepare the 'done' status 24 | 25 | #### Test code start #### 26 | 27 | ori $v0, $s1, 0 28 | 29 | #### Test code end #### 30 | 31 | sw $v0, 8($s0) # Set the test result 32 | sw $s1, 4($s0) # Set 'done' 33 | 34 | $done: 35 | jr $ra 36 | nop 37 | 38 | .end test 39 | -------------------------------------------------------------------------------- /crates/mipsevm/open_mips_tests/test/sb.asm: -------------------------------------------------------------------------------- 1 | ############################################################################### 2 | # File : sb.asm 3 | # Project : MIPS32 MUX 4 | # Author: : Grant Ayers (ayers@cs.stanford.edu) 5 | # 6 | # Standards/Formatting: 7 | # MIPS gas, soft tab, 80 column 8 | # 9 | # Description: 10 | # Test the functionality of the 'sb' instruction. 11 | # 12 | ############################################################################### 13 | 14 | 15 | .section .test, "x" 16 | .balign 4 17 | .set noreorder 18 | .global test 19 | .ent test 20 | test: 21 | lui $s0, 0xbfff # Load the base address 0xbffffff0 22 | ori $s0, 0xfff0 23 | ori $s1, $0, 1 # Prepare the 'done' status 24 | 25 | #### Test code start #### 26 | 27 | lui $t0, 0xbfc0 # Load address 0xbfc007fc (last word in 2KB starting 28 | ori $t0, 0x07fc # from 0xbfc00000) 29 | sw $0, 0($t0) 30 | ori $t1, $0, 0xc0 31 | ori $t2, $0, 0x01 32 | ori $t3, $0, 0xca 33 | ori $t4, $0, 0xfe 34 | sb $t1, 0($t0) 35 | sb $t2, 1($t0) 36 | sb $t3, 2($t0) 37 | sb $t4, 3($t0) 38 | lw $t5, 0($t0) 39 | .ifdef big_endian 40 | lui $t6, 0xc001 41 | ori $t6, 0xcafe 42 | .else 43 | lui $t6, 0xfeca 44 | ori $t6, 0x01c0 45 | .endif 46 | subu $t7, $t5, $t6 47 | sltiu $v0, $t7, 1 48 | 49 | #### Test code end #### 50 | 51 | sw $v0, 8($s0) # Set the test result 52 | sw $s1, 4($s0) # Set 'done' 53 | 54 | $done: 55 | jr $ra 56 | nop 57 | 58 | .end test 59 | -------------------------------------------------------------------------------- /crates/mipsevm/open_mips_tests/test/sh.asm: -------------------------------------------------------------------------------- 1 | ############################################################################### 2 | # File : sh.asm 3 | # Project : MIPS32 MUX 4 | # Author: : Grant Ayers (ayers@cs.stanford.edu) 5 | # 6 | # Standards/Formatting: 7 | # MIPS gas, soft tab, 80 column 8 | # 9 | # Description: 10 | # Test the functionality of the 'sh' instruction. 11 | # 12 | ############################################################################### 13 | 14 | 15 | .section .test, "x" 16 | .balign 4 17 | .set noreorder 18 | .global test 19 | .ent test 20 | test: 21 | lui $s0, 0xbfff # Load the base address 0xbffffff0 22 | ori $s0, 0xfff0 23 | ori $s1, $0, 1 # Prepare the 'done' status 24 | 25 | #### Test code start #### 26 | 27 | lui $t0, 0xbfc0 # Load address 0xbfc007fc (last word in 2KB starting 28 | ori $t0, 0x07fc # from 0xbfc00000) 29 | sw $0, 0($t0) 30 | ori $t1, $0, 0xc001 31 | ori $t2, $0, 0xcafe 32 | sh $t1, 0($t0) 33 | sh $t2, 2($t0) 34 | lw $t3, 0($t0) 35 | .ifdef big_endian 36 | lui $t4, 0xc001 37 | ori $t4, 0xcafe 38 | .else 39 | lui $t4, 0xcafe 40 | ori $t4, 0xc001 41 | .endif 42 | subu $t5, $t3, $t4 43 | sltiu $v0, $t5, 1 44 | 45 | #### Test code end #### 46 | 47 | sw $v0, 8($s0) # Set the test result 48 | sw $s1, 4($s0) # Set 'done' 49 | 50 | $done: 51 | jr $ra 52 | nop 53 | 54 | .end test 55 | -------------------------------------------------------------------------------- /crates/mipsevm/open_mips_tests/test/sll.asm: -------------------------------------------------------------------------------- 1 | ############################################################################### 2 | # File : sll.asm 3 | # Project : MIPS32 MUX 4 | # Author: : Grant Ayers (ayers@cs.stanford.edu) 5 | # 6 | # Standards/Formatting: 7 | # MIPS gas, soft tab, 80 column 8 | # 9 | # Description: 10 | # Test the functionality of the 'sll' instruction. 11 | # 12 | ############################################################################### 13 | 14 | 15 | .section .test, "x" 16 | .balign 4 17 | .set noreorder 18 | .global test 19 | .ent test 20 | test: 21 | lui $s0, 0xbfff # Load the base address 0xbffffff0 22 | ori $s0, 0xfff0 23 | ori $s1, $0, 1 # Prepare the 'done' status 24 | 25 | #### Test code start #### 26 | 27 | lui $t0, 0xdeaf # A = 0xdeafbeef 28 | ori $t0, 0xbeef 29 | sll $t1, $t0, 4 # B = 0xdeafbeef << 4 = 0xeafbeef0 30 | lui $t2, 0xeafb # C = 0xeafbeef0 31 | ori $t2, 0xeef0 32 | subu $t3, $t1, $t2 33 | sltiu $v0, $t3, 1 34 | 35 | #### Test code end #### 36 | 37 | sw $v0, 8($s0) # Set the test result 38 | sw $s1, 4($s0) # Set 'done' 39 | 40 | $done: 41 | jr $ra 42 | nop 43 | 44 | .end test 45 | -------------------------------------------------------------------------------- /crates/mipsevm/open_mips_tests/test/sllv.asm: -------------------------------------------------------------------------------- 1 | ############################################################################### 2 | # File : sllv.asm 3 | # Project : MIPS32 MUX 4 | # Author: : Grant Ayers (ayers@cs.stanford.edu) 5 | # 6 | # Standards/Formatting: 7 | # MIPS gas, soft tab, 80 column 8 | # 9 | # Description: 10 | # Test the functionality of the 'sllv' instruction. 11 | # 12 | ############################################################################### 13 | 14 | 15 | .section .test, "x" 16 | .balign 4 17 | .set noreorder 18 | .global test 19 | .ent test 20 | test: 21 | lui $s0, 0xbfff # Load the base address 0xbffffff0 22 | ori $s0, 0xfff0 23 | ori $s1, $0, 1 # Prepare the 'done' status 24 | 25 | #### Test code start #### 26 | 27 | lui $t0, 0xdeaf # A = 0xdeafbeef 28 | ori $t0, 0xbeef 29 | ori $t1, $0, 12 30 | sllv $t2, $t0, $t1 # B = 0xdeafbeef << 12 = 0xfbeef000 31 | lui $t3, 0xfbee 32 | ori $t3, 0xf000 33 | subu $t4, $t2, $t3 34 | sltiu $v0, $t4, 1 35 | 36 | #### Test code end #### 37 | 38 | sw $v0, 8($s0) # Set the test result 39 | sw $s1, 4($s0) # Set 'done' 40 | 41 | $done: 42 | jr $ra 43 | nop 44 | 45 | .end test 46 | -------------------------------------------------------------------------------- /crates/mipsevm/open_mips_tests/test/slt.asm: -------------------------------------------------------------------------------- 1 | ############################################################################### 2 | # File : slt.asm 3 | # Project : MIPS32 MUX 4 | # Author: : Grant Ayers (ayers@cs.stanford.edu) 5 | # 6 | # Standards/Formatting: 7 | # MIPS gas, soft tab, 80 column 8 | # 9 | # Description: 10 | # Test the functionality of the 'slt' instruction. 11 | # 12 | ############################################################################### 13 | 14 | 15 | .section .test, "x" 16 | .balign 4 17 | .set noreorder 18 | .global test 19 | .ent test 20 | test: 21 | lui $s0, 0xbfff # Load the base address 0xbffffff0 22 | ori $s0, 0xfff0 23 | ori $s1, $0, 1 # Prepare the 'done' status 24 | 25 | #### Test code start #### 26 | 27 | lui $t0, 0xffff 28 | ori $t0, 0xffff 29 | slt $v0, $t0, $s1 30 | 31 | #### Test code end #### 32 | 33 | sw $v0, 8($s0) # Set the test result 34 | sw $s1, 4($s0) # Set 'done' 35 | 36 | $done: 37 | jr $ra 38 | nop 39 | 40 | .end test 41 | -------------------------------------------------------------------------------- /crates/mipsevm/open_mips_tests/test/slti.asm: -------------------------------------------------------------------------------- 1 | ############################################################################### 2 | # File : slti.asm 3 | # Project : MIPS32 MUX 4 | # Author: : Grant Ayers (ayers@cs.stanford.edu) 5 | # 6 | # Standards/Formatting: 7 | # MIPS gas, soft tab, 80 column 8 | # 9 | # Description: 10 | # Test the functionality of the 'slti' instruction. 11 | # 12 | ############################################################################### 13 | 14 | 15 | .section .test, "x" 16 | .balign 4 17 | .set noreorder 18 | .global test 19 | .ent test 20 | test: 21 | lui $s0, 0xbfff # Load the base address 0xbffffff0 22 | ori $s0, 0xfff0 23 | ori $s1, $0, 1 # Prepare the 'done' status 24 | 25 | #### Test code start #### 26 | 27 | lui $t0, 0x8000 28 | slti $v0, $t0, 0xffff 29 | slti $v1, $t0, 0 30 | and $v0, $v0, $v1 31 | 32 | #### Test code end #### 33 | 34 | sw $v0, 8($s0) # Set the test result 35 | sw $s1, 4($s0) # Set 'done' 36 | 37 | $done: 38 | jr $ra 39 | nop 40 | 41 | .end test 42 | -------------------------------------------------------------------------------- /crates/mipsevm/open_mips_tests/test/sltiu.asm: -------------------------------------------------------------------------------- 1 | ############################################################################### 2 | # File : sltiu.asm 3 | # Project : MIPS32 MUX 4 | # Author: : Grant Ayers (ayers@cs.stanford.edu) 5 | # 6 | # Standards/Formatting: 7 | # MIPS gas, soft tab, 80 column 8 | # 9 | # Description: 10 | # Test the functionality of the 'sltiu' instruction. 11 | # 12 | ############################################################################### 13 | 14 | 15 | .section .test, "x" 16 | .balign 4 17 | .set noreorder 18 | .global test 19 | .ent test 20 | test: 21 | lui $s0, 0xbfff # Load the base address 0xbffffff0 22 | ori $s0, 0xfff0 23 | ori $s1, $0, 1 # Prepare the 'done' status 24 | 25 | #### Test code start #### 26 | 27 | lui $t0, 0x8000 28 | sltiu $v0, $t0, 0xffff 29 | sltiu $v1, $0, 0xffff 30 | and $v0, $v0, $v1 31 | 32 | #### Test code end #### 33 | 34 | sw $v0, 8($s0) # Set the test result 35 | sw $s1, 4($s0) # Set 'done' 36 | 37 | $done: 38 | jr $ra 39 | nop 40 | 41 | .end test 42 | -------------------------------------------------------------------------------- /crates/mipsevm/open_mips_tests/test/sltu.asm: -------------------------------------------------------------------------------- 1 | ############################################################################### 2 | # File : sltu.asm 3 | # Project : MIPS32 MUX 4 | # Author: : Grant Ayers (ayers@cs.stanford.edu) 5 | # 6 | # Standards/Formatting: 7 | # MIPS gas, soft tab, 80 column 8 | # 9 | # Description: 10 | # Test the functionality of the 'sltu' instruction. 11 | # 12 | ############################################################################### 13 | 14 | 15 | .section .test, "x" 16 | .balign 4 17 | .set noreorder 18 | .global test 19 | .ent test 20 | test: 21 | lui $s0, 0xbfff # Load the base address 0xbffffff0 22 | ori $s0, 0xfff0 23 | ori $s1, $0, 1 # Prepare the 'done' status 24 | 25 | #### Test code start #### 26 | 27 | lui $t0, 0xffff 28 | ori $t0, 0xffff 29 | sltu $v0, $s1, $t0 30 | 31 | #### Test code end #### 32 | 33 | sw $v0, 8($s0) # Set the test result 34 | sw $s1, 4($s0) # Set 'done' 35 | 36 | $done: 37 | jr $ra 38 | nop 39 | 40 | .end test 41 | -------------------------------------------------------------------------------- /crates/mipsevm/open_mips_tests/test/sra.asm: -------------------------------------------------------------------------------- 1 | ############################################################################### 2 | # File : sra.asm 3 | # Project : MIPS32 MUX 4 | # Author: : Grant Ayers (ayers@cs.stanford.edu) 5 | # 6 | # Standards/Formatting: 7 | # MIPS gas, soft tab, 80 column 8 | # 9 | # Description: 10 | # Test the functionality of the 'sra' instruction. 11 | # 12 | ############################################################################### 13 | 14 | 15 | .section .test, "x" 16 | .balign 4 17 | .set noreorder 18 | .global test 19 | .ent test 20 | test: 21 | lui $s0, 0xbfff # Load the base address 0xbffffff0 22 | ori $s0, 0xfff0 23 | ori $s1, $0, 1 # Prepare the 'done' status 24 | 25 | #### Test code start #### 26 | 27 | lui $t0, 0xdeaf # A = 0xdeafbeef 28 | ori $t0, 0xbeef 29 | sra $t1, $t0, 4 # B = 0xdeafbeef >> 4 = 0xfdeafbee 30 | lui $t2, 0xfdea # C = 0xfdeafbee 31 | ori $t2, 0xfbee 32 | subu $t3, $t1, $t2 # D = B - C = 0 33 | sltiu $v0, $t3, 1 34 | 35 | #### Test code end #### 36 | 37 | sw $v0, 8($s0) # Set the test result 38 | sw $s1, 4($s0) # Set 'done' 39 | 40 | $done: 41 | jr $ra 42 | nop 43 | 44 | .end test 45 | -------------------------------------------------------------------------------- /crates/mipsevm/open_mips_tests/test/srav.asm: -------------------------------------------------------------------------------- 1 | ############################################################################### 2 | # File : srav.asm 3 | # Project : MIPS32 MUX 4 | # Author: : Grant Ayers (ayers@cs.stanford.edu) 5 | # 6 | # Standards/Formatting: 7 | # MIPS gas, soft tab, 80 column 8 | # 9 | # Description: 10 | # Test the functionality of the 'srav' instruction. 11 | # 12 | ############################################################################### 13 | 14 | 15 | .section .test, "x" 16 | .balign 4 17 | .set noreorder 18 | .global test 19 | .ent test 20 | test: 21 | lui $s0, 0xbfff # Load the base address 0xbffffff0 22 | ori $s0, 0xfff0 23 | ori $s1, $0, 1 # Prepare the 'done' status 24 | 25 | #### Test code start #### 26 | 27 | lui $t0, 0xdeaf # A = 0xdeafbeef 28 | ori $t0, 0xbeef 29 | ori $t1, $0, 12 30 | srav $t2, $t0, $t1 # B = 0xdeafbeef >> 12 = 0xfffdeafb 31 | lui $t3, 0xfffd 32 | ori $t3, 0xeafb 33 | subu $t4, $t2, $t3 34 | sltiu $v0, $t4, 1 35 | 36 | #### Test code end #### 37 | 38 | sw $v0, 8($s0) # Set the test result 39 | sw $s1, 4($s0) # Set 'done' 40 | 41 | $done: 42 | jr $ra 43 | nop 44 | 45 | .end test 46 | -------------------------------------------------------------------------------- /crates/mipsevm/open_mips_tests/test/srl.asm: -------------------------------------------------------------------------------- 1 | ############################################################################### 2 | # File : srl.asm 3 | # Project : MIPS32 MUX 4 | # Author: : Grant Ayers (ayers@cs.stanford.edu) 5 | # 6 | # Standards/Formatting: 7 | # MIPS gas, soft tab, 80 column 8 | # 9 | # Description: 10 | # Test the functionality of the 'srl' instruction. 11 | # 12 | ############################################################################### 13 | 14 | 15 | .section .test, "x" 16 | .balign 4 17 | .set noreorder 18 | .global test 19 | .ent test 20 | test: 21 | lui $s0, 0xbfff # Load the base address 0xbffffff0 22 | ori $s0, 0xfff0 23 | ori $s1, $0, 1 # Prepare the 'done' status 24 | 25 | #### Test code start #### 26 | 27 | lui $t0, 0xdeaf # A = 0xdeafbeef 28 | ori $t0, 0xbeef 29 | srl $t1, $t0, 4 # B = 0xdeafbeef >> 4 = 0x0deafbee 30 | lui $t2, 0x0dea 31 | ori $t2, 0xfbee 32 | subu $t3, $t1, $t2 # D = B - C = 0 33 | sltiu $v0, $t3, 1 34 | 35 | #### Test code end #### 36 | 37 | sw $v0, 8($s0) # Set the test result 38 | sw $s1, 4($s0) # Set 'done' 39 | 40 | $done: 41 | jr $ra 42 | nop 43 | 44 | .end test 45 | -------------------------------------------------------------------------------- /crates/mipsevm/open_mips_tests/test/srlv.asm: -------------------------------------------------------------------------------- 1 | ############################################################################### 2 | # File : srlv.asm 3 | # Project : MIPS32 MUX 4 | # Author: : Grant Ayers (ayers@cs.stanford.edu) 5 | # 6 | # Standards/Formatting: 7 | # MIPS gas, soft tab, 80 column 8 | # 9 | # Description: 10 | # Test the functionality of the 'srlv' instruction. 11 | # 12 | ############################################################################### 13 | 14 | 15 | .section .test, "x" 16 | .balign 4 17 | .set noreorder 18 | .global test 19 | .ent test 20 | test: 21 | lui $s0, 0xbfff # Load the base address 0xbffffff0 22 | ori $s0, 0xfff0 23 | ori $s1, $0, 1 # Prepare the 'done' status 24 | 25 | #### Test code start #### 26 | 27 | lui $t0, 0xdeaf # A = 0xdeafbeef 28 | ori $t0, 0xbeef 29 | ori $t1, $0, 12 30 | srlv $t2, $t0, $t1 # B = 0xdeafbeef >> 12 = 0x000deafb 31 | lui $t3, 0x000d 32 | ori $t3, 0xeafb 33 | subu $t4, $t2, $t3 34 | sltiu $v0, $t4, 1 35 | 36 | #### Test code end #### 37 | 38 | sw $v0, 8($s0) # Set the test result 39 | sw $s1, 4($s0) # Set 'done' 40 | 41 | $done: 42 | jr $ra 43 | nop 44 | 45 | .end test 46 | -------------------------------------------------------------------------------- /crates/mipsevm/open_mips_tests/test/sub.asm: -------------------------------------------------------------------------------- 1 | ############################################################################### 2 | # File : sub.asm 3 | # Project : MIPS32 MUX 4 | # Author: : Grant Ayers (ayers@cs.stanford.edu) 5 | # 6 | # Standards/Formatting: 7 | # MIPS gas, soft tab, 80 column 8 | # 9 | # Description: 10 | # Test the functionality of the 'sub' instruction. 11 | # 12 | ############################################################################### 13 | 14 | 15 | .section .test, "x" 16 | .balign 4 17 | .set noreorder 18 | .global test 19 | .ent test 20 | test: 21 | lui $s0, 0xbfff # Load the base address 0xbffffff0 22 | ori $s0, 0xfff0 23 | ori $s1, $0, 1 # Prepare the 'done' status 24 | 25 | #### Test code start #### 26 | 27 | lui $t0, 0xffff # A = 0xfffffffd (-3) 28 | ori $t0, 0xfffd 29 | sub $t1, $t0, $t0 # B = A - A = 0 30 | sub $t2, $t1, $t0 # C = B - A = 0 - A = 3 31 | ori $t3, $0, 3 # D = 2 32 | sub $t4, $t2, $t3 # E = C - D = C - 2 = 0 33 | sltiu $v0, $t4, 1 34 | 35 | #### Test code end #### 36 | 37 | sw $v0, 8($s0) # Set the test result 38 | sw $s1, 4($s0) # Set 'done' 39 | 40 | $done: 41 | jr $ra 42 | nop 43 | 44 | .end test 45 | -------------------------------------------------------------------------------- /crates/mipsevm/open_mips_tests/test/subu.asm: -------------------------------------------------------------------------------- 1 | ############################################################################### 2 | # File : subu.asm 3 | # Project : MIPS32 MUX 4 | # Author: : Grant Ayers (ayers@cs.stanford.edu) 5 | # 6 | # Standards/Formatting: 7 | # MIPS gas, soft tab, 80 column 8 | # 9 | # Description: 10 | # Test the functionality of the 'subu' instruction. 11 | # 12 | ############################################################################### 13 | 14 | 15 | .section .test, "x" 16 | .balign 4 17 | .set noreorder 18 | .global test 19 | .ent test 20 | test: 21 | lui $s0, 0xbfff # Load the base address 0xbffffff0 22 | ori $s0, 0xfff0 23 | ori $s1, $0, 1 # Prepare the 'done' status 24 | 25 | #### Test code start #### 26 | 27 | lui $t0, 0xffff # A = 0xfffffffd (-3) 28 | ori $t0, 0xfffd 29 | ori $t1, $0, 4 # B = 4 30 | subu $t2, $t0, $t1 # C = A - B = 0xfffffff9 (-7) 31 | lui $t3, 0xffff # D = 0xfffffff8 (like -8 mod 2^32) 32 | ori $t3, 0xfff8 33 | subu $t4, $t2, $t3 # F = C - D = 1 34 | subu $t5, $t4, $s1 # G = F - 1 = 0 35 | sltiu $v0, $t5, 1 36 | 37 | #### Test code end #### 38 | 39 | sw $v0, 8($s0) # Set the test result 40 | sw $s1, 4($s0) # Set 'done' 41 | 42 | $done: 43 | jr $ra 44 | nop 45 | 46 | .end test 47 | -------------------------------------------------------------------------------- /crates/mipsevm/open_mips_tests/test/swl.asm: -------------------------------------------------------------------------------- 1 | ############################################################################### 2 | # File : swl.asm 3 | # Project : MIPS32 MUX 4 | # Author: : Grant Ayers (ayers@cs.stanford.edu) 5 | # 6 | # Standards/Formatting: 7 | # MIPS gas, soft tab, 80 column 8 | # 9 | # Description: 10 | # Test the functionality of the 'swl' instruction. 11 | # 12 | ############################################################################### 13 | 14 | 15 | .section .test, "x" 16 | .balign 4 17 | .set noreorder 18 | .global test 19 | .ent test 20 | test: 21 | lui $s0, 0xbfff # Load the base address 0xbffffff0 22 | ori $s0, 0xfff0 23 | ori $s1, $0, 1 # Prepare the 'done' status 24 | 25 | #### Test code start #### 26 | 27 | lui $t0, 0xbfc0 # Load address 0xbfc007ec (last four words in 2KB starting 28 | ori $t0, 0x07ec # from 0xbfc00000) 29 | lui $t1, 0xc001 # Memory word is 0xc001cafe 30 | ori $t1, 0xcafe 31 | sw $t1, 0($t0) 32 | sw $t1, 4($t0) 33 | sw $t1, 8($t0) 34 | sw $t1, 12($t0) 35 | lui $t2, 0xdeaf # Register word is 0xdeafbeef 36 | ori $t2, 0xbeef 37 | swl $t2, 0($t0) 38 | swl $t2, 5($t0) 39 | swl $t2, 10($t0) 40 | swl $t2, 15($t0) 41 | lw $s2, 0($t0) 42 | lw $s3, 4($t0) 43 | lw $s4, 8($t0) 44 | lw $s5, 12($t0) 45 | .ifdef big_endian 46 | lui $t3, 0xdeaf # 0xdeafbeef 47 | ori $t3, 0xbeef 48 | lui $t4, 0xc0de # 0xc0deafbe 49 | ori $t4, 0xafbe 50 | lui $t5, 0xc001 # 0xc001deaf 51 | ori $t5, 0xdeaf 52 | lui $t6, 0xc001 # 0xc001cade 53 | ori $t6, 0xcade 54 | .else 55 | lui $t3, 0xc001 # 0xc001cade 56 | ori $t3, 0xcade 57 | lui $t4, 0xc001 # 0xc001deaf 58 | ori $t4, 0xdeaf 59 | lui $t5, 0xc0de # 0xc0deafbe 60 | ori $t5, 0xafbe 61 | lui $t6, 0xdeaf # 0xdeafbeef 62 | ori $t6, 0xbeef 63 | .endif 64 | subu $t7, $s2, $t3 65 | sltiu $v0, $t7, 1 66 | subu $t7, $s3, $t4 67 | sltiu $v1, $t7, 1 68 | and $v0, $v0, $v1 69 | subu $t7, $s4, $t5 70 | sltiu $v1, $t7, 1 71 | and $v0, $v0, $v1 72 | subu $t7, $s5, $t6 73 | sltiu $v1, $t7, 1 74 | and $v0, $v0, $v1 75 | 76 | #### Test code end #### 77 | 78 | sw $v0, 8($s0) # Set the test result 79 | sw $s1, 4($s0) # Set 'done' 80 | 81 | $done: 82 | jr $ra 83 | nop 84 | 85 | .end test 86 | -------------------------------------------------------------------------------- /crates/mipsevm/open_mips_tests/test/swr.asm: -------------------------------------------------------------------------------- 1 | ############################################################################### 2 | # File : swr.asm 3 | # Project : MIPS32 MUX 4 | # Author: : Grant Ayers (ayers@cs.stanford.edu) 5 | # 6 | # Standards/Formatting: 7 | # MIPS gas, soft tab, 80 column 8 | # 9 | # Description: 10 | # Test the functionality of the 'swr' instruction. 11 | # 12 | ############################################################################### 13 | 14 | 15 | .section .test, "x" 16 | .balign 4 17 | .set noreorder 18 | .global test 19 | .ent test 20 | test: 21 | lui $s0, 0xbfff # Load the base address 0xbffffff0 22 | ori $s0, 0xfff0 23 | ori $s1, $0, 1 # Prepare the 'done' status 24 | 25 | #### Test code start #### 26 | 27 | lui $t0, 0xbfc0 # Load address 0xbfc007ec (last four words in 2KB starting 28 | ori $t0, 0x07ec # from 0xbfc00000) 29 | lui $t1, 0xc001 # Memory words are 0xc001cafe 30 | ori $t1, 0xcafe 31 | sw $t1, 0($t0) 32 | sw $t1, 4($t0) 33 | sw $t1, 8($t0) 34 | sw $t1, 12($t0) 35 | lui $t2, 0xdeaf # Register word is 0xdeafbeef 36 | ori $t2, 0xbeef 37 | swr $t2, 0($t0) 38 | swr $t2, 5($t0) 39 | swr $t2, 10($t0) 40 | swr $t2, 15($t0) 41 | lw $s2, 0($t0) 42 | lw $s3, 4($t0) 43 | lw $s4, 8($t0) 44 | lw $s5, 12($t0) 45 | .ifdef big_endian 46 | lui $t3, 0xef01 # 0xef01cafe 47 | ori $t3, 0xcafe 48 | lui $t4, 0xbeef # 0xbeefcafe 49 | ori $t4, 0xcafe 50 | lui $t5, 0xafbe # 0xafbeeffe 51 | ori $t5, 0xeffe 52 | lui $t6, 0xdeaf # 0xdeafbeef 53 | ori $t6, 0xbeef 54 | .else 55 | lui $t3, 0xdeaf # 0xdeafbeef 56 | ori $t3, 0xbeef 57 | lui $t4, 0xafbe # 0xafbeeffe 58 | ori $t4, 0xeffe 59 | lui $t5, 0xbeef # 0xbeefcafe 60 | ori $t5, 0xcafe 61 | lui $t6, 0xef01 # 0xef01cafe 62 | ori $t6, 0xcafe 63 | .endif 64 | subu $t7, $s2, $t3 65 | sltiu $v0, $t7, 1 66 | subu $t7, $s3, $t4 67 | sltiu $v1, $t7, 1 68 | and $v0, $v0, $v1 69 | subu $t7, $s4, $t5 70 | sltiu $v1, $t7, 1 71 | and $v0, $v0, $v1 72 | subu $t7, $s5, $t6 73 | sltiu $v1, $t7, 1 74 | and $v0, $v0, $v1 75 | 76 | #### Test code end #### 77 | 78 | sw $v0, 8($s0) # Set the test result 79 | sw $s1, 4($s0) # Set 'done' 80 | 81 | $done: 82 | jr $ra 83 | nop 84 | 85 | .end test 86 | -------------------------------------------------------------------------------- /crates/mipsevm/open_mips_tests/test/xor.asm: -------------------------------------------------------------------------------- 1 | ############################################################################### 2 | # File : xor.asm 3 | # Project : MIPS32 MUX 4 | # Author: : Grant Ayers (ayers@cs.stanford.edu) 5 | # 6 | # Standards/Formatting: 7 | # MIPS gas, soft tab, 80 column 8 | # 9 | # Description: 10 | # Test the functionality of the 'xor' instruction. 11 | # 12 | ############################################################################### 13 | 14 | 15 | .section .test, "x" 16 | .balign 4 17 | .set noreorder 18 | .global test 19 | .ent test 20 | test: 21 | lui $s0, 0xbfff # Load the base address 0xbffffff0 22 | ori $s0, 0xfff0 23 | ori $s1, $0, 1 # Prepare the 'done' status 24 | 25 | #### Test code start #### 26 | 27 | lui $t0, 0xdeaf # A = 0xdeafbeef 28 | ori $t0, 0xbeef 29 | lui $t1, 0x3141 # B = 0x31415926 30 | ori $t1, 0x5926 31 | lui $t2, 0xefee # C = 0xefeee7c8 32 | ori $t2, 0xe7c8 33 | xor $t3, $t0, $t1 # D = xor(A,B) = 0xefeee7c8 34 | xor $t4, $t2, $t3 # E = xor(C,D) = 0x1 35 | xor $t5, $t4, $s1 # F = xor(E,1) = 0 36 | sltiu $v0, $t5, 1 37 | 38 | #### Test code end #### 39 | 40 | sw $v0, 8($s0) # Set the test result 41 | sw $s1, 4($s0) # Set 'done' 42 | 43 | $done: 44 | jr $ra 45 | nop 46 | 47 | .end test 48 | -------------------------------------------------------------------------------- /crates/mipsevm/open_mips_tests/test/xori.asm: -------------------------------------------------------------------------------- 1 | ############################################################################### 2 | # File : xori.asm 3 | # Project : MIPS32 MUX 4 | # Author: : Grant Ayers (ayers@cs.stanford.edu) 5 | # 6 | # Standards/Formatting: 7 | # MIPS gas, soft tab, 80 column 8 | # 9 | # Description: 10 | # Test the functionality of the 'xori' instruction. 11 | # 12 | ############################################################################### 13 | 14 | 15 | .section .test, "x" 16 | .balign 4 17 | .set noreorder 18 | .global test 19 | .ent test 20 | test: 21 | lui $s0, 0xbfff # Load the base address 0xbffffff0 22 | ori $s0, 0xfff0 23 | ori $s1, $0, 1 # Prepare the 'done' status 24 | 25 | #### Test code start #### 26 | 27 | ori $t0, $0, 0xdeaf # A = 0xdeaf 28 | xori $t1, $t0, 0x3141 # B = xor(A, 0x3141) = 0xefee 29 | xori $t2, $t1, 0xefef # C = xor(B, 0xefef) = 0x1 30 | xori $t3, $t2, 1 # D = xor(C, 1) = 0 31 | sltiu $v0, $t3, 1 32 | 33 | #### Test code end #### 34 | 35 | sw $v0, 8($s0) # Set the test result 36 | sw $s1, 4($s0) # Set 'done' 37 | 38 | $done: 39 | jr $ra 40 | nop 41 | 42 | .end test 43 | -------------------------------------------------------------------------------- /crates/mipsevm/src/lib.rs: -------------------------------------------------------------------------------- 1 | // #![doc = include_str!("../README.md")] 2 | #![feature(generic_const_exprs)] 3 | #![allow(incomplete_features)] 4 | 5 | pub(crate) mod traces; 6 | 7 | mod memory; 8 | pub use self::memory::Memory; 9 | 10 | mod page; 11 | pub use self::page::CachedPage; 12 | 13 | mod state; 14 | pub use self::state::State; 15 | 16 | mod traits; 17 | pub use self::traits::{PreimageOracle, StateWitnessHasher}; 18 | 19 | mod witness; 20 | pub use witness::{StepWitness, STATE_WITNESS_SIZE}; 21 | 22 | mod utils; 23 | 24 | mod types; 25 | pub use types::{Address, Fd, Gindex, Page, PageIndex, StateWitness, VMStatus}; 26 | 27 | mod mips; 28 | pub use mips::InstrumentedState; 29 | 30 | mod patch; 31 | pub use patch::{load_elf, patch_go, patch_stack, MultiReader}; 32 | 33 | pub mod ser; 34 | 35 | pub mod test_utils; 36 | -------------------------------------------------------------------------------- /crates/mipsevm/src/mips/mod.rs: -------------------------------------------------------------------------------- 1 | //! The MIPS module contains the implementation of the [InstrumentedState] and the MIPS emulator. 2 | 3 | mod instrumented; 4 | pub use self::instrumented::InstrumentedState; 5 | 6 | mod mips_vm; 7 | -------------------------------------------------------------------------------- /crates/mipsevm/src/ser.rs: -------------------------------------------------------------------------------- 1 | //! Serialization utilities for the `cannon-mipsevm` crate. 2 | 3 | /// Generates a hex string serialization module for a fixed-size byte array. 4 | macro_rules! fixed_hex_ser { 5 | ($module_name:ident, $size:expr) => { 6 | pub mod $module_name { 7 | use alloy_primitives::hex; 8 | use serde::{self, Deserialize, Deserializer, Serializer}; 9 | 10 | pub fn serialize(bytes: &[u8; $size], serializer: S) -> Result 11 | where 12 | S: Serializer, 13 | { 14 | serializer.serialize_str(&format!("0x{}", hex::encode(bytes))) 15 | } 16 | 17 | pub fn deserialize<'de, D>(deserializer: D) -> Result<[u8; $size], D::Error> 18 | where 19 | D: Deserializer<'de>, 20 | { 21 | let s = String::deserialize(deserializer)?; 22 | hex::decode(s) 23 | .map_err(serde::de::Error::custom) 24 | .map(|bytes| { 25 | let mut array = [0u8; $size]; 26 | array.copy_from_slice(&bytes); 27 | array 28 | }) 29 | } 30 | } 31 | }; 32 | } 33 | 34 | fixed_hex_ser!(fixed_32_hex, 32); 35 | fixed_hex_ser!(page_hex, crate::page::PAGE_SIZE); 36 | fixed_hex_ser!(state_witness_hex, crate::witness::STATE_WITNESS_SIZE); 37 | 38 | pub mod vec_u8_hex { 39 | use alloy_primitives::hex; 40 | use serde::{self, Deserialize, Deserializer, Serializer}; 41 | 42 | pub fn serialize(bytes: &Vec, serializer: S) -> Result 43 | where 44 | S: Serializer, 45 | { 46 | serializer.serialize_str(&format!("0x{}", hex::encode(bytes))) 47 | } 48 | 49 | pub fn deserialize<'de, D>(deserializer: D) -> Result, D::Error> 50 | where 51 | D: Deserializer<'de>, 52 | { 53 | let s = String::deserialize(deserializer)?; 54 | hex::decode(s).map_err(serde::de::Error::custom) 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /crates/mipsevm/src/state.rs: -------------------------------------------------------------------------------- 1 | //! This module contains the data structure for the state of the MIPS emulator. 2 | 3 | use crate::{witness::STATE_WITNESS_SIZE, Memory, StateWitness, VMStatus}; 4 | use anyhow::Result; 5 | use serde::{Deserialize, Serialize}; 6 | 7 | /// The [State] struct contains the internal model of the MIPS emulator state. 8 | /// 9 | /// The [State] by itself does not contain functionality for performing instruction steps 10 | /// or executing the MIPS emulator. For this, use the [crate::InstrumentedState] struct. 11 | #[derive(Clone, Debug, Default, Serialize, Deserialize)] 12 | #[serde(rename_all = "camelCase")] 13 | pub struct State { 14 | /// The [Memory] of the emulated MIPS thread context. 15 | pub memory: Memory, 16 | /// The preimage key for the given state. 17 | #[serde(with = "crate::ser::fixed_32_hex")] 18 | pub preimage_key: [u8; 32], 19 | /// The preimage offset. 20 | pub preimage_offset: u32, 21 | /// The current program counter. 22 | pub pc: u32, 23 | /// The next program counter. 24 | pub next_pc: u32, 25 | /// The lo register 26 | pub lo: u32, 27 | /// The hi register 28 | pub hi: u32, 29 | /// The heap pointer 30 | pub heap: u32, 31 | /// The exit code of the MIPS emulator. 32 | pub exit_code: u8, 33 | /// The exited status of the MIPS emulator. 34 | pub exited: bool, 35 | /// The current step of the MIPS emulator. 36 | pub step: u64, 37 | /// The MIPS emulator's registers. 38 | pub registers: [u32; 32], 39 | /// The last hint sent to the host. 40 | #[serde(with = "crate::ser::vec_u8_hex")] 41 | pub last_hint: Vec, 42 | } 43 | 44 | impl State { 45 | /// Encode the current [State] into a [StateWitness]. 46 | /// 47 | /// ### Returns 48 | /// - A [Result] containing the encoded [StateWitness] or an error if the encoding failed. 49 | pub fn encode_witness(&mut self) -> Result { 50 | let mut witness: StateWitness = [0u8; STATE_WITNESS_SIZE]; 51 | witness[..32].copy_from_slice(self.memory.merkle_root()?.as_slice()); 52 | witness[32..64].copy_from_slice(self.preimage_key.as_slice()); 53 | witness[64..68].copy_from_slice(&self.preimage_offset.to_be_bytes()); 54 | witness[68..72].copy_from_slice(&self.pc.to_be_bytes()); 55 | witness[72..76].copy_from_slice(&self.next_pc.to_be_bytes()); 56 | witness[76..80].copy_from_slice(&self.lo.to_be_bytes()); 57 | witness[80..84].copy_from_slice(&self.hi.to_be_bytes()); 58 | witness[84..88].copy_from_slice(&self.heap.to_be_bytes()); 59 | witness[88] = self.exit_code; 60 | witness[89] = self.exited as u8; 61 | witness[90..98].copy_from_slice(&self.step.to_be_bytes()); 62 | for (i, r) in self.registers.iter().enumerate() { 63 | let start = 98 + i * 4; 64 | witness[start..start + 4].copy_from_slice(&r.to_be_bytes()); 65 | } 66 | Ok(witness) 67 | } 68 | 69 | /// Return the [VMStatus] given `exited` and `exit_code` statuses. 70 | pub fn vm_status(exited: bool, exit_code: u8) -> VMStatus { 71 | if !exited { 72 | return VMStatus::Unfinished; 73 | } 74 | 75 | match exit_code { 76 | 0 => VMStatus::Valid, 77 | 1 => VMStatus::Invalid, 78 | _ => VMStatus::Panic, 79 | } 80 | } 81 | } 82 | -------------------------------------------------------------------------------- /crates/mipsevm/src/test_utils/mod.rs: -------------------------------------------------------------------------------- 1 | //! Testing utilities. 2 | 3 | use crate::{utils::concat_fixed, utils::keccak256, PreimageOracle}; 4 | use alloy_primitives::hex; 5 | use anyhow::Result; 6 | use preimage_oracle::{Hint, Keccak256Key, Key, LocalIndexKey}; 7 | use rustc_hash::FxHashMap; 8 | 9 | pub mod evm; 10 | 11 | /// Used in tests to write the results to 12 | pub const BASE_ADDR_END: u32 = 0xBF_FF_FF_F0; 13 | 14 | /// Used as the return-address for tests 15 | pub const END_ADDR: u32 = 0xA7_EF_00_D0; 16 | 17 | #[derive(Default)] 18 | pub struct StaticOracle { 19 | preimage_data: Vec, 20 | } 21 | 22 | impl StaticOracle { 23 | pub fn new(preimage_data: Vec) -> Self { 24 | Self { preimage_data } 25 | } 26 | } 27 | 28 | impl PreimageOracle for StaticOracle { 29 | fn hint(&mut self, _value: impl Hint) -> Result<()> { 30 | // noop 31 | Ok(()) 32 | } 33 | 34 | fn get(&mut self, key: [u8; 32]) -> anyhow::Result> { 35 | if key != (key as Keccak256Key).preimage_key() { 36 | anyhow::bail!("Invalid preimage ") 37 | } 38 | Ok(self.preimage_data.clone()) 39 | } 40 | } 41 | 42 | pub struct ClaimTestOracle { 43 | images: FxHashMap<[u8; 32], Vec>, 44 | } 45 | 46 | impl ClaimTestOracle { 47 | pub(crate) const S: u64 = 1000; 48 | pub(crate) const A: u64 = 3; 49 | pub(crate) const B: u64 = 4; 50 | 51 | #[inline(always)] 52 | pub fn diff() -> [u8; 64] { 53 | concat_fixed( 54 | keccak256(Self::A.to_be_bytes()).into(), 55 | keccak256(Self::B.to_be_bytes()).into(), 56 | ) 57 | } 58 | 59 | #[inline(always)] 60 | pub fn pre_hash() -> [u8; 32] { 61 | *keccak256(Self::S.to_be_bytes()) 62 | } 63 | 64 | #[inline(always)] 65 | pub fn diff_hash() -> [u8; 32] { 66 | *keccak256(Self::diff().as_slice()) 67 | } 68 | } 69 | 70 | impl Default for ClaimTestOracle { 71 | fn default() -> Self { 72 | let mut s = Self { 73 | images: Default::default(), 74 | }; 75 | 76 | s.images.insert( 77 | (0 as LocalIndexKey).preimage_key(), 78 | Self::pre_hash().to_vec(), 79 | ); 80 | s.images.insert( 81 | (1 as LocalIndexKey).preimage_key(), 82 | Self::diff_hash().to_vec(), 83 | ); 84 | s.images.insert( 85 | (2 as LocalIndexKey).preimage_key(), 86 | (Self::S * Self::A + Self::B).to_be_bytes().to_vec(), 87 | ); 88 | 89 | s 90 | } 91 | } 92 | 93 | impl PreimageOracle for ClaimTestOracle { 94 | fn hint(&mut self, value: impl Hint) -> Result<()> { 95 | let s = String::from_utf8(value.hint().to_vec()).unwrap(); 96 | let parts: Vec<&str> = s.split(' ').collect(); 97 | 98 | assert_eq!(parts.len(), 2); 99 | 100 | let part = hex::decode(parts[1]).unwrap(); 101 | assert_eq!(part.len(), 32); 102 | let hash: [u8; 32] = part.try_into().unwrap(); 103 | 104 | match parts[0] { 105 | "fetch-state" => { 106 | assert_eq!( 107 | hash, 108 | Self::pre_hash(), 109 | "Expecting request for pre-state preimage" 110 | ); 111 | 112 | self.images.insert( 113 | (Self::pre_hash() as Keccak256Key).preimage_key(), 114 | Self::S.to_be_bytes().to_vec(), 115 | ); 116 | } 117 | "fetch-diff" => { 118 | assert_eq!( 119 | hash, 120 | Self::diff_hash(), 121 | "Expecting request for diff preimage" 122 | ); 123 | self.images.insert( 124 | (Self::diff_hash() as Keccak256Key).preimage_key(), 125 | Self::diff().to_vec(), 126 | ); 127 | self.images.insert( 128 | (*keccak256(Self::A.to_be_bytes()) as Keccak256Key).preimage_key(), 129 | Self::A.to_be_bytes().to_vec(), 130 | ); 131 | self.images.insert( 132 | (*keccak256(Self::B.to_be_bytes()) as Keccak256Key).preimage_key(), 133 | Self::B.to_be_bytes().to_vec(), 134 | ); 135 | } 136 | _ => panic!("Unexpected hint: {}", parts[0]), 137 | } 138 | 139 | Ok(()) 140 | } 141 | 142 | fn get(&mut self, key: [u8; 32]) -> anyhow::Result> { 143 | Ok(self 144 | .images 145 | .get(&key) 146 | .ok_or(anyhow::anyhow!("No image for key"))? 147 | .to_vec()) 148 | } 149 | } 150 | -------------------------------------------------------------------------------- /crates/mipsevm/src/traces.rs: -------------------------------------------------------------------------------- 1 | #![allow(unused_imports)] 2 | 3 | /// Performs a tracing debug if the `tracing` feature is enabled. 4 | #[macro_export] 5 | macro_rules! debug { 6 | ($($arg:tt)*) => { 7 | #[cfg(feature = "tracing")] 8 | tracing::debug!($($arg)*); 9 | }; 10 | } 11 | pub use debug; 12 | 13 | /// Performs a tracing info if the `tracing` feature is enabled. 14 | #[macro_export] 15 | macro_rules! info { 16 | ($($arg:tt)*) => { 17 | #[cfg(feature = "tracing")] 18 | tracing::info!($($arg)*); 19 | }; 20 | } 21 | pub use info; 22 | 23 | /// Performs a tracing error if the `tracing` feature is enabled. 24 | #[macro_export] 25 | macro_rules! error { 26 | ($($arg:tt)*) => { 27 | #[cfg(feature = "tracing")] 28 | tracing::error!($($arg)*); 29 | }; 30 | } 31 | pub use error; 32 | 33 | /// Performs a tracing warn if the `tracing` feature is enabled. 34 | #[macro_export] 35 | macro_rules! warn { 36 | ($($arg:tt)*) => { 37 | #[cfg(feature = "tracing")] 38 | tracing::warn!($($arg)*); 39 | }; 40 | } 41 | pub use crate::warn; 42 | 43 | #[cfg(test)] 44 | mod tests { 45 | use super::*; 46 | 47 | #[test] 48 | fn test_debug() { 49 | debug!("test"); 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /crates/mipsevm/src/traits.rs: -------------------------------------------------------------------------------- 1 | //! This module contains the various traits used in this crate. 2 | 3 | use anyhow::Result; 4 | use preimage_oracle::Hint; 5 | 6 | /// A [StateWitnessHasher] is a trait describing the functionality of a type 7 | /// that computes a witness hash. 8 | pub trait StateWitnessHasher { 9 | /// Compute the [crate::StateWitness] hash. 10 | fn state_hash(&self) -> [u8; 32]; 11 | } 12 | 13 | /// A [PreimageOracle] is a trait describing the functionality of a preimage 14 | /// server. 15 | pub trait PreimageOracle { 16 | /// Insert the given preimage into the oracle. 17 | /// 18 | /// ### Takes 19 | /// - `value`: The preimage to insert. 20 | fn hint(&mut self, value: impl Hint) -> Result<()>; 21 | 22 | /// Fetch the preimage for the given key. 23 | /// 24 | /// ### Takes 25 | /// - `key`: The keccak digest to fetch the preimage for. 26 | /// 27 | /// ### Returns 28 | /// - `Ok(Some(preimage))`: The preimage for the given key. 29 | /// - `Ok(None)`: The preimage for the given key does not exist. 30 | /// - `Err(_)`: An error occurred while fetching the preimage. 31 | fn get(&mut self, key: [u8; 32]) -> Result>; 32 | } 33 | -------------------------------------------------------------------------------- /crates/mipsevm/src/types.rs: -------------------------------------------------------------------------------- 1 | //! This module contains all of the type aliases and enums used within this crate. 2 | 3 | use crate::CachedPage; 4 | use std::{cell::RefCell, rc::Rc}; 5 | 6 | /// A [Page] is a portion of memory of size `PAGE_SIZE`. 7 | pub type Page = [u8; crate::page::PAGE_SIZE]; 8 | 9 | /// A [CachedPage] with shared ownership. 10 | pub type SharedCachedPage = Rc>; 11 | 12 | /// A [StateWitness] is an encoded commitment to the current [crate::State] of the MIPS emulator. 13 | pub type StateWitness = [u8; crate::witness::STATE_WITNESS_SIZE]; 14 | 15 | /// A [PageIndex] is the index of a [Page] within the [crate::Memory] mappings. 16 | pub type PageIndex = u64; 17 | 18 | /// A [Gindex] is a generalized index, defined as $2^{\text{depth}} + \text{index}$. 19 | pub type Gindex = u64; 20 | 21 | /// An [Address] is a 32 bit address in the MIPS emulator's memory. 22 | pub type Address = u32; 23 | 24 | /// The [VMStatus] is an indicator within the [StateWitness] hash that indicates 25 | /// the current status of the MIPS emulator. 26 | #[repr(u8)] 27 | pub enum VMStatus { 28 | Valid = 0, 29 | Invalid = 1, 30 | Panic = 2, 31 | Unfinished = 3, 32 | } 33 | 34 | /// Identifiers for special file descriptors used by the MIPS emulator. 35 | #[repr(u8)] 36 | pub enum Fd { 37 | StdIn = 0, 38 | Stdout = 1, 39 | StdErr = 2, 40 | HintRead = 3, 41 | HintWrite = 4, 42 | PreimageRead = 5, 43 | PreimageWrite = 6, 44 | } 45 | 46 | impl TryFrom for Fd { 47 | type Error = anyhow::Error; 48 | 49 | fn try_from(n: u8) -> Result { 50 | match n { 51 | 0 => Ok(Fd::StdIn), 52 | 1 => Ok(Fd::Stdout), 53 | 2 => Ok(Fd::StdErr), 54 | 3 => Ok(Fd::HintRead), 55 | 4 => Ok(Fd::HintWrite), 56 | 5 => Ok(Fd::PreimageRead), 57 | 6 => Ok(Fd::PreimageWrite), 58 | _ => anyhow::bail!("Failed to convert {} to Fd", n), 59 | } 60 | } 61 | } 62 | 63 | /// A [Syscall] is a system call that can be made within the MIPS emulator. 64 | pub enum Syscall { 65 | Mmap = 4090, 66 | Brk = 4045, 67 | Clone = 4120, 68 | ExitGroup = 4246, 69 | Read = 4003, 70 | Write = 4004, 71 | Fcntl = 4055, 72 | } 73 | 74 | impl TryFrom for Syscall { 75 | type Error = anyhow::Error; 76 | 77 | fn try_from(n: u32) -> Result { 78 | match n { 79 | 4090 => Ok(Syscall::Mmap), 80 | 4045 => Ok(Syscall::Brk), 81 | 4120 => Ok(Syscall::Clone), 82 | 4246 => Ok(Syscall::ExitGroup), 83 | 4003 => Ok(Syscall::Read), 84 | 4004 => Ok(Syscall::Write), 85 | 4055 => Ok(Syscall::Fcntl), 86 | _ => anyhow::bail!("Failed to convert {} to Syscall", n), 87 | } 88 | } 89 | } 90 | -------------------------------------------------------------------------------- /crates/mipsevm/src/utils.rs: -------------------------------------------------------------------------------- 1 | //! This module contains utility and helper functions for this crate. 2 | 3 | use alloy_primitives::B256; 4 | 5 | /// Concatenate two fixed sized arrays together into a new array with minimal reallocation. 6 | #[inline(always)] 7 | pub(crate) fn concat_fixed(a: [T; N], b: [T; M]) -> [T; N + M] 8 | where 9 | T: Copy + Default, 10 | { 11 | let mut concatenated: [T; N + M] = [T::default(); N + M]; 12 | let (left, right) = concatenated.split_at_mut(N); 13 | left.copy_from_slice(&a); 14 | right.copy_from_slice(&b); 15 | concatenated 16 | } 17 | 18 | /// Hash the concatenation of two 32 byte digests. 19 | #[inline(always)] 20 | pub(crate) fn keccak_concat_hashes(a: [u8; 32], b: [u8; 32]) -> B256 { 21 | #[cfg(feature = "simd-keccak")] 22 | { 23 | let mut out = B256::ZERO; 24 | keccak256_aarch64_simd::simd_keccak256_64b_single(&concat_fixed(a, b), out.as_mut()); 25 | out 26 | } 27 | 28 | #[cfg(not(feature = "simd-keccak"))] 29 | keccak256(concat_fixed(a, b).as_slice()) 30 | } 31 | 32 | #[inline(always)] 33 | pub(crate) fn keccak256>(input: T) -> B256 { 34 | let mut out = B256::ZERO; 35 | xkcp_rs::keccak256(input.as_ref(), out.as_mut()); 36 | out 37 | } 38 | -------------------------------------------------------------------------------- /crates/mipsevm/src/witness.rs: -------------------------------------------------------------------------------- 1 | //! This module contains the various witness types. 2 | 3 | use crate::{utils::keccak256, State, StateWitness, StateWitnessHasher}; 4 | use alloy_primitives::{B256, U256}; 5 | use alloy_sol_types::{sol, SolCall}; 6 | use preimage_oracle::KeyType; 7 | use revm::primitives::Bytes; 8 | 9 | /// The size of an encoded [StateWitness] in bytes. 10 | pub const STATE_WITNESS_SIZE: usize = 226; 11 | 12 | impl StateWitnessHasher for StateWitness { 13 | fn state_hash(&self) -> [u8; 32] { 14 | let mut hash = keccak256(self); 15 | let offset = 32 * 2 + 4 * 6; 16 | let exit_code = self[offset]; 17 | let exited = self[offset + 1] == 1; 18 | hash[0] = State::vm_status(exited, exit_code) as u8; 19 | *hash 20 | } 21 | } 22 | 23 | /// A [StepWitness] is produced after each instruction step of the MIPS emulator. It contains 24 | /// the encoded [StateWitness], the proof of memory access, and the preimage key, value, and 25 | /// offset. 26 | pub struct StepWitness { 27 | /// The encoded state witness 28 | pub state: StateWitness, 29 | /// The proof of memory access 30 | pub mem_proof: Vec, 31 | /// The preimage key 32 | pub preimage_key: Option<[u8; 32]>, 33 | /// The preimage value 34 | pub preimage_value: Option>, 35 | /// The preimage offset 36 | pub preimage_offset: Option, 37 | } 38 | 39 | impl Default for StepWitness { 40 | fn default() -> Self { 41 | Self { 42 | state: [0u8; crate::witness::STATE_WITNESS_SIZE], 43 | mem_proof: Vec::with_capacity(28 * 32 * 2), 44 | preimage_key: Default::default(), 45 | preimage_value: Default::default(), 46 | preimage_offset: Default::default(), 47 | } 48 | } 49 | } 50 | 51 | sol! { 52 | /// `PreimageOracle` loadLocalData function. 53 | function loadLocalData(uint256,bytes32,uint256,uint256) external returns (bytes32); 54 | 55 | /// `PreimageOracle` loadKeccak256PreimagePart function. 56 | function loadKeccak256PreimagePart(uint256,bytes) external; 57 | 58 | /// `MIPS` step function. 59 | function step(bytes,bytes) external returns (bytes32); 60 | } 61 | 62 | impl StepWitness { 63 | /// Returns `true` if the step witness has a preimage. 64 | pub fn has_preimage(&self) -> bool { 65 | self.preimage_key.is_some() 66 | } 67 | 68 | /// ABI encodes the input to the preimage oracle, if the [StepWitness] has a preimage request. 69 | /// 70 | /// ### Returns 71 | /// - `Some(input)` if the [StepWitness] has a preimage request. 72 | /// - `None` if the [StepWitness] does not have a preimage request. 73 | pub fn encode_preimage_oracle_input(&self) -> Option { 74 | let preimage_key = self.preimage_key?; 75 | 76 | match KeyType::from(preimage_key[0]) { 77 | KeyType::_Illegal => { 78 | crate::error!(target: "mipsevm::step_witness", "Illegal key type"); 79 | None 80 | } 81 | KeyType::Local => { 82 | let preimage_value = &self.preimage_value.clone()?; 83 | 84 | if preimage_value.len() > 32 + 8 { 85 | crate::error!(target: "mipsevm::step_witness", "Local preimage value exceeds maximum size of 32 bytes with key 0x{:x}", B256::from(self.preimage_key?)); 86 | return None; 87 | } 88 | 89 | let preimage_part = &preimage_value[8..]; 90 | let mut tmp = [0u8; 32]; 91 | tmp[0..preimage_part.len()].copy_from_slice(preimage_part); 92 | 93 | let call = loadLocalDataCall { 94 | _0: B256::from(preimage_key).into(), 95 | _1: B256::from(tmp), 96 | _2: U256::from(preimage_value.len() - 8), 97 | _3: U256::from(self.preimage_offset?), 98 | }; 99 | 100 | Some(call.abi_encode().into()) 101 | } 102 | KeyType::GlobalKeccak => { 103 | let call = loadKeccak256PreimagePartCall { 104 | _0: U256::from(self.preimage_offset?), 105 | _1: self.preimage_value.clone()?[8..].to_vec(), 106 | }; 107 | 108 | Some(call.abi_encode().into()) 109 | } 110 | } 111 | } 112 | 113 | /// ABI encodes the input to the MIPS step function. 114 | /// 115 | /// ### Returns 116 | /// - The ABI encoded input to the MIPS step function. 117 | pub fn encode_step_input(&self) -> Bytes { 118 | let call = stepCall { 119 | _0: self.state.to_vec(), 120 | _1: self.mem_proof.to_vec(), 121 | }; 122 | 123 | call.abi_encode().into() 124 | } 125 | } 126 | -------------------------------------------------------------------------------- /crates/preimage/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "preimage-oracle" 3 | description = "Bindings for interacting as a client or server over the Pre-image Oracle ABI" 4 | edition = "2021" 5 | 6 | version.workspace = true 7 | authors.workspace = true 8 | 9 | [dependencies] 10 | # workspace 11 | alloy-primitives.workspace = true 12 | anyhow.workspace = true 13 | tokio.workspace = true 14 | 15 | # misc 16 | os_pipe = "1.1.5" 17 | tracing = { version = "0.1.40", optional = true } 18 | 19 | [dev-dependencies] 20 | rand = "0.8.5" 21 | 22 | [features] 23 | tracing = ["dep:tracing"] 24 | -------------------------------------------------------------------------------- /crates/preimage/README.md: -------------------------------------------------------------------------------- 1 | # `preimage-oracle` 2 | 3 | The `preimage-oracle` crate offers bindings to interact as client or sever over the Pre-image Oracle ABI. 4 | 5 | Read more about the Preimage Oracle in the OP Stack [specs][specs]. 6 | 7 | See the OP Stack's [op-program][op-program] and [Cannon client examples](../../example) for client-side usage. 8 | See [`mipsevm`](../mipsevm) for server-side usage. 9 | 10 | [specs]: https://github.com/ethereum-optimism/optimism/blob/6c7f366a55febbb119aa0b02d73f008c1c909900/specs/fault-proof.md 11 | [op-program]: https://github.com/ethereum-optimism/optimism/tree/develop/op-program 12 | -------------------------------------------------------------------------------- /crates/preimage/src/file_chan.rs: -------------------------------------------------------------------------------- 1 | //! This module contains the an implementation of the [FileChannel] trait in the form of 2 | //! [ReadWritePair]. 3 | 4 | use crate::{traits::FileChannel, types::PreimageFds}; 5 | use anyhow::Result; 6 | use std::fs::File; 7 | use std::io::{self, Read, Write}; 8 | use std::os::fd::{FromRawFd, IntoRawFd}; 9 | 10 | /// A [ReadWritePair] represents a pair of file descriptors that can be used for reading and writing. 11 | pub struct ReadWritePair { 12 | r: File, 13 | w: File, 14 | } 15 | 16 | impl ReadWritePair { 17 | pub fn new(r: File, w: File) -> Self { 18 | Self { r, w } 19 | } 20 | 21 | pub fn reader(&self) -> &File { 22 | &self.r 23 | } 24 | 25 | pub fn writer(&self) -> &File { 26 | &self.w 27 | } 28 | 29 | /// Helper to create a hinter channel. 30 | pub fn client_hinter_channel() -> ReadWritePair { 31 | let r = unsafe { File::from_raw_fd(PreimageFds::HintClientRead as i32) }; 32 | let w = unsafe { File::from_raw_fd(PreimageFds::HintClientWrite as i32) }; 33 | ReadWritePair::new(r, w) 34 | } 35 | 36 | /// Helper to create a preimage channel. 37 | pub fn client_preimage_channel() -> ReadWritePair { 38 | let r = unsafe { File::from_raw_fd(PreimageFds::PreimageClientRead as i32) }; 39 | let w = unsafe { File::from_raw_fd(PreimageFds::PreimageClientWrite as i32) }; 40 | ReadWritePair::new(r, w) 41 | } 42 | } 43 | 44 | impl Read for ReadWritePair { 45 | fn read(&mut self, buf: &mut [u8]) -> io::Result { 46 | self.r.read(buf) 47 | } 48 | } 49 | 50 | impl Write for ReadWritePair { 51 | fn write(&mut self, buf: &[u8]) -> io::Result { 52 | self.w.write(buf) 53 | } 54 | 55 | fn flush(&mut self) -> io::Result<()> { 56 | self.w.flush() 57 | } 58 | } 59 | 60 | impl FileChannel for ReadWritePair { 61 | fn reader(&mut self) -> &mut File { 62 | &mut self.r 63 | } 64 | 65 | fn writer(&mut self) -> &mut File { 66 | &mut self.w 67 | } 68 | 69 | fn close(self) -> anyhow::Result<()> { 70 | // Self is dropped here, closing the file descriptors. 71 | Ok(()) 72 | } 73 | } 74 | 75 | /// Helper to create a bidirectional channel through file descriptors opened by this process. 76 | pub fn create_bidirectional_channel() -> Result<(ReadWritePair, ReadWritePair)> { 77 | let (ar, bw) = os_pipe::pipe()?; 78 | let (br, aw) = os_pipe::pipe()?; 79 | Ok(( 80 | ReadWritePair::new(unsafe { File::from_raw_fd(ar.into_raw_fd()) }, unsafe { 81 | File::from_raw_fd(aw.into_raw_fd()) 82 | }), 83 | ReadWritePair::new(unsafe { File::from_raw_fd(br.into_raw_fd()) }, unsafe { 84 | File::from_raw_fd(bw.into_raw_fd()) 85 | }), 86 | )) 87 | } 88 | -------------------------------------------------------------------------------- /crates/preimage/src/lib.rs: -------------------------------------------------------------------------------- 1 | #![doc = include_str!("../README.md")] 2 | 3 | pub(crate) mod traces; 4 | 5 | mod oracle; 6 | pub use oracle::{OracleClient, OracleServer}; 7 | 8 | mod traits; 9 | pub use traits::{FileChannel, Hint, Hinter, Key, Oracle}; 10 | 11 | mod types; 12 | pub use types::{Keccak256Key, KeyType, LocalIndexKey, PreimageGetter, RawKey}; 13 | 14 | mod hints; 15 | pub use hints::{HintReader, HintWriter}; 16 | 17 | mod file_chan; 18 | pub use file_chan::{create_bidirectional_channel, ReadWritePair}; 19 | -------------------------------------------------------------------------------- /crates/preimage/src/oracle.rs: -------------------------------------------------------------------------------- 1 | //! This module contains the [Client] struct and its implementation. 2 | 3 | use crate::{Key, Oracle, PreimageGetter, ReadWritePair}; 4 | use anyhow::Result; 5 | use std::io::{Read, Write}; 6 | 7 | /// The [OracleClient] is a client that can make requests and write to the [OracleServer]. 8 | /// It contains a [ReadWritePair] that is one half of a bidirectional channel, with the other 9 | /// half being owned by the [OracleServer]. 10 | pub struct OracleClient { 11 | io: ReadWritePair, 12 | } 13 | 14 | impl OracleClient { 15 | pub fn new(io: ReadWritePair) -> Self { 16 | Self { io } 17 | } 18 | } 19 | 20 | impl Oracle for OracleClient { 21 | fn get(&mut self, key: impl Key) -> Result> { 22 | let hash = key.preimage_key(); 23 | self.io.write_all(&hash)?; 24 | 25 | let mut length = [0u8; 8]; 26 | self.io.read_exact(&mut length)?; 27 | let length = u64::from_be_bytes(length) as usize; 28 | 29 | let payload = if length == 0 { 30 | Vec::default() 31 | } else { 32 | let mut payload = vec![0u8; length]; 33 | self.io.read_exact(&mut payload)?; 34 | payload 35 | }; 36 | Ok(payload) 37 | } 38 | } 39 | 40 | /// The [OracleServer] is a server that can receive requests from the [OracleClient] and 41 | /// respond to them. It contains a [ReadWritePair] that is one half of a bidirectional channel, 42 | /// with the other half being owned by the [OracleClient]. 43 | pub struct OracleServer { 44 | io: ReadWritePair, 45 | } 46 | 47 | impl OracleServer { 48 | pub fn new(io: ReadWritePair) -> Self { 49 | Self { io } 50 | } 51 | } 52 | 53 | impl OracleServer { 54 | pub fn new_preimage_request(&mut self, getter: PreimageGetter) -> Result<()> { 55 | let mut key = [0u8; 32]; 56 | self.io.read_exact(&mut key)?; 57 | 58 | let value = getter(key)?; 59 | 60 | self.io.write_all(&(value.len() as u64).to_be_bytes())?; 61 | if !value.is_empty() { 62 | self.io.write_all(&value)?; 63 | } 64 | 65 | Ok(()) 66 | } 67 | } 68 | 69 | #[cfg(test)] 70 | mod test { 71 | use super::{Oracle, OracleClient, OracleServer}; 72 | use crate::{Keccak256Key, Key}; 73 | use alloy_primitives::keccak256; 74 | use std::{collections::HashMap, sync::Arc}; 75 | use tokio::sync::Mutex; 76 | 77 | async fn test_preimage(preimages: Vec>) { 78 | let (a, b) = crate::create_bidirectional_channel().unwrap(); 79 | 80 | let client = Arc::new(Mutex::new(OracleClient::new(a))); 81 | let server = Arc::new(Mutex::new(OracleServer::new(b))); 82 | 83 | let preimage_by_hash = { 84 | let mut preimage_by_hash: HashMap<[u8; 32], Vec> = Default::default(); 85 | for preimage in preimages.iter() { 86 | let k = *keccak256(preimage) as Keccak256Key; 87 | preimage_by_hash.insert(k.preimage_key(), preimage.clone()); 88 | } 89 | Arc::new(preimage_by_hash) 90 | }; 91 | 92 | for preimage in preimages.into_iter() { 93 | let k = *keccak256(preimage) as Keccak256Key; 94 | 95 | let join_a = tokio::task::spawn({ 96 | let (client, preimage_by_hash) = 97 | (Arc::clone(&client), Arc::clone(&preimage_by_hash)); 98 | async move { 99 | // Lock the client 100 | let mut cl = client.lock().await; 101 | let result = cl.get(k).unwrap(); 102 | 103 | // Pull the expected value from the map 104 | let expected = preimage_by_hash.get(&k.preimage_key()).unwrap(); 105 | assert_eq!(expected, &result); 106 | } 107 | }); 108 | 109 | let join_b = tokio::task::spawn({ 110 | let (server, preimage_by_hash) = 111 | (Arc::clone(&server), Arc::clone(&preimage_by_hash)); 112 | async move { 113 | // Lock the server 114 | let mut server = server.lock().await; 115 | server 116 | .new_preimage_request(Box::new(move |key: [u8; 32]| { 117 | let dat = preimage_by_hash.get(&key).unwrap(); 118 | Ok(dat.clone()) 119 | })) 120 | .unwrap(); 121 | } 122 | }); 123 | 124 | tokio::try_join!(join_a, join_b).unwrap(); 125 | } 126 | } 127 | 128 | #[tokio::test(flavor = "multi_thread", worker_threads = 2)] 129 | async fn empty_preimage() { 130 | test_preimage(vec![vec![]]).await; 131 | } 132 | 133 | #[tokio::test(flavor = "multi_thread", worker_threads = 2)] 134 | async fn zero() { 135 | test_preimage(vec![vec![0u8]]).await; 136 | } 137 | 138 | #[tokio::test(flavor = "multi_thread", worker_threads = 2)] 139 | async fn multiple() { 140 | test_preimage(vec![ 141 | b"tx from alice".to_vec(), 142 | vec![0x13, 0x37], 143 | b"tx from bob".to_vec(), 144 | ]) 145 | .await; 146 | } 147 | 148 | #[tokio::test(flavor = "multi_thread", worker_threads = 2)] 149 | async fn zeros() { 150 | test_preimage(vec![vec![0u8; 1000]]).await; 151 | } 152 | 153 | #[tokio::test(flavor = "multi_thread", worker_threads = 2)] 154 | async fn random() { 155 | use rand::RngCore; 156 | 157 | let mut preimage = vec![0; 1000]; 158 | rand::thread_rng().fill_bytes(&mut preimage[..]); 159 | 160 | test_preimage(vec![preimage]).await; 161 | } 162 | } 163 | -------------------------------------------------------------------------------- /crates/preimage/src/traces.rs: -------------------------------------------------------------------------------- 1 | #![allow(unused_imports)] 2 | 3 | /// Performs a tracing debug if the `tracing` feature is enabled. 4 | #[macro_export] 5 | macro_rules! debug { 6 | ($($arg:tt)*) => { 7 | #[cfg(feature = "tracing")] 8 | tracing::debug!($($arg)*); 9 | }; 10 | } 11 | pub use debug; 12 | 13 | /// Performs a tracing info if the `tracing` feature is enabled. 14 | #[macro_export] 15 | macro_rules! info { 16 | ($($arg:tt)*) => { 17 | #[cfg(feature = "tracing")] 18 | tracing::info!($($arg)*); 19 | }; 20 | } 21 | pub use info; 22 | 23 | /// Performs a tracing error if the `tracing` feature is enabled. 24 | #[macro_export] 25 | macro_rules! error { 26 | ($($arg:tt)*) => { 27 | #[cfg(feature = "tracing")] 28 | tracing::error!($($arg)*); 29 | }; 30 | } 31 | pub use error; 32 | 33 | /// Performs a tracing warn if the `tracing` feature is enabled. 34 | #[macro_export] 35 | macro_rules! warn { 36 | ($($arg:tt)*) => { 37 | #[cfg(feature = "tracing")] 38 | tracing::warn!($($arg)*); 39 | }; 40 | } 41 | pub use crate::warn; 42 | 43 | #[cfg(test)] 44 | mod tests { 45 | use super::*; 46 | 47 | #[test] 48 | fn test_debug() { 49 | debug!("test"); 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /crates/preimage/src/traits.rs: -------------------------------------------------------------------------------- 1 | //! This module contains the traits for the preimage-oracle crate. 2 | 3 | use anyhow::Result; 4 | use std::{ 5 | fs::File, 6 | io::{Read, Write}, 7 | }; 8 | 9 | /// The [Key] trait describes the behavior of a pre-image key that may be wrapped 10 | /// into a 32-byte type-prefixed key. 11 | pub trait Key { 12 | /// Changes the [Key] commitment into a 32-byte type-prefixed preimage key. 13 | fn preimage_key(self) -> [u8; 32]; 14 | } 15 | 16 | /// The [Oracle] trait describes the behavior of a read-only pre-image oracle. 17 | pub trait Oracle { 18 | /// Get the full pre-image of a given pre-image key. 19 | fn get(&mut self, key: impl Key) -> Result>; 20 | } 21 | 22 | // [Hint] is an trait to enable any program type to function as a hint, 23 | // When passed to the Hinter interface, returning a string representation 24 | // of what data the host should prepare pre-images for. 25 | pub trait Hint { 26 | /// Returns a string representation of the data the host should prepare 27 | /// pre-images for. 28 | fn hint(&self) -> &[u8]; 29 | } 30 | 31 | // [Hinter] is an trait describing behavior for writing hints to the host. 32 | // This may be implemented as a no-op or logging hinter if the program is executing 33 | // in a read-only environment where the host is expected to have all pre-images ready. 34 | pub trait Hinter { 35 | /// Sends a hint to the host. 36 | /// 37 | /// ### Takes 38 | /// - `hint` - The hint to send to the host. 39 | /// 40 | /// ### Returns 41 | /// - A [Result] indicating whether or not the hint was successfully sent. 42 | fn hint(&mut self, hint: impl Hint) -> Result<()>; 43 | } 44 | 45 | /// The [FileChannel] trait represents a dual channel that can be used to read 46 | /// and write information to file descriptors. 47 | pub trait FileChannel: Read + Write { 48 | /// Returns the reader file descriptor. 49 | fn reader(&mut self) -> &mut File; 50 | 51 | /// Returns the writer file descriptor. 52 | fn writer(&mut self) -> &mut File; 53 | 54 | /// Closes the file descriptors. 55 | fn close(self) -> Result<()>; 56 | } 57 | -------------------------------------------------------------------------------- /crates/preimage/src/types.rs: -------------------------------------------------------------------------------- 1 | //! This module contains the types for the preimage-oracle crate. 2 | 3 | use crate::{Hint, Key}; 4 | use anyhow::Result; 5 | 6 | /// A [PreimageGetter] is a function that can be used to fetch pre-images. 7 | pub type PreimageGetter = Box Result>>; 8 | 9 | /// A [HintHandler] is a function that can be used to handle hints from a [crate::HintWriter]. 10 | pub type HintHandler = Box Result<()>>; 11 | 12 | /// A [Keccak256Key] wraps a keccak256 hash to use it as a typed pre-image key. 13 | pub type Keccak256Key = [u8; 32]; 14 | 15 | /// A [RawKey] wraps a raw 32-byte key which remains unaffected in the [Key] trait impl. 16 | pub struct RawKey(pub [u8; 32]); 17 | 18 | /// A [LocalIndexKey] is a key local to the program, indexing a special program input. 19 | pub type LocalIndexKey = u64; 20 | 21 | /// The [KeyType] enum represents the different types of keys that can be used to index 22 | /// pre-images. 23 | #[repr(u8)] 24 | pub enum KeyType { 25 | /// The zero key type is illegal to use. 26 | _Illegal = 0, 27 | /// The local key type is used to index a local variable, specific to the program instance. 28 | Local = 1, 29 | /// The global key type is used to index a global keccak256 preimage. 30 | GlobalKeccak = 2, 31 | } 32 | 33 | /// The [PreimageFds] enum represents the file descriptors used for hinting and pre-image 34 | /// communication. 35 | #[repr(u8)] 36 | pub enum PreimageFds { 37 | HintClientRead = 3, 38 | HintClientWrite = 4, 39 | PreimageClientRead = 5, 40 | PreimageClientWrite = 6, 41 | } 42 | 43 | impl From for KeyType { 44 | fn from(n: u8) -> Self { 45 | match n { 46 | 1 => KeyType::Local, 47 | 2 => KeyType::GlobalKeccak, 48 | _ => KeyType::_Illegal, 49 | } 50 | } 51 | } 52 | 53 | impl Key for LocalIndexKey { 54 | fn preimage_key(self) -> [u8; 32] { 55 | let mut out = [0u8; 32]; 56 | out[0] = KeyType::Local as u8; 57 | out[24..].copy_from_slice(&self.to_be_bytes()); 58 | out 59 | } 60 | } 61 | 62 | impl Key for Keccak256Key { 63 | fn preimage_key(mut self) -> [u8; 32] { 64 | self[0] = KeyType::GlobalKeccak as u8; 65 | self 66 | } 67 | } 68 | 69 | impl Key for RawKey { 70 | fn preimage_key(self) -> [u8; 32] { 71 | self.0 72 | } 73 | } 74 | 75 | impl Hint for &[u8] { 76 | fn hint(&self) -> &[u8] { 77 | self 78 | } 79 | } 80 | -------------------------------------------------------------------------------- /docker/README.md: -------------------------------------------------------------------------------- 1 | # `cannon-rs` Docker Image 2 | 3 | This folder contains a Dockerfile that includes the `cannon-rs` release binary. 4 | 5 | ## Building 6 | 7 | Dependencies: [Docker](https://www.docker.com/) 8 | 9 | ```sh 10 | ./build.sh 11 | ``` 12 | -------------------------------------------------------------------------------- /docker/build.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Grab the directory of this script. 4 | DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )" 5 | 6 | echo "Building binary..." 7 | cargo build --release --bin cannon 8 | 9 | # Check if `docker` is installed 10 | if ! command -v docker &> /dev/null 11 | then 12 | echo "Error: docker not found. Please install docker and try again." 13 | exit 14 | fi 15 | 16 | echo "Building image..." 17 | docker build -f cannon-rs.dockerfile $DIR/.. -t cannon-rs 18 | -------------------------------------------------------------------------------- /docker/cannon-rs.dockerfile: -------------------------------------------------------------------------------- 1 | FROM alpine:3.14 2 | 3 | COPY target/release/cannon /usr/local/bin 4 | -------------------------------------------------------------------------------- /example/Makefile: -------------------------------------------------------------------------------- 1 | all: elf dump 2 | 3 | .PHONY: elf 4 | elf: $(patsubst %/go.mod,bin/%.elf,$(wildcard */go.mod)) 5 | 6 | .PHONY: dump 7 | dump: $(patsubst %/go.mod,bin/%.dump,$(wildcard */go.mod)) 8 | 9 | bin: 10 | mkdir bin 11 | 12 | # take any directory with a go mod, and build an ELF 13 | # verify output with: readelf -h bin/.elf 14 | # result is mips32, big endian, R3000 15 | bin/%.elf: bin 16 | cd $(@:bin/%.elf=%) && GOOS=linux GOARCH=mips GOMIPS=softfloat go build -o ../$@ . 17 | 18 | # take any ELF and dump it 19 | # TODO: currently have the little-endian toolchain, but should use the big-endian one. The -EB compat flag works though. 20 | bin/%.dump: bin/%.elf 21 | mipsel-linux-gnu-objdump -D --disassembler-options=no-aliases --wide --source -m mips:3000 -EB $(@:%.dump=%.elf) > $@ 22 | -------------------------------------------------------------------------------- /example/bin/claim.elf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/op-rs/cannon-rs/5ab846ae9d4cc0d2cf26c4a7af88f86f5339644b/example/bin/claim.elf -------------------------------------------------------------------------------- /example/bin/hello.elf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/op-rs/cannon-rs/5ab846ae9d4cc0d2cf26c4a7af88f86f5339644b/example/bin/hello.elf -------------------------------------------------------------------------------- /example/claim/go.mod: -------------------------------------------------------------------------------- 1 | module claim 2 | 3 | go 1.20 4 | 5 | require github.com/ethereum-optimism/optimism v1.1.4 6 | 7 | require ( 8 | golang.org/x/crypto v0.13.0 // indirect 9 | golang.org/x/sys v0.12.0 // indirect 10 | ) 11 | -------------------------------------------------------------------------------- /example/claim/go.sum: -------------------------------------------------------------------------------- 1 | github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= 2 | github.com/ethereum-optimism/optimism v1.1.4 h1:S9PDyO/e8UTTDAFXQUV4d4GsWNNkTp4BxjPI35ug0rY= 3 | github.com/ethereum-optimism/optimism v1.1.4/go.mod h1:GG+CktYLDQs4I2pIfFs8vGeh/PvX2ydpZ6sxgyzhAFg= 4 | github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= 5 | github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk= 6 | golang.org/x/crypto v0.13.0 h1:mvySKfSWJ+UKUii46M40LOvyWfN0s2U+46/jDd0e6Ck= 7 | golang.org/x/crypto v0.13.0/go.mod h1:y6Z2r+Rw4iayiXXAIxJIDAJ1zMW4yaTpebo8fPOliYc= 8 | golang.org/x/sys v0.12.0 h1:CM0HF96J0hcLAwsHPJZjfdNzs0gftsLfgKt57wWHJ0o= 9 | golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= 10 | gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= 11 | -------------------------------------------------------------------------------- /example/claim/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "encoding/binary" 5 | "fmt" 6 | "os" 7 | 8 | "github.com/ethereum-optimism/optimism/op-preimage" 9 | ) 10 | 11 | type rawHint string 12 | 13 | func (rh rawHint) Hint() string { 14 | return string(rh) 15 | } 16 | 17 | func main() { 18 | _, _ = os.Stderr.Write([]byte("started!")) 19 | 20 | po := preimage.NewOracleClient(preimage.ClientPreimageChannel()) 21 | hinter := preimage.NewHintWriter(preimage.ClientHinterChannel()) 22 | 23 | preHash := *(*[32]byte)(po.Get(preimage.LocalIndexKey(0))) 24 | diffHash := *(*[32]byte)(po.Get(preimage.LocalIndexKey(1))) 25 | claimData := *(*[8]byte)(po.Get(preimage.LocalIndexKey(2))) 26 | 27 | // Hints are used to indicate which things the program will access, 28 | // so the server can be prepared to serve the corresponding pre-images. 29 | hinter.Hint(rawHint(fmt.Sprintf("fetch-state %x", preHash))) 30 | pre := po.Get(preimage.Keccak256Key(preHash)) 31 | 32 | // Multiple pre-images may be fetched based on a hint. 33 | // E.g. when we need all values of a merkle-tree. 34 | hinter.Hint(rawHint(fmt.Sprintf("fetch-diff %x", diffHash))) 35 | diff := po.Get(preimage.Keccak256Key(diffHash)) 36 | diffPartA := po.Get(preimage.Keccak256Key(*(*[32]byte)(diff[:32]))) 37 | diffPartB := po.Get(preimage.Keccak256Key(*(*[32]byte)(diff[32:]))) 38 | 39 | // Example state-transition function: s' = s*a + b 40 | s := binary.BigEndian.Uint64(pre) 41 | a := binary.BigEndian.Uint64(diffPartA) 42 | b := binary.BigEndian.Uint64(diffPartB) 43 | fmt.Printf("computing %d * %d + %d\n", s, a, b) 44 | sOut := s*a + b 45 | 46 | sClaim := binary.BigEndian.Uint64(claimData[:]) 47 | if sOut != sClaim { 48 | fmt.Printf("claim %d is bad! Correct result is %d\n", sOut, sClaim) 49 | os.Exit(1) 50 | } else { 51 | fmt.Printf("claim %d is good!\n", sOut) 52 | os.Exit(0) 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /example/hello/go.mod: -------------------------------------------------------------------------------- 1 | module hello 2 | 3 | go 1.20 4 | -------------------------------------------------------------------------------- /example/hello/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "os" 4 | 5 | func main() { 6 | _, _ = os.Stdout.Write([]byte("hello world!\n")) 7 | } 8 | --------------------------------------------------------------------------------