lightning_sys/
jitstate.rs

1use crate::bindings;
2use crate::Reg;
3use crate::JitNode;
4use crate::{JitWord, JitPointer};
5use crate::ToFFI;
6use std::ffi::{CString, c_void};
7use std::ptr::null_mut;
8
9#[derive(Debug)]
10pub struct JitState<'a> {
11    pub(crate) state: *mut bindings::jit_state_t,
12    pub(crate) phantom: std::marker::PhantomData<&'a ()>,
13}
14
15impl<'a> Drop for JitState<'a> {
16    fn drop(&mut self) {
17        unsafe {
18            bindings::_jit_destroy_state(self.state);
19        }
20    }
21}
22
23
24macro_rules! jit_impl {
25    ( $op:ident, _ ) => { jit_impl_inner!($op, _); };
26
27    ( $op:ident, w ) => { jit_impl_inner!($op, w, a: Reg => JitWord); };
28    //( $op:ident, f ) => { jit_impl_inner!($op, f, a: Reg => JitWord); };
29    //( $op:ident, d ) => { jit_impl_inner!($op, d, a: Reg => JitWord); };
30    //( $op:ident, p ) => { jit_impl_inner!($op, p, a: Reg => JitWord); };
31
32    ( $op:ident, i_w ) => { jit_impl_inner!($op, w, a: JitWord => _); };
33    ( $op:ident, i_f ) => { jit_impl_inner!($op, f, a: f32 => _); };
34    ( $op:ident, i_d ) => { jit_impl_inner!($op, d, a: f64 => _); };
35    ( $op:ident, i_p ) => { jit_impl_inner!($op, p, a: JitPointer => _); };
36
37    ( $op:ident, ww ) => { jit_impl_inner!($op, ww, a: Reg => JitWord, b: Reg => JitWord); };
38    //( $op:ident, wp ) => { jit_impl_inner!($op, wp, a: Reg => JitWord, b: Reg => JitWord); };
39    //( $op:ident, fp ) => { jit_impl_inner!($op, fp, a: Reg => JitWord, b: Reg => JitWord); };
40    //( $op:ident, dp ) => { jit_impl_inner!($op, dp, a: Reg => JitWord, b: Reg => JitWord); };
41    //( $op:ident, pw ) => { jit_impl_inner!($op, pw, a: Reg => JitWord, b: Reg => JitWord); };
42    //( $op:ident, wf ) => { jit_impl_inner!($op, wf, a: Reg => JitWord, b: Reg => JitWord); };
43    //( $op:ident, wd ) => { jit_impl_inner!($op, wd, a: Reg => JitWord, b: Reg => JitWord); };
44
45    ( $op:ident, i_ww ) => { jit_impl_inner!($op, ww, a: Reg => JitWord, b: JitWord => _); };
46    ( $op:ident, i_wp ) => { jit_impl_inner!($op, wp, a: Reg => JitWord, b: JitPointer => _); };
47    ( $op:ident, i_fp ) => { jit_impl_inner!($op, fp, a: Reg => JitWord, b: JitPointer => _); };
48    ( $op:ident, i_dp ) => { jit_impl_inner!($op, dp, a: Reg => JitWord, b: JitPointer => _); };
49    ( $op:ident, i_pw ) => { jit_impl_inner!($op, pw, a: JitPointer => _, b: Reg => JitWord); };
50    ( $op:ident, i_wf ) => { jit_impl_inner!($op, wf, a: Reg => JitWord, b: f32 => _); };
51    ( $op:ident, i_wd ) => { jit_impl_inner!($op, wd, a: Reg => JitWord, b: f64 => _); };
52
53    ( $op:ident, www ) => { jit_impl_inner!($op, www, a: Reg => JitWord, b: Reg => JitWord, c: Reg => JitWord); };
54    //( $op:ident, wwf ) => { jit_impl_inner!($op, wwf, a: Reg => JitWord, b: Reg => JitWord, c: Reg => JitWord); };
55    //( $op:ident, wwd ) => { jit_impl_inner!($op, wwd, a: Reg => JitWord, b: Reg => JitWord, c: Reg => JitWord); };
56    //( $op:ident, pww ) => { jit_impl_inner!($op, pww, a: Reg => JitWord, b: Reg => JitWord, c: Reg => JitWord); };
57    //( $op:ident, pwf ) => { jit_impl_inner!($op, pwf, a: Reg => JitWord, b: Reg => JitWord, c: Reg => JitWord); };
58    //( $op:ident, pwd ) => { jit_impl_inner!($op, pwd, a: Reg => JitWord, b: Reg => JitWord, c: Reg => JitWord); };
59
60    ( $op:ident, i_www ) => { jit_impl_inner!($op, www, a: Reg => JitWord, b: Reg => JitWord, c: JitWord => _); };
61    ( $op:ident, i_wwf ) => { jit_impl_inner!($op, wwf, a: Reg => JitWord, b: Reg => JitWord, c: f32 => _); };
62    ( $op:ident, i_wwd ) => { jit_impl_inner!($op, wwd, a: Reg => JitWord, b: Reg => JitWord, c: f64 => _); };
63    ( $op:ident, i_pww ) => { jit_impl_inner!($op, pww, a: Reg => JitWord, b: Reg => JitWord, c: JitWord => _); };
64    ( $op:ident, i_pwf ) => { jit_impl_inner!($op, pwf, a: Reg => JitWord, b: Reg => JitWord, c: f32 => _); };
65    ( $op:ident, i_pwd ) => { jit_impl_inner!($op, pwd, a: Reg => JitWord, b: Reg => JitWord, c: f64 => _); };
66
67    ( $op:ident, qww ) => { jit_impl_inner!($op, qww, a: Reg => i32, b: Reg => i32, c: Reg => JitWord, d: Reg => JitWord); };
68    ( $op:ident, i_qww ) => { jit_impl_inner!($op, qww, a: Reg => i32, b: Reg => i32, c: Reg => JitWord, d: JitWord => _); };
69}
70
71macro_rules! jit_store {
72    ( $op:ident, ww ) => { jit_impl_inner!($op, ww, a: Reg => JitWord, b: Reg => JitWord); };
73
74    ( $op:ident, i_pw ) => { jit_impl_inner!($op, pw, a: JitPointer => _, b: Reg => JitWord); };
75
76    ( $op:ident, www ) => { jit_impl_inner!($op, www, a: Reg => JitWord, b: Reg => JitWord, c: Reg => JitWord); };
77
78    ( $op:ident, i_www ) => { jit_impl_inner!($op, www, a: JitWord => _, b: Reg => JitWord, c: Reg => JitWord); };
79
80}
81
82macro_rules! jit_impl_type {
83    ( $e:expr => _ ) => { $e };
84    ( $e:expr => $t:ty ) => { $e as $t };
85}
86
87macro_rules! jit_impl_inner {
88    ( $op:ident, $ifmt:ident $(, $arg:ident: $type:ty => $target:ty)* ) => {
89        paste::item! {
90            pub fn $op(&mut self $(, $arg: $type)*) -> JitNode<'a> {
91                JitNode{
92                    node: unsafe { bindings::[< _jit_new_node_ $ifmt >](self.state, bindings::jit_code_t::[< jit_code_ $op >] $(, jit_impl_type!($arg.to_ffi() => $target))*) },
93                    phantom: std::marker::PhantomData,
94                }
95            }
96        }
97    };
98    ( $op:ident, $ifmt:ident $(, $arg:ident: $type:ty)* ) => {
99        jit_impl_inner!(kkk);
100    };
101}
102
103macro_rules! jit_reexport {
104    ( $fn:ident $(, $arg:ident : $typ:ty )*; -> JitNode) => {
105        paste::item! {
106            pub fn $fn(&mut self $(, $arg: $typ )*) -> JitNode<'a> {
107                JitNode{
108                    node: unsafe { bindings::[< _jit_ $fn >](self.state $(, $arg.to_ffi())*) },
109                    phantom: std::marker::PhantomData,
110                }
111            }
112        }
113    };
114    ( $fn:ident $(, $arg:ident : $typ:ty )*; -> bool) => {
115        paste::item! {
116            pub fn $fn(&mut self $(, $arg: $typ )*) -> bool {
117                unsafe { bindings::[< _jit_ $fn >](self.state $(, $arg.to_ffi())*) != 0 }
118            }
119        }
120    };
121    ( $fn:ident $(, $arg:ident : $typ:ty )*; -> $ret:ty) => {
122        paste::item! {
123            pub fn $fn(&mut self $(, $arg: $typ )*) -> $ret {
124                unsafe { bindings::[< _jit_ $fn >](self.state $(, $arg.to_ffi())*) }
125            }
126        }
127    };
128    ( $fn:ident $(, $arg:ident : $typ:ty )*) => { jit_reexport!($fn $(, $arg : $typ)*; -> ()); }
129}
130
131macro_rules! jit_imm {
132    (i) => { JitWord };
133    (r) => { Reg };
134    (f) => { f32 };
135    (d) => { f64 };
136}
137
138macro_rules! jit_branch {
139    ( $fn:ident, $t:ident ) => {
140        paste::item! {
141            pub fn $fn(&mut self, a: Reg, b: jit_imm!($t)) -> JitNode<'a> {
142                JitNode{
143                    node: unsafe{ bindings::_jit_new_node_pww(self.state, bindings::jit_code_t::[< jit_code_ $fn >], null_mut::<c_void>(), a.to_ffi() as JitWord, b.to_ffi() as JitWord) },
144                    phantom: std::marker::PhantomData,
145                }
146            }
147        }
148    };
149}
150
151macro_rules! jit_alias {
152    ( $targ:ident => $new:ident $(, $arg:ident : $typ:ty )*; -> JitNode ) => {
153        pub fn $new(&mut self $(, $arg: $typ )*) -> JitNode<'a> {
154            self.$targ($( $arg ),*)
155        }
156    };
157    ( $targ:ident => $new:ident $(, $arg:ident : $typ:ty )*; -> $ret:ty) => {
158        pub fn $new(&mut self $(, $arg: $typ )*) -> $ret {
159            self.$targ($( $arg ),*)
160        }
161    };
162    ( $targ:ident => $new:ident $(, $arg:ident : $typ:ty )*) => { jit_alias!($targ => $new $(, $arg : $typ)*; -> ()); }
163}
164
165/// Convert a nullable reference into the C type representing it.
166fn pointer_from<T>(p: Option<&mut T>) -> * mut T {
167    p.map(|x| x as _).unwrap_or(std::ptr::null_mut())
168}
169
170/// `JitState` utility methods
171impl<'a> JitState<'a> {
172    pub fn clear(&mut self) {
173        unsafe {
174            bindings::_jit_clear_state(self.state);
175        }
176    }
177
178    // there is no way to require a function type in a trait bound
179    // without specifying the number of arguments
180    pub unsafe fn emit<T: Copy>(&mut self) -> T {
181        *(&bindings::_jit_emit(self.state) as *const *mut core::ffi::c_void as *const T)
182    }
183
184    pub fn raw_emit(&mut self) -> JitPointer {
185        unsafe {
186            bindings::_jit_emit(self.state)
187        }
188    }
189
190    jit_reexport!(address, node: &JitNode; -> JitPointer);
191
192    jit_reexport!(forward_p, node: &JitNode; -> bool);
193    jit_reexport!(indirect_p, node: &JitNode; -> bool);
194    jit_reexport!(target_p, node: &JitNode; -> bool);
195    jit_reexport!(arg_register_p, node: &JitNode; -> bool);
196    jit_reexport!(callee_save_p, reg: Reg; -> bool);
197    jit_reexport!(pointer_p, ptr: JitPointer; -> bool);
198
199    jit_reexport!(patch, instr: &JitNode);
200    jit_reexport!(patch_at, instr: &JitNode, target: &JitNode);
201    jit_reexport!(patch_abs, instr: &JitNode, target: JitPointer);
202    jit_reexport!(realize);
203
204    // get_code needs argument mangling that jit_reexport currently does not
205    // provide
206    pub fn get_code(&self, code_size: Option<&mut JitWord>) -> JitPointer {
207        unsafe { bindings::_jit_get_code(self.state, pointer_from(code_size)) }
208    }
209
210    jit_reexport!(set_code, buf: JitPointer, size: JitWord; -> ());
211
212    // get_data needs argument mangling that jit_reexport currently does not
213    // provide
214    pub fn get_data(
215        &self,
216        data_size: Option<&mut JitWord>,
217        note_size: Option<&mut JitWord>
218    ) -> JitPointer {
219        unsafe {
220            bindings::_jit_get_data(
221                self.state,
222                pointer_from(data_size),
223                pointer_from(note_size),
224            )
225        }
226    }
227
228    jit_reexport!(set_data, buf: JitPointer, data_size: JitWord, flags: JitWord; -> ());
229
230    jit_reexport!(print);
231}
232
233/// implmentations of general instructions
234impl<'a> JitState<'a> {
235    jit_impl!(live, w);
236    jit_impl!(align, w);
237
238    pub fn name(&mut self, name: &str) -> JitNode<'a> {
239        // I looked at the lightning code, this will be copied
240        let cs = CString::new(name).unwrap();
241        JitNode{
242            node: unsafe { bindings::_jit_name(self.state, cs.as_ptr()) },
243            phantom: std::marker::PhantomData,
244        }
245    }
246
247    pub fn note(&mut self, file: Option<&str>, line: u32) -> JitNode<'a> {
248        // I looked at the lightning code, this will be copied
249        let cs = file
250            .map(CString::new)
251            .map(Result::unwrap)
252            .map(|c| c.as_ptr())
253            .unwrap_or(core::ptr::null());
254        JitNode{
255            node: unsafe { bindings::_jit_note(self.state, cs, line as i32) },
256            phantom: std::marker::PhantomData,
257        }
258    }
259
260    jit_reexport!(label; -> JitNode);
261    jit_reexport!(forward; -> JitNode);
262    jit_reexport!(indirect; -> JitNode);
263    jit_reexport!(link, node: &JitNode);
264
265    jit_reexport!(prolog);
266    jit_reexport!(ellipsis);
267
268    jit_reexport!(allocai, size: i32; -> i32);
269    jit_reexport!(allocar, off: Reg, size: Reg);
270
271    jit_reexport!(arg; -> JitNode);
272
273    jit_reexport!(getarg_c, reg: Reg, node: &JitNode);
274    jit_reexport!(getarg_uc, reg: Reg, node: &JitNode);
275    jit_reexport!(getarg_s, reg: Reg, node: &JitNode);
276    jit_reexport!(getarg_us, reg: Reg, node: &JitNode);
277    jit_reexport!(getarg_i, reg: Reg, node: &JitNode);
278    #[cfg(target_pointer_width = "64")]
279    jit_reexport!(getarg_ui, reg: Reg, node: &JitNode);
280    #[cfg(target_pointer_width = "64")]
281    jit_reexport!(getarg_l, reg: Reg, node: &JitNode);
282    #[cfg(target_pointer_width = "64")]
283    jit_alias!(getarg_l => getarg, reg: Reg, node: &JitNode);
284    #[cfg(target_pointer_width = "32")]
285    jit_alias!(getarg_i => getarg, reg: Reg, node: &JitNode);
286
287    jit_reexport!(putargr, reg: Reg, arg: &JitNode);
288    jit_reexport!(putargi, imm: JitWord, arg: &JitNode);
289
290    jit_impl!(va_start, w);
291    jit_impl!(va_arg, ww);
292    jit_impl!(va_arg_d, ww);
293    jit_reexport!(va_push, arg: Reg);
294    jit_impl!(va_end, w);
295
296    jit_impl!(addr, www);
297    jit_impl!(addi, i_www);
298    jit_impl!(addcr, www);
299    jit_impl!(addci, i_www);
300    jit_impl!(addxr, www);
301    jit_impl!(addxi, i_www);
302    jit_impl!(subr, www);
303    jit_impl!(subi, i_www);
304    jit_impl!(subcr, www);
305    jit_impl!(subci, i_www);
306    jit_impl!(subxr, www);
307    jit_impl!(subxi, i_www);
308
309    pub fn rsbr(&mut self, a: Reg, b: Reg, c: Reg) -> JitNode<'a> {
310        self.subr(a, c, b)
311    }
312
313    jit_impl!(rsbi, i_www);
314
315    jit_impl!(mulr, www);
316    jit_impl!(muli, i_www);
317    jit_impl!(qmulr, qww);
318    jit_impl!(qmuli, i_qww);
319    jit_impl!(qmulr_u, qww);
320    jit_impl!(qmuli_u, i_qww);
321    jit_impl!(divr, www);
322    jit_impl!(divi, i_www);
323    jit_impl!(divr_u, www);
324    jit_impl!(divi_u, i_www);
325    jit_impl!(qdivr, qww);
326    jit_impl!(qdivi, i_qww);
327    jit_impl!(qdivr_u, qww);
328    jit_impl!(qdivi_u, i_qww);
329    jit_impl!(remr, www);
330    jit_impl!(remi, i_www);
331    jit_impl!(remr_u, www);
332    jit_impl!(remi_u, i_www);
333
334    jit_impl!(andr, www);
335    jit_impl!(andi, i_www);
336    jit_impl!(orr, www);
337    jit_impl!(ori, i_www);
338    jit_impl!(xorr, www);
339    jit_impl!(xori, i_www);
340
341    jit_impl!(lshr, www);
342    jit_impl!(lshi, i_www);
343    jit_impl!(rshr, www);
344    jit_impl!(rshi, i_www);
345    jit_impl!(rshi_u, i_www);
346    jit_impl!(rshr_u, www);
347
348    jit_impl!(negr, ww);
349    jit_impl!(comr, ww);
350
351    jit_impl!(ltr, www);
352    jit_impl!(lti, i_www);
353    jit_impl!(ltr_u, www);
354    jit_impl!(lti_u, i_www);
355    jit_impl!(ler, www);
356    jit_impl!(lei, i_www);
357    jit_impl!(ler_u, www);
358    jit_impl!(lei_u, i_www);
359    jit_impl!(eqr, www);
360    jit_impl!(eqi, i_www);
361    jit_impl!(ger, www);
362    jit_impl!(ger_u, www);
363    jit_impl!(gei, i_www);
364    jit_impl!(gei_u, i_www);
365    jit_impl!(gtr, www);
366    jit_impl!(gti, i_www);
367    jit_impl!(gtr_u, www);
368    jit_impl!(gti_u, i_www);
369    jit_impl!(ner, www);
370    jit_impl!(nei, i_www);
371
372    jit_impl!(movr, ww);
373    jit_impl!(movi, i_ww);
374
375    jit_impl!(extr_c, ww);
376    jit_impl!(extr_uc, ww);
377    jit_impl!(extr_s, ww);
378    jit_impl!(extr_us, ww);
379    #[cfg(target_pointer_width = "64")]
380    jit_impl!(extr_i, ww);
381    #[cfg(target_pointer_width = "64")]
382    jit_impl!(extr_ui, ww);
383
384    jit_impl!(htonr_us, ww);
385    jit_alias!(htonr_us => ntohr_us, targ: Reg, src: Reg; -> JitNode);
386    jit_impl!(htonr_ui, ww);
387    jit_alias!(htonr_ui => ntohr_ui, targ: Reg, src: Reg; -> JitNode);
388    #[cfg(target_pointer_width = "64")]
389    jit_impl!(htonr_ul, ww);
390    #[cfg(target_pointer_width = "64")]
391    jit_alias!(htonr_ul => ntohr_ul, targ: Reg, src: Reg; -> JitNode);
392    #[cfg(target_pointer_width = "32")]
393    jit_alias!(htonr_ui => htonr, targ: Reg, src: Reg; -> JitNode);
394    #[cfg(target_pointer_width = "64")]
395    jit_alias!(htonr_ul => htonr, targ: Reg, src: Reg; -> JitNode);
396    jit_alias!(htonr => ntohr, targ: Reg, src: Reg; -> JitNode);
397
398    jit_impl!(ldr_c, ww);
399    jit_impl!(ldi_c, i_wp);
400    jit_impl!(ldr_uc, ww);
401    jit_impl!(ldi_uc, i_wp);
402    jit_impl!(ldr_s, ww);
403    jit_impl!(ldi_s, i_wp);
404    jit_impl!(ldr_us, ww);
405    jit_impl!(ldi_us, i_wp);
406    jit_impl!(ldr_i, ww);
407    jit_impl!(ldi_i, i_wp);
408    #[cfg(target_pointer_width = "64")]
409    jit_impl!(ldr_ui, ww);
410    #[cfg(target_pointer_width = "64")]
411    jit_impl!(ldi_ui, i_wp);
412    #[cfg(target_pointer_width = "64")]
413    jit_impl!(ldr_l, ww);
414    #[cfg(target_pointer_width = "64")]
415    jit_impl!(ldi_l, i_wp);
416    #[cfg(target_pointer_width = "32")]
417    jit_alias!(ldr_i => ldr, targ: Reg, src: Reg; -> JitNode);
418    #[cfg(target_pointer_width = "32")]
419    jit_alias!(ldi_i => ldi, targ: Reg, src: JitPointer; -> JitNode);
420    #[cfg(target_pointer_width = "64")]
421    jit_alias!(ldr_l => ldr, targ: Reg, src: Reg; -> JitNode);
422    #[cfg(target_pointer_width = "64")]
423    jit_alias!(ldi_l => ldi, targ: Reg, src: JitPointer; -> JitNode);
424
425    jit_impl!(ldxr_c, www);
426    jit_impl!(ldxi_c, i_www);
427    jit_impl!(ldxr_uc, www);
428    jit_impl!(ldxi_uc, i_www);
429    jit_impl!(ldxr_s, www);
430    jit_impl!(ldxi_s, i_www);
431    jit_impl!(ldxr_us, www);
432    jit_impl!(ldxi_us, i_www);
433    jit_impl!(ldxr_i, www);
434    jit_impl!(ldxi_i, i_www);
435    #[cfg(target_pointer_width = "64")]
436    jit_impl!(ldxr_ui, www);
437    #[cfg(target_pointer_width = "64")]
438    jit_impl!(ldxi_ui, i_www);
439    #[cfg(target_pointer_width = "64")]
440    jit_impl!(ldxr_l, www);
441    #[cfg(target_pointer_width = "64")]
442    jit_impl!(ldxi_l, i_www);
443    #[cfg(target_pointer_width = "32")]
444    jit_alias!(ldxr_i => ldxr, targ: Reg, a: Reg, b: Reg; -> JitNode);
445    #[cfg(target_pointer_width = "32")]
446    jit_alias!(ldxi_i => ldxi, targ: Reg, src: Reg, off: JitWord; -> JitNode);
447    #[cfg(target_pointer_width = "64")]
448    jit_alias!(ldxr_l => ldxr, targ: Reg, a: Reg, b: Reg; -> JitNode);
449    #[cfg(target_pointer_width = "64")]
450    jit_alias!(ldxi_l => ldxi, targ: Reg, src: Reg, off: JitWord; -> JitNode);
451
452    jit_store!(str_c, ww);
453    jit_store!(sti_c, i_pw);
454    jit_store!(str_s, ww);
455    jit_store!(sti_s, i_pw);
456    jit_store!(str_i, ww);
457    jit_store!(sti_i, i_pw);
458    #[cfg(target_pointer_width = "64")]
459    jit_store!(str_l, ww);
460    #[cfg(target_pointer_width = "64")]
461    jit_store!(sti_l, i_pw);
462    #[cfg(target_pointer_width = "32")]
463    jit_alias!(str_i => str, targ: Reg, src: Reg; -> JitNode);
464    #[cfg(target_pointer_width = "32")]
465    jit_alias!(sti_i => sti, targ: JitPointer, src: Reg; -> JitNode);
466    #[cfg(target_pointer_width = "64")]
467    jit_alias!(str_l => str, targ: Reg, src: Reg; -> JitNode);
468    #[cfg(target_pointer_width = "64")]
469    jit_alias!(sti_i => sti, targ: JitPointer, src: Reg; -> JitNode);
470
471    jit_store!(stxr_c, www);
472    jit_store!(stxi_c, i_www);
473    jit_store!(stxr_s, www);
474    jit_store!(stxi_s, i_www);
475    jit_store!(stxr_i, www);
476    jit_store!(stxi_i, i_www);
477    #[cfg(target_pointer_width = "64")]
478    jit_store!(stxr_l, www);
479    #[cfg(target_pointer_width = "64")]
480    jit_store!(stxi_l, i_www);
481    #[cfg(target_pointer_width = "32")]
482    jit_alias!(stxr_i => stxr, off: Reg, targ: Reg, src: Reg; -> JitNode);
483    #[cfg(target_pointer_width = "32")]
484    jit_alias!(stxi_i => stxi, off: JitWord, targ: Reg, src: Reg; -> JitNode);
485    #[cfg(target_pointer_width = "64")]
486    jit_alias!(stxr_l => stxr, off: Reg, targ: Reg, src: Reg; -> JitNode);
487    #[cfg(target_pointer_width = "64")]
488    jit_alias!(stxi_l => stxi, off: JitWord, targ: Reg, src: Reg; -> JitNode);
489
490    jit_branch!(bltr, r);
491    jit_branch!(blti, i);
492    jit_branch!(bltr_u, r);
493    jit_branch!(blti_u, i);
494    jit_branch!(bler, r);
495    jit_branch!(blei, i);
496    jit_branch!(bler_u, r);
497    jit_branch!(blei_u, i);
498    jit_branch!(beqr, r);
499    jit_branch!(beqi, i);
500    jit_branch!(bger, r);
501    jit_branch!(bgei, i);
502    jit_branch!(bger_u, r);
503    jit_branch!(bgei_u, i);
504    jit_branch!(bgtr, r);
505    jit_branch!(bgti, i);
506    jit_branch!(bgtr_u, r);
507    jit_branch!(bgti_u, i);
508    jit_branch!(bner, r);
509    jit_branch!(bnei, i);
510    jit_branch!(bmsr, r);
511    jit_branch!(bmsi, i);
512    jit_branch!(bmcr, r);
513    jit_branch!(bmci, i);
514    jit_branch!(boaddr, r);
515    jit_branch!(boaddi, i);
516    jit_branch!(boaddr_u, r);
517    jit_branch!(boaddi_u, i);
518    jit_branch!(bxaddr, r);
519    jit_branch!(bxaddi, i);
520    jit_branch!(bxaddr_u, r);
521    jit_branch!(bxaddi_u, i);
522    jit_branch!(bosubr, r);
523    jit_branch!(bosubi, i);
524    jit_branch!(bosubr_u, r);
525    jit_branch!(bosubi_u, i);
526    jit_branch!(bxsubr, r);
527    jit_branch!(bxsubi, i);
528    jit_branch!(bxsubr_u, r);
529    jit_branch!(bxsubi_u, i);
530
531    jit_impl!(jmpr, w);
532
533    pub fn jmpi(&mut self) -> JitNode<'a> {
534        // I looked at the lightning code, this will be copied
535        JitNode{
536            node: unsafe { bindings::_jit_new_node_p(self.state, bindings::jit_code_t::jit_code_jmpi, std::ptr::null_mut::<c_void >()) },
537            phantom: std::marker::PhantomData,
538        }
539    }
540
541    jit_impl!(callr, w);
542    jit_impl!(calli, i_p);
543
544    jit_reexport!(prepare);
545    jit_reexport!(pushargr, arg: Reg);
546    jit_reexport!(pushargi, arg: JitWord);
547    jit_reexport!(finishr, arg: Reg);
548    jit_reexport!(finishi, arg: JitPointer; -> JitNode);
549    jit_reexport!(ret);
550    jit_reexport!(retr, rv: Reg);
551    jit_reexport!(reti, rv: JitWord);
552    jit_reexport!(retval_c, rv: Reg);
553    jit_reexport!(retval_uc, rv: Reg);
554    jit_reexport!(retval_s, rv: Reg);
555    jit_reexport!(retval_us, rv: Reg);
556    jit_reexport!(retval_i, rv: Reg);
557
558    pub fn get_note(
559        &self,
560        code: JitPointer,
561        name: Option<&mut * mut std::os::raw::c_char>,
562        file: Option<&mut * mut std::os::raw::c_char>,
563        lineno: Option<&mut bindings::jit_int32_t>,
564    ) -> bool {
565        unsafe {
566            bindings::_jit_get_note(
567                self.state,
568                code,
569                pointer_from(name),
570                pointer_from(file),
571                pointer_from(lineno),
572            ) != 0
573        }
574    }
575
576    #[cfg(target_pointer_width = "64")]
577    jit_reexport!(retval_ui, rv: Reg);
578    #[cfg(target_pointer_width = "64")]
579    jit_reexport!(retval_l, rv: Reg);
580    #[cfg(target_pointer_width = "32")]
581    jit_alias!(retval_i => retval, rv: Reg);
582    #[cfg(target_pointer_width = "64")]
583    jit_alias!(retval_l => retval, rv: Reg);
584    jit_reexport!(epilog);
585
586    jit_reexport!(frame, size: i32);
587    jit_reexport!(tramp, fsize: i32);
588}
589
590/// implmentations of 32-bit float instructions
591impl<'a> JitState<'a> {
592    jit_reexport!(arg_f; -> JitNode);
593    jit_reexport!(getarg_f, reg: Reg, arg: &JitNode);
594    jit_reexport!(putargr_f, reg: Reg, arg: &JitNode);
595    jit_reexport!(putargi_f, imm: f32, arg: &JitNode);
596
597    jit_impl!(addr_f, www);
598    jit_impl!(addi_f, i_wwf);
599    jit_impl!(subr_f, www);
600    jit_impl!(subi_f, i_wwf);
601
602    pub fn rsbr_f(&mut self, a: Reg, b: Reg, c: Reg) -> JitNode<'a> {
603        self.subr_f(a, c, b)
604    }
605
606    jit_impl!(rsbi_f, i_wwf);
607    jit_impl!(mulr_f, www);
608    jit_impl!(muli_f, i_wwf);
609    jit_impl!(divr_f, www);
610    jit_impl!(divi_f, i_wwf);
611    jit_impl!(negr_f, ww);
612    jit_impl!(absr_f, ww);
613    jit_impl!(sqrtr_f, ww);
614
615    jit_impl!(ltr_f, www);
616    jit_impl!(lti_f, i_wwf);
617    jit_impl!(ler_f, www);
618    jit_impl!(lei_f, i_wwf);
619    jit_impl!(eqr_f, www);
620    jit_impl!(eqi_f, i_wwf);
621    jit_impl!(ger_f, www);
622    jit_impl!(gei_f, i_wwf);
623    jit_impl!(gtr_f, www);
624    jit_impl!(gti_f, i_wwf);
625    jit_impl!(ner_f, www);
626    jit_impl!(nei_f, i_wwf);
627    jit_impl!(unltr_f, www);
628    jit_impl!(unlti_f, i_wwf);
629    jit_impl!(unler_f, www);
630    jit_impl!(unlei_f, i_wwf);
631    jit_impl!(uneqr_f, www);
632    jit_impl!(uneqi_f, i_wwf);
633    jit_impl!(unger_f, www);
634    jit_impl!(ungei_f, i_wwf);
635    jit_impl!(ungtr_f, www);
636    jit_impl!(ungti_f, i_wwf);
637    jit_impl!(ltgtr_f, www);
638    jit_impl!(ltgti_f, i_wwf);
639    jit_impl!(ordr_f, www);
640    jit_impl!(ordi_f, i_wwf);
641    jit_impl!(unordr_f, www);
642    jit_impl!(unordi_f, i_wwf);
643
644    jit_impl!(truncr_f_i, ww);
645    #[cfg(target_pointer_width = "64")]
646    jit_impl!(truncr_f_l, ww);
647    #[cfg(target_pointer_width = "32")]
648    jit_alias!(truncr_f_i => truncr_f, int: Reg, float: Reg; -> JitNode);
649    #[cfg(target_pointer_width = "64")]
650    jit_alias!(truncr_f_l => truncr_f, int: Reg, float: Reg; -> JitNode);
651
652    jit_impl!(extr_f, ww);
653    jit_impl!(extr_d_f, ww);
654    jit_impl!(movr_f, ww);
655    jit_impl!(movi_f, i_wf);
656
657    jit_impl!(ldr_f, ww);
658    jit_impl!(ldi_f, i_wp);
659    jit_impl!(ldxr_f, www);
660    jit_impl!(ldxi_f, i_www);
661
662    jit_store!(str_f, ww);
663    jit_store!(sti_f, i_pw);
664    jit_store!(stxr_f, www);
665    jit_store!(stxi_f, i_www);
666
667    jit_branch!(bltr_f, r);
668    jit_branch!(blti_f, f);
669    jit_branch!(bler_f, r);
670    jit_branch!(blei_f, f);
671    jit_branch!(beqr_f, r);
672    jit_branch!(beqi_f, f);
673    jit_branch!(bger_f, r);
674    jit_branch!(bgei_f, f);
675    jit_branch!(bgtr_f, r);
676    jit_branch!(bgti_f, f);
677    jit_branch!(bner_f, r);
678    jit_branch!(bnei_f, f);
679    jit_branch!(bunltr_f, r);
680    jit_branch!(bunlti_f, f);
681    jit_branch!(bunler_f, r);
682    jit_branch!(bunlei_f, f);
683    jit_branch!(buneqr_f, r);
684    jit_branch!(buneqi_f, f);
685    jit_branch!(bunger_f, r);
686    jit_branch!(bungei_f, f);
687    jit_branch!(bungtr_f, r);
688    jit_branch!(bungti_f, f);
689    jit_branch!(bltgtr_f, r);
690    jit_branch!(bltgti_f, f);
691    jit_branch!(bordr_f, r);
692    jit_branch!(bordi_f, f);
693    jit_branch!(bunordr_f, r);
694    jit_branch!(bunordi_f, f);
695
696    jit_reexport!(pushargr_f, reg: Reg);
697    jit_reexport!(pushargi_f, imm: f32);
698    jit_reexport!(retr_f, reg: Reg);
699    jit_reexport!(reti_f, imm: f32);
700    jit_reexport!(retval_f, reg: Reg);
701}
702
703/// implmentations of 64-bit float instructions
704impl<'a> JitState<'a> {
705    jit_reexport!(arg_d; -> JitNode);
706    jit_reexport!(getarg_d, reg: Reg, arg: &JitNode);
707    jit_reexport!(putargr_d, reg: Reg, arg: &JitNode);
708    jit_reexport!(putargi_d, imm: f64, arg: &JitNode);
709
710    jit_impl!(addr_d, www);
711    jit_impl!(addi_d, i_wwd);
712    jit_impl!(subr_d, www);
713    jit_impl!(subi_d, i_wwd);
714
715    pub fn rsbr_d(&mut self, a: Reg, b: Reg, c: Reg) -> JitNode<'a> {
716        self.subr_d(a, c, b)
717    }
718
719    jit_impl!(rsbi_d, i_wwd);
720    jit_impl!(mulr_d, www);
721    jit_impl!(muli_d, i_wwd);
722    jit_impl!(divr_d, www);
723    jit_impl!(divi_d, i_wwd);
724    jit_impl!(negr_d, ww);
725    jit_impl!(absr_d, ww);
726    jit_impl!(sqrtr_d, ww);
727
728    jit_impl!(ltr_d, www);
729    jit_impl!(lti_d, i_wwd);
730    jit_impl!(ler_d, www);
731    jit_impl!(lei_d, i_wwd);
732    jit_impl!(eqr_d, www);
733    jit_impl!(eqi_d, i_wwd);
734    jit_impl!(ger_d, www);
735    jit_impl!(gei_d, i_wwd);
736    jit_impl!(gtr_d, www);
737    jit_impl!(gti_d, i_wwd);
738    jit_impl!(ner_d, www);
739    jit_impl!(nei_d, i_wwd);
740    jit_impl!(unltr_d, www);
741    jit_impl!(unlti_d, i_wwd);
742    jit_impl!(unler_d, www);
743    jit_impl!(unlei_d, i_wwd);
744    jit_impl!(uneqr_d, www);
745    jit_impl!(uneqi_d, i_wwd);
746    jit_impl!(unger_d, www);
747    jit_impl!(ungei_d, i_wwd);
748    jit_impl!(ungtr_d, www);
749    jit_impl!(ungti_d, i_wwd);
750    jit_impl!(ltgtr_d, www);
751    jit_impl!(ltgti_d, i_wwd);
752    jit_impl!(ordr_d, www);
753    jit_impl!(ordi_d, i_wwd);
754    jit_impl!(unordr_d, www);
755    jit_impl!(unordi_d, i_wwd);
756
757    jit_impl!(truncr_d_i, ww);
758    #[cfg(target_pointer_width = "64")]
759    jit_impl!(truncr_d_l, ww);
760    #[cfg(target_pointer_width = "32")]
761    jit_alias!(truncr_d_i => truncr_d, int: Reg, float: Reg; -> JitNode);
762    #[cfg(target_pointer_width = "64")]
763    jit_alias!(truncr_d_l => truncr_d, int: Reg, float: Reg; -> JitNode);
764
765    jit_impl!(extr_d, ww);
766    jit_impl!(extr_f_d, ww);
767    jit_impl!(movr_d, ww);
768    jit_impl!(movi_d, i_wd);
769
770    jit_impl!(ldr_d, ww);
771    jit_impl!(ldi_d, i_wp);
772    jit_impl!(ldxr_d, www);
773    jit_impl!(ldxi_d, i_www);
774
775    jit_store!(str_d, ww);
776    jit_store!(sti_d, i_pw);
777    jit_store!(stxr_d, www);
778    jit_store!(stxi_d, i_www);
779
780    jit_branch!(bltr_d, r);
781    jit_branch!(blti_d, d);
782    jit_branch!(bler_d, r);
783    jit_branch!(blei_d, d);
784    jit_branch!(beqr_d, r);
785    jit_branch!(beqi_d, d);
786    jit_branch!(bger_d, r);
787    jit_branch!(bgei_d, d);
788    jit_branch!(bgtr_d, r);
789    jit_branch!(bgti_d, d);
790    jit_branch!(bner_d, r);
791    jit_branch!(bnei_d, d);
792    jit_branch!(bunltr_d, r);
793    jit_branch!(bunlti_d, d);
794    jit_branch!(bunler_d, r);
795    jit_branch!(bunlei_d, d);
796    jit_branch!(buneqr_d, r);
797    jit_branch!(buneqi_d, d);
798    jit_branch!(bunger_d, r);
799    jit_branch!(bungei_d, d);
800    jit_branch!(bungtr_d, r);
801    jit_branch!(bungti_d, d);
802    jit_branch!(bltgtr_d, r);
803    jit_branch!(bltgti_d, d);
804    jit_branch!(bordr_d, r);
805    jit_branch!(bordi_d, d);
806    jit_branch!(bunordr_d, r);
807    jit_branch!(bunordi_d, d);
808
809    jit_reexport!(pushargr_d, reg: Reg);
810    jit_reexport!(pushargi_d, imm: f64);
811    jit_reexport!(retr_d, reg: Reg);
812    jit_reexport!(reti_d, imm: f64);
813    jit_reexport!(retval_d, reg: Reg);
814}