jit_assembler/lib.rs
1#![cfg_attr(not(feature = "std"), no_std)]
2
3//! # Multi-Architecture JIT Assembler
4//!
5//! A multi-architecture JIT assembler library for runtime code generation.
6//!
7//! ## Features
8//!
9//! - **Multi-architecture support**: RISC-V, AArch64, x86-64 (planned)
10//! - **Host-independent**: Runs on any host architecture to generate target code
11//! - **No-std compatible**: Works in both `std` and `no_std` environments
12//! - **Macro-based DSL**: Convenient syntax for writing assembly
13//! - **JIT execution**: Direct execution of assembled code as functions (std-only)
14//!
15//! ## Supported Architectures
16//!
17//! - **RISC-V 64-bit** (`riscv` feature, enabled by default)
18//! - **AArch64** (`aarch64` feature, enabled by default) - Basic arithmetic and logical operations
19//! - **x86-64** (`x86_64` feature) - Coming soon
20//!
21//! ## Usage
22//!
23//! ```rust
24//! # #[cfg(feature = "riscv64")]
25//! # {
26//! use jit_assembler::riscv64::{reg, csr, Riscv64InstructionBuilder};
27//! use jit_assembler::common::InstructionBuilder;
28//!
29//! // Method chaining style (recommended)
30//! let mut builder = Riscv64InstructionBuilder::new();
31//! let instructions = builder
32//! .csrrw(reg::RA, csr::MSTATUS, reg::SP)
33//! .addi(reg::A0, reg::ZERO, 100)
34//! .add(reg::A1, reg::A0, reg::SP)
35//! .ret()
36//! .instructions();
37//!
38//! // Macro style (concise and assembly-like)
39//! let instructions3 = jit_assembler::riscv64_asm! {
40//! csrrw(reg::RA, csr::MSTATUS, reg::SP);
41//! addi(reg::A0, reg::ZERO, 100);
42//! add(reg::A1, reg::A0, reg::SP);
43//! ret();
44//! };
45//!
46//! // Traditional style
47//! let mut builder2 = Riscv64InstructionBuilder::new();
48//! builder2.csrrw(reg::RA, csr::MSTATUS, reg::SP);
49//! builder2.addi(reg::A0, reg::ZERO, 100);
50//! builder2.ret();
51//! let instructions2 = builder2.instructions();
52//! // InstructionCollection provides convenient methods
53//! let bytes = instructions.to_bytes(); // Convert all to bytes
54//! let size = instructions.total_size(); // Get total size
55//! let count = instructions.len(); // Get instruction count
56//!
57//! // Iterate over instructions
58//! for instr in instructions {
59//! let bytes = instr.bytes();
60//! // Write to executable memory...
61//! }
62//! # }
63//! ```
64//!
65//! ## AArch64 Usage
66//!
67//! ```rust
68//! # #[cfg(feature = "aarch64")]
69//! # {
70//! use jit_assembler::aarch64::{reg, Aarch64InstructionBuilder};
71//! use jit_assembler::common::InstructionBuilder;
72//!
73//! // Create an AArch64 function that adds two numbers
74//! let mut builder = Aarch64InstructionBuilder::new();
75//! let instructions = builder
76//! .add(reg::X0, reg::X0, reg::X1) // Add first two arguments (X0 + X1 -> X0)
77//! .ret() // Return
78//! .instructions();
79//!
80//! // Macro style (concise and assembly-like)
81//! let instructions3 = jit_assembler::aarch64_asm! {
82//! add(reg::X0, reg::X0, reg::X1); // Add first two arguments
83//! mov_imm(reg::X1, 42); // Load immediate 42 into X1
84//! mul(reg::X0, reg::X0, reg::X1); // Multiply X0 by 42
85//! ret(); // Return
86//! };
87//!
88//! // More complex AArch64 example with immediate values
89//! let mut builder2 = Aarch64InstructionBuilder::new();
90//! let instructions2 = builder2
91//! .mov_imm(reg::X1, 42) // Load immediate 42 into X1
92//! .mul(reg::X0, reg::X0, reg::X1) // Multiply X0 by 42
93//! .addi(reg::X0, reg::X0, 100) // Add 100 to result
94//! .ret() // Return
95//! .instructions();
96//! # }
97//! ```
98//!
99//! ## JIT Execution (std-only)
100//!
101//! ```rust,no_run
102//! # #[cfg(feature = "riscv64")]
103//! # {
104//! use jit_assembler::riscv64::{reg, Riscv64InstructionBuilder};
105//! use jit_assembler::common::InstructionBuilder;
106//!
107//! // Create a JIT function that adds two numbers
108//! let add_func = unsafe {
109//! Riscv64InstructionBuilder::new()
110//! .add(reg::A0, reg::A0, reg::A1) // Add first two arguments
111//! .ret() // Return result
112//! .function::<fn(u64, u64) -> u64>()
113//! }.expect("Failed to create JIT function");
114//!
115//! // Call the JIT function naturally!
116//! let result = add_func.call(10, 20);
117//! assert_eq!(result, 30);
118//! # }
119//! ```
120
121#[cfg(not(feature = "std"))]
122extern crate alloc;
123
124// Common types and traits shared across architectures
125pub mod common;
126
127// Re-export JIT functionality when std is available
128#[cfg(feature = "std")]
129pub use common::jit::{CallableJitFunction, JitError};
130
131// Architecture-specific modules
132#[cfg(feature = "riscv64")]
133pub mod riscv64;
134
135#[cfg(feature = "x86_64")]
136pub mod x86_64;
137
138#[cfg(feature = "aarch64")]
139pub mod aarch64;
140
141// Re-export for convenience (default to RISC-V if available)
142#[cfg(feature = "riscv64")]
143pub use riscv64 as default_arch;
144
145/// Generic JIT assembler macro - Reference implementation
146///
147/// This is a reference implementation that can be used by each architecture.
148/// Each architecture can provide their own specialized version by specifying
149/// the appropriate InstructionBuilder type.
150///
151/// Usage pattern for architecture-specific implementations:
152/// ```rust
153/// #[macro_export]
154/// macro_rules! arch_asm {
155/// ($($method:ident($($args:expr),*);)*) => {{
156/// $crate::jit_asm_generic!(YourArchInstructionBuilder, $($method($($args),*);)*)
157/// }};
158/// }
159/// ```
160#[macro_export]
161macro_rules! jit_asm_generic {
162 ($builder_type:ty, $($method:ident($($args:expr),*);)*) => {{
163 let mut builder = <$builder_type>::new();
164 $(
165 builder.$method($($args),*);
166 )*
167 builder.instructions().to_vec()
168 }};
169}