juicebox_asm/
lib.rs

1// SPDX-License-Identifier: MIT
2//
3// Copyright (c) 2023, Johannes Stoelp <dev@memzero.de>
4
5//! A simple `x64` jit assembler with a minimal runtime to execute emitted code for fun.
6//!
7//! The following is an fibonacci example implementation.
8//! ```rust
9//! use juicebox_asm::{Asm, Reg64, Imm64, Label};
10//! use juicebox_asm::insn::*;
11//! use juicebox_asm::Runtime;
12//!
13//! const fn fib_rs(n: u64) -> u64 {
14//!     match n {
15//!         0 => 0,
16//!         1 => 1,
17//!         _ => fib_rs(n - 2) + fib_rs(n - 1),
18//!     }
19//! }
20//!
21//! fn main() {
22//!     let mut asm = Asm::new();
23//!
24//!     let mut lp = Label::new();
25//!     let mut end = Label::new();
26//!
27//!     // Reference implementation:
28//!     //
29//!     // int fib(int n) {
30//!     //   int tmp = 0;
31//!     //   int prv = 1;
32//!     //   int sum = 0;
33//!     // loop:
34//!     //   if (n == 0) goto end;
35//!     //   tmp = sum;
36//!     //   sum += prv;
37//!     //   prv = tmp;
38//!     //   --n;
39//!     //   goto loop;
40//!     // end:
41//!     //   return sum;
42//!     // }
43//!
44//!     // SystemV abi:
45//!     //   rdi -> first argument
46//!     //   rax -> return value
47//!     let n = Reg64::rdi;
48//!     let sum = Reg64::rax;
49//!
50//!     let tmp = Reg64::rcx;
51//!     let prv = Reg64::rbx;
52//!
53//!     asm.mov(tmp, Imm64::from(0));
54//!     asm.mov(prv, Imm64::from(1));
55//!     asm.mov(sum, Imm64::from(0));
56//!
57//!     asm.bind(&mut lp);
58//!     asm.test(n, n);
59//!     asm.jz(&mut end);
60//!     asm.mov(tmp, sum);
61//!     asm.add(sum, prv);
62//!     asm.mov(prv, tmp);
63//!     asm.dec(n);
64//!     asm.jmp(&mut lp);
65//!     asm.bind(&mut end);
66//!     asm.ret();
67//!
68//!     // Move code into executable page and get function pointer to it.
69//!     let mut rt = Runtime::new();
70//!     let fib = unsafe { rt.add_code::<extern "C" fn(u64) -> u64>(&asm.into_code()) };
71//!
72//!     for n in 0..15 {
73//!         let fib_jit = fib(n);
74//!         println!("fib({}) = {}", n, fib_jit);
75//!         assert_eq!(fib_jit, fib_rs(n));
76//!     }
77//! }
78//! ```
79
80mod asm;
81mod disasm;
82mod imm;
83mod label;
84mod mem;
85mod reg;
86mod rt;
87
88pub mod insn;
89
90pub use asm::Asm;
91pub use imm::{Imm16, Imm32, Imm64, Imm8};
92pub use label::Label;
93pub use mem::{Mem16, Mem32, Mem64, Mem8};
94pub use reg::{Reg16, Reg32, Reg64, Reg8};
95pub use rt::Runtime;