use libc::c_int; use lightning_sys::*; use core::mem::size_of; fn stack_push(js: &mut JitState, reg: Reg, sp: &mut c_int) { js.stxi_i((*sp).into(), Reg::FP, reg); *sp += size_of::() as c_int; } fn stack_pop(js: &mut JitState, reg: Reg, sp: &mut c_int) { *sp -= size_of::() as c_int; js.ldxi_i(reg, Reg::FP, (*sp).into()); } fn compile_rpn<'a>(js: &mut JitState<'a>, mut expr: &str) -> JitNode<'a> { let func = js.note(None, 0); js.prolog(); let inp = js.arg(); let stack_base = js.allocai(32 * size_of::() as c_int); let mut stack_ptr = stack_base; js.getarg_i(Reg::R(2), &inp); while ! expr.is_empty() { if expr.starts_with(|c: char| c.is_ascii_digit()) { let s: String = expr.chars().take_while(char::is_ascii_digit).collect(); let val = s.parse::().unwrap(); expr = &expr[s.len()..]; stack_push(js, Reg::R(0), &mut stack_ptr); js.movi(Reg::R(0), val); } else { match expr.as_bytes().get(0) { Some(b'x') => { stack_push(js, Reg::R(0), &mut stack_ptr); js.movr(Reg::R(0), Reg::R(2)); }, Some(b'+') => { stack_pop(js, Reg::R(1), &mut stack_ptr); js.addr(Reg::R(0), Reg::R(1), Reg::R(0)); }, Some(b'-') => { stack_pop(js, Reg::R(1), &mut stack_ptr); js.subr(Reg::R(0), Reg::R(1), Reg::R(0)); }, Some(b'*') => { stack_pop(js, Reg::R(1), &mut stack_ptr); js.mulr(Reg::R(0), Reg::R(1), Reg::R(0)); }, Some(b'/') => { stack_pop(js, Reg::R(1), &mut stack_ptr); js.divr(Reg::R(0), Reg::R(1), Reg::R(0)); }, _ => panic!("cannot compile: {}", expr), } expr = &expr[1..]; } } js.retr(Reg::R(0)); js.epilog(); func } fn main() { let mut j = Jit::new(); let mut js = j.new_state(); let nc = compile_rpn(&mut js, "32x9*5/+"); let nf = compile_rpn(&mut js, "x32-5*9/"); let _ = js.raw_emit(); unsafe fn to_func(ptr: JitPointer) -> extern "C" fn(T) -> R { *(&ptr as *const *mut core::ffi::c_void as *const extern "C" fn(T) -> R) } let c2f = js.address(&nc); let c2f = unsafe { to_func::<_, c_int>(c2f) }; let f2c = js.address(&nf); let f2c = unsafe { to_func::<_, c_int>(f2c) }; js.clear(); print!("\nC:"); for i in 0..=10 { print!("{:3} ", i * 10); } print!("\nF:"); for i in 0..=10 { print!("{:3} ", c2f(i * 10)); } println!(); print!("\nF:"); for i in 0..=10 { print!("{:3} ", i * 18 + 32); } print!("\nC:"); for i in 0..=10 { print!("{:3} ", f2c(i * 18 + 32)); } println!(); }