├── .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 |
3 |
4 |
5 |
6 | An alternative implementation of the OP Stack's Cannon in Rust.
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
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 |
--------------------------------------------------------------------------------