From 8316b628bbc9945fd1d08305317cf49a6482801f Mon Sep 17 00:00:00 2001 From: Johannes Stoelp Date: Sun, 5 Mar 2023 22:20:48 +0100 Subject: Added CALL and call extern fn example --- examples/add.rs | 30 ++++++++++++++++++++++++++++++ src/insn.rs | 6 ++++++ src/insn/call.rs | 7 +++++++ src/prelude.rs | 2 +- src/rt.rs | 3 ++- 5 files changed, 46 insertions(+), 2 deletions(-) create mode 100644 examples/add.rs create mode 100644 src/insn/call.rs diff --git a/examples/add.rs b/examples/add.rs new file mode 100644 index 0000000..ef010b6 --- /dev/null +++ b/examples/add.rs @@ -0,0 +1,30 @@ +use juicebox_asm::prelude::*; +use juicebox_asm::Runtime; +use Reg64::*; + +extern "C" fn add(a: u32, b: u32) -> u32 { + a + b +} + +fn main() { + let mut asm = Asm::new(); + + // SystemV abi: + // rdi -> first argument + // rsi -> second argument + // rax -> return value + // + asm.mov(rsi, Imm64::from(42)); + asm.mov(rax, Imm64::from(add as u64)); + asm.call(rax); + asm.ret(); + + let code = asm.into_code(); + std::fs::write("jit.asm", &code).unwrap(); + + let rt = Runtime::new(&code); + let add42 = unsafe { rt.as_fn:: u32>() }; + + let res = add42(5); + assert_eq!(res, 47); +} diff --git a/src/insn.rs b/src/insn.rs index 2a6ca42..8810085 100644 --- a/src/insn.rs +++ b/src/insn.rs @@ -1,6 +1,7 @@ //! Trait definitions of various instructions. mod add; +mod call; mod dec; mod jmp; mod jnz; @@ -15,6 +16,11 @@ pub trait Add { fn add(&mut self, op1: T, op2: U); } +pub trait Call { + /// Emit a call instruction. + fn call(&mut self, op1: T); +} + pub trait Dec { /// Emit a decrement instruction. fn dec(&mut self, op1: T); diff --git a/src/insn/call.rs b/src/insn/call.rs new file mode 100644 index 0000000..8a71db8 --- /dev/null +++ b/src/insn/call.rs @@ -0,0 +1,7 @@ +use crate::prelude::*; + +impl Call for Asm { + fn call(&mut self, op1: Reg64) { + self.encode_r(0xff, 0x2, op1); + } +} diff --git a/src/prelude.rs b/src/prelude.rs index 0093240..b21d67c 100644 --- a/src/prelude.rs +++ b/src/prelude.rs @@ -7,4 +7,4 @@ pub use crate::imm::{Imm16, Imm32, Imm64, Imm8}; pub use crate::label::Label; pub use crate::reg::{Reg16, Reg32, Reg64, Reg8}; -pub use crate::insn::{Add, Dec, Jmp, Jnz, Jz, Mov, Test}; +pub use crate::insn::{Add, Call, Dec, Jmp, Jnz, Jz, Mov, Test}; diff --git a/src/rt.rs b/src/rt.rs index 1e9289e..7b5f74b 100644 --- a/src/rt.rs +++ b/src/rt.rs @@ -11,7 +11,7 @@ pub struct Runtime { impl Runtime { /// Create a new [Runtime]. - pub fn new(code: &[u8]) -> Runtime { + pub fn new(code: impl AsRef<[u8]>) -> Runtime { // Allocate a single page. let len = core::num::NonZeroUsize::new(4096).unwrap(); let buf = unsafe { @@ -27,6 +27,7 @@ impl Runtime { }; { // Copy over code. + let code = code.as_ref(); assert!(code.len() < len.get()); unsafe { std::ptr::copy_nonoverlapping(code.as_ptr(), buf.cast(), len.get()) }; } -- cgit v1.2.3