gen/
gen.rs

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
//! Add example.
//!
//! Jit compile a function at runtime (generate native host code) which calls a function defined in
//! the example based on the SystemV abi to demonstrate the [`juicebox_asm`] crate.

#[cfg(not(any(target_arch = "x86_64", target_os = "linux")))]
compile_error!("Only supported on x86_64 with SystemV abi");

use juicebox_asm::insn::*;
use juicebox_asm::{Asm, Imm8, Reg64::*, Runtime};
use juicebox_asm::{Mem16, Mem32, Mem64, Mem8};

extern "C" fn add(a: u32, b: u32) -> u32 {
    a + b
}

fn main() {
    let mut asm1 = Asm::new();
    //asm1.add(Mem16::indirect(rdi), Imm8::from(0x80u8));
    asm1.test(rax, rax);
    asm1.cmp(Mem8::indirect(rax), Imm8::from(0u8));
    asm1.ret();

    let code = asm1.into_code();
    std::fs::write("jit.asm", &code).unwrap();

    let mut asm2 = Asm::new();
    //asm2.mov(Reg16::cx, Imm16::from(1u16));
    //asm2.mov(Mem::Indirect(rdi), Reg16::cx);
    asm2.ret();

    let mut rt = Runtime::new();
    let fn1 = unsafe { rt.add_code::<extern "C" fn(*mut u64)>(code) };
    let fn2 = unsafe { rt.add_code::<extern "C" fn(*mut u64)>(asm2.into_code()) };

    let mut data = 0xffff_ffff_ffff_ff80u64;
    fn1(&mut data as *mut u64);
    println!("data={:x}", data);

    let mut data = 0xffff_ffff_ffff_ffffu64;
    fn2(&mut data as *mut u64);
    println!("data={:x}", data);
}