1*22dc650dSSadaf Ebrahimi /*
2*22dc650dSSadaf Ebrahimi * Stack-less Just-In-Time compiler
3*22dc650dSSadaf Ebrahimi *
4*22dc650dSSadaf Ebrahimi * Copyright Zoltan Herczeg ([email protected]). All rights reserved.
5*22dc650dSSadaf Ebrahimi *
6*22dc650dSSadaf Ebrahimi * Redistribution and use in source and binary forms, with or without modification, are
7*22dc650dSSadaf Ebrahimi * permitted provided that the following conditions are met:
8*22dc650dSSadaf Ebrahimi *
9*22dc650dSSadaf Ebrahimi * 1. Redistributions of source code must retain the above copyright notice, this list of
10*22dc650dSSadaf Ebrahimi * conditions and the following disclaimer.
11*22dc650dSSadaf Ebrahimi *
12*22dc650dSSadaf Ebrahimi * 2. Redistributions in binary form must reproduce the above copyright notice, this list
13*22dc650dSSadaf Ebrahimi * of conditions and the following disclaimer in the documentation and/or other materials
14*22dc650dSSadaf Ebrahimi * provided with the distribution.
15*22dc650dSSadaf Ebrahimi *
16*22dc650dSSadaf Ebrahimi * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) AND CONTRIBUTORS ``AS IS'' AND ANY
17*22dc650dSSadaf Ebrahimi * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
18*22dc650dSSadaf Ebrahimi * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
19*22dc650dSSadaf Ebrahimi * SHALL THE COPYRIGHT HOLDER(S) OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
20*22dc650dSSadaf Ebrahimi * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
21*22dc650dSSadaf Ebrahimi * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
22*22dc650dSSadaf Ebrahimi * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
23*22dc650dSSadaf Ebrahimi * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
24*22dc650dSSadaf Ebrahimi * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25*22dc650dSSadaf Ebrahimi */
26*22dc650dSSadaf Ebrahimi
27*22dc650dSSadaf Ebrahimi #ifndef SLJIT_LIR_H_
28*22dc650dSSadaf Ebrahimi #define SLJIT_LIR_H_
29*22dc650dSSadaf Ebrahimi
30*22dc650dSSadaf Ebrahimi /*
31*22dc650dSSadaf Ebrahimi ------------------------------------------------------------------------
32*22dc650dSSadaf Ebrahimi Stack-Less JIT compiler for multiple architectures (x86, ARM, PowerPC)
33*22dc650dSSadaf Ebrahimi ------------------------------------------------------------------------
34*22dc650dSSadaf Ebrahimi
35*22dc650dSSadaf Ebrahimi Short description
36*22dc650dSSadaf Ebrahimi Advantages:
37*22dc650dSSadaf Ebrahimi - The execution can be continued from any LIR instruction. In other
38*22dc650dSSadaf Ebrahimi words, it is possible to jump to any label from anywhere, even from
39*22dc650dSSadaf Ebrahimi a code fragment, which is compiled later, as long as the compiling
40*22dc650dSSadaf Ebrahimi context is the same. See sljit_emit_enter for more details.
41*22dc650dSSadaf Ebrahimi - Supports self modifying code: target of any jump and call
42*22dc650dSSadaf Ebrahimi instructions and some constant values can be dynamically modified
43*22dc650dSSadaf Ebrahimi during runtime. See SLJIT_REWRITABLE_JUMP.
44*22dc650dSSadaf Ebrahimi - although it is not suggested to do it frequently
45*22dc650dSSadaf Ebrahimi - can be used for inline caching: save an important value once
46*22dc650dSSadaf Ebrahimi in the instruction stream
47*22dc650dSSadaf Ebrahimi - A fixed stack space can be allocated for local variables
48*22dc650dSSadaf Ebrahimi - The compiler is thread-safe
49*22dc650dSSadaf Ebrahimi - The compiler is highly configurable through preprocessor macros.
50*22dc650dSSadaf Ebrahimi You can disable unneeded features (multithreading in single
51*22dc650dSSadaf Ebrahimi threaded applications), and you can use your own system functions
52*22dc650dSSadaf Ebrahimi (including memory allocators). See sljitConfig.h.
53*22dc650dSSadaf Ebrahimi Disadvantages:
54*22dc650dSSadaf Ebrahimi - The compiler is more like a platform independent assembler, so
55*22dc650dSSadaf Ebrahimi there is no built-in variable management. Registers and stack must
56*22dc650dSSadaf Ebrahimi be managed manually (the name of the compiler refers to this).
57*22dc650dSSadaf Ebrahimi In practice:
58*22dc650dSSadaf Ebrahimi - This approach is very effective for interpreters
59*22dc650dSSadaf Ebrahimi - One of the saved registers typically points to a stack interface
60*22dc650dSSadaf Ebrahimi - It can jump to any exception handler anytime (even if it belongs
61*22dc650dSSadaf Ebrahimi to another function)
62*22dc650dSSadaf Ebrahimi - Hot paths can be modified during runtime reflecting the changes
63*22dc650dSSadaf Ebrahimi of the fastest execution path of the dynamic language
64*22dc650dSSadaf Ebrahimi - SLJIT supports complex memory addressing modes
65*22dc650dSSadaf Ebrahimi - mainly position and context independent code (except some cases)
66*22dc650dSSadaf Ebrahimi
67*22dc650dSSadaf Ebrahimi For valgrind users:
68*22dc650dSSadaf Ebrahimi - pass --smc-check=all argument to valgrind, since JIT is a "self-modifying code"
69*22dc650dSSadaf Ebrahimi */
70*22dc650dSSadaf Ebrahimi
71*22dc650dSSadaf Ebrahimi #if (defined SLJIT_HAVE_CONFIG_PRE && SLJIT_HAVE_CONFIG_PRE)
72*22dc650dSSadaf Ebrahimi #include "sljitConfigPre.h"
73*22dc650dSSadaf Ebrahimi #endif /* SLJIT_HAVE_CONFIG_PRE */
74*22dc650dSSadaf Ebrahimi
75*22dc650dSSadaf Ebrahimi #include "sljitConfigCPU.h"
76*22dc650dSSadaf Ebrahimi #include "sljitConfig.h"
77*22dc650dSSadaf Ebrahimi
78*22dc650dSSadaf Ebrahimi /* The following header file defines useful macros for fine tuning
79*22dc650dSSadaf Ebrahimi SLJIT based code generators. They are listed in the beginning
80*22dc650dSSadaf Ebrahimi of sljitConfigInternal.h */
81*22dc650dSSadaf Ebrahimi
82*22dc650dSSadaf Ebrahimi #include "sljitConfigInternal.h"
83*22dc650dSSadaf Ebrahimi
84*22dc650dSSadaf Ebrahimi #if (defined SLJIT_HAVE_CONFIG_POST && SLJIT_HAVE_CONFIG_POST)
85*22dc650dSSadaf Ebrahimi #include "sljitConfigPost.h"
86*22dc650dSSadaf Ebrahimi #endif /* SLJIT_HAVE_CONFIG_POST */
87*22dc650dSSadaf Ebrahimi
88*22dc650dSSadaf Ebrahimi #ifdef __cplusplus
89*22dc650dSSadaf Ebrahimi extern "C" {
90*22dc650dSSadaf Ebrahimi #endif
91*22dc650dSSadaf Ebrahimi
92*22dc650dSSadaf Ebrahimi /* Version numbers. */
93*22dc650dSSadaf Ebrahimi #define SLJIT_MAJOR_VERSION 0
94*22dc650dSSadaf Ebrahimi #define SLJIT_MINOR_VERSION 95
95*22dc650dSSadaf Ebrahimi
96*22dc650dSSadaf Ebrahimi /* --------------------------------------------------------------------- */
97*22dc650dSSadaf Ebrahimi /* Error codes */
98*22dc650dSSadaf Ebrahimi /* --------------------------------------------------------------------- */
99*22dc650dSSadaf Ebrahimi
100*22dc650dSSadaf Ebrahimi /* Indicates no error. */
101*22dc650dSSadaf Ebrahimi #define SLJIT_SUCCESS 0
102*22dc650dSSadaf Ebrahimi /* After the call of sljit_generate_code(), the error code of the compiler
103*22dc650dSSadaf Ebrahimi is set to this value to avoid further code generation.
104*22dc650dSSadaf Ebrahimi The complier should be freed after sljit_generate_code(). */
105*22dc650dSSadaf Ebrahimi #define SLJIT_ERR_COMPILED 1
106*22dc650dSSadaf Ebrahimi /* Cannot allocate non-executable memory. */
107*22dc650dSSadaf Ebrahimi #define SLJIT_ERR_ALLOC_FAILED 2
108*22dc650dSSadaf Ebrahimi /* Cannot allocate executable memory.
109*22dc650dSSadaf Ebrahimi Only sljit_generate_code() returns with this error code. */
110*22dc650dSSadaf Ebrahimi #define SLJIT_ERR_EX_ALLOC_FAILED 3
111*22dc650dSSadaf Ebrahimi /* Unsupported instruction form. */
112*22dc650dSSadaf Ebrahimi #define SLJIT_ERR_UNSUPPORTED 4
113*22dc650dSSadaf Ebrahimi /* An invalid argument is passed to any SLJIT function. */
114*22dc650dSSadaf Ebrahimi #define SLJIT_ERR_BAD_ARGUMENT 5
115*22dc650dSSadaf Ebrahimi
116*22dc650dSSadaf Ebrahimi /* --------------------------------------------------------------------- */
117*22dc650dSSadaf Ebrahimi /* Registers */
118*22dc650dSSadaf Ebrahimi /* --------------------------------------------------------------------- */
119*22dc650dSSadaf Ebrahimi
120*22dc650dSSadaf Ebrahimi /*
121*22dc650dSSadaf Ebrahimi Scratch (R) registers: registers which may not preserve their values
122*22dc650dSSadaf Ebrahimi across function calls.
123*22dc650dSSadaf Ebrahimi
124*22dc650dSSadaf Ebrahimi Saved (S) registers: registers which preserve their values across
125*22dc650dSSadaf Ebrahimi function calls.
126*22dc650dSSadaf Ebrahimi
127*22dc650dSSadaf Ebrahimi The scratch and saved register sets overlap. The last scratch register
128*22dc650dSSadaf Ebrahimi is the first saved register, the one before the last is the second saved
129*22dc650dSSadaf Ebrahimi register, and so on.
130*22dc650dSSadaf Ebrahimi
131*22dc650dSSadaf Ebrahimi For example, in an architecture with only five registers (A-E), if two
132*22dc650dSSadaf Ebrahimi are scratch and three saved registers, they will be defined as follows:
133*22dc650dSSadaf Ebrahimi
134*22dc650dSSadaf Ebrahimi A | R0 | | R0 always represent scratch register A
135*22dc650dSSadaf Ebrahimi B | R1 | | R1 always represent scratch register B
136*22dc650dSSadaf Ebrahimi C | [R2] | S2 | R2 and S2 represent the same physical register C
137*22dc650dSSadaf Ebrahimi D | [R3] | S1 | R3 and S1 represent the same physical register D
138*22dc650dSSadaf Ebrahimi E | [R4] | S0 | R4 and S0 represent the same physical register E
139*22dc650dSSadaf Ebrahimi
140*22dc650dSSadaf Ebrahimi Note: SLJIT_NUMBER_OF_SCRATCH_REGISTERS will be 2 and
141*22dc650dSSadaf Ebrahimi SLJIT_NUMBER_OF_SAVED_REGISTERS will be 3.
142*22dc650dSSadaf Ebrahimi
143*22dc650dSSadaf Ebrahimi Note: For all supported architectures SLJIT_NUMBER_OF_REGISTERS >= 12
144*22dc650dSSadaf Ebrahimi and SLJIT_NUMBER_OF_SAVED_REGISTERS >= 6. However, 6 registers
145*22dc650dSSadaf Ebrahimi are virtual on x86-32. See below.
146*22dc650dSSadaf Ebrahimi
147*22dc650dSSadaf Ebrahimi The purpose of this definition is convenience: saved registers can
148*22dc650dSSadaf Ebrahimi be used as extra scratch registers. For example, building in the
149*22dc650dSSadaf Ebrahimi previous example, four registers can be specified as scratch registers
150*22dc650dSSadaf Ebrahimi and the fifth one as saved register, allowing any user code which requires
151*22dc650dSSadaf Ebrahimi four scratch registers to run unmodified. The SLJIT compiler automatically
152*22dc650dSSadaf Ebrahimi saves the content of the two extra scratch register on the stack. Scratch
153*22dc650dSSadaf Ebrahimi registers can also be preserved by saving their value on the stack but
154*22dc650dSSadaf Ebrahimi that needs to be done manually.
155*22dc650dSSadaf Ebrahimi
156*22dc650dSSadaf Ebrahimi Note: To emphasize that registers assigned to R2-R4 are saved
157*22dc650dSSadaf Ebrahimi registers, they are enclosed by square brackets.
158*22dc650dSSadaf Ebrahimi
159*22dc650dSSadaf Ebrahimi Note: sljit_emit_enter and sljit_set_context define whether a register
160*22dc650dSSadaf Ebrahimi is S or R register. E.g: if in the previous example 3 scratches and
161*22dc650dSSadaf Ebrahimi 1 saved are mapped by sljit_emit_enter, the allowed register set
162*22dc650dSSadaf Ebrahimi will be: R0-R2 and S0. Although S2 is mapped to the same register
163*22dc650dSSadaf Ebrahimi than R2, it is not available in that configuration. Furthermore
164*22dc650dSSadaf Ebrahimi the S1 register cannot be used at all.
165*22dc650dSSadaf Ebrahimi */
166*22dc650dSSadaf Ebrahimi
167*22dc650dSSadaf Ebrahimi /* Scratch registers. */
168*22dc650dSSadaf Ebrahimi #define SLJIT_R0 1
169*22dc650dSSadaf Ebrahimi #define SLJIT_R1 2
170*22dc650dSSadaf Ebrahimi #define SLJIT_R2 3
171*22dc650dSSadaf Ebrahimi /* Note: on x86-32, R3 - R6 (same as S3 - S6) are emulated (they
172*22dc650dSSadaf Ebrahimi are allocated on the stack). These registers are called virtual
173*22dc650dSSadaf Ebrahimi and cannot be used for memory addressing (cannot be part of
174*22dc650dSSadaf Ebrahimi any SLJIT_MEM1, SLJIT_MEM2 construct). There is no such
175*22dc650dSSadaf Ebrahimi limitation on other CPUs. See sljit_get_register_index(). */
176*22dc650dSSadaf Ebrahimi #define SLJIT_R3 4
177*22dc650dSSadaf Ebrahimi #define SLJIT_R4 5
178*22dc650dSSadaf Ebrahimi #define SLJIT_R5 6
179*22dc650dSSadaf Ebrahimi #define SLJIT_R6 7
180*22dc650dSSadaf Ebrahimi #define SLJIT_R7 8
181*22dc650dSSadaf Ebrahimi #define SLJIT_R8 9
182*22dc650dSSadaf Ebrahimi #define SLJIT_R9 10
183*22dc650dSSadaf Ebrahimi /* All R registers provided by the architecture can be accessed by SLJIT_R(i)
184*22dc650dSSadaf Ebrahimi The i parameter must be >= 0 and < SLJIT_NUMBER_OF_REGISTERS. */
185*22dc650dSSadaf Ebrahimi #define SLJIT_R(i) (1 + (i))
186*22dc650dSSadaf Ebrahimi
187*22dc650dSSadaf Ebrahimi /* Saved registers. */
188*22dc650dSSadaf Ebrahimi #define SLJIT_S0 (SLJIT_NUMBER_OF_REGISTERS)
189*22dc650dSSadaf Ebrahimi #define SLJIT_S1 (SLJIT_NUMBER_OF_REGISTERS - 1)
190*22dc650dSSadaf Ebrahimi #define SLJIT_S2 (SLJIT_NUMBER_OF_REGISTERS - 2)
191*22dc650dSSadaf Ebrahimi /* Note: on x86-32, S3 - S6 (same as R3 - R6) are emulated (they
192*22dc650dSSadaf Ebrahimi are allocated on the stack). These registers are called virtual
193*22dc650dSSadaf Ebrahimi and cannot be used for memory addressing (cannot be part of
194*22dc650dSSadaf Ebrahimi any SLJIT_MEM1, SLJIT_MEM2 construct). There is no such
195*22dc650dSSadaf Ebrahimi limitation on other CPUs. See sljit_get_register_index(). */
196*22dc650dSSadaf Ebrahimi #define SLJIT_S3 (SLJIT_NUMBER_OF_REGISTERS - 3)
197*22dc650dSSadaf Ebrahimi #define SLJIT_S4 (SLJIT_NUMBER_OF_REGISTERS - 4)
198*22dc650dSSadaf Ebrahimi #define SLJIT_S5 (SLJIT_NUMBER_OF_REGISTERS - 5)
199*22dc650dSSadaf Ebrahimi #define SLJIT_S6 (SLJIT_NUMBER_OF_REGISTERS - 6)
200*22dc650dSSadaf Ebrahimi #define SLJIT_S7 (SLJIT_NUMBER_OF_REGISTERS - 7)
201*22dc650dSSadaf Ebrahimi #define SLJIT_S8 (SLJIT_NUMBER_OF_REGISTERS - 8)
202*22dc650dSSadaf Ebrahimi #define SLJIT_S9 (SLJIT_NUMBER_OF_REGISTERS - 9)
203*22dc650dSSadaf Ebrahimi /* All S registers provided by the architecture can be accessed by SLJIT_S(i)
204*22dc650dSSadaf Ebrahimi The i parameter must be >= 0 and < SLJIT_NUMBER_OF_SAVED_REGISTERS. */
205*22dc650dSSadaf Ebrahimi #define SLJIT_S(i) (SLJIT_NUMBER_OF_REGISTERS - (i))
206*22dc650dSSadaf Ebrahimi
207*22dc650dSSadaf Ebrahimi /* Registers >= SLJIT_FIRST_SAVED_REG are saved registers. */
208*22dc650dSSadaf Ebrahimi #define SLJIT_FIRST_SAVED_REG (SLJIT_S0 - SLJIT_NUMBER_OF_SAVED_REGISTERS + 1)
209*22dc650dSSadaf Ebrahimi
210*22dc650dSSadaf Ebrahimi /* The SLJIT_SP provides direct access to the linear stack space allocated by
211*22dc650dSSadaf Ebrahimi sljit_emit_enter. It can only be used in the following form: SLJIT_MEM1(SLJIT_SP).
212*22dc650dSSadaf Ebrahimi The immediate offset is extended by the relative stack offset automatically.
213*22dc650dSSadaf Ebrahimi sljit_get_local_base can be used to obtain the real address of a value. */
214*22dc650dSSadaf Ebrahimi #define SLJIT_SP (SLJIT_NUMBER_OF_REGISTERS + 1)
215*22dc650dSSadaf Ebrahimi
216*22dc650dSSadaf Ebrahimi /* Return with machine word. */
217*22dc650dSSadaf Ebrahimi
218*22dc650dSSadaf Ebrahimi #define SLJIT_RETURN_REG SLJIT_R0
219*22dc650dSSadaf Ebrahimi
220*22dc650dSSadaf Ebrahimi /* --------------------------------------------------------------------- */
221*22dc650dSSadaf Ebrahimi /* Floating point registers */
222*22dc650dSSadaf Ebrahimi /* --------------------------------------------------------------------- */
223*22dc650dSSadaf Ebrahimi
224*22dc650dSSadaf Ebrahimi /* Each floating point register can store a 32 or a 64 bit precision
225*22dc650dSSadaf Ebrahimi value. The FR and FS register sets overlap in the same way as R
226*22dc650dSSadaf Ebrahimi and S register sets. See above. */
227*22dc650dSSadaf Ebrahimi
228*22dc650dSSadaf Ebrahimi /* Floating point scratch registers. */
229*22dc650dSSadaf Ebrahimi #define SLJIT_FR0 1
230*22dc650dSSadaf Ebrahimi #define SLJIT_FR1 2
231*22dc650dSSadaf Ebrahimi #define SLJIT_FR2 3
232*22dc650dSSadaf Ebrahimi #define SLJIT_FR3 4
233*22dc650dSSadaf Ebrahimi #define SLJIT_FR4 5
234*22dc650dSSadaf Ebrahimi #define SLJIT_FR5 6
235*22dc650dSSadaf Ebrahimi #define SLJIT_FR6 7
236*22dc650dSSadaf Ebrahimi #define SLJIT_FR7 8
237*22dc650dSSadaf Ebrahimi #define SLJIT_FR8 9
238*22dc650dSSadaf Ebrahimi #define SLJIT_FR9 10
239*22dc650dSSadaf Ebrahimi /* All FR registers provided by the architecture can be accessed by SLJIT_FR(i)
240*22dc650dSSadaf Ebrahimi The i parameter must be >= 0 and < SLJIT_NUMBER_OF_FLOAT_REGISTERS. */
241*22dc650dSSadaf Ebrahimi #define SLJIT_FR(i) (1 + (i))
242*22dc650dSSadaf Ebrahimi
243*22dc650dSSadaf Ebrahimi /* Floating point saved registers. */
244*22dc650dSSadaf Ebrahimi #define SLJIT_FS0 (SLJIT_NUMBER_OF_FLOAT_REGISTERS)
245*22dc650dSSadaf Ebrahimi #define SLJIT_FS1 (SLJIT_NUMBER_OF_FLOAT_REGISTERS - 1)
246*22dc650dSSadaf Ebrahimi #define SLJIT_FS2 (SLJIT_NUMBER_OF_FLOAT_REGISTERS - 2)
247*22dc650dSSadaf Ebrahimi #define SLJIT_FS3 (SLJIT_NUMBER_OF_FLOAT_REGISTERS - 3)
248*22dc650dSSadaf Ebrahimi #define SLJIT_FS4 (SLJIT_NUMBER_OF_FLOAT_REGISTERS - 4)
249*22dc650dSSadaf Ebrahimi #define SLJIT_FS5 (SLJIT_NUMBER_OF_FLOAT_REGISTERS - 5)
250*22dc650dSSadaf Ebrahimi #define SLJIT_FS6 (SLJIT_NUMBER_OF_FLOAT_REGISTERS - 6)
251*22dc650dSSadaf Ebrahimi #define SLJIT_FS7 (SLJIT_NUMBER_OF_FLOAT_REGISTERS - 7)
252*22dc650dSSadaf Ebrahimi #define SLJIT_FS8 (SLJIT_NUMBER_OF_FLOAT_REGISTERS - 8)
253*22dc650dSSadaf Ebrahimi #define SLJIT_FS9 (SLJIT_NUMBER_OF_FLOAT_REGISTERS - 9)
254*22dc650dSSadaf Ebrahimi /* All S registers provided by the architecture can be accessed by SLJIT_FS(i)
255*22dc650dSSadaf Ebrahimi The i parameter must be >= 0 and < SLJIT_NUMBER_OF_SAVED_FLOAT_REGISTERS. */
256*22dc650dSSadaf Ebrahimi #define SLJIT_FS(i) (SLJIT_NUMBER_OF_FLOAT_REGISTERS - (i))
257*22dc650dSSadaf Ebrahimi
258*22dc650dSSadaf Ebrahimi /* Float registers >= SLJIT_FIRST_SAVED_FLOAT_REG are saved registers. */
259*22dc650dSSadaf Ebrahimi #define SLJIT_FIRST_SAVED_FLOAT_REG (SLJIT_FS0 - SLJIT_NUMBER_OF_SAVED_FLOAT_REGISTERS + 1)
260*22dc650dSSadaf Ebrahimi
261*22dc650dSSadaf Ebrahimi /* Return with floating point arg. */
262*22dc650dSSadaf Ebrahimi
263*22dc650dSSadaf Ebrahimi #define SLJIT_RETURN_FREG SLJIT_FR0
264*22dc650dSSadaf Ebrahimi
265*22dc650dSSadaf Ebrahimi /* --------------------------------------------------------------------- */
266*22dc650dSSadaf Ebrahimi /* Argument type definitions */
267*22dc650dSSadaf Ebrahimi /* --------------------------------------------------------------------- */
268*22dc650dSSadaf Ebrahimi
269*22dc650dSSadaf Ebrahimi /* The following argument type definitions are used by sljit_emit_enter,
270*22dc650dSSadaf Ebrahimi sljit_set_context, sljit_emit_call, and sljit_emit_icall functions.
271*22dc650dSSadaf Ebrahimi
272*22dc650dSSadaf Ebrahimi For sljit_emit_call and sljit_emit_icall, the first integer argument
273*22dc650dSSadaf Ebrahimi must be placed into SLJIT_R0, the second one into SLJIT_R1, and so on.
274*22dc650dSSadaf Ebrahimi Similarly the first floating point argument must be placed into SLJIT_FR0,
275*22dc650dSSadaf Ebrahimi the second one into SLJIT_FR1, and so on.
276*22dc650dSSadaf Ebrahimi
277*22dc650dSSadaf Ebrahimi For sljit_emit_enter, the integer arguments can be stored in scratch
278*22dc650dSSadaf Ebrahimi or saved registers. Scratch registers are identified by a _R suffix.
279*22dc650dSSadaf Ebrahimi
280*22dc650dSSadaf Ebrahimi If only saved registers are used, then the allocation mirrors what is
281*22dc650dSSadaf Ebrahimi done for the "call" functions but using saved registers, meaning that
282*22dc650dSSadaf Ebrahimi the first integer argument goes to SLJIT_S0, the second one goes into
283*22dc650dSSadaf Ebrahimi SLJIT_S1, and so on.
284*22dc650dSSadaf Ebrahimi
285*22dc650dSSadaf Ebrahimi If scratch registers are used, then the way the integer registers are
286*22dc650dSSadaf Ebrahimi allocated changes so that SLJIT_S0, SLJIT_S1, etc; will be assigned
287*22dc650dSSadaf Ebrahimi only for the arguments not using scratch registers, while SLJIT_R<n>
288*22dc650dSSadaf Ebrahimi will be used for the ones using scratch registers.
289*22dc650dSSadaf Ebrahimi
290*22dc650dSSadaf Ebrahimi Furthermore, the index (shown as "n" above) that will be used for the
291*22dc650dSSadaf Ebrahimi scratch register depends on how many previous integer registers
292*22dc650dSSadaf Ebrahimi (scratch or saved) were used already, starting with SLJIT_R0.
293*22dc650dSSadaf Ebrahimi Eventhough some indexes will be likely skipped, they still need to be
294*22dc650dSSadaf Ebrahimi accounted for in the scratches parameter of sljit_emit_enter. See below
295*22dc650dSSadaf Ebrahimi for some examples.
296*22dc650dSSadaf Ebrahimi
297*22dc650dSSadaf Ebrahimi The floating point arguments always use scratch registers (but not the
298*22dc650dSSadaf Ebrahimi _R suffix like the integer arguments) and must use SLJIT_FR0, SLJIT_FR1,
299*22dc650dSSadaf Ebrahimi just like in the "call" functions.
300*22dc650dSSadaf Ebrahimi
301*22dc650dSSadaf Ebrahimi Note: the mapping for scratch registers is part of the compiler context
302*22dc650dSSadaf Ebrahimi and therefore a new context after sljit_emit_call/sljit_emit_icall
303*22dc650dSSadaf Ebrahimi could remove access to some scratch registers that were used as
304*22dc650dSSadaf Ebrahimi arguments.
305*22dc650dSSadaf Ebrahimi
306*22dc650dSSadaf Ebrahimi Example function definition:
307*22dc650dSSadaf Ebrahimi sljit_f32 SLJIT_FUNC example_c_callback(void *arg_a,
308*22dc650dSSadaf Ebrahimi sljit_f64 arg_b, sljit_u32 arg_c, sljit_f32 arg_d);
309*22dc650dSSadaf Ebrahimi
310*22dc650dSSadaf Ebrahimi Argument type definition:
311*22dc650dSSadaf Ebrahimi SLJIT_ARG_RETURN(SLJIT_ARG_TYPE_F32)
312*22dc650dSSadaf Ebrahimi | SLJIT_ARG_VALUE(SLJIT_ARG_TYPE_P, 1) | SLJIT_ARG_VALUE(SLJIT_ARG_TYPE_F64, 2)
313*22dc650dSSadaf Ebrahimi | SLJIT_ARG_VALUE(SLJIT_ARG_TYPE_32, 3) | SLJIT_ARG_VALUE(SLJIT_ARG_TYPE_F32, 4)
314*22dc650dSSadaf Ebrahimi
315*22dc650dSSadaf Ebrahimi Short form of argument type definition:
316*22dc650dSSadaf Ebrahimi SLJIT_ARGS4(F32, P, F64, 32, F32)
317*22dc650dSSadaf Ebrahimi
318*22dc650dSSadaf Ebrahimi Argument passing:
319*22dc650dSSadaf Ebrahimi arg_a must be placed in SLJIT_R0
320*22dc650dSSadaf Ebrahimi arg_b must be placed in SLJIT_FR0
321*22dc650dSSadaf Ebrahimi arg_c must be placed in SLJIT_R1
322*22dc650dSSadaf Ebrahimi arg_d must be placed in SLJIT_FR1
323*22dc650dSSadaf Ebrahimi
324*22dc650dSSadaf Ebrahimi Examples for argument processing by sljit_emit_enter:
325*22dc650dSSadaf Ebrahimi SLJIT_ARGS4V(P, 32_R, F32, W)
326*22dc650dSSadaf Ebrahimi Arguments are placed into: SLJIT_S0, SLJIT_R1, SLJIT_FR0, SLJIT_S1
327*22dc650dSSadaf Ebrahimi The type of the result is void.
328*22dc650dSSadaf Ebrahimi
329*22dc650dSSadaf Ebrahimi SLJIT_ARGS4(F32, W, W_R, W, W_R)
330*22dc650dSSadaf Ebrahimi Arguments are placed into: SLJIT_S0, SLJIT_R1, SLJIT_S1, SLJIT_R3
331*22dc650dSSadaf Ebrahimi The type of the result is sljit_f32.
332*22dc650dSSadaf Ebrahimi
333*22dc650dSSadaf Ebrahimi SLJIT_ARGS4(P, W, F32, P_R)
334*22dc650dSSadaf Ebrahimi Arguments are placed into: SLJIT_FR0, SLJIT_S0, SLJIT_FR1, SLJIT_R1
335*22dc650dSSadaf Ebrahimi The type of the result is pointer.
336*22dc650dSSadaf Ebrahimi
337*22dc650dSSadaf Ebrahimi Note: it is recommended to pass the scratch arguments first
338*22dc650dSSadaf Ebrahimi followed by the saved arguments:
339*22dc650dSSadaf Ebrahimi
340*22dc650dSSadaf Ebrahimi SLJIT_ARGS4(W, W_R, W_R, W, W)
341*22dc650dSSadaf Ebrahimi Arguments are placed into: SLJIT_R0, SLJIT_R1, SLJIT_S0, SLJIT_S1
342*22dc650dSSadaf Ebrahimi The type of the result is sljit_sw / sljit_uw.
343*22dc650dSSadaf Ebrahimi */
344*22dc650dSSadaf Ebrahimi
345*22dc650dSSadaf Ebrahimi /* The following flag is only allowed for the integer arguments of
346*22dc650dSSadaf Ebrahimi sljit_emit_enter. When the flag is set, the integer argument is
347*22dc650dSSadaf Ebrahimi stored in a scratch register instead of a saved register. */
348*22dc650dSSadaf Ebrahimi #define SLJIT_ARG_TYPE_SCRATCH_REG 0x8
349*22dc650dSSadaf Ebrahimi
350*22dc650dSSadaf Ebrahimi /* No return value, only supported by SLJIT_ARG_RETURN. */
351*22dc650dSSadaf Ebrahimi #define SLJIT_ARG_TYPE_RET_VOID 0
352*22dc650dSSadaf Ebrahimi /* Machine word sized integer argument or result. */
353*22dc650dSSadaf Ebrahimi #define SLJIT_ARG_TYPE_W 1
354*22dc650dSSadaf Ebrahimi #define SLJIT_ARG_TYPE_W_R (SLJIT_ARG_TYPE_W | SLJIT_ARG_TYPE_SCRATCH_REG)
355*22dc650dSSadaf Ebrahimi /* 32 bit integer argument or result. */
356*22dc650dSSadaf Ebrahimi #define SLJIT_ARG_TYPE_32 2
357*22dc650dSSadaf Ebrahimi #define SLJIT_ARG_TYPE_32_R (SLJIT_ARG_TYPE_32 | SLJIT_ARG_TYPE_SCRATCH_REG)
358*22dc650dSSadaf Ebrahimi /* Pointer sized integer argument or result. */
359*22dc650dSSadaf Ebrahimi #define SLJIT_ARG_TYPE_P 3
360*22dc650dSSadaf Ebrahimi #define SLJIT_ARG_TYPE_P_R (SLJIT_ARG_TYPE_P | SLJIT_ARG_TYPE_SCRATCH_REG)
361*22dc650dSSadaf Ebrahimi /* 64 bit floating point argument or result. */
362*22dc650dSSadaf Ebrahimi #define SLJIT_ARG_TYPE_F64 4
363*22dc650dSSadaf Ebrahimi /* 32 bit floating point argument or result. */
364*22dc650dSSadaf Ebrahimi #define SLJIT_ARG_TYPE_F32 5
365*22dc650dSSadaf Ebrahimi
366*22dc650dSSadaf Ebrahimi #define SLJIT_ARG_SHIFT 4
367*22dc650dSSadaf Ebrahimi #define SLJIT_ARG_RETURN(type) (type)
368*22dc650dSSadaf Ebrahimi #define SLJIT_ARG_VALUE(type, idx) ((type) << ((idx) * SLJIT_ARG_SHIFT))
369*22dc650dSSadaf Ebrahimi
370*22dc650dSSadaf Ebrahimi /* Simplified argument list definitions.
371*22dc650dSSadaf Ebrahimi
372*22dc650dSSadaf Ebrahimi The following definition:
373*22dc650dSSadaf Ebrahimi SLJIT_ARG_RETURN(SLJIT_ARG_TYPE_W) | SLJIT_ARG_VALUE(SLJIT_ARG_TYPE_F32, 1)
374*22dc650dSSadaf Ebrahimi
375*22dc650dSSadaf Ebrahimi can be shortened to:
376*22dc650dSSadaf Ebrahimi SLJIT_ARGS1(W, F32)
377*22dc650dSSadaf Ebrahimi
378*22dc650dSSadaf Ebrahimi Another example where no value is returned:
379*22dc650dSSadaf Ebrahimi SLJIT_ARG_RETURN(SLJIT_ARG_TYPE_RET_VOID) | SLJIT_ARG_VALUE(SLJIT_ARG_TYPE_W_R, 1)
380*22dc650dSSadaf Ebrahimi
381*22dc650dSSadaf Ebrahimi can be shortened to:
382*22dc650dSSadaf Ebrahimi SLJIT_ARGS1V(W_R)
383*22dc650dSSadaf Ebrahimi */
384*22dc650dSSadaf Ebrahimi
385*22dc650dSSadaf Ebrahimi #define SLJIT_ARG_TO_TYPE(type) SLJIT_ARG_TYPE_ ## type
386*22dc650dSSadaf Ebrahimi
387*22dc650dSSadaf Ebrahimi #define SLJIT_ARGS0(ret) \
388*22dc650dSSadaf Ebrahimi SLJIT_ARG_RETURN(SLJIT_ARG_TO_TYPE(ret))
389*22dc650dSSadaf Ebrahimi #define SLJIT_ARGS0V() \
390*22dc650dSSadaf Ebrahimi SLJIT_ARG_RETURN(SLJIT_ARG_TYPE_RET_VOID)
391*22dc650dSSadaf Ebrahimi
392*22dc650dSSadaf Ebrahimi #define SLJIT_ARGS1(ret, arg1) \
393*22dc650dSSadaf Ebrahimi (SLJIT_ARGS0(ret) | SLJIT_ARG_VALUE(SLJIT_ARG_TO_TYPE(arg1), 1))
394*22dc650dSSadaf Ebrahimi #define SLJIT_ARGS1V(arg1) \
395*22dc650dSSadaf Ebrahimi (SLJIT_ARGS0V() | SLJIT_ARG_VALUE(SLJIT_ARG_TO_TYPE(arg1), 1))
396*22dc650dSSadaf Ebrahimi
397*22dc650dSSadaf Ebrahimi #define SLJIT_ARGS2(ret, arg1, arg2) \
398*22dc650dSSadaf Ebrahimi (SLJIT_ARGS1(ret, arg1) | SLJIT_ARG_VALUE(SLJIT_ARG_TO_TYPE(arg2), 2))
399*22dc650dSSadaf Ebrahimi #define SLJIT_ARGS2V(arg1, arg2) \
400*22dc650dSSadaf Ebrahimi (SLJIT_ARGS1V(arg1) | SLJIT_ARG_VALUE(SLJIT_ARG_TO_TYPE(arg2), 2))
401*22dc650dSSadaf Ebrahimi
402*22dc650dSSadaf Ebrahimi #define SLJIT_ARGS3(ret, arg1, arg2, arg3) \
403*22dc650dSSadaf Ebrahimi (SLJIT_ARGS2(ret, arg1, arg2) | SLJIT_ARG_VALUE(SLJIT_ARG_TO_TYPE(arg3), 3))
404*22dc650dSSadaf Ebrahimi #define SLJIT_ARGS3V(arg1, arg2, arg3) \
405*22dc650dSSadaf Ebrahimi (SLJIT_ARGS2V(arg1, arg2) | SLJIT_ARG_VALUE(SLJIT_ARG_TO_TYPE(arg3), 3))
406*22dc650dSSadaf Ebrahimi
407*22dc650dSSadaf Ebrahimi #define SLJIT_ARGS4(ret, arg1, arg2, arg3, arg4) \
408*22dc650dSSadaf Ebrahimi (SLJIT_ARGS3(ret, arg1, arg2, arg3) | SLJIT_ARG_VALUE(SLJIT_ARG_TO_TYPE(arg4), 4))
409*22dc650dSSadaf Ebrahimi #define SLJIT_ARGS4V(arg1, arg2, arg3, arg4) \
410*22dc650dSSadaf Ebrahimi (SLJIT_ARGS3V(arg1, arg2, arg3) | SLJIT_ARG_VALUE(SLJIT_ARG_TO_TYPE(arg4), 4))
411*22dc650dSSadaf Ebrahimi
412*22dc650dSSadaf Ebrahimi /* --------------------------------------------------------------------- */
413*22dc650dSSadaf Ebrahimi /* Main structures and functions */
414*22dc650dSSadaf Ebrahimi /* --------------------------------------------------------------------- */
415*22dc650dSSadaf Ebrahimi
416*22dc650dSSadaf Ebrahimi /*
417*22dc650dSSadaf Ebrahimi The following structures are private, and can be changed in the
418*22dc650dSSadaf Ebrahimi future. Keeping them here allows code inlining.
419*22dc650dSSadaf Ebrahimi */
420*22dc650dSSadaf Ebrahimi
421*22dc650dSSadaf Ebrahimi struct sljit_memory_fragment {
422*22dc650dSSadaf Ebrahimi struct sljit_memory_fragment *next;
423*22dc650dSSadaf Ebrahimi sljit_uw used_size;
424*22dc650dSSadaf Ebrahimi /* Must be aligned to sljit_sw. */
425*22dc650dSSadaf Ebrahimi sljit_u8 memory[1];
426*22dc650dSSadaf Ebrahimi };
427*22dc650dSSadaf Ebrahimi
428*22dc650dSSadaf Ebrahimi struct sljit_label {
429*22dc650dSSadaf Ebrahimi struct sljit_label *next;
430*22dc650dSSadaf Ebrahimi union {
431*22dc650dSSadaf Ebrahimi sljit_uw index;
432*22dc650dSSadaf Ebrahimi sljit_uw addr;
433*22dc650dSSadaf Ebrahimi } u;
434*22dc650dSSadaf Ebrahimi /* The maximum size difference. */
435*22dc650dSSadaf Ebrahimi sljit_uw size;
436*22dc650dSSadaf Ebrahimi };
437*22dc650dSSadaf Ebrahimi
438*22dc650dSSadaf Ebrahimi struct sljit_jump {
439*22dc650dSSadaf Ebrahimi struct sljit_jump *next;
440*22dc650dSSadaf Ebrahimi sljit_uw addr;
441*22dc650dSSadaf Ebrahimi /* Architecture dependent flags. */
442*22dc650dSSadaf Ebrahimi sljit_uw flags;
443*22dc650dSSadaf Ebrahimi union {
444*22dc650dSSadaf Ebrahimi sljit_uw target;
445*22dc650dSSadaf Ebrahimi struct sljit_label *label;
446*22dc650dSSadaf Ebrahimi } u;
447*22dc650dSSadaf Ebrahimi };
448*22dc650dSSadaf Ebrahimi
449*22dc650dSSadaf Ebrahimi struct sljit_const {
450*22dc650dSSadaf Ebrahimi struct sljit_const *next;
451*22dc650dSSadaf Ebrahimi sljit_uw addr;
452*22dc650dSSadaf Ebrahimi };
453*22dc650dSSadaf Ebrahimi
454*22dc650dSSadaf Ebrahimi struct sljit_generate_code_buffer {
455*22dc650dSSadaf Ebrahimi void *buffer;
456*22dc650dSSadaf Ebrahimi sljit_uw size;
457*22dc650dSSadaf Ebrahimi sljit_sw executable_offset;
458*22dc650dSSadaf Ebrahimi };
459*22dc650dSSadaf Ebrahimi
460*22dc650dSSadaf Ebrahimi struct sljit_compiler {
461*22dc650dSSadaf Ebrahimi sljit_s32 error;
462*22dc650dSSadaf Ebrahimi sljit_s32 options;
463*22dc650dSSadaf Ebrahimi
464*22dc650dSSadaf Ebrahimi struct sljit_label *labels;
465*22dc650dSSadaf Ebrahimi struct sljit_jump *jumps;
466*22dc650dSSadaf Ebrahimi struct sljit_const *consts;
467*22dc650dSSadaf Ebrahimi struct sljit_label *last_label;
468*22dc650dSSadaf Ebrahimi struct sljit_jump *last_jump;
469*22dc650dSSadaf Ebrahimi struct sljit_const *last_const;
470*22dc650dSSadaf Ebrahimi
471*22dc650dSSadaf Ebrahimi void *allocator_data;
472*22dc650dSSadaf Ebrahimi void *user_data;
473*22dc650dSSadaf Ebrahimi struct sljit_memory_fragment *buf;
474*22dc650dSSadaf Ebrahimi struct sljit_memory_fragment *abuf;
475*22dc650dSSadaf Ebrahimi
476*22dc650dSSadaf Ebrahimi /* Number of labels created by the compiler. */
477*22dc650dSSadaf Ebrahimi sljit_uw label_count;
478*22dc650dSSadaf Ebrahimi /* Available scratch registers. */
479*22dc650dSSadaf Ebrahimi sljit_s32 scratches;
480*22dc650dSSadaf Ebrahimi /* Available saved registers. */
481*22dc650dSSadaf Ebrahimi sljit_s32 saveds;
482*22dc650dSSadaf Ebrahimi /* Available float scratch registers. */
483*22dc650dSSadaf Ebrahimi sljit_s32 fscratches;
484*22dc650dSSadaf Ebrahimi /* Available float saved registers. */
485*22dc650dSSadaf Ebrahimi sljit_s32 fsaveds;
486*22dc650dSSadaf Ebrahimi /* Local stack size. */
487*22dc650dSSadaf Ebrahimi sljit_s32 local_size;
488*22dc650dSSadaf Ebrahimi /* Maximum code size. */
489*22dc650dSSadaf Ebrahimi sljit_uw size;
490*22dc650dSSadaf Ebrahimi /* Relative offset of the executable mapping from the writable mapping. */
491*22dc650dSSadaf Ebrahimi sljit_sw executable_offset;
492*22dc650dSSadaf Ebrahimi /* Executable size for statistical purposes. */
493*22dc650dSSadaf Ebrahimi sljit_uw executable_size;
494*22dc650dSSadaf Ebrahimi
495*22dc650dSSadaf Ebrahimi #if (defined SLJIT_HAS_STATUS_FLAGS_STATE && SLJIT_HAS_STATUS_FLAGS_STATE)
496*22dc650dSSadaf Ebrahimi sljit_s32 status_flags_state;
497*22dc650dSSadaf Ebrahimi #endif /* SLJIT_HAS_STATUS_FLAGS_STATE */
498*22dc650dSSadaf Ebrahimi
499*22dc650dSSadaf Ebrahimi #if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
500*22dc650dSSadaf Ebrahimi sljit_s32 args_size;
501*22dc650dSSadaf Ebrahimi #endif /* SLJIT_CONFIG_X86_32 */
502*22dc650dSSadaf Ebrahimi
503*22dc650dSSadaf Ebrahimi #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
504*22dc650dSSadaf Ebrahimi /* Temporary fields. */
505*22dc650dSSadaf Ebrahimi sljit_s32 mode32;
506*22dc650dSSadaf Ebrahimi #endif /* SLJIT_CONFIG_X86_64 */
507*22dc650dSSadaf Ebrahimi
508*22dc650dSSadaf Ebrahimi #if (defined SLJIT_CONFIG_ARM_V6 && SLJIT_CONFIG_ARM_V6)
509*22dc650dSSadaf Ebrahimi /* Constant pool handling. */
510*22dc650dSSadaf Ebrahimi sljit_uw *cpool;
511*22dc650dSSadaf Ebrahimi sljit_u8 *cpool_unique;
512*22dc650dSSadaf Ebrahimi sljit_uw cpool_diff;
513*22dc650dSSadaf Ebrahimi sljit_uw cpool_fill;
514*22dc650dSSadaf Ebrahimi /* Other members. */
515*22dc650dSSadaf Ebrahimi /* Contains pointer, "ldr pc, [...]" pairs. */
516*22dc650dSSadaf Ebrahimi sljit_uw patches;
517*22dc650dSSadaf Ebrahimi #endif /* SLJIT_CONFIG_ARM_V6 */
518*22dc650dSSadaf Ebrahimi
519*22dc650dSSadaf Ebrahimi #if (defined SLJIT_CONFIG_ARM_V6 && SLJIT_CONFIG_ARM_V6) || (defined SLJIT_CONFIG_ARM_V7 && SLJIT_CONFIG_ARM_V7)
520*22dc650dSSadaf Ebrahimi /* Temporary fields. */
521*22dc650dSSadaf Ebrahimi sljit_uw shift_imm;
522*22dc650dSSadaf Ebrahimi #endif /* SLJIT_CONFIG_ARM_V6 || SLJIT_CONFIG_ARM_V6 */
523*22dc650dSSadaf Ebrahimi
524*22dc650dSSadaf Ebrahimi #if (defined SLJIT_CONFIG_ARM_32 && SLJIT_CONFIG_ARM_32) && (defined __SOFTFP__)
525*22dc650dSSadaf Ebrahimi sljit_uw args_size;
526*22dc650dSSadaf Ebrahimi #endif /* SLJIT_CONFIG_ARM_32 && __SOFTFP__ */
527*22dc650dSSadaf Ebrahimi
528*22dc650dSSadaf Ebrahimi #if (defined SLJIT_CONFIG_PPC && SLJIT_CONFIG_PPC)
529*22dc650dSSadaf Ebrahimi /* Temporary fields. */
530*22dc650dSSadaf Ebrahimi sljit_u32 imm;
531*22dc650dSSadaf Ebrahimi #endif /* SLJIT_CONFIG_PPC */
532*22dc650dSSadaf Ebrahimi
533*22dc650dSSadaf Ebrahimi #if (defined SLJIT_CONFIG_MIPS && SLJIT_CONFIG_MIPS)
534*22dc650dSSadaf Ebrahimi sljit_s32 delay_slot;
535*22dc650dSSadaf Ebrahimi /* Temporary fields. */
536*22dc650dSSadaf Ebrahimi sljit_s32 cache_arg;
537*22dc650dSSadaf Ebrahimi sljit_sw cache_argw;
538*22dc650dSSadaf Ebrahimi #endif /* SLJIT_CONFIG_MIPS */
539*22dc650dSSadaf Ebrahimi
540*22dc650dSSadaf Ebrahimi #if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
541*22dc650dSSadaf Ebrahimi sljit_uw args_size;
542*22dc650dSSadaf Ebrahimi #endif /* SLJIT_CONFIG_MIPS_32 */
543*22dc650dSSadaf Ebrahimi
544*22dc650dSSadaf Ebrahimi #if (defined SLJIT_CONFIG_RISCV && SLJIT_CONFIG_RISCV)
545*22dc650dSSadaf Ebrahimi /* Temporary fields. */
546*22dc650dSSadaf Ebrahimi sljit_s32 cache_arg;
547*22dc650dSSadaf Ebrahimi sljit_sw cache_argw;
548*22dc650dSSadaf Ebrahimi #endif /* SLJIT_CONFIG_RISCV */
549*22dc650dSSadaf Ebrahimi
550*22dc650dSSadaf Ebrahimi #if (defined SLJIT_CONFIG_S390X && SLJIT_CONFIG_S390X)
551*22dc650dSSadaf Ebrahimi /* Need to allocate register save area to make calls. */
552*22dc650dSSadaf Ebrahimi /* Temporary fields. */
553*22dc650dSSadaf Ebrahimi sljit_s32 mode;
554*22dc650dSSadaf Ebrahimi #endif /* SLJIT_CONFIG_S390X */
555*22dc650dSSadaf Ebrahimi
556*22dc650dSSadaf Ebrahimi #if (defined SLJIT_CONFIG_LOONGARCH && SLJIT_CONFIG_LOONGARCH)
557*22dc650dSSadaf Ebrahimi /* Temporary fields. */
558*22dc650dSSadaf Ebrahimi sljit_s32 cache_arg;
559*22dc650dSSadaf Ebrahimi sljit_sw cache_argw;
560*22dc650dSSadaf Ebrahimi #endif /* SLJIT_CONFIG_LOONGARCH */
561*22dc650dSSadaf Ebrahimi
562*22dc650dSSadaf Ebrahimi #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
563*22dc650dSSadaf Ebrahimi FILE* verbose;
564*22dc650dSSadaf Ebrahimi #endif /* SLJIT_VERBOSE */
565*22dc650dSSadaf Ebrahimi
566*22dc650dSSadaf Ebrahimi #if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS) \
567*22dc650dSSadaf Ebrahimi || (defined SLJIT_DEBUG && SLJIT_DEBUG)
568*22dc650dSSadaf Ebrahimi /* Flags specified by the last arithmetic instruction.
569*22dc650dSSadaf Ebrahimi It contains the type of the variable flag. */
570*22dc650dSSadaf Ebrahimi sljit_s32 last_flags;
571*22dc650dSSadaf Ebrahimi /* Return value type set by entry functions. */
572*22dc650dSSadaf Ebrahimi sljit_s32 last_return;
573*22dc650dSSadaf Ebrahimi /* Local size passed to entry functions. */
574*22dc650dSSadaf Ebrahimi sljit_s32 logical_local_size;
575*22dc650dSSadaf Ebrahimi #endif /* SLJIT_ARGUMENT_CHECKS || SLJIT_DEBUG */
576*22dc650dSSadaf Ebrahimi
577*22dc650dSSadaf Ebrahimi #if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS) \
578*22dc650dSSadaf Ebrahimi || (defined SLJIT_DEBUG && SLJIT_DEBUG) \
579*22dc650dSSadaf Ebrahimi || (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
580*22dc650dSSadaf Ebrahimi /* Trust arguments when an API function is called.
581*22dc650dSSadaf Ebrahimi Used internally for calling API functions. */
582*22dc650dSSadaf Ebrahimi sljit_s32 skip_checks;
583*22dc650dSSadaf Ebrahimi #endif /* SLJIT_ARGUMENT_CHECKS || SLJIT_DEBUG || SLJIT_VERBOSE */
584*22dc650dSSadaf Ebrahimi };
585*22dc650dSSadaf Ebrahimi
586*22dc650dSSadaf Ebrahimi /* --------------------------------------------------------------------- */
587*22dc650dSSadaf Ebrahimi /* Main functions */
588*22dc650dSSadaf Ebrahimi /* --------------------------------------------------------------------- */
589*22dc650dSSadaf Ebrahimi
590*22dc650dSSadaf Ebrahimi /* Creates an SLJIT compiler. The allocator_data is required by some
591*22dc650dSSadaf Ebrahimi custom memory managers. This pointer is passed to SLJIT_MALLOC
592*22dc650dSSadaf Ebrahimi and SLJIT_FREE macros. Most allocators (including the default
593*22dc650dSSadaf Ebrahimi one) ignores this value, and it is recommended to pass NULL
594*22dc650dSSadaf Ebrahimi as a dummy value for allocator_data.
595*22dc650dSSadaf Ebrahimi
596*22dc650dSSadaf Ebrahimi Returns NULL if failed. */
597*22dc650dSSadaf Ebrahimi SLJIT_API_FUNC_ATTRIBUTE struct sljit_compiler* sljit_create_compiler(void *allocator_data);
598*22dc650dSSadaf Ebrahimi
599*22dc650dSSadaf Ebrahimi /* Frees everything except the compiled machine code. */
600*22dc650dSSadaf Ebrahimi SLJIT_API_FUNC_ATTRIBUTE void sljit_free_compiler(struct sljit_compiler *compiler);
601*22dc650dSSadaf Ebrahimi
602*22dc650dSSadaf Ebrahimi /* Returns the current error code. If an error occurres, future calls
603*22dc650dSSadaf Ebrahimi which uses the same compiler argument returns early with the same
604*22dc650dSSadaf Ebrahimi error code. Thus there is no need for checking the error after every
605*22dc650dSSadaf Ebrahimi call, it is enough to do it after the code is compiled. Removing
606*22dc650dSSadaf Ebrahimi these checks increases the performance of the compiling process. */
sljit_get_compiler_error(struct sljit_compiler * compiler)607*22dc650dSSadaf Ebrahimi static SLJIT_INLINE sljit_s32 sljit_get_compiler_error(struct sljit_compiler *compiler) { return compiler->error; }
608*22dc650dSSadaf Ebrahimi
609*22dc650dSSadaf Ebrahimi /* Sets the compiler error code to SLJIT_ERR_ALLOC_FAILED except
610*22dc650dSSadaf Ebrahimi if an error was detected before. After the error code is set
611*22dc650dSSadaf Ebrahimi the compiler behaves as if the allocation failure happened
612*22dc650dSSadaf Ebrahimi during an SLJIT function call. This can greatly simplify error
613*22dc650dSSadaf Ebrahimi checking, since it is enough to check the compiler status
614*22dc650dSSadaf Ebrahimi after the code is compiled. */
615*22dc650dSSadaf Ebrahimi SLJIT_API_FUNC_ATTRIBUTE void sljit_set_compiler_memory_error(struct sljit_compiler *compiler);
616*22dc650dSSadaf Ebrahimi
617*22dc650dSSadaf Ebrahimi /* Allocate a small amount of memory. The size must be <= 64 bytes on 32 bit,
618*22dc650dSSadaf Ebrahimi and <= 128 bytes on 64 bit architectures. The memory area is owned by the
619*22dc650dSSadaf Ebrahimi compiler, and freed by sljit_free_compiler. The returned pointer is
620*22dc650dSSadaf Ebrahimi sizeof(sljit_sw) aligned. Excellent for allocating small blocks during
621*22dc650dSSadaf Ebrahimi compiling, and no need to worry about freeing them. The size is enough
622*22dc650dSSadaf Ebrahimi to contain at most 16 pointers. If the size is outside of the range,
623*22dc650dSSadaf Ebrahimi the function will return with NULL. However, this return value does not
624*22dc650dSSadaf Ebrahimi indicate that there is no more memory (does not set the current error code
625*22dc650dSSadaf Ebrahimi of the compiler to out-of-memory status). */
626*22dc650dSSadaf Ebrahimi SLJIT_API_FUNC_ATTRIBUTE void* sljit_alloc_memory(struct sljit_compiler *compiler, sljit_s32 size);
627*22dc650dSSadaf Ebrahimi
628*22dc650dSSadaf Ebrahimi /* Returns the allocator data passed to sljit_create_compiler. */
sljit_compiler_get_allocator_data(struct sljit_compiler * compiler)629*22dc650dSSadaf Ebrahimi static SLJIT_INLINE void* sljit_compiler_get_allocator_data(struct sljit_compiler *compiler) { return compiler->allocator_data; }
630*22dc650dSSadaf Ebrahimi /* Sets/get the user data for a compiler. */
sljit_compiler_set_user_data(struct sljit_compiler * compiler,void * user_data)631*22dc650dSSadaf Ebrahimi static SLJIT_INLINE void sljit_compiler_set_user_data(struct sljit_compiler *compiler, void *user_data) { compiler->user_data = user_data; }
sljit_compiler_get_user_data(struct sljit_compiler * compiler)632*22dc650dSSadaf Ebrahimi static SLJIT_INLINE void* sljit_compiler_get_user_data(struct sljit_compiler *compiler) { return compiler->user_data; }
633*22dc650dSSadaf Ebrahimi
634*22dc650dSSadaf Ebrahimi #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
635*22dc650dSSadaf Ebrahimi /* Passing NULL disables verbose. */
636*22dc650dSSadaf Ebrahimi SLJIT_API_FUNC_ATTRIBUTE void sljit_compiler_verbose(struct sljit_compiler *compiler, FILE* verbose);
637*22dc650dSSadaf Ebrahimi #endif
638*22dc650dSSadaf Ebrahimi
639*22dc650dSSadaf Ebrahimi /* Option bits for sljit_generate_code. */
640*22dc650dSSadaf Ebrahimi
641*22dc650dSSadaf Ebrahimi /* The exec_allocator_data points to a pre-allocated
642*22dc650dSSadaf Ebrahimi buffer which type is sljit_generate_code_buffer. */
643*22dc650dSSadaf Ebrahimi #define SLJIT_GENERATE_CODE_BUFFER 0x1
644*22dc650dSSadaf Ebrahimi
645*22dc650dSSadaf Ebrahimi /* Create executable code from the instruction stream. This is the final step
646*22dc650dSSadaf Ebrahimi of the code generation, and no more instructions can be emitted after this call.
647*22dc650dSSadaf Ebrahimi
648*22dc650dSSadaf Ebrahimi options is the combination of SLJIT_GENERATE_CODE_* bits
649*22dc650dSSadaf Ebrahimi exec_allocator_data is passed to SLJIT_MALLOC_EXEC and
650*22dc650dSSadaf Ebrahimi SLJIT_MALLOC_FREE functions */
651*22dc650dSSadaf Ebrahimi
652*22dc650dSSadaf Ebrahimi SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compiler, sljit_s32 options, void *exec_allocator_data);
653*22dc650dSSadaf Ebrahimi
654*22dc650dSSadaf Ebrahimi /* Free executable code. */
655*22dc650dSSadaf Ebrahimi
656*22dc650dSSadaf Ebrahimi SLJIT_API_FUNC_ATTRIBUTE void sljit_free_code(void* code, void *exec_allocator_data);
657*22dc650dSSadaf Ebrahimi
658*22dc650dSSadaf Ebrahimi /* When the protected executable allocator is used the JIT code is mapped
659*22dc650dSSadaf Ebrahimi twice. The first mapping has read/write and the second mapping has read/exec
660*22dc650dSSadaf Ebrahimi permissions. This function returns with the relative offset of the executable
661*22dc650dSSadaf Ebrahimi mapping using the writable mapping as the base after the machine code is
662*22dc650dSSadaf Ebrahimi successfully generated. The returned value is always 0 for the normal executable
663*22dc650dSSadaf Ebrahimi allocator, since it uses only one mapping with read/write/exec permissions.
664*22dc650dSSadaf Ebrahimi Dynamic code modifications requires this value.
665*22dc650dSSadaf Ebrahimi
666*22dc650dSSadaf Ebrahimi Before a successful code generation, this function returns with 0. */
sljit_get_executable_offset(struct sljit_compiler * compiler)667*22dc650dSSadaf Ebrahimi static SLJIT_INLINE sljit_sw sljit_get_executable_offset(struct sljit_compiler *compiler) { return compiler->executable_offset; }
668*22dc650dSSadaf Ebrahimi
669*22dc650dSSadaf Ebrahimi /* The executable memory consumption of the generated code can be retrieved by
670*22dc650dSSadaf Ebrahimi this function. The returned value can be used for statistical purposes.
671*22dc650dSSadaf Ebrahimi
672*22dc650dSSadaf Ebrahimi Before a successful code generation, this function returns with 0. */
sljit_get_generated_code_size(struct sljit_compiler * compiler)673*22dc650dSSadaf Ebrahimi static SLJIT_INLINE sljit_uw sljit_get_generated_code_size(struct sljit_compiler *compiler) { return compiler->executable_size; }
674*22dc650dSSadaf Ebrahimi
675*22dc650dSSadaf Ebrahimi /* Returns with non-zero if the feature or limitation type passed as its
676*22dc650dSSadaf Ebrahimi argument is present on the current CPU. The return value is one, if a
677*22dc650dSSadaf Ebrahimi feature is fully supported, and it is two, if partially supported.
678*22dc650dSSadaf Ebrahimi
679*22dc650dSSadaf Ebrahimi Some features (e.g. floating point operations) require hardware (CPU)
680*22dc650dSSadaf Ebrahimi support while others (e.g. move with update) are emulated if not available.
681*22dc650dSSadaf Ebrahimi However, even when a feature is emulated, specialized code paths may be
682*22dc650dSSadaf Ebrahimi faster than the emulation. Some limitations are emulated as well so their
683*22dc650dSSadaf Ebrahimi general case is supported but it has extra performance costs. */
684*22dc650dSSadaf Ebrahimi
685*22dc650dSSadaf Ebrahimi /* [Not emulated] Floating-point support is available. */
686*22dc650dSSadaf Ebrahimi #define SLJIT_HAS_FPU 0
687*22dc650dSSadaf Ebrahimi /* [Limitation] Some registers are virtual registers. */
688*22dc650dSSadaf Ebrahimi #define SLJIT_HAS_VIRTUAL_REGISTERS 1
689*22dc650dSSadaf Ebrahimi /* [Emulated] Has zero register (setting a memory location to zero is efficient). */
690*22dc650dSSadaf Ebrahimi #define SLJIT_HAS_ZERO_REGISTER 2
691*22dc650dSSadaf Ebrahimi /* [Emulated] Count leading zero is supported. */
692*22dc650dSSadaf Ebrahimi #define SLJIT_HAS_CLZ 3
693*22dc650dSSadaf Ebrahimi /* [Emulated] Count trailing zero is supported. */
694*22dc650dSSadaf Ebrahimi #define SLJIT_HAS_CTZ 4
695*22dc650dSSadaf Ebrahimi /* [Emulated] Reverse the order of bytes is supported. */
696*22dc650dSSadaf Ebrahimi #define SLJIT_HAS_REV 5
697*22dc650dSSadaf Ebrahimi /* [Emulated] Rotate left/right is supported. */
698*22dc650dSSadaf Ebrahimi #define SLJIT_HAS_ROT 6
699*22dc650dSSadaf Ebrahimi /* [Emulated] Conditional move is supported. */
700*22dc650dSSadaf Ebrahimi #define SLJIT_HAS_CMOV 7
701*22dc650dSSadaf Ebrahimi /* [Emulated] Prefetch instruction is available (emulated as a nop). */
702*22dc650dSSadaf Ebrahimi #define SLJIT_HAS_PREFETCH 8
703*22dc650dSSadaf Ebrahimi /* [Emulated] Copy from/to f32 operation is available (see sljit_emit_fcopy). */
704*22dc650dSSadaf Ebrahimi #define SLJIT_HAS_COPY_F32 9
705*22dc650dSSadaf Ebrahimi /* [Emulated] Copy from/to f64 operation is available (see sljit_emit_fcopy). */
706*22dc650dSSadaf Ebrahimi #define SLJIT_HAS_COPY_F64 10
707*22dc650dSSadaf Ebrahimi /* [Not emulated] The 64 bit floating point registers can be used as
708*22dc650dSSadaf Ebrahimi two separate 32 bit floating point registers (e.g. ARM32). The
709*22dc650dSSadaf Ebrahimi second 32 bit part can be accessed by SLJIT_F64_SECOND. */
710*22dc650dSSadaf Ebrahimi #define SLJIT_HAS_F64_AS_F32_PAIR 11
711*22dc650dSSadaf Ebrahimi /* [Not emulated] Some SIMD operations are supported by the compiler. */
712*22dc650dSSadaf Ebrahimi #define SLJIT_HAS_SIMD 12
713*22dc650dSSadaf Ebrahimi /* [Not emulated] SIMD registers are mapped to a pair of double precision
714*22dc650dSSadaf Ebrahimi floating point registers. E.g. passing either SLJIT_FR0 or SLJIT_FR1 to
715*22dc650dSSadaf Ebrahimi a simd operation represents the same 128 bit register, and both SLJIT_FR0
716*22dc650dSSadaf Ebrahimi and SLJIT_FR1 are overwritten. */
717*22dc650dSSadaf Ebrahimi #define SLJIT_SIMD_REGS_ARE_PAIRS 13
718*22dc650dSSadaf Ebrahimi /* [Not emulated] Atomic support is available (fine-grained). */
719*22dc650dSSadaf Ebrahimi #define SLJIT_HAS_ATOMIC 14
720*22dc650dSSadaf Ebrahimi
721*22dc650dSSadaf Ebrahimi #if (defined SLJIT_CONFIG_X86 && SLJIT_CONFIG_X86)
722*22dc650dSSadaf Ebrahimi /* [Not emulated] AVX support is available on x86. */
723*22dc650dSSadaf Ebrahimi #define SLJIT_HAS_AVX 100
724*22dc650dSSadaf Ebrahimi /* [Not emulated] AVX2 support is available on x86. */
725*22dc650dSSadaf Ebrahimi #define SLJIT_HAS_AVX2 101
726*22dc650dSSadaf Ebrahimi #endif
727*22dc650dSSadaf Ebrahimi
728*22dc650dSSadaf Ebrahimi #if (defined SLJIT_CONFIG_LOONGARCH)
729*22dc650dSSadaf Ebrahimi /* [Not emulated] LASX support is available on LoongArch */
730*22dc650dSSadaf Ebrahimi #define SLJIT_HAS_LASX 201
731*22dc650dSSadaf Ebrahimi #endif
732*22dc650dSSadaf Ebrahimi
733*22dc650dSSadaf Ebrahimi SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_has_cpu_feature(sljit_s32 feature_type);
734*22dc650dSSadaf Ebrahimi
735*22dc650dSSadaf Ebrahimi /* If type is between SLJIT_ORDERED_EQUAL and SLJIT_ORDERED_LESS_EQUAL,
736*22dc650dSSadaf Ebrahimi sljit_cmp_info returns with:
737*22dc650dSSadaf Ebrahimi zero - if the cpu supports the floating point comparison type
738*22dc650dSSadaf Ebrahimi one - if the comparison requires two machine instructions
739*22dc650dSSadaf Ebrahimi two - if the comparison requires more than two machine instructions
740*22dc650dSSadaf Ebrahimi
741*22dc650dSSadaf Ebrahimi When the result is non-zero, it is recommended to avoid
742*22dc650dSSadaf Ebrahimi using the specified comparison type if it is easy to do so.
743*22dc650dSSadaf Ebrahimi
744*22dc650dSSadaf Ebrahimi Otherwise it returns zero. */
745*22dc650dSSadaf Ebrahimi SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_cmp_info(sljit_s32 type);
746*22dc650dSSadaf Ebrahimi
747*22dc650dSSadaf Ebrahimi /* The following functions generate machine code. If there is no
748*22dc650dSSadaf Ebrahimi error, they return with SLJIT_SUCCESS, otherwise they return
749*22dc650dSSadaf Ebrahimi with an error code. */
750*22dc650dSSadaf Ebrahimi
751*22dc650dSSadaf Ebrahimi /*
752*22dc650dSSadaf Ebrahimi The executable code is a function from the viewpoint of the C
753*22dc650dSSadaf Ebrahimi language. The function calls must conform to the ABI (Application
754*22dc650dSSadaf Ebrahimi Binary Interface) of the platform, which specify the purpose of
755*22dc650dSSadaf Ebrahimi machine registers and stack handling among other things. The
756*22dc650dSSadaf Ebrahimi sljit_emit_enter function emits the necessary instructions for
757*22dc650dSSadaf Ebrahimi setting up a new context for the executable code. This is often
758*22dc650dSSadaf Ebrahimi called as function prologue. Furthermore the options argument
759*22dc650dSSadaf Ebrahimi can be used to pass configuration options to the compiler. The
760*22dc650dSSadaf Ebrahimi available options are listed before sljit_emit_enter.
761*22dc650dSSadaf Ebrahimi
762*22dc650dSSadaf Ebrahimi The function argument list is specified by the SLJIT_ARGSx
763*22dc650dSSadaf Ebrahimi (SLJIT_ARGS0 .. SLJIT_ARGS4) macros. Currently maximum four
764*22dc650dSSadaf Ebrahimi arguments are supported. See the description of SLJIT_ARGSx
765*22dc650dSSadaf Ebrahimi macros about argument passing. Furthermore the register set
766*22dc650dSSadaf Ebrahimi used by the function must be declared as well. The number of
767*22dc650dSSadaf Ebrahimi scratch and saved registers available to the function must
768*22dc650dSSadaf Ebrahimi be passed to sljit_emit_enter. Only R registers between R0
769*22dc650dSSadaf Ebrahimi and "scratches" argument can be used later. E.g. if "scratches"
770*22dc650dSSadaf Ebrahimi is set to two, the scratch register set will be limited to
771*22dc650dSSadaf Ebrahimi SLJIT_R0 and SLJIT_R1. The S registers and the floating point
772*22dc650dSSadaf Ebrahimi registers ("fscratches" and "fsaveds") are specified in a
773*22dc650dSSadaf Ebrahimi similar manner. The sljit_emit_enter is also capable of
774*22dc650dSSadaf Ebrahimi allocating a stack space for local data. The "local_size"
775*22dc650dSSadaf Ebrahimi argument contains the size in bytes of this local area, and
776*22dc650dSSadaf Ebrahimi it can be accessed using SLJIT_MEM1(SLJIT_SP). The memory
777*22dc650dSSadaf Ebrahimi area between SLJIT_SP (inclusive) and SLJIT_SP + local_size
778*22dc650dSSadaf Ebrahimi (exclusive) can be modified freely until the function returns.
779*22dc650dSSadaf Ebrahimi The stack space is not initialized to zero.
780*22dc650dSSadaf Ebrahimi
781*22dc650dSSadaf Ebrahimi Note: the following conditions must met:
782*22dc650dSSadaf Ebrahimi 0 <= scratches <= SLJIT_NUMBER_OF_REGISTERS
783*22dc650dSSadaf Ebrahimi 0 <= saveds <= SLJIT_NUMBER_OF_SAVED_REGISTERS
784*22dc650dSSadaf Ebrahimi scratches + saveds <= SLJIT_NUMBER_OF_REGISTERS
785*22dc650dSSadaf Ebrahimi 0 <= fscratches <= SLJIT_NUMBER_OF_FLOAT_REGISTERS
786*22dc650dSSadaf Ebrahimi 0 <= fsaveds <= SLJIT_NUMBER_OF_SAVED_FLOAT_REGISTERS
787*22dc650dSSadaf Ebrahimi fscratches + fsaveds <= SLJIT_NUMBER_OF_FLOAT_REGISTERS
788*22dc650dSSadaf Ebrahimi
789*22dc650dSSadaf Ebrahimi Note: the compiler can use saved registers as scratch registers,
790*22dc650dSSadaf Ebrahimi but the opposite is not supported
791*22dc650dSSadaf Ebrahimi
792*22dc650dSSadaf Ebrahimi Note: every call of sljit_emit_enter and sljit_set_context
793*22dc650dSSadaf Ebrahimi overwrites the previous context.
794*22dc650dSSadaf Ebrahimi */
795*22dc650dSSadaf Ebrahimi
796*22dc650dSSadaf Ebrahimi /* Saved registers between SLJIT_S0 and SLJIT_S(n - 1) (inclusive)
797*22dc650dSSadaf Ebrahimi are not saved / restored on function enter / return. Instead,
798*22dc650dSSadaf Ebrahimi these registers can be used to pass / return data (such as
799*22dc650dSSadaf Ebrahimi global / local context pointers) across function calls. The
800*22dc650dSSadaf Ebrahimi value of n must be between 1 and 3. This option is only
801*22dc650dSSadaf Ebrahimi supported by SLJIT_ENTER_REG_ARG calling convention. */
802*22dc650dSSadaf Ebrahimi #define SLJIT_ENTER_KEEP(n) (n)
803*22dc650dSSadaf Ebrahimi
804*22dc650dSSadaf Ebrahimi /* The compiled function uses an SLJIT specific register argument
805*22dc650dSSadaf Ebrahimi calling convention. This is a lightweight function call type where
806*22dc650dSSadaf Ebrahimi both the caller and the called functions must be compiled by
807*22dc650dSSadaf Ebrahimi SLJIT. The type argument of the call must be SLJIT_CALL_REG_ARG
808*22dc650dSSadaf Ebrahimi and all arguments must be stored in scratch registers. */
809*22dc650dSSadaf Ebrahimi #define SLJIT_ENTER_REG_ARG 0x00000004
810*22dc650dSSadaf Ebrahimi
811*22dc650dSSadaf Ebrahimi /* The local_size must be >= 0 and <= SLJIT_MAX_LOCAL_SIZE. */
812*22dc650dSSadaf Ebrahimi #define SLJIT_MAX_LOCAL_SIZE 1048576
813*22dc650dSSadaf Ebrahimi
814*22dc650dSSadaf Ebrahimi #if (defined SLJIT_CONFIG_X86 && SLJIT_CONFIG_X86)
815*22dc650dSSadaf Ebrahimi /* Use VEX prefix for all SIMD operations on x86. */
816*22dc650dSSadaf Ebrahimi #define SLJIT_ENTER_USE_VEX 0x00010000
817*22dc650dSSadaf Ebrahimi #endif /* !SLJIT_CONFIG_X86 */
818*22dc650dSSadaf Ebrahimi
819*22dc650dSSadaf Ebrahimi SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_enter(struct sljit_compiler *compiler,
820*22dc650dSSadaf Ebrahimi sljit_s32 options, sljit_s32 arg_types, sljit_s32 scratches, sljit_s32 saveds,
821*22dc650dSSadaf Ebrahimi sljit_s32 fscratches, sljit_s32 fsaveds, sljit_s32 local_size);
822*22dc650dSSadaf Ebrahimi
823*22dc650dSSadaf Ebrahimi /* The SLJIT compiler has a current context (which contains the local
824*22dc650dSSadaf Ebrahimi stack space size, number of used registers, etc.) which is initialized
825*22dc650dSSadaf Ebrahimi by sljit_emit_enter. Several functions (such as sljit_emit_return)
826*22dc650dSSadaf Ebrahimi requires this context to be able to generate the appropriate code.
827*22dc650dSSadaf Ebrahimi However, some code fragments (compiled separately) may have no
828*22dc650dSSadaf Ebrahimi normal entry point so their context is unknown to the compiler.
829*22dc650dSSadaf Ebrahimi
830*22dc650dSSadaf Ebrahimi sljit_set_context and sljit_emit_enter have the same arguments,
831*22dc650dSSadaf Ebrahimi but sljit_set_context does not generate any machine code.
832*22dc650dSSadaf Ebrahimi
833*22dc650dSSadaf Ebrahimi Note: every call of sljit_emit_enter and sljit_set_context overwrites
834*22dc650dSSadaf Ebrahimi the previous context. */
835*22dc650dSSadaf Ebrahimi
836*22dc650dSSadaf Ebrahimi SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_set_context(struct sljit_compiler *compiler,
837*22dc650dSSadaf Ebrahimi sljit_s32 options, sljit_s32 arg_types, sljit_s32 scratches, sljit_s32 saveds,
838*22dc650dSSadaf Ebrahimi sljit_s32 fscratches, sljit_s32 fsaveds, sljit_s32 local_size);
839*22dc650dSSadaf Ebrahimi
840*22dc650dSSadaf Ebrahimi /* Return to the caller function. The sljit_emit_return_void function
841*22dc650dSSadaf Ebrahimi does not return with any value. The sljit_emit_return function returns
842*22dc650dSSadaf Ebrahimi with a single value loaded from its source operand. The load operation
843*22dc650dSSadaf Ebrahimi can be between SLJIT_MOV and SLJIT_MOV_P (see sljit_emit_op1) and
844*22dc650dSSadaf Ebrahimi SLJIT_MOV_F32/SLJIT_MOV_F64 (see sljit_emit_fop1) depending on the
845*22dc650dSSadaf Ebrahimi return value specified by sljit_emit_enter/sljit_set_context. */
846*22dc650dSSadaf Ebrahimi
847*22dc650dSSadaf Ebrahimi SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_return_void(struct sljit_compiler *compiler);
848*22dc650dSSadaf Ebrahimi
849*22dc650dSSadaf Ebrahimi SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_return(struct sljit_compiler *compiler, sljit_s32 op,
850*22dc650dSSadaf Ebrahimi sljit_s32 src, sljit_sw srcw);
851*22dc650dSSadaf Ebrahimi
852*22dc650dSSadaf Ebrahimi /* Restores the saved registers and free the stack area, then the execution
853*22dc650dSSadaf Ebrahimi continues from the address specified by the source operand. This
854*22dc650dSSadaf Ebrahimi operation is similar to sljit_emit_return, but it ignores the return
855*22dc650dSSadaf Ebrahimi address. The code where the exection continues should use the same context
856*22dc650dSSadaf Ebrahimi as the caller function (see sljit_set_context). A word (pointer) value
857*22dc650dSSadaf Ebrahimi can be passed in the SLJIT_RETURN_REG register. This function can be used
858*22dc650dSSadaf Ebrahimi to jump to exception handlers. */
859*22dc650dSSadaf Ebrahimi
860*22dc650dSSadaf Ebrahimi SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_return_to(struct sljit_compiler *compiler,
861*22dc650dSSadaf Ebrahimi sljit_s32 src, sljit_sw srcw);
862*22dc650dSSadaf Ebrahimi
863*22dc650dSSadaf Ebrahimi /*
864*22dc650dSSadaf Ebrahimi Source and destination operands for arithmetical instructions
865*22dc650dSSadaf Ebrahimi imm - a simple immediate value (cannot be used as a destination)
866*22dc650dSSadaf Ebrahimi reg - any of the available registers (immediate argument must be 0)
867*22dc650dSSadaf Ebrahimi [imm] - absolute memory address
868*22dc650dSSadaf Ebrahimi [reg+imm] - indirect memory address
869*22dc650dSSadaf Ebrahimi [reg+(reg<<imm)] - indirect indexed memory address (shift must be between 0 and 3)
870*22dc650dSSadaf Ebrahimi useful for accessing arrays (fully supported by both x86 and
871*22dc650dSSadaf Ebrahimi ARM architectures, and cheap operation on others)
872*22dc650dSSadaf Ebrahimi */
873*22dc650dSSadaf Ebrahimi
874*22dc650dSSadaf Ebrahimi /*
875*22dc650dSSadaf Ebrahimi IMPORTANT NOTE: memory accesses MUST be naturally aligned unless
876*22dc650dSSadaf Ebrahimi SLJIT_UNALIGNED macro is defined and its value is 1.
877*22dc650dSSadaf Ebrahimi
878*22dc650dSSadaf Ebrahimi length | alignment
879*22dc650dSSadaf Ebrahimi ---------+-----------
880*22dc650dSSadaf Ebrahimi byte | 1 byte (any physical_address is accepted)
881*22dc650dSSadaf Ebrahimi half | 2 byte (physical_address & 0x1 == 0)
882*22dc650dSSadaf Ebrahimi int | 4 byte (physical_address & 0x3 == 0)
883*22dc650dSSadaf Ebrahimi word | 4 byte if SLJIT_32BIT_ARCHITECTURE is defined and its value is 1
884*22dc650dSSadaf Ebrahimi | 8 byte if SLJIT_64BIT_ARCHITECTURE is defined and its value is 1
885*22dc650dSSadaf Ebrahimi pointer | size of sljit_up type (4 byte on 32 bit machines, 4 or 8 byte
886*22dc650dSSadaf Ebrahimi | on 64 bit machines)
887*22dc650dSSadaf Ebrahimi
888*22dc650dSSadaf Ebrahimi Note: Different architectures have different addressing limitations.
889*22dc650dSSadaf Ebrahimi A single instruction is enough for the following addressing
890*22dc650dSSadaf Ebrahimi modes. Other addressing modes are emulated by instruction
891*22dc650dSSadaf Ebrahimi sequences. This information could help to improve those code
892*22dc650dSSadaf Ebrahimi generators which focuses only a few architectures.
893*22dc650dSSadaf Ebrahimi
894*22dc650dSSadaf Ebrahimi x86: [reg+imm], -2^32+1 <= imm <= 2^32-1 (full address space on x86-32)
895*22dc650dSSadaf Ebrahimi [reg+(reg<<imm)] is supported
896*22dc650dSSadaf Ebrahimi [imm], -2^32+1 <= imm <= 2^32-1 is supported
897*22dc650dSSadaf Ebrahimi Write-back is not supported
898*22dc650dSSadaf Ebrahimi arm: [reg+imm], -4095 <= imm <= 4095 or -255 <= imm <= 255 for signed
899*22dc650dSSadaf Ebrahimi bytes, any halfs or floating point values)
900*22dc650dSSadaf Ebrahimi [reg+(reg<<imm)] is supported
901*22dc650dSSadaf Ebrahimi Write-back is supported
902*22dc650dSSadaf Ebrahimi arm-t2: [reg+imm], -255 <= imm <= 4095
903*22dc650dSSadaf Ebrahimi [reg+(reg<<imm)] is supported
904*22dc650dSSadaf Ebrahimi Write back is supported only for [reg+imm], where -255 <= imm <= 255
905*22dc650dSSadaf Ebrahimi arm64: [reg+imm], -256 <= imm <= 255, 0 <= aligned imm <= 4095 * alignment
906*22dc650dSSadaf Ebrahimi [reg+(reg<<imm)] is supported
907*22dc650dSSadaf Ebrahimi Write back is supported only for [reg+imm], where -256 <= imm <= 255
908*22dc650dSSadaf Ebrahimi ppc: [reg+imm], -65536 <= imm <= 65535. 64 bit loads/stores and 32 bit
909*22dc650dSSadaf Ebrahimi signed load on 64 bit requires immediates divisible by 4.
910*22dc650dSSadaf Ebrahimi [reg+imm] is not supported for signed 8 bit values.
911*22dc650dSSadaf Ebrahimi [reg+reg] is supported
912*22dc650dSSadaf Ebrahimi Write-back is supported except for one instruction: 32 bit signed
913*22dc650dSSadaf Ebrahimi load with [reg+imm] addressing mode on 64 bit.
914*22dc650dSSadaf Ebrahimi mips: [reg+imm], -65536 <= imm <= 65535
915*22dc650dSSadaf Ebrahimi Write-back is not supported
916*22dc650dSSadaf Ebrahimi riscv: [reg+imm], -2048 <= imm <= 2047
917*22dc650dSSadaf Ebrahimi Write-back is not supported
918*22dc650dSSadaf Ebrahimi s390x: [reg+imm], -2^19 <= imm < 2^19
919*22dc650dSSadaf Ebrahimi [reg+reg] is supported
920*22dc650dSSadaf Ebrahimi Write-back is not supported
921*22dc650dSSadaf Ebrahimi loongarch: [reg+imm], -2048 <= imm <= 2047
922*22dc650dSSadaf Ebrahimi [reg+reg] is supported
923*22dc650dSSadaf Ebrahimi Write-back is not supported
924*22dc650dSSadaf Ebrahimi */
925*22dc650dSSadaf Ebrahimi
926*22dc650dSSadaf Ebrahimi /* Macros for specifying operand types. */
927*22dc650dSSadaf Ebrahimi #define SLJIT_MEM 0x80
928*22dc650dSSadaf Ebrahimi #define SLJIT_MEM0() (SLJIT_MEM)
929*22dc650dSSadaf Ebrahimi #define SLJIT_MEM1(r1) (SLJIT_MEM | (r1))
930*22dc650dSSadaf Ebrahimi #define SLJIT_MEM2(r1, r2) (SLJIT_MEM | (r1) | ((r2) << 8))
931*22dc650dSSadaf Ebrahimi #define SLJIT_IMM 0x7f
932*22dc650dSSadaf Ebrahimi #define SLJIT_REG_PAIR(r1, r2) ((r1) | ((r2) << 8))
933*22dc650dSSadaf Ebrahimi
934*22dc650dSSadaf Ebrahimi /* Macros for checking operand types (only for valid arguments). */
935*22dc650dSSadaf Ebrahimi #define SLJIT_IS_REG(arg) ((arg) > 0 && (arg) < SLJIT_IMM)
936*22dc650dSSadaf Ebrahimi #define SLJIT_IS_MEM(arg) ((arg) & SLJIT_MEM)
937*22dc650dSSadaf Ebrahimi #define SLJIT_IS_MEM0(arg) ((arg) == SLJIT_MEM)
938*22dc650dSSadaf Ebrahimi #define SLJIT_IS_MEM1(arg) ((arg) > SLJIT_MEM && (arg) < (SLJIT_MEM << 1))
939*22dc650dSSadaf Ebrahimi #define SLJIT_IS_MEM2(arg) (((arg) & SLJIT_MEM) && (arg) >= (SLJIT_MEM << 1))
940*22dc650dSSadaf Ebrahimi #define SLJIT_IS_IMM(arg) ((arg) == SLJIT_IMM)
941*22dc650dSSadaf Ebrahimi #define SLJIT_IS_REG_PAIR(arg) (!((arg) & SLJIT_MEM) && (arg) >= (SLJIT_MEM << 1))
942*22dc650dSSadaf Ebrahimi
943*22dc650dSSadaf Ebrahimi /* Macros for extracting registers from operands. */
944*22dc650dSSadaf Ebrahimi /* Support operands which contains a single register or
945*22dc650dSSadaf Ebrahimi constructed using SLJIT_MEM1, SLJIT_MEM2, or SLJIT_REG_PAIR. */
946*22dc650dSSadaf Ebrahimi #define SLJIT_EXTRACT_REG(arg) ((arg) & 0x7f)
947*22dc650dSSadaf Ebrahimi /* Support operands which constructed using SLJIT_MEM2, or SLJIT_REG_PAIR. */
948*22dc650dSSadaf Ebrahimi #define SLJIT_EXTRACT_SECOND_REG(arg) ((arg) >> 8)
949*22dc650dSSadaf Ebrahimi
950*22dc650dSSadaf Ebrahimi /* Sets 32 bit operation mode on 64 bit CPUs. This option is ignored on
951*22dc650dSSadaf Ebrahimi 32 bit CPUs. When this option is set for an arithmetic operation, only
952*22dc650dSSadaf Ebrahimi the lower 32 bits of the input registers are used, and the CPU status
953*22dc650dSSadaf Ebrahimi flags are set according to the 32 bit result. Although the higher 32 bit
954*22dc650dSSadaf Ebrahimi of the input and the result registers are not defined by SLJIT, it might
955*22dc650dSSadaf Ebrahimi be defined by the CPU architecture (e.g. MIPS). To satisfy these CPU
956*22dc650dSSadaf Ebrahimi requirements all source registers must be the result of those operations
957*22dc650dSSadaf Ebrahimi where this option was also set. Memory loads read 32 bit values rather
958*22dc650dSSadaf Ebrahimi than 64 bit ones. In other words 32 bit and 64 bit operations cannot be
959*22dc650dSSadaf Ebrahimi mixed. The only exception is SLJIT_MOV32 which source register can hold
960*22dc650dSSadaf Ebrahimi any 32 or 64 bit value, and it is converted to a 32 bit compatible format
961*22dc650dSSadaf Ebrahimi first. When the source and destination registers are the same, this
962*22dc650dSSadaf Ebrahimi conversion is free (no instructions are emitted) on most CPUs. A 32 bit
963*22dc650dSSadaf Ebrahimi value can also be converted to a 64 bit value by SLJIT_MOV_S32
964*22dc650dSSadaf Ebrahimi (sign extension) or SLJIT_MOV_U32 (zero extension).
965*22dc650dSSadaf Ebrahimi
966*22dc650dSSadaf Ebrahimi As for floating-point operations, this option sets 32 bit single
967*22dc650dSSadaf Ebrahimi precision mode. Similar to the integer operations, all register arguments
968*22dc650dSSadaf Ebrahimi must be the result of those operations where this option was also set.
969*22dc650dSSadaf Ebrahimi
970*22dc650dSSadaf Ebrahimi Note: memory addressing always uses 64 bit values on 64 bit systems so
971*22dc650dSSadaf Ebrahimi the result of a 32 bit operation must not be used with SLJIT_MEMx
972*22dc650dSSadaf Ebrahimi macros.
973*22dc650dSSadaf Ebrahimi
974*22dc650dSSadaf Ebrahimi This option is part of the instruction name, so there is no need to
975*22dc650dSSadaf Ebrahimi manually set it. E.g:
976*22dc650dSSadaf Ebrahimi
977*22dc650dSSadaf Ebrahimi SLJIT_ADD32 == (SLJIT_ADD | SLJIT_32) */
978*22dc650dSSadaf Ebrahimi #define SLJIT_32 0x100
979*22dc650dSSadaf Ebrahimi
980*22dc650dSSadaf Ebrahimi /* Many CPUs (x86, ARM, PPC) have status flag bits which can be set according
981*22dc650dSSadaf Ebrahimi to the result of an operation. Other CPUs (MIPS) do not have status
982*22dc650dSSadaf Ebrahimi flag bits, and results must be stored in registers. To cover both
983*22dc650dSSadaf Ebrahimi architecture types efficiently only two flags are defined by SLJIT:
984*22dc650dSSadaf Ebrahimi
985*22dc650dSSadaf Ebrahimi * Zero (equal) flag: it is set if the result is zero
986*22dc650dSSadaf Ebrahimi * Variable flag: its value is defined by the arithmetic operation
987*22dc650dSSadaf Ebrahimi
988*22dc650dSSadaf Ebrahimi SLJIT instructions can set any or both of these flags. The value of
989*22dc650dSSadaf Ebrahimi these flags is undefined if the instruction does not specify their
990*22dc650dSSadaf Ebrahimi value. The description of each instruction contains the list of
991*22dc650dSSadaf Ebrahimi allowed flag types.
992*22dc650dSSadaf Ebrahimi
993*22dc650dSSadaf Ebrahimi Note: the logical or operation can be used to set flags.
994*22dc650dSSadaf Ebrahimi
995*22dc650dSSadaf Ebrahimi Example: SLJIT_ADD can set the Z, OVERFLOW, CARRY flags hence
996*22dc650dSSadaf Ebrahimi
997*22dc650dSSadaf Ebrahimi sljit_op2(..., SLJIT_ADD, ...)
998*22dc650dSSadaf Ebrahimi Both the zero and variable flags are undefined so they can
999*22dc650dSSadaf Ebrahimi have any value after the operation is completed.
1000*22dc650dSSadaf Ebrahimi
1001*22dc650dSSadaf Ebrahimi sljit_op2(..., SLJIT_ADD | SLJIT_SET_Z, ...)
1002*22dc650dSSadaf Ebrahimi Sets the zero flag if the result is zero, clears it otherwise.
1003*22dc650dSSadaf Ebrahimi The variable flag is undefined.
1004*22dc650dSSadaf Ebrahimi
1005*22dc650dSSadaf Ebrahimi sljit_op2(..., SLJIT_ADD | SLJIT_SET_OVERFLOW, ...)
1006*22dc650dSSadaf Ebrahimi Sets the variable flag if an integer overflow occurs, clears
1007*22dc650dSSadaf Ebrahimi it otherwise. The zero flag is undefined.
1008*22dc650dSSadaf Ebrahimi
1009*22dc650dSSadaf Ebrahimi sljit_op2(..., SLJIT_ADD | SLJIT_SET_Z | SLJIT_SET_CARRY, ...)
1010*22dc650dSSadaf Ebrahimi Sets the zero flag if the result is zero, clears it otherwise.
1011*22dc650dSSadaf Ebrahimi Sets the variable flag if unsigned overflow (carry) occurs,
1012*22dc650dSSadaf Ebrahimi clears it otherwise.
1013*22dc650dSSadaf Ebrahimi
1014*22dc650dSSadaf Ebrahimi Certain instructions (e.g. SLJIT_MOV) does not modify flags, so
1015*22dc650dSSadaf Ebrahimi status flags are unchanged.
1016*22dc650dSSadaf Ebrahimi
1017*22dc650dSSadaf Ebrahimi Example:
1018*22dc650dSSadaf Ebrahimi
1019*22dc650dSSadaf Ebrahimi sljit_op2(..., SLJIT_ADD | SLJIT_SET_Z, ...)
1020*22dc650dSSadaf Ebrahimi sljit_op1(..., SLJIT_MOV, ...)
1021*22dc650dSSadaf Ebrahimi Zero flag is set according to the result of SLJIT_ADD.
1022*22dc650dSSadaf Ebrahimi
1023*22dc650dSSadaf Ebrahimi sljit_op2(..., SLJIT_ADD | SLJIT_SET_Z, ...)
1024*22dc650dSSadaf Ebrahimi sljit_op2(..., SLJIT_ADD, ...)
1025*22dc650dSSadaf Ebrahimi Zero flag has unknown value.
1026*22dc650dSSadaf Ebrahimi
1027*22dc650dSSadaf Ebrahimi These flags can be used for code optimization. E.g. a fast loop can be
1028*22dc650dSSadaf Ebrahimi implemented by decreasing a counter register and set the zero flag
1029*22dc650dSSadaf Ebrahimi using a single instruction. The zero register can be used by a
1030*22dc650dSSadaf Ebrahimi conditional jump to restart the loop. A single comparison can set a
1031*22dc650dSSadaf Ebrahimi zero and less flags to check if a value is less, equal, or greater
1032*22dc650dSSadaf Ebrahimi than another value.
1033*22dc650dSSadaf Ebrahimi
1034*22dc650dSSadaf Ebrahimi Motivation: although some CPUs can set a large number of flag bits,
1035*22dc650dSSadaf Ebrahimi usually their values are ignored or only a few of them are used. Emulating
1036*22dc650dSSadaf Ebrahimi a large number of flags on systems without a flag register is complicated
1037*22dc650dSSadaf Ebrahimi so SLJIT instructions must specify the flag they want to use and only
1038*22dc650dSSadaf Ebrahimi that flag is computed. The last arithmetic instruction can be repeated if
1039*22dc650dSSadaf Ebrahimi multiple flags need to be checked.
1040*22dc650dSSadaf Ebrahimi */
1041*22dc650dSSadaf Ebrahimi
1042*22dc650dSSadaf Ebrahimi /* Set Zero status flag. */
1043*22dc650dSSadaf Ebrahimi #define SLJIT_SET_Z 0x0200
1044*22dc650dSSadaf Ebrahimi /* Set the variable status flag if condition is true.
1045*22dc650dSSadaf Ebrahimi See comparison types (e.g. SLJIT_SET_LESS, SLJIT_SET_F_EQUAL). */
1046*22dc650dSSadaf Ebrahimi #define SLJIT_SET(condition) ((condition) << 10)
1047*22dc650dSSadaf Ebrahimi
1048*22dc650dSSadaf Ebrahimi /* Starting index of opcodes for sljit_emit_op0. */
1049*22dc650dSSadaf Ebrahimi #define SLJIT_OP0_BASE 0
1050*22dc650dSSadaf Ebrahimi
1051*22dc650dSSadaf Ebrahimi /* Flags: - (does not modify flags)
1052*22dc650dSSadaf Ebrahimi Note: breakpoint instruction is not supported by all architectures (e.g. ppc)
1053*22dc650dSSadaf Ebrahimi It falls back to SLJIT_NOP in those cases. */
1054*22dc650dSSadaf Ebrahimi #define SLJIT_BREAKPOINT (SLJIT_OP0_BASE + 0)
1055*22dc650dSSadaf Ebrahimi /* Flags: - (does not modify flags)
1056*22dc650dSSadaf Ebrahimi Note: may or may not cause an extra cycle wait
1057*22dc650dSSadaf Ebrahimi it can even decrease the runtime in a few cases. */
1058*22dc650dSSadaf Ebrahimi #define SLJIT_NOP (SLJIT_OP0_BASE + 1)
1059*22dc650dSSadaf Ebrahimi /* Flags: - (may destroy flags)
1060*22dc650dSSadaf Ebrahimi Unsigned multiplication of SLJIT_R0 and SLJIT_R1.
1061*22dc650dSSadaf Ebrahimi Result is placed into SLJIT_R1:SLJIT_R0 (high:low) word */
1062*22dc650dSSadaf Ebrahimi #define SLJIT_LMUL_UW (SLJIT_OP0_BASE + 2)
1063*22dc650dSSadaf Ebrahimi /* Flags: - (may destroy flags)
1064*22dc650dSSadaf Ebrahimi Signed multiplication of SLJIT_R0 and SLJIT_R1.
1065*22dc650dSSadaf Ebrahimi Result is placed into SLJIT_R1:SLJIT_R0 (high:low) word */
1066*22dc650dSSadaf Ebrahimi #define SLJIT_LMUL_SW (SLJIT_OP0_BASE + 3)
1067*22dc650dSSadaf Ebrahimi /* Flags: - (may destroy flags)
1068*22dc650dSSadaf Ebrahimi Unsigned divide of the value in SLJIT_R0 by the value in SLJIT_R1.
1069*22dc650dSSadaf Ebrahimi The result is placed into SLJIT_R0 and the remainder into SLJIT_R1.
1070*22dc650dSSadaf Ebrahimi Note: if SLJIT_R1 is 0, the behaviour is undefined. */
1071*22dc650dSSadaf Ebrahimi #define SLJIT_DIVMOD_UW (SLJIT_OP0_BASE + 4)
1072*22dc650dSSadaf Ebrahimi #define SLJIT_DIVMOD_U32 (SLJIT_DIVMOD_UW | SLJIT_32)
1073*22dc650dSSadaf Ebrahimi /* Flags: - (may destroy flags)
1074*22dc650dSSadaf Ebrahimi Signed divide of the value in SLJIT_R0 by the value in SLJIT_R1.
1075*22dc650dSSadaf Ebrahimi The result is placed into SLJIT_R0 and the remainder into SLJIT_R1.
1076*22dc650dSSadaf Ebrahimi Note: if SLJIT_R1 is 0, the behaviour is undefined.
1077*22dc650dSSadaf Ebrahimi Note: if SLJIT_R1 is -1 and SLJIT_R0 is integer min (0x800..00),
1078*22dc650dSSadaf Ebrahimi the behaviour is undefined. */
1079*22dc650dSSadaf Ebrahimi #define SLJIT_DIVMOD_SW (SLJIT_OP0_BASE + 5)
1080*22dc650dSSadaf Ebrahimi #define SLJIT_DIVMOD_S32 (SLJIT_DIVMOD_SW | SLJIT_32)
1081*22dc650dSSadaf Ebrahimi /* Flags: - (may destroy flags)
1082*22dc650dSSadaf Ebrahimi Unsigned divide of the value in SLJIT_R0 by the value in SLJIT_R1.
1083*22dc650dSSadaf Ebrahimi The result is placed into SLJIT_R0. SLJIT_R1 preserves its value.
1084*22dc650dSSadaf Ebrahimi Note: if SLJIT_R1 is 0, the behaviour is undefined. */
1085*22dc650dSSadaf Ebrahimi #define SLJIT_DIV_UW (SLJIT_OP0_BASE + 6)
1086*22dc650dSSadaf Ebrahimi #define SLJIT_DIV_U32 (SLJIT_DIV_UW | SLJIT_32)
1087*22dc650dSSadaf Ebrahimi /* Flags: - (may destroy flags)
1088*22dc650dSSadaf Ebrahimi Signed divide of the value in SLJIT_R0 by the value in SLJIT_R1.
1089*22dc650dSSadaf Ebrahimi The result is placed into SLJIT_R0. SLJIT_R1 preserves its value.
1090*22dc650dSSadaf Ebrahimi Note: if SLJIT_R1 is 0, the behaviour is undefined.
1091*22dc650dSSadaf Ebrahimi Note: if SLJIT_R1 is -1 and SLJIT_R0 is integer min (0x800..00),
1092*22dc650dSSadaf Ebrahimi the behaviour is undefined. */
1093*22dc650dSSadaf Ebrahimi #define SLJIT_DIV_SW (SLJIT_OP0_BASE + 7)
1094*22dc650dSSadaf Ebrahimi #define SLJIT_DIV_S32 (SLJIT_DIV_SW | SLJIT_32)
1095*22dc650dSSadaf Ebrahimi /* Flags: - (does not modify flags)
1096*22dc650dSSadaf Ebrahimi ENDBR32 instruction for x86-32 and ENDBR64 instruction for x86-64
1097*22dc650dSSadaf Ebrahimi when Intel Control-flow Enforcement Technology (CET) is enabled.
1098*22dc650dSSadaf Ebrahimi No instructions are emitted for other architectures. */
1099*22dc650dSSadaf Ebrahimi #define SLJIT_ENDBR (SLJIT_OP0_BASE + 8)
1100*22dc650dSSadaf Ebrahimi /* Flags: - (may destroy flags)
1101*22dc650dSSadaf Ebrahimi Skip stack frames before return when Intel Control-flow
1102*22dc650dSSadaf Ebrahimi Enforcement Technology (CET) is enabled. No instructions
1103*22dc650dSSadaf Ebrahimi are emitted for other architectures. */
1104*22dc650dSSadaf Ebrahimi #define SLJIT_SKIP_FRAMES_BEFORE_RETURN (SLJIT_OP0_BASE + 9)
1105*22dc650dSSadaf Ebrahimi
1106*22dc650dSSadaf Ebrahimi SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op0(struct sljit_compiler *compiler, sljit_s32 op);
1107*22dc650dSSadaf Ebrahimi
1108*22dc650dSSadaf Ebrahimi /* Starting index of opcodes for sljit_emit_op1. */
1109*22dc650dSSadaf Ebrahimi #define SLJIT_OP1_BASE 32
1110*22dc650dSSadaf Ebrahimi
1111*22dc650dSSadaf Ebrahimi /* The MOV instruction transfers data from source to destination.
1112*22dc650dSSadaf Ebrahimi
1113*22dc650dSSadaf Ebrahimi MOV instruction suffixes:
1114*22dc650dSSadaf Ebrahimi
1115*22dc650dSSadaf Ebrahimi U8 - unsigned 8 bit data transfer
1116*22dc650dSSadaf Ebrahimi S8 - signed 8 bit data transfer
1117*22dc650dSSadaf Ebrahimi U16 - unsigned 16 bit data transfer
1118*22dc650dSSadaf Ebrahimi S16 - signed 16 bit data transfer
1119*22dc650dSSadaf Ebrahimi U32 - unsigned int (32 bit) data transfer
1120*22dc650dSSadaf Ebrahimi S32 - signed int (32 bit) data transfer
1121*22dc650dSSadaf Ebrahimi P - pointer (sljit_up) data transfer
1122*22dc650dSSadaf Ebrahimi */
1123*22dc650dSSadaf Ebrahimi
1124*22dc650dSSadaf Ebrahimi /* Flags: - (does not modify flags) */
1125*22dc650dSSadaf Ebrahimi #define SLJIT_MOV (SLJIT_OP1_BASE + 0)
1126*22dc650dSSadaf Ebrahimi /* Flags: - (does not modify flags) */
1127*22dc650dSSadaf Ebrahimi #define SLJIT_MOV_U8 (SLJIT_OP1_BASE + 1)
1128*22dc650dSSadaf Ebrahimi #define SLJIT_MOV32_U8 (SLJIT_MOV_U8 | SLJIT_32)
1129*22dc650dSSadaf Ebrahimi /* Flags: - (does not modify flags) */
1130*22dc650dSSadaf Ebrahimi #define SLJIT_MOV_S8 (SLJIT_OP1_BASE + 2)
1131*22dc650dSSadaf Ebrahimi #define SLJIT_MOV32_S8 (SLJIT_MOV_S8 | SLJIT_32)
1132*22dc650dSSadaf Ebrahimi /* Flags: - (does not modify flags) */
1133*22dc650dSSadaf Ebrahimi #define SLJIT_MOV_U16 (SLJIT_OP1_BASE + 3)
1134*22dc650dSSadaf Ebrahimi #define SLJIT_MOV32_U16 (SLJIT_MOV_U16 | SLJIT_32)
1135*22dc650dSSadaf Ebrahimi /* Flags: - (does not modify flags) */
1136*22dc650dSSadaf Ebrahimi #define SLJIT_MOV_S16 (SLJIT_OP1_BASE + 4)
1137*22dc650dSSadaf Ebrahimi #define SLJIT_MOV32_S16 (SLJIT_MOV_S16 | SLJIT_32)
1138*22dc650dSSadaf Ebrahimi /* Flags: - (does not modify flags)
1139*22dc650dSSadaf Ebrahimi Note: no SLJIT_MOV32_U32 form, since it is the same as SLJIT_MOV32 */
1140*22dc650dSSadaf Ebrahimi #define SLJIT_MOV_U32 (SLJIT_OP1_BASE + 5)
1141*22dc650dSSadaf Ebrahimi /* Flags: - (does not modify flags)
1142*22dc650dSSadaf Ebrahimi Note: no SLJIT_MOV32_S32 form, since it is the same as SLJIT_MOV32 */
1143*22dc650dSSadaf Ebrahimi #define SLJIT_MOV_S32 (SLJIT_OP1_BASE + 6)
1144*22dc650dSSadaf Ebrahimi /* Flags: - (does not modify flags) */
1145*22dc650dSSadaf Ebrahimi #define SLJIT_MOV32 (SLJIT_OP1_BASE + 7)
1146*22dc650dSSadaf Ebrahimi /* Flags: - (does not modify flags)
1147*22dc650dSSadaf Ebrahimi Note: loads a pointer sized data, useful on x32 mode (a 64 bit mode
1148*22dc650dSSadaf Ebrahimi on x86-64 which uses 32 bit pointers) or similar compiling modes */
1149*22dc650dSSadaf Ebrahimi #define SLJIT_MOV_P (SLJIT_OP1_BASE + 8)
1150*22dc650dSSadaf Ebrahimi /* Count leading zeroes
1151*22dc650dSSadaf Ebrahimi Flags: - (may destroy flags)
1152*22dc650dSSadaf Ebrahimi Note: immediate source argument is not supported */
1153*22dc650dSSadaf Ebrahimi #define SLJIT_CLZ (SLJIT_OP1_BASE + 9)
1154*22dc650dSSadaf Ebrahimi #define SLJIT_CLZ32 (SLJIT_CLZ | SLJIT_32)
1155*22dc650dSSadaf Ebrahimi /* Count trailing zeroes
1156*22dc650dSSadaf Ebrahimi Flags: - (may destroy flags)
1157*22dc650dSSadaf Ebrahimi Note: immediate source argument is not supported */
1158*22dc650dSSadaf Ebrahimi #define SLJIT_CTZ (SLJIT_OP1_BASE + 10)
1159*22dc650dSSadaf Ebrahimi #define SLJIT_CTZ32 (SLJIT_CTZ | SLJIT_32)
1160*22dc650dSSadaf Ebrahimi /* Reverse the order of bytes
1161*22dc650dSSadaf Ebrahimi Flags: - (may destroy flags)
1162*22dc650dSSadaf Ebrahimi Note: converts between little and big endian formats
1163*22dc650dSSadaf Ebrahimi Note: immediate source argument is not supported */
1164*22dc650dSSadaf Ebrahimi #define SLJIT_REV (SLJIT_OP1_BASE + 11)
1165*22dc650dSSadaf Ebrahimi #define SLJIT_REV32 (SLJIT_REV | SLJIT_32)
1166*22dc650dSSadaf Ebrahimi /* Reverse the order of bytes in the lower 16 bit and extend as unsigned
1167*22dc650dSSadaf Ebrahimi Flags: - (may destroy flags)
1168*22dc650dSSadaf Ebrahimi Note: converts between little and big endian formats
1169*22dc650dSSadaf Ebrahimi Note: immediate source argument is not supported */
1170*22dc650dSSadaf Ebrahimi #define SLJIT_REV_U16 (SLJIT_OP1_BASE + 12)
1171*22dc650dSSadaf Ebrahimi #define SLJIT_REV32_U16 (SLJIT_REV_U16 | SLJIT_32)
1172*22dc650dSSadaf Ebrahimi /* Reverse the order of bytes in the lower 16 bit and extend as signed
1173*22dc650dSSadaf Ebrahimi Flags: - (may destroy flags)
1174*22dc650dSSadaf Ebrahimi Note: converts between little and big endian formats
1175*22dc650dSSadaf Ebrahimi Note: immediate source argument is not supported */
1176*22dc650dSSadaf Ebrahimi #define SLJIT_REV_S16 (SLJIT_OP1_BASE + 13)
1177*22dc650dSSadaf Ebrahimi #define SLJIT_REV32_S16 (SLJIT_REV_S16 | SLJIT_32)
1178*22dc650dSSadaf Ebrahimi /* Reverse the order of bytes in the lower 32 bit and extend as unsigned
1179*22dc650dSSadaf Ebrahimi Flags: - (may destroy flags)
1180*22dc650dSSadaf Ebrahimi Note: converts between little and big endian formats
1181*22dc650dSSadaf Ebrahimi Note: immediate source argument is not supported */
1182*22dc650dSSadaf Ebrahimi #define SLJIT_REV_U32 (SLJIT_OP1_BASE + 14)
1183*22dc650dSSadaf Ebrahimi /* Reverse the order of bytes in the lower 32 bit and extend as signed
1184*22dc650dSSadaf Ebrahimi Flags: - (may destroy flags)
1185*22dc650dSSadaf Ebrahimi Note: converts between little and big endian formats
1186*22dc650dSSadaf Ebrahimi Note: immediate source argument is not supported */
1187*22dc650dSSadaf Ebrahimi #define SLJIT_REV_S32 (SLJIT_OP1_BASE + 15)
1188*22dc650dSSadaf Ebrahimi
1189*22dc650dSSadaf Ebrahimi /* The following unary operations are supported by using sljit_emit_op2:
1190*22dc650dSSadaf Ebrahimi - binary not: SLJIT_XOR with immedate -1 as src1 or src2
1191*22dc650dSSadaf Ebrahimi - negate: SLJIT_SUB with immedate 0 as src1
1192*22dc650dSSadaf Ebrahimi Note: these operations are optimized by the compiler if the
1193*22dc650dSSadaf Ebrahimi target CPU has specialized instruction forms for them. */
1194*22dc650dSSadaf Ebrahimi
1195*22dc650dSSadaf Ebrahimi SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op1(struct sljit_compiler *compiler, sljit_s32 op,
1196*22dc650dSSadaf Ebrahimi sljit_s32 dst, sljit_sw dstw,
1197*22dc650dSSadaf Ebrahimi sljit_s32 src, sljit_sw srcw);
1198*22dc650dSSadaf Ebrahimi
1199*22dc650dSSadaf Ebrahimi /* Starting index of opcodes for sljit_emit_op2. */
1200*22dc650dSSadaf Ebrahimi #define SLJIT_OP2_BASE 64
1201*22dc650dSSadaf Ebrahimi
1202*22dc650dSSadaf Ebrahimi /* Flags: Z | OVERFLOW | CARRY */
1203*22dc650dSSadaf Ebrahimi #define SLJIT_ADD (SLJIT_OP2_BASE + 0)
1204*22dc650dSSadaf Ebrahimi #define SLJIT_ADD32 (SLJIT_ADD | SLJIT_32)
1205*22dc650dSSadaf Ebrahimi /* Flags: CARRY */
1206*22dc650dSSadaf Ebrahimi #define SLJIT_ADDC (SLJIT_OP2_BASE + 1)
1207*22dc650dSSadaf Ebrahimi #define SLJIT_ADDC32 (SLJIT_ADDC | SLJIT_32)
1208*22dc650dSSadaf Ebrahimi /* Flags: Z | LESS | GREATER_EQUAL | GREATER | LESS_EQUAL
1209*22dc650dSSadaf Ebrahimi SIG_LESS | SIG_GREATER_EQUAL | SIG_GREATER
1210*22dc650dSSadaf Ebrahimi SIG_LESS_EQUAL | OVERFLOW | CARRY */
1211*22dc650dSSadaf Ebrahimi #define SLJIT_SUB (SLJIT_OP2_BASE + 2)
1212*22dc650dSSadaf Ebrahimi #define SLJIT_SUB32 (SLJIT_SUB | SLJIT_32)
1213*22dc650dSSadaf Ebrahimi /* Flags: CARRY */
1214*22dc650dSSadaf Ebrahimi #define SLJIT_SUBC (SLJIT_OP2_BASE + 3)
1215*22dc650dSSadaf Ebrahimi #define SLJIT_SUBC32 (SLJIT_SUBC | SLJIT_32)
1216*22dc650dSSadaf Ebrahimi /* Note: integer mul
1217*22dc650dSSadaf Ebrahimi Flags: OVERFLOW */
1218*22dc650dSSadaf Ebrahimi #define SLJIT_MUL (SLJIT_OP2_BASE + 4)
1219*22dc650dSSadaf Ebrahimi #define SLJIT_MUL32 (SLJIT_MUL | SLJIT_32)
1220*22dc650dSSadaf Ebrahimi /* Flags: Z */
1221*22dc650dSSadaf Ebrahimi #define SLJIT_AND (SLJIT_OP2_BASE + 5)
1222*22dc650dSSadaf Ebrahimi #define SLJIT_AND32 (SLJIT_AND | SLJIT_32)
1223*22dc650dSSadaf Ebrahimi /* Flags: Z */
1224*22dc650dSSadaf Ebrahimi #define SLJIT_OR (SLJIT_OP2_BASE + 6)
1225*22dc650dSSadaf Ebrahimi #define SLJIT_OR32 (SLJIT_OR | SLJIT_32)
1226*22dc650dSSadaf Ebrahimi /* Flags: Z */
1227*22dc650dSSadaf Ebrahimi #define SLJIT_XOR (SLJIT_OP2_BASE + 7)
1228*22dc650dSSadaf Ebrahimi #define SLJIT_XOR32 (SLJIT_XOR | SLJIT_32)
1229*22dc650dSSadaf Ebrahimi /* Flags: Z
1230*22dc650dSSadaf Ebrahimi Let bit_length be the length of the shift operation: 32 or 64.
1231*22dc650dSSadaf Ebrahimi If src2 is immediate, src2w is masked by (bit_length - 1).
1232*22dc650dSSadaf Ebrahimi Otherwise, if the content of src2 is outside the range from 0
1233*22dc650dSSadaf Ebrahimi to bit_length - 1, the result is undefined. */
1234*22dc650dSSadaf Ebrahimi #define SLJIT_SHL (SLJIT_OP2_BASE + 8)
1235*22dc650dSSadaf Ebrahimi #define SLJIT_SHL32 (SLJIT_SHL | SLJIT_32)
1236*22dc650dSSadaf Ebrahimi /* Flags: Z
1237*22dc650dSSadaf Ebrahimi Same as SLJIT_SHL, except the the second operand is
1238*22dc650dSSadaf Ebrahimi always masked by the length of the shift operation. */
1239*22dc650dSSadaf Ebrahimi #define SLJIT_MSHL (SLJIT_OP2_BASE + 9)
1240*22dc650dSSadaf Ebrahimi #define SLJIT_MSHL32 (SLJIT_MSHL | SLJIT_32)
1241*22dc650dSSadaf Ebrahimi /* Flags: Z
1242*22dc650dSSadaf Ebrahimi Let bit_length be the length of the shift operation: 32 or 64.
1243*22dc650dSSadaf Ebrahimi If src2 is immediate, src2w is masked by (bit_length - 1).
1244*22dc650dSSadaf Ebrahimi Otherwise, if the content of src2 is outside the range from 0
1245*22dc650dSSadaf Ebrahimi to bit_length - 1, the result is undefined. */
1246*22dc650dSSadaf Ebrahimi #define SLJIT_LSHR (SLJIT_OP2_BASE + 10)
1247*22dc650dSSadaf Ebrahimi #define SLJIT_LSHR32 (SLJIT_LSHR | SLJIT_32)
1248*22dc650dSSadaf Ebrahimi /* Flags: Z
1249*22dc650dSSadaf Ebrahimi Same as SLJIT_LSHR, except the the second operand is
1250*22dc650dSSadaf Ebrahimi always masked by the length of the shift operation. */
1251*22dc650dSSadaf Ebrahimi #define SLJIT_MLSHR (SLJIT_OP2_BASE + 11)
1252*22dc650dSSadaf Ebrahimi #define SLJIT_MLSHR32 (SLJIT_MLSHR | SLJIT_32)
1253*22dc650dSSadaf Ebrahimi /* Flags: Z
1254*22dc650dSSadaf Ebrahimi Let bit_length be the length of the shift operation: 32 or 64.
1255*22dc650dSSadaf Ebrahimi If src2 is immediate, src2w is masked by (bit_length - 1).
1256*22dc650dSSadaf Ebrahimi Otherwise, if the content of src2 is outside the range from 0
1257*22dc650dSSadaf Ebrahimi to bit_length - 1, the result is undefined. */
1258*22dc650dSSadaf Ebrahimi #define SLJIT_ASHR (SLJIT_OP2_BASE + 12)
1259*22dc650dSSadaf Ebrahimi #define SLJIT_ASHR32 (SLJIT_ASHR | SLJIT_32)
1260*22dc650dSSadaf Ebrahimi /* Flags: Z
1261*22dc650dSSadaf Ebrahimi Same as SLJIT_ASHR, except the the second operand is
1262*22dc650dSSadaf Ebrahimi always masked by the length of the shift operation. */
1263*22dc650dSSadaf Ebrahimi #define SLJIT_MASHR (SLJIT_OP2_BASE + 13)
1264*22dc650dSSadaf Ebrahimi #define SLJIT_MASHR32 (SLJIT_MASHR | SLJIT_32)
1265*22dc650dSSadaf Ebrahimi /* Flags: - (may destroy flags)
1266*22dc650dSSadaf Ebrahimi Let bit_length be the length of the rotate operation: 32 or 64.
1267*22dc650dSSadaf Ebrahimi The second operand is always masked by (bit_length - 1). */
1268*22dc650dSSadaf Ebrahimi #define SLJIT_ROTL (SLJIT_OP2_BASE + 14)
1269*22dc650dSSadaf Ebrahimi #define SLJIT_ROTL32 (SLJIT_ROTL | SLJIT_32)
1270*22dc650dSSadaf Ebrahimi /* Flags: - (may destroy flags)
1271*22dc650dSSadaf Ebrahimi Let bit_length be the length of the rotate operation: 32 or 64.
1272*22dc650dSSadaf Ebrahimi The second operand is always masked by (bit_length - 1). */
1273*22dc650dSSadaf Ebrahimi #define SLJIT_ROTR (SLJIT_OP2_BASE + 15)
1274*22dc650dSSadaf Ebrahimi #define SLJIT_ROTR32 (SLJIT_ROTR | SLJIT_32)
1275*22dc650dSSadaf Ebrahimi
1276*22dc650dSSadaf Ebrahimi SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op2(struct sljit_compiler *compiler, sljit_s32 op,
1277*22dc650dSSadaf Ebrahimi sljit_s32 dst, sljit_sw dstw,
1278*22dc650dSSadaf Ebrahimi sljit_s32 src1, sljit_sw src1w,
1279*22dc650dSSadaf Ebrahimi sljit_s32 src2, sljit_sw src2w);
1280*22dc650dSSadaf Ebrahimi
1281*22dc650dSSadaf Ebrahimi /* The sljit_emit_op2u function is the same as sljit_emit_op2
1282*22dc650dSSadaf Ebrahimi except the result is discarded. */
1283*22dc650dSSadaf Ebrahimi
1284*22dc650dSSadaf Ebrahimi SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op2u(struct sljit_compiler *compiler, sljit_s32 op,
1285*22dc650dSSadaf Ebrahimi sljit_s32 src1, sljit_sw src1w,
1286*22dc650dSSadaf Ebrahimi sljit_s32 src2, sljit_sw src2w);
1287*22dc650dSSadaf Ebrahimi
1288*22dc650dSSadaf Ebrahimi /* Starting index of opcodes for sljit_emit_op2r. */
1289*22dc650dSSadaf Ebrahimi #define SLJIT_OP2R_BASE 96
1290*22dc650dSSadaf Ebrahimi
1291*22dc650dSSadaf Ebrahimi /* Flags: - (may destroy flags) */
1292*22dc650dSSadaf Ebrahimi #define SLJIT_MULADD (SLJIT_OP2R_BASE + 0)
1293*22dc650dSSadaf Ebrahimi #define SLJIT_MULADD32 (SLJIT_MULADD | SLJIT_32)
1294*22dc650dSSadaf Ebrahimi
1295*22dc650dSSadaf Ebrahimi /* Similar to sljit_emit_fop2, except the destination is always a register. */
1296*22dc650dSSadaf Ebrahimi SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op2r(struct sljit_compiler *compiler, sljit_s32 op,
1297*22dc650dSSadaf Ebrahimi sljit_s32 dst_reg,
1298*22dc650dSSadaf Ebrahimi sljit_s32 src1, sljit_sw src1w,
1299*22dc650dSSadaf Ebrahimi sljit_s32 src2, sljit_sw src2w);
1300*22dc650dSSadaf Ebrahimi
1301*22dc650dSSadaf Ebrahimi /* Emit a left or right shift operation, where the bits shifted
1302*22dc650dSSadaf Ebrahimi in comes from a separate source operand. All operands are
1303*22dc650dSSadaf Ebrahimi interpreted as unsigned integers.
1304*22dc650dSSadaf Ebrahimi
1305*22dc650dSSadaf Ebrahimi In the followings the value_mask variable is 31 for 32 bit
1306*22dc650dSSadaf Ebrahimi operations and word_size - 1 otherwise.
1307*22dc650dSSadaf Ebrahimi
1308*22dc650dSSadaf Ebrahimi op must be one of the following operations:
1309*22dc650dSSadaf Ebrahimi SLJIT_SHL or SLJIT_SHL32:
1310*22dc650dSSadaf Ebrahimi dst_reg = src1_reg << src3_reg
1311*22dc650dSSadaf Ebrahimi dst_reg |= ((src2_reg >> 1) >> (src3 ^ value_mask))
1312*22dc650dSSadaf Ebrahimi SLJIT_MSHL or SLJIT_MSHL32:
1313*22dc650dSSadaf Ebrahimi src3 &= value_mask
1314*22dc650dSSadaf Ebrahimi perform the SLJIT_SHL or SLJIT_SHL32 operation
1315*22dc650dSSadaf Ebrahimi SLJIT_LSHR or SLJIT_LSHR32:
1316*22dc650dSSadaf Ebrahimi dst_reg = src1_reg >> src3_reg
1317*22dc650dSSadaf Ebrahimi dst_reg |= ((src2_reg << 1) << (src3 ^ value_mask))
1318*22dc650dSSadaf Ebrahimi SLJIT_MLSHR or SLJIT_MLSHR32:
1319*22dc650dSSadaf Ebrahimi src3 &= value_mask
1320*22dc650dSSadaf Ebrahimi perform the SLJIT_LSHR or SLJIT_LSHR32 operation
1321*22dc650dSSadaf Ebrahimi
1322*22dc650dSSadaf Ebrahimi op can be combined (or'ed) with SLJIT_SHIFT_INTO_NON_ZERO
1323*22dc650dSSadaf Ebrahimi
1324*22dc650dSSadaf Ebrahimi dst_reg specifies the destination register, where dst_reg
1325*22dc650dSSadaf Ebrahimi and src2_reg cannot be the same registers
1326*22dc650dSSadaf Ebrahimi src1_reg specifies the source register
1327*22dc650dSSadaf Ebrahimi src2_reg specifies the register which is shifted into src1_reg
1328*22dc650dSSadaf Ebrahimi src3 / src3w contains the shift amount
1329*22dc650dSSadaf Ebrahimi
1330*22dc650dSSadaf Ebrahimi Note: a rotate operation is performed if src1_reg and
1331*22dc650dSSadaf Ebrahimi src2_reg are the same registers
1332*22dc650dSSadaf Ebrahimi
1333*22dc650dSSadaf Ebrahimi Flags: - (may destroy flags) */
1334*22dc650dSSadaf Ebrahimi
1335*22dc650dSSadaf Ebrahimi /* The src3 operand contains a non-zero value. Improves
1336*22dc650dSSadaf Ebrahimi the generated code on certain architectures, which
1337*22dc650dSSadaf Ebrahimi provides a small performance improvement. */
1338*22dc650dSSadaf Ebrahimi #define SLJIT_SHIFT_INTO_NON_ZERO 0x200
1339*22dc650dSSadaf Ebrahimi
1340*22dc650dSSadaf Ebrahimi SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_shift_into(struct sljit_compiler *compiler, sljit_s32 op,
1341*22dc650dSSadaf Ebrahimi sljit_s32 dst_reg,
1342*22dc650dSSadaf Ebrahimi sljit_s32 src1_reg,
1343*22dc650dSSadaf Ebrahimi sljit_s32 src2_reg,
1344*22dc650dSSadaf Ebrahimi sljit_s32 src3, sljit_sw src3w);
1345*22dc650dSSadaf Ebrahimi
1346*22dc650dSSadaf Ebrahimi /* Starting index of opcodes for sljit_emit_op_src
1347*22dc650dSSadaf Ebrahimi and sljit_emit_op_dst. */
1348*22dc650dSSadaf Ebrahimi #define SLJIT_OP_SRC_DST_BASE 112
1349*22dc650dSSadaf Ebrahimi
1350*22dc650dSSadaf Ebrahimi /* Fast return, see SLJIT_FAST_CALL for more details.
1351*22dc650dSSadaf Ebrahimi Note: src cannot be an immedate value
1352*22dc650dSSadaf Ebrahimi Flags: - (does not modify flags) */
1353*22dc650dSSadaf Ebrahimi #define SLJIT_FAST_RETURN (SLJIT_OP_SRC_DST_BASE + 0)
1354*22dc650dSSadaf Ebrahimi /* Skip stack frames before fast return.
1355*22dc650dSSadaf Ebrahimi Note: src cannot be an immedate value
1356*22dc650dSSadaf Ebrahimi Flags: may destroy flags. */
1357*22dc650dSSadaf Ebrahimi #define SLJIT_SKIP_FRAMES_BEFORE_FAST_RETURN (SLJIT_OP_SRC_DST_BASE + 1)
1358*22dc650dSSadaf Ebrahimi /* Prefetch value into the level 1 data cache
1359*22dc650dSSadaf Ebrahimi Note: if the target CPU does not support data prefetch,
1360*22dc650dSSadaf Ebrahimi no instructions are emitted.
1361*22dc650dSSadaf Ebrahimi Note: this instruction never fails, even if the memory address is invalid.
1362*22dc650dSSadaf Ebrahimi Flags: - (does not modify flags) */
1363*22dc650dSSadaf Ebrahimi #define SLJIT_PREFETCH_L1 (SLJIT_OP_SRC_DST_BASE + 2)
1364*22dc650dSSadaf Ebrahimi /* Prefetch value into the level 2 data cache
1365*22dc650dSSadaf Ebrahimi Note: same as SLJIT_PREFETCH_L1 if the target CPU
1366*22dc650dSSadaf Ebrahimi does not support this instruction form.
1367*22dc650dSSadaf Ebrahimi Note: this instruction never fails, even if the memory address is invalid.
1368*22dc650dSSadaf Ebrahimi Flags: - (does not modify flags) */
1369*22dc650dSSadaf Ebrahimi #define SLJIT_PREFETCH_L2 (SLJIT_OP_SRC_DST_BASE + 3)
1370*22dc650dSSadaf Ebrahimi /* Prefetch value into the level 3 data cache
1371*22dc650dSSadaf Ebrahimi Note: same as SLJIT_PREFETCH_L2 if the target CPU
1372*22dc650dSSadaf Ebrahimi does not support this instruction form.
1373*22dc650dSSadaf Ebrahimi Note: this instruction never fails, even if the memory address is invalid.
1374*22dc650dSSadaf Ebrahimi Flags: - (does not modify flags) */
1375*22dc650dSSadaf Ebrahimi #define SLJIT_PREFETCH_L3 (SLJIT_OP_SRC_DST_BASE + 4)
1376*22dc650dSSadaf Ebrahimi /* Prefetch a value which is only used once (and can be discarded afterwards)
1377*22dc650dSSadaf Ebrahimi Note: same as SLJIT_PREFETCH_L1 if the target CPU
1378*22dc650dSSadaf Ebrahimi does not support this instruction form.
1379*22dc650dSSadaf Ebrahimi Note: this instruction never fails, even if the memory address is invalid.
1380*22dc650dSSadaf Ebrahimi Flags: - (does not modify flags) */
1381*22dc650dSSadaf Ebrahimi #define SLJIT_PREFETCH_ONCE (SLJIT_OP_SRC_DST_BASE + 5)
1382*22dc650dSSadaf Ebrahimi
1383*22dc650dSSadaf Ebrahimi SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_src(struct sljit_compiler *compiler, sljit_s32 op,
1384*22dc650dSSadaf Ebrahimi sljit_s32 src, sljit_sw srcw);
1385*22dc650dSSadaf Ebrahimi
1386*22dc650dSSadaf Ebrahimi /* Fast enter, see SLJIT_FAST_CALL for more details.
1387*22dc650dSSadaf Ebrahimi Flags: - (does not modify flags) */
1388*22dc650dSSadaf Ebrahimi #define SLJIT_FAST_ENTER (SLJIT_OP_SRC_DST_BASE + 6)
1389*22dc650dSSadaf Ebrahimi
1390*22dc650dSSadaf Ebrahimi /* Copies the return address into dst. The return address is the
1391*22dc650dSSadaf Ebrahimi address where the execution continues after the called function
1392*22dc650dSSadaf Ebrahimi returns (see: sljit_emit_return / sljit_emit_return_void).
1393*22dc650dSSadaf Ebrahimi Flags: - (does not modify flags) */
1394*22dc650dSSadaf Ebrahimi #define SLJIT_GET_RETURN_ADDRESS (SLJIT_OP_SRC_DST_BASE + 7)
1395*22dc650dSSadaf Ebrahimi
1396*22dc650dSSadaf Ebrahimi SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_dst(struct sljit_compiler *compiler, sljit_s32 op,
1397*22dc650dSSadaf Ebrahimi sljit_s32 dst, sljit_sw dstw);
1398*22dc650dSSadaf Ebrahimi
1399*22dc650dSSadaf Ebrahimi /* Starting index of opcodes for sljit_emit_fop1. */
1400*22dc650dSSadaf Ebrahimi #define SLJIT_FOP1_BASE 144
1401*22dc650dSSadaf Ebrahimi
1402*22dc650dSSadaf Ebrahimi /* Flags: - (does not modify flags) */
1403*22dc650dSSadaf Ebrahimi #define SLJIT_MOV_F64 (SLJIT_FOP1_BASE + 0)
1404*22dc650dSSadaf Ebrahimi #define SLJIT_MOV_F32 (SLJIT_MOV_F64 | SLJIT_32)
1405*22dc650dSSadaf Ebrahimi /* Convert opcodes: CONV[DST_TYPE].FROM[SRC_TYPE]
1406*22dc650dSSadaf Ebrahimi SRC/DST TYPE can be: F64, F32, S32, SW
1407*22dc650dSSadaf Ebrahimi Rounding mode when the destination is SW or S32: round towards zero. */
1408*22dc650dSSadaf Ebrahimi /* Flags: - (may destroy flags) */
1409*22dc650dSSadaf Ebrahimi #define SLJIT_CONV_F64_FROM_F32 (SLJIT_FOP1_BASE + 1)
1410*22dc650dSSadaf Ebrahimi #define SLJIT_CONV_F32_FROM_F64 (SLJIT_CONV_F64_FROM_F32 | SLJIT_32)
1411*22dc650dSSadaf Ebrahimi /* Flags: - (may destroy flags) */
1412*22dc650dSSadaf Ebrahimi #define SLJIT_CONV_SW_FROM_F64 (SLJIT_FOP1_BASE + 2)
1413*22dc650dSSadaf Ebrahimi #define SLJIT_CONV_SW_FROM_F32 (SLJIT_CONV_SW_FROM_F64 | SLJIT_32)
1414*22dc650dSSadaf Ebrahimi /* Flags: - (may destroy flags) */
1415*22dc650dSSadaf Ebrahimi #define SLJIT_CONV_S32_FROM_F64 (SLJIT_FOP1_BASE + 3)
1416*22dc650dSSadaf Ebrahimi #define SLJIT_CONV_S32_FROM_F32 (SLJIT_CONV_S32_FROM_F64 | SLJIT_32)
1417*22dc650dSSadaf Ebrahimi /* Flags: - (may destroy flags) */
1418*22dc650dSSadaf Ebrahimi #define SLJIT_CONV_F64_FROM_SW (SLJIT_FOP1_BASE + 4)
1419*22dc650dSSadaf Ebrahimi #define SLJIT_CONV_F32_FROM_SW (SLJIT_CONV_F64_FROM_SW | SLJIT_32)
1420*22dc650dSSadaf Ebrahimi /* Flags: - (may destroy flags) */
1421*22dc650dSSadaf Ebrahimi #define SLJIT_CONV_F64_FROM_S32 (SLJIT_FOP1_BASE + 5)
1422*22dc650dSSadaf Ebrahimi #define SLJIT_CONV_F32_FROM_S32 (SLJIT_CONV_F64_FROM_S32 | SLJIT_32)
1423*22dc650dSSadaf Ebrahimi /* Flags: - (may destroy flags) */
1424*22dc650dSSadaf Ebrahimi #define SLJIT_CONV_F64_FROM_UW (SLJIT_FOP1_BASE + 6)
1425*22dc650dSSadaf Ebrahimi #define SLJIT_CONV_F32_FROM_UW (SLJIT_CONV_F64_FROM_UW | SLJIT_32)
1426*22dc650dSSadaf Ebrahimi /* Flags: - (may destroy flags) */
1427*22dc650dSSadaf Ebrahimi #define SLJIT_CONV_F64_FROM_U32 (SLJIT_FOP1_BASE + 7)
1428*22dc650dSSadaf Ebrahimi #define SLJIT_CONV_F32_FROM_U32 (SLJIT_CONV_F64_FROM_U32 | SLJIT_32)
1429*22dc650dSSadaf Ebrahimi /* Note: dst is the left and src is the right operand for SLJIT_CMP_F32/64.
1430*22dc650dSSadaf Ebrahimi Flags: EQUAL_F | LESS_F | GREATER_EQUAL_F | GREATER_F | LESS_EQUAL_F */
1431*22dc650dSSadaf Ebrahimi #define SLJIT_CMP_F64 (SLJIT_FOP1_BASE + 8)
1432*22dc650dSSadaf Ebrahimi #define SLJIT_CMP_F32 (SLJIT_CMP_F64 | SLJIT_32)
1433*22dc650dSSadaf Ebrahimi /* Flags: - (may destroy flags) */
1434*22dc650dSSadaf Ebrahimi #define SLJIT_NEG_F64 (SLJIT_FOP1_BASE + 9)
1435*22dc650dSSadaf Ebrahimi #define SLJIT_NEG_F32 (SLJIT_NEG_F64 | SLJIT_32)
1436*22dc650dSSadaf Ebrahimi /* Flags: - (may destroy flags) */
1437*22dc650dSSadaf Ebrahimi #define SLJIT_ABS_F64 (SLJIT_FOP1_BASE + 10)
1438*22dc650dSSadaf Ebrahimi #define SLJIT_ABS_F32 (SLJIT_ABS_F64 | SLJIT_32)
1439*22dc650dSSadaf Ebrahimi
1440*22dc650dSSadaf Ebrahimi SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fop1(struct sljit_compiler *compiler, sljit_s32 op,
1441*22dc650dSSadaf Ebrahimi sljit_s32 dst, sljit_sw dstw,
1442*22dc650dSSadaf Ebrahimi sljit_s32 src, sljit_sw srcw);
1443*22dc650dSSadaf Ebrahimi
1444*22dc650dSSadaf Ebrahimi /* Starting index of opcodes for sljit_emit_fop2. */
1445*22dc650dSSadaf Ebrahimi #define SLJIT_FOP2_BASE 176
1446*22dc650dSSadaf Ebrahimi
1447*22dc650dSSadaf Ebrahimi /* Flags: - (may destroy flags) */
1448*22dc650dSSadaf Ebrahimi #define SLJIT_ADD_F64 (SLJIT_FOP2_BASE + 0)
1449*22dc650dSSadaf Ebrahimi #define SLJIT_ADD_F32 (SLJIT_ADD_F64 | SLJIT_32)
1450*22dc650dSSadaf Ebrahimi /* Flags: - (may destroy flags) */
1451*22dc650dSSadaf Ebrahimi #define SLJIT_SUB_F64 (SLJIT_FOP2_BASE + 1)
1452*22dc650dSSadaf Ebrahimi #define SLJIT_SUB_F32 (SLJIT_SUB_F64 | SLJIT_32)
1453*22dc650dSSadaf Ebrahimi /* Flags: - (may destroy flags) */
1454*22dc650dSSadaf Ebrahimi #define SLJIT_MUL_F64 (SLJIT_FOP2_BASE + 2)
1455*22dc650dSSadaf Ebrahimi #define SLJIT_MUL_F32 (SLJIT_MUL_F64 | SLJIT_32)
1456*22dc650dSSadaf Ebrahimi /* Flags: - (may destroy flags) */
1457*22dc650dSSadaf Ebrahimi #define SLJIT_DIV_F64 (SLJIT_FOP2_BASE + 3)
1458*22dc650dSSadaf Ebrahimi #define SLJIT_DIV_F32 (SLJIT_DIV_F64 | SLJIT_32)
1459*22dc650dSSadaf Ebrahimi
1460*22dc650dSSadaf Ebrahimi SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fop2(struct sljit_compiler *compiler, sljit_s32 op,
1461*22dc650dSSadaf Ebrahimi sljit_s32 dst, sljit_sw dstw,
1462*22dc650dSSadaf Ebrahimi sljit_s32 src1, sljit_sw src1w,
1463*22dc650dSSadaf Ebrahimi sljit_s32 src2, sljit_sw src2w);
1464*22dc650dSSadaf Ebrahimi
1465*22dc650dSSadaf Ebrahimi /* Starting index of opcodes for sljit_emit_fop2r. */
1466*22dc650dSSadaf Ebrahimi #define SLJIT_FOP2R_BASE 192
1467*22dc650dSSadaf Ebrahimi
1468*22dc650dSSadaf Ebrahimi /* Flags: - (may destroy flags) */
1469*22dc650dSSadaf Ebrahimi #define SLJIT_COPYSIGN_F64 (SLJIT_FOP2R_BASE + 0)
1470*22dc650dSSadaf Ebrahimi #define SLJIT_COPYSIGN_F32 (SLJIT_COPYSIGN_F64 | SLJIT_32)
1471*22dc650dSSadaf Ebrahimi
1472*22dc650dSSadaf Ebrahimi /* Similar to sljit_emit_fop2, except the destination is always a register. */
1473*22dc650dSSadaf Ebrahimi SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fop2r(struct sljit_compiler *compiler, sljit_s32 op,
1474*22dc650dSSadaf Ebrahimi sljit_s32 dst_freg,
1475*22dc650dSSadaf Ebrahimi sljit_s32 src1, sljit_sw src1w,
1476*22dc650dSSadaf Ebrahimi sljit_s32 src2, sljit_sw src2w);
1477*22dc650dSSadaf Ebrahimi
1478*22dc650dSSadaf Ebrahimi /* Sets a floating point register to an immediate value. */
1479*22dc650dSSadaf Ebrahimi
1480*22dc650dSSadaf Ebrahimi SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fset32(struct sljit_compiler *compiler,
1481*22dc650dSSadaf Ebrahimi sljit_s32 freg, sljit_f32 value);
1482*22dc650dSSadaf Ebrahimi SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fset64(struct sljit_compiler *compiler,
1483*22dc650dSSadaf Ebrahimi sljit_s32 freg, sljit_f64 value);
1484*22dc650dSSadaf Ebrahimi
1485*22dc650dSSadaf Ebrahimi /* The following opcodes are used by sljit_emit_fcopy(). */
1486*22dc650dSSadaf Ebrahimi
1487*22dc650dSSadaf Ebrahimi /* 64 bit: copy a 64 bit value from an integer register into a
1488*22dc650dSSadaf Ebrahimi 64 bit floating point register without any modifications.
1489*22dc650dSSadaf Ebrahimi 32 bit: copy a 32 bit register or register pair into a 64 bit
1490*22dc650dSSadaf Ebrahimi floating point register without any modifications. The
1491*22dc650dSSadaf Ebrahimi register, or the first register of the register pair
1492*22dc650dSSadaf Ebrahimi replaces the high order 32 bit of the floating point
1493*22dc650dSSadaf Ebrahimi register. If a register pair is passed, the low
1494*22dc650dSSadaf Ebrahimi order 32 bit is replaced by the second register.
1495*22dc650dSSadaf Ebrahimi Otherwise, the low order 32 bit is unchanged. */
1496*22dc650dSSadaf Ebrahimi #define SLJIT_COPY_TO_F64 1
1497*22dc650dSSadaf Ebrahimi /* Copy a 32 bit value from an integer register into a 32 bit
1498*22dc650dSSadaf Ebrahimi floating point register without any modifications. */
1499*22dc650dSSadaf Ebrahimi #define SLJIT_COPY32_TO_F32 (SLJIT_COPY_TO_F64 | SLJIT_32)
1500*22dc650dSSadaf Ebrahimi /* 64 bit: copy the value of a 64 bit floating point register into
1501*22dc650dSSadaf Ebrahimi an integer register without any modifications.
1502*22dc650dSSadaf Ebrahimi 32 bit: copy a 64 bit floating point register into a 32 bit register
1503*22dc650dSSadaf Ebrahimi or a 32 bit register pair without any modifications. The
1504*22dc650dSSadaf Ebrahimi high order 32 bit of the floating point register is copied
1505*22dc650dSSadaf Ebrahimi into the register, or the first register of the register
1506*22dc650dSSadaf Ebrahimi pair. If a register pair is passed, the low order 32 bit
1507*22dc650dSSadaf Ebrahimi is copied into the second register. */
1508*22dc650dSSadaf Ebrahimi #define SLJIT_COPY_FROM_F64 2
1509*22dc650dSSadaf Ebrahimi /* Copy the value of a 32 bit floating point register into an integer
1510*22dc650dSSadaf Ebrahimi register without any modifications. The register should be processed
1511*22dc650dSSadaf Ebrahimi with 32 bit operations later. */
1512*22dc650dSSadaf Ebrahimi #define SLJIT_COPY32_FROM_F32 (SLJIT_COPY_FROM_F64 | SLJIT_32)
1513*22dc650dSSadaf Ebrahimi
1514*22dc650dSSadaf Ebrahimi /* Special data copy which involves floating point registers.
1515*22dc650dSSadaf Ebrahimi
1516*22dc650dSSadaf Ebrahimi op must be between SLJIT_COPY_TO_F64 and SLJIT_COPY32_FROM_F32
1517*22dc650dSSadaf Ebrahimi freg must be a floating point register
1518*22dc650dSSadaf Ebrahimi reg must be a register or register pair */
1519*22dc650dSSadaf Ebrahimi
1520*22dc650dSSadaf Ebrahimi SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fcopy(struct sljit_compiler *compiler, sljit_s32 op,
1521*22dc650dSSadaf Ebrahimi sljit_s32 freg, sljit_s32 reg);
1522*22dc650dSSadaf Ebrahimi
1523*22dc650dSSadaf Ebrahimi /* Label and jump instructions. */
1524*22dc650dSSadaf Ebrahimi
1525*22dc650dSSadaf Ebrahimi SLJIT_API_FUNC_ATTRIBUTE struct sljit_label* sljit_emit_label(struct sljit_compiler *compiler);
1526*22dc650dSSadaf Ebrahimi
1527*22dc650dSSadaf Ebrahimi /* The SLJIT_FAST_CALL is a calling method for creating lightweight function
1528*22dc650dSSadaf Ebrahimi calls. This type of calls preserve the values of all registers and stack
1529*22dc650dSSadaf Ebrahimi frame. Unlike normal function calls, the enter and return operations must
1530*22dc650dSSadaf Ebrahimi be performed by the SLJIT_FAST_ENTER and SLJIT_FAST_RETURN operations
1531*22dc650dSSadaf Ebrahimi respectively. The return address is stored in the dst argument of the
1532*22dc650dSSadaf Ebrahimi SLJIT_FAST_ENTER operation, and this return address should be passed as
1533*22dc650dSSadaf Ebrahimi the src argument for the SLJIT_FAST_RETURN operation to return from the
1534*22dc650dSSadaf Ebrahimi called function.
1535*22dc650dSSadaf Ebrahimi
1536*22dc650dSSadaf Ebrahimi Fast calls are cheap operations (usually only a single call instruction is
1537*22dc650dSSadaf Ebrahimi emitted) but they do not preserve any registers. However the callee function
1538*22dc650dSSadaf Ebrahimi can freely use / update any registers and the locals area which can be
1539*22dc650dSSadaf Ebrahimi efficiently exploited by various optimizations. Registers can be saved
1540*22dc650dSSadaf Ebrahimi and restored manually if needed.
1541*22dc650dSSadaf Ebrahimi
1542*22dc650dSSadaf Ebrahimi Although returning to different address by SLJIT_FAST_RETURN is possible,
1543*22dc650dSSadaf Ebrahimi this address usually cannot be predicted by the return address predictor of
1544*22dc650dSSadaf Ebrahimi modern CPUs which may reduce performance. Furthermore certain security
1545*22dc650dSSadaf Ebrahimi enhancement technologies such as Intel Control-flow Enforcement Technology
1546*22dc650dSSadaf Ebrahimi (CET) may disallow returning to a different address (indirect jumps
1547*22dc650dSSadaf Ebrahimi can be used instead, see SLJIT_SKIP_FRAMES_BEFORE_FAST_RETURN). */
1548*22dc650dSSadaf Ebrahimi
1549*22dc650dSSadaf Ebrahimi /* Invert (negate) conditional type: xor (^) with 0x1 */
1550*22dc650dSSadaf Ebrahimi
1551*22dc650dSSadaf Ebrahimi /* Integer comparison types. */
1552*22dc650dSSadaf Ebrahimi #define SLJIT_EQUAL 0
1553*22dc650dSSadaf Ebrahimi #define SLJIT_ZERO SLJIT_EQUAL
1554*22dc650dSSadaf Ebrahimi #define SLJIT_NOT_EQUAL 1
1555*22dc650dSSadaf Ebrahimi #define SLJIT_NOT_ZERO SLJIT_NOT_EQUAL
1556*22dc650dSSadaf Ebrahimi
1557*22dc650dSSadaf Ebrahimi #define SLJIT_LESS 2
1558*22dc650dSSadaf Ebrahimi #define SLJIT_SET_LESS SLJIT_SET(SLJIT_LESS)
1559*22dc650dSSadaf Ebrahimi #define SLJIT_GREATER_EQUAL 3
1560*22dc650dSSadaf Ebrahimi #define SLJIT_SET_GREATER_EQUAL SLJIT_SET(SLJIT_LESS)
1561*22dc650dSSadaf Ebrahimi #define SLJIT_GREATER 4
1562*22dc650dSSadaf Ebrahimi #define SLJIT_SET_GREATER SLJIT_SET(SLJIT_GREATER)
1563*22dc650dSSadaf Ebrahimi #define SLJIT_LESS_EQUAL 5
1564*22dc650dSSadaf Ebrahimi #define SLJIT_SET_LESS_EQUAL SLJIT_SET(SLJIT_GREATER)
1565*22dc650dSSadaf Ebrahimi #define SLJIT_SIG_LESS 6
1566*22dc650dSSadaf Ebrahimi #define SLJIT_SET_SIG_LESS SLJIT_SET(SLJIT_SIG_LESS)
1567*22dc650dSSadaf Ebrahimi #define SLJIT_SIG_GREATER_EQUAL 7
1568*22dc650dSSadaf Ebrahimi #define SLJIT_SET_SIG_GREATER_EQUAL SLJIT_SET(SLJIT_SIG_LESS)
1569*22dc650dSSadaf Ebrahimi #define SLJIT_SIG_GREATER 8
1570*22dc650dSSadaf Ebrahimi #define SLJIT_SET_SIG_GREATER SLJIT_SET(SLJIT_SIG_GREATER)
1571*22dc650dSSadaf Ebrahimi #define SLJIT_SIG_LESS_EQUAL 9
1572*22dc650dSSadaf Ebrahimi #define SLJIT_SET_SIG_LESS_EQUAL SLJIT_SET(SLJIT_SIG_GREATER)
1573*22dc650dSSadaf Ebrahimi
1574*22dc650dSSadaf Ebrahimi #define SLJIT_OVERFLOW 10
1575*22dc650dSSadaf Ebrahimi #define SLJIT_SET_OVERFLOW SLJIT_SET(SLJIT_OVERFLOW)
1576*22dc650dSSadaf Ebrahimi #define SLJIT_NOT_OVERFLOW 11
1577*22dc650dSSadaf Ebrahimi
1578*22dc650dSSadaf Ebrahimi /* Unlike other flags, sljit_emit_jump may destroy the carry flag. */
1579*22dc650dSSadaf Ebrahimi #define SLJIT_CARRY 12
1580*22dc650dSSadaf Ebrahimi #define SLJIT_SET_CARRY SLJIT_SET(SLJIT_CARRY)
1581*22dc650dSSadaf Ebrahimi #define SLJIT_NOT_CARRY 13
1582*22dc650dSSadaf Ebrahimi
1583*22dc650dSSadaf Ebrahimi #define SLJIT_ATOMIC_STORED 14
1584*22dc650dSSadaf Ebrahimi #define SLJIT_SET_ATOMIC_STORED SLJIT_SET(SLJIT_ATOMIC_STORED)
1585*22dc650dSSadaf Ebrahimi #define SLJIT_ATOMIC_NOT_STORED 15
1586*22dc650dSSadaf Ebrahimi
1587*22dc650dSSadaf Ebrahimi /* Basic floating point comparison types.
1588*22dc650dSSadaf Ebrahimi
1589*22dc650dSSadaf Ebrahimi Note: when the comparison result is unordered, their behaviour is unspecified. */
1590*22dc650dSSadaf Ebrahimi
1591*22dc650dSSadaf Ebrahimi #define SLJIT_F_EQUAL 16
1592*22dc650dSSadaf Ebrahimi #define SLJIT_SET_F_EQUAL SLJIT_SET(SLJIT_F_EQUAL)
1593*22dc650dSSadaf Ebrahimi #define SLJIT_F_NOT_EQUAL 17
1594*22dc650dSSadaf Ebrahimi #define SLJIT_SET_F_NOT_EQUAL SLJIT_SET(SLJIT_F_EQUAL)
1595*22dc650dSSadaf Ebrahimi #define SLJIT_F_LESS 18
1596*22dc650dSSadaf Ebrahimi #define SLJIT_SET_F_LESS SLJIT_SET(SLJIT_F_LESS)
1597*22dc650dSSadaf Ebrahimi #define SLJIT_F_GREATER_EQUAL 19
1598*22dc650dSSadaf Ebrahimi #define SLJIT_SET_F_GREATER_EQUAL SLJIT_SET(SLJIT_F_LESS)
1599*22dc650dSSadaf Ebrahimi #define SLJIT_F_GREATER 20
1600*22dc650dSSadaf Ebrahimi #define SLJIT_SET_F_GREATER SLJIT_SET(SLJIT_F_GREATER)
1601*22dc650dSSadaf Ebrahimi #define SLJIT_F_LESS_EQUAL 21
1602*22dc650dSSadaf Ebrahimi #define SLJIT_SET_F_LESS_EQUAL SLJIT_SET(SLJIT_F_GREATER)
1603*22dc650dSSadaf Ebrahimi
1604*22dc650dSSadaf Ebrahimi /* Jumps when either argument contains a NaN value. */
1605*22dc650dSSadaf Ebrahimi #define SLJIT_UNORDERED 22
1606*22dc650dSSadaf Ebrahimi #define SLJIT_SET_UNORDERED SLJIT_SET(SLJIT_UNORDERED)
1607*22dc650dSSadaf Ebrahimi /* Jumps when neither argument contains a NaN value. */
1608*22dc650dSSadaf Ebrahimi #define SLJIT_ORDERED 23
1609*22dc650dSSadaf Ebrahimi #define SLJIT_SET_ORDERED SLJIT_SET(SLJIT_UNORDERED)
1610*22dc650dSSadaf Ebrahimi
1611*22dc650dSSadaf Ebrahimi /* Ordered / unordered floating point comparison types.
1612*22dc650dSSadaf Ebrahimi
1613*22dc650dSSadaf Ebrahimi Note: each comparison type has an ordered and unordered form. Some
1614*22dc650dSSadaf Ebrahimi architectures supports only either of them (see: sljit_cmp_info). */
1615*22dc650dSSadaf Ebrahimi
1616*22dc650dSSadaf Ebrahimi #define SLJIT_ORDERED_EQUAL 24
1617*22dc650dSSadaf Ebrahimi #define SLJIT_SET_ORDERED_EQUAL SLJIT_SET(SLJIT_ORDERED_EQUAL)
1618*22dc650dSSadaf Ebrahimi #define SLJIT_UNORDERED_OR_NOT_EQUAL 25
1619*22dc650dSSadaf Ebrahimi #define SLJIT_SET_UNORDERED_OR_NOT_EQUAL SLJIT_SET(SLJIT_ORDERED_EQUAL)
1620*22dc650dSSadaf Ebrahimi #define SLJIT_ORDERED_LESS 26
1621*22dc650dSSadaf Ebrahimi #define SLJIT_SET_ORDERED_LESS SLJIT_SET(SLJIT_ORDERED_LESS)
1622*22dc650dSSadaf Ebrahimi #define SLJIT_UNORDERED_OR_GREATER_EQUAL 27
1623*22dc650dSSadaf Ebrahimi #define SLJIT_SET_UNORDERED_OR_GREATER_EQUAL SLJIT_SET(SLJIT_ORDERED_LESS)
1624*22dc650dSSadaf Ebrahimi #define SLJIT_ORDERED_GREATER 28
1625*22dc650dSSadaf Ebrahimi #define SLJIT_SET_ORDERED_GREATER SLJIT_SET(SLJIT_ORDERED_GREATER)
1626*22dc650dSSadaf Ebrahimi #define SLJIT_UNORDERED_OR_LESS_EQUAL 29
1627*22dc650dSSadaf Ebrahimi #define SLJIT_SET_UNORDERED_OR_LESS_EQUAL SLJIT_SET(SLJIT_ORDERED_GREATER)
1628*22dc650dSSadaf Ebrahimi
1629*22dc650dSSadaf Ebrahimi #define SLJIT_UNORDERED_OR_EQUAL 30
1630*22dc650dSSadaf Ebrahimi #define SLJIT_SET_UNORDERED_OR_EQUAL SLJIT_SET(SLJIT_UNORDERED_OR_EQUAL)
1631*22dc650dSSadaf Ebrahimi #define SLJIT_ORDERED_NOT_EQUAL 31
1632*22dc650dSSadaf Ebrahimi #define SLJIT_SET_ORDERED_NOT_EQUAL SLJIT_SET(SLJIT_UNORDERED_OR_EQUAL)
1633*22dc650dSSadaf Ebrahimi #define SLJIT_UNORDERED_OR_LESS 32
1634*22dc650dSSadaf Ebrahimi #define SLJIT_SET_UNORDERED_OR_LESS SLJIT_SET(SLJIT_UNORDERED_OR_LESS)
1635*22dc650dSSadaf Ebrahimi #define SLJIT_ORDERED_GREATER_EQUAL 33
1636*22dc650dSSadaf Ebrahimi #define SLJIT_SET_ORDERED_GREATER_EQUAL SLJIT_SET(SLJIT_UNORDERED_OR_LESS)
1637*22dc650dSSadaf Ebrahimi #define SLJIT_UNORDERED_OR_GREATER 34
1638*22dc650dSSadaf Ebrahimi #define SLJIT_SET_UNORDERED_OR_GREATER SLJIT_SET(SLJIT_UNORDERED_OR_GREATER)
1639*22dc650dSSadaf Ebrahimi #define SLJIT_ORDERED_LESS_EQUAL 35
1640*22dc650dSSadaf Ebrahimi #define SLJIT_SET_ORDERED_LESS_EQUAL SLJIT_SET(SLJIT_UNORDERED_OR_GREATER)
1641*22dc650dSSadaf Ebrahimi
1642*22dc650dSSadaf Ebrahimi /* Unconditional jump types. */
1643*22dc650dSSadaf Ebrahimi #define SLJIT_JUMP 36
1644*22dc650dSSadaf Ebrahimi /* Fast calling method. See the description above. */
1645*22dc650dSSadaf Ebrahimi #define SLJIT_FAST_CALL 37
1646*22dc650dSSadaf Ebrahimi /* Default C calling convention. */
1647*22dc650dSSadaf Ebrahimi #define SLJIT_CALL 38
1648*22dc650dSSadaf Ebrahimi /* Called function must be compiled by SLJIT.
1649*22dc650dSSadaf Ebrahimi See SLJIT_ENTER_REG_ARG option. */
1650*22dc650dSSadaf Ebrahimi #define SLJIT_CALL_REG_ARG 39
1651*22dc650dSSadaf Ebrahimi
1652*22dc650dSSadaf Ebrahimi /* The target can be changed during runtime (see: sljit_set_jump_addr). */
1653*22dc650dSSadaf Ebrahimi #define SLJIT_REWRITABLE_JUMP 0x1000
1654*22dc650dSSadaf Ebrahimi /* When this flag is passed, the execution of the current function ends and
1655*22dc650dSSadaf Ebrahimi the called function returns to the caller of the current function. The
1656*22dc650dSSadaf Ebrahimi stack usage is reduced before the call, but it is not necessarily reduced
1657*22dc650dSSadaf Ebrahimi to zero. In the latter case the compiler needs to allocate space for some
1658*22dc650dSSadaf Ebrahimi arguments and the return address must be stored on the stack as well. */
1659*22dc650dSSadaf Ebrahimi #define SLJIT_CALL_RETURN 0x2000
1660*22dc650dSSadaf Ebrahimi
1661*22dc650dSSadaf Ebrahimi /* Emit a jump instruction. The destination is not set, only the type of the jump.
1662*22dc650dSSadaf Ebrahimi type must be between SLJIT_EQUAL and SLJIT_FAST_CALL
1663*22dc650dSSadaf Ebrahimi type can be combined (or'ed) with SLJIT_REWRITABLE_JUMP
1664*22dc650dSSadaf Ebrahimi
1665*22dc650dSSadaf Ebrahimi Flags: does not modify flags. */
1666*22dc650dSSadaf Ebrahimi SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_jump(struct sljit_compiler *compiler, sljit_s32 type);
1667*22dc650dSSadaf Ebrahimi
1668*22dc650dSSadaf Ebrahimi /* Emit a C compiler (ABI) compatible function call.
1669*22dc650dSSadaf Ebrahimi type must be SLJIT_CALL or SLJIT_CALL_REG_ARG
1670*22dc650dSSadaf Ebrahimi type can be combined (or'ed) with SLJIT_REWRITABLE_JUMP and/or SLJIT_CALL_RETURN
1671*22dc650dSSadaf Ebrahimi arg_types can be specified by SLJIT_ARGSx (SLJIT_ARG_RETURN / SLJIT_ARG_VALUE) macros
1672*22dc650dSSadaf Ebrahimi
1673*22dc650dSSadaf Ebrahimi Flags: destroy all flags. */
1674*22dc650dSSadaf Ebrahimi SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_call(struct sljit_compiler *compiler, sljit_s32 type, sljit_s32 arg_types);
1675*22dc650dSSadaf Ebrahimi
1676*22dc650dSSadaf Ebrahimi /* Basic arithmetic comparison. In most architectures it is implemented as
1677*22dc650dSSadaf Ebrahimi a compare operation followed by a sljit_emit_jump. However some
1678*22dc650dSSadaf Ebrahimi architectures (i.e: ARM64 or MIPS) may employ special optimizations
1679*22dc650dSSadaf Ebrahimi here. It is suggested to use this comparison form when appropriate.
1680*22dc650dSSadaf Ebrahimi type must be between SLJIT_EQUAL and SLJIT_SIG_LESS_EQUAL
1681*22dc650dSSadaf Ebrahimi type can be combined (or'ed) with SLJIT_REWRITABLE_JUMP
1682*22dc650dSSadaf Ebrahimi
1683*22dc650dSSadaf Ebrahimi Flags: may destroy flags. */
1684*22dc650dSSadaf Ebrahimi SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_cmp(struct sljit_compiler *compiler, sljit_s32 type,
1685*22dc650dSSadaf Ebrahimi sljit_s32 src1, sljit_sw src1w,
1686*22dc650dSSadaf Ebrahimi sljit_s32 src2, sljit_sw src2w);
1687*22dc650dSSadaf Ebrahimi
1688*22dc650dSSadaf Ebrahimi /* Basic floating point comparison. In most architectures it is implemented as
1689*22dc650dSSadaf Ebrahimi a SLJIT_CMP_F32/64 operation (setting appropriate flags) followed by a
1690*22dc650dSSadaf Ebrahimi sljit_emit_jump. However some architectures (i.e: MIPS) may employ
1691*22dc650dSSadaf Ebrahimi special optimizations here. It is suggested to use this comparison form
1692*22dc650dSSadaf Ebrahimi when appropriate.
1693*22dc650dSSadaf Ebrahimi type must be between SLJIT_F_EQUAL and SLJIT_ORDERED_LESS_EQUAL
1694*22dc650dSSadaf Ebrahimi type can be combined (or'ed) with SLJIT_REWRITABLE_JUMP
1695*22dc650dSSadaf Ebrahimi Flags: destroy flags.
1696*22dc650dSSadaf Ebrahimi Note: when an operand is NaN the behaviour depends on the comparison type. */
1697*22dc650dSSadaf Ebrahimi SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_fcmp(struct sljit_compiler *compiler, sljit_s32 type,
1698*22dc650dSSadaf Ebrahimi sljit_s32 src1, sljit_sw src1w,
1699*22dc650dSSadaf Ebrahimi sljit_s32 src2, sljit_sw src2w);
1700*22dc650dSSadaf Ebrahimi
1701*22dc650dSSadaf Ebrahimi /* Set the destination of the jump to this label. */
1702*22dc650dSSadaf Ebrahimi SLJIT_API_FUNC_ATTRIBUTE void sljit_set_label(struct sljit_jump *jump, struct sljit_label* label);
1703*22dc650dSSadaf Ebrahimi /* Set the destination address of the jump to this label. */
1704*22dc650dSSadaf Ebrahimi SLJIT_API_FUNC_ATTRIBUTE void sljit_set_target(struct sljit_jump *jump, sljit_uw target);
1705*22dc650dSSadaf Ebrahimi
1706*22dc650dSSadaf Ebrahimi /* Emit an indirect jump or fast call.
1707*22dc650dSSadaf Ebrahimi Direct form: set src to SLJIT_IMM() and srcw to the address
1708*22dc650dSSadaf Ebrahimi Indirect form: any other valid addressing mode
1709*22dc650dSSadaf Ebrahimi type must be between SLJIT_JUMP and SLJIT_FAST_CALL
1710*22dc650dSSadaf Ebrahimi
1711*22dc650dSSadaf Ebrahimi Flags: does not modify flags. */
1712*22dc650dSSadaf Ebrahimi SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_ijump(struct sljit_compiler *compiler, sljit_s32 type, sljit_s32 src, sljit_sw srcw);
1713*22dc650dSSadaf Ebrahimi
1714*22dc650dSSadaf Ebrahimi /* Emit a C compiler (ABI) compatible function call.
1715*22dc650dSSadaf Ebrahimi Direct form: set src to SLJIT_IMM() and srcw to the address
1716*22dc650dSSadaf Ebrahimi Indirect form: any other valid addressing mode
1717*22dc650dSSadaf Ebrahimi type must be SLJIT_CALL or SLJIT_CALL_REG_ARG
1718*22dc650dSSadaf Ebrahimi type can be combined (or'ed) with SLJIT_CALL_RETURN
1719*22dc650dSSadaf Ebrahimi arg_types can be specified by SLJIT_ARGSx (SLJIT_ARG_RETURN / SLJIT_ARG_VALUE) macros
1720*22dc650dSSadaf Ebrahimi
1721*22dc650dSSadaf Ebrahimi Flags: destroy all flags. */
1722*22dc650dSSadaf Ebrahimi SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_icall(struct sljit_compiler *compiler, sljit_s32 type, sljit_s32 arg_types, sljit_s32 src, sljit_sw srcw);
1723*22dc650dSSadaf Ebrahimi
1724*22dc650dSSadaf Ebrahimi /* Perform an operation using the conditional flags as the second argument.
1725*22dc650dSSadaf Ebrahimi Type must always be between SLJIT_EQUAL and SLJIT_ORDERED_LESS_EQUAL.
1726*22dc650dSSadaf Ebrahimi The value represented by the type is 1, if the condition represented
1727*22dc650dSSadaf Ebrahimi by the type is fulfilled, and 0 otherwise.
1728*22dc650dSSadaf Ebrahimi
1729*22dc650dSSadaf Ebrahimi When op is SLJIT_MOV or SLJIT_MOV32:
1730*22dc650dSSadaf Ebrahimi Set dst to the value represented by the type (0 or 1).
1731*22dc650dSSadaf Ebrahimi Flags: - (does not modify flags)
1732*22dc650dSSadaf Ebrahimi When op is SLJIT_AND, SLJIT_AND32, SLJIT_OR, SLJIT_OR32, SLJIT_XOR, or SLJIT_XOR32
1733*22dc650dSSadaf Ebrahimi Performs the binary operation using dst as the first, and the value
1734*22dc650dSSadaf Ebrahimi represented by type as the second argument. Result is written into dst.
1735*22dc650dSSadaf Ebrahimi Flags: Z (may destroy flags) */
1736*22dc650dSSadaf Ebrahimi SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_flags(struct sljit_compiler *compiler, sljit_s32 op,
1737*22dc650dSSadaf Ebrahimi sljit_s32 dst, sljit_sw dstw,
1738*22dc650dSSadaf Ebrahimi sljit_s32 type);
1739*22dc650dSSadaf Ebrahimi
1740*22dc650dSSadaf Ebrahimi /* Emit a conditional select instruction which moves src1 to dst_reg,
1741*22dc650dSSadaf Ebrahimi if the condition is satisfied, or src2_reg to dst_reg otherwise.
1742*22dc650dSSadaf Ebrahimi
1743*22dc650dSSadaf Ebrahimi type must be between SLJIT_EQUAL and SLJIT_ORDERED_LESS_EQUAL
1744*22dc650dSSadaf Ebrahimi type can be combined (or'ed) with SLJIT_32 to move 32 bit
1745*22dc650dSSadaf Ebrahimi register values instead of word sized ones
1746*22dc650dSSadaf Ebrahimi dst_reg and src2_reg must be valid registers
1747*22dc650dSSadaf Ebrahimi src1 must be valid operand
1748*22dc650dSSadaf Ebrahimi
1749*22dc650dSSadaf Ebrahimi Note: if src1 is a memory operand, its value
1750*22dc650dSSadaf Ebrahimi might be loaded even if the condition is false.
1751*22dc650dSSadaf Ebrahimi
1752*22dc650dSSadaf Ebrahimi Flags: - (does not modify flags) */
1753*22dc650dSSadaf Ebrahimi SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_select(struct sljit_compiler *compiler, sljit_s32 type,
1754*22dc650dSSadaf Ebrahimi sljit_s32 dst_reg,
1755*22dc650dSSadaf Ebrahimi sljit_s32 src1, sljit_sw src1w,
1756*22dc650dSSadaf Ebrahimi sljit_s32 src2_reg);
1757*22dc650dSSadaf Ebrahimi
1758*22dc650dSSadaf Ebrahimi /* Emit a conditional floating point select instruction which moves
1759*22dc650dSSadaf Ebrahimi src1 to dst_reg, if the condition is satisfied, or src2_reg to
1760*22dc650dSSadaf Ebrahimi dst_reg otherwise.
1761*22dc650dSSadaf Ebrahimi
1762*22dc650dSSadaf Ebrahimi type must be between SLJIT_EQUAL and SLJIT_ORDERED_LESS_EQUAL
1763*22dc650dSSadaf Ebrahimi type can be combined (or'ed) with SLJIT_32 to move 32 bit
1764*22dc650dSSadaf Ebrahimi floating point values instead of 64 bit ones
1765*22dc650dSSadaf Ebrahimi dst_freg and src2_freg must be valid floating point registers
1766*22dc650dSSadaf Ebrahimi src1 must be valid operand
1767*22dc650dSSadaf Ebrahimi
1768*22dc650dSSadaf Ebrahimi Note: if src1 is a memory operand, its value
1769*22dc650dSSadaf Ebrahimi might be loaded even if the condition is false.
1770*22dc650dSSadaf Ebrahimi
1771*22dc650dSSadaf Ebrahimi Flags: - (does not modify flags) */
1772*22dc650dSSadaf Ebrahimi SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fselect(struct sljit_compiler *compiler, sljit_s32 type,
1773*22dc650dSSadaf Ebrahimi sljit_s32 dst_freg,
1774*22dc650dSSadaf Ebrahimi sljit_s32 src1, sljit_sw src1w,
1775*22dc650dSSadaf Ebrahimi sljit_s32 src2_freg);
1776*22dc650dSSadaf Ebrahimi
1777*22dc650dSSadaf Ebrahimi /* The following flags are used by sljit_emit_mem(), sljit_emit_mem_update(),
1778*22dc650dSSadaf Ebrahimi sljit_emit_fmem(), and sljit_emit_fmem_update(). */
1779*22dc650dSSadaf Ebrahimi
1780*22dc650dSSadaf Ebrahimi /* Memory load operation. This is the default. */
1781*22dc650dSSadaf Ebrahimi #define SLJIT_MEM_LOAD 0x000000
1782*22dc650dSSadaf Ebrahimi /* Memory store operation. */
1783*22dc650dSSadaf Ebrahimi #define SLJIT_MEM_STORE 0x000200
1784*22dc650dSSadaf Ebrahimi
1785*22dc650dSSadaf Ebrahimi /* The following flags are used by sljit_emit_mem() and sljit_emit_fmem(). */
1786*22dc650dSSadaf Ebrahimi
1787*22dc650dSSadaf Ebrahimi /* Load or stora data from an unaligned (byte aligned) address. */
1788*22dc650dSSadaf Ebrahimi #define SLJIT_MEM_UNALIGNED 0x000400
1789*22dc650dSSadaf Ebrahimi /* Load or stora data from a 16 bit aligned address. */
1790*22dc650dSSadaf Ebrahimi #define SLJIT_MEM_ALIGNED_16 0x000800
1791*22dc650dSSadaf Ebrahimi /* Load or stora data from a 32 bit aligned address. */
1792*22dc650dSSadaf Ebrahimi #define SLJIT_MEM_ALIGNED_32 0x001000
1793*22dc650dSSadaf Ebrahimi
1794*22dc650dSSadaf Ebrahimi /* The following flags are used by sljit_emit_mem_update(),
1795*22dc650dSSadaf Ebrahimi and sljit_emit_fmem_update(). */
1796*22dc650dSSadaf Ebrahimi
1797*22dc650dSSadaf Ebrahimi /* Base register is updated before the memory access (default). */
1798*22dc650dSSadaf Ebrahimi #define SLJIT_MEM_PRE 0x000000
1799*22dc650dSSadaf Ebrahimi /* Base register is updated after the memory access. */
1800*22dc650dSSadaf Ebrahimi #define SLJIT_MEM_POST 0x000400
1801*22dc650dSSadaf Ebrahimi
1802*22dc650dSSadaf Ebrahimi /* When SLJIT_MEM_SUPP is passed, no instructions are emitted.
1803*22dc650dSSadaf Ebrahimi Instead the function returns with SLJIT_SUCCESS if the instruction
1804*22dc650dSSadaf Ebrahimi form is supported and SLJIT_ERR_UNSUPPORTED otherwise. This flag
1805*22dc650dSSadaf Ebrahimi allows runtime checking of available instruction forms. */
1806*22dc650dSSadaf Ebrahimi #define SLJIT_MEM_SUPP 0x000800
1807*22dc650dSSadaf Ebrahimi
1808*22dc650dSSadaf Ebrahimi /* The sljit_emit_mem emits instructions for various memory operations:
1809*22dc650dSSadaf Ebrahimi
1810*22dc650dSSadaf Ebrahimi When SLJIT_MEM_UNALIGNED / SLJIT_MEM_ALIGNED_16 /
1811*22dc650dSSadaf Ebrahimi SLJIT_MEM_ALIGNED_32 is set in type argument:
1812*22dc650dSSadaf Ebrahimi Emit instructions for unaligned memory loads or stores. When
1813*22dc650dSSadaf Ebrahimi SLJIT_UNALIGNED is not defined, the only way to access unaligned
1814*22dc650dSSadaf Ebrahimi memory data is using sljit_emit_mem. Otherwise all operations (e.g.
1815*22dc650dSSadaf Ebrahimi sljit_emit_op1/2, or sljit_emit_fop1/2) supports unaligned access.
1816*22dc650dSSadaf Ebrahimi In general, the performance of unaligned memory accesses are often
1817*22dc650dSSadaf Ebrahimi lower than aligned and should be avoided.
1818*22dc650dSSadaf Ebrahimi
1819*22dc650dSSadaf Ebrahimi When a pair of registers is passed in reg argument:
1820*22dc650dSSadaf Ebrahimi Emit instructions for moving data between a register pair and
1821*22dc650dSSadaf Ebrahimi memory. The register pair can be specified by the SLJIT_REG_PAIR
1822*22dc650dSSadaf Ebrahimi macro. The first register is loaded from or stored into the
1823*22dc650dSSadaf Ebrahimi location specified by the mem/memw arguments, and the end address
1824*22dc650dSSadaf Ebrahimi of this operation is the starting address of the data transfer
1825*22dc650dSSadaf Ebrahimi between the second register and memory. The type argument must
1826*22dc650dSSadaf Ebrahimi be SLJIT_MOV. The SLJIT_MEM_UNALIGNED / SLJIT_MEM_ALIGNED_*
1827*22dc650dSSadaf Ebrahimi options are allowed for this operation.
1828*22dc650dSSadaf Ebrahimi
1829*22dc650dSSadaf Ebrahimi type must be between SLJIT_MOV and SLJIT_MOV_P and can be
1830*22dc650dSSadaf Ebrahimi combined (or'ed) with SLJIT_MEM_* flags
1831*22dc650dSSadaf Ebrahimi reg is a register or register pair, which is the source or
1832*22dc650dSSadaf Ebrahimi destination of the operation
1833*22dc650dSSadaf Ebrahimi mem must be a memory operand
1834*22dc650dSSadaf Ebrahimi
1835*22dc650dSSadaf Ebrahimi Flags: - (does not modify flags) */
1836*22dc650dSSadaf Ebrahimi SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_mem(struct sljit_compiler *compiler, sljit_s32 type,
1837*22dc650dSSadaf Ebrahimi sljit_s32 reg,
1838*22dc650dSSadaf Ebrahimi sljit_s32 mem, sljit_sw memw);
1839*22dc650dSSadaf Ebrahimi
1840*22dc650dSSadaf Ebrahimi /* Emit a single memory load or store with update instruction.
1841*22dc650dSSadaf Ebrahimi When the requested instruction form is not supported by the CPU,
1842*22dc650dSSadaf Ebrahimi it returns with SLJIT_ERR_UNSUPPORTED instead of emulating the
1843*22dc650dSSadaf Ebrahimi instruction. This allows specializing tight loops based on
1844*22dc650dSSadaf Ebrahimi the supported instruction forms (see SLJIT_MEM_SUPP flag).
1845*22dc650dSSadaf Ebrahimi Absolute address (SLJIT_MEM0) forms are never supported
1846*22dc650dSSadaf Ebrahimi and the base (first) register specified by the mem argument
1847*22dc650dSSadaf Ebrahimi must not be SLJIT_SP and must also be different from the
1848*22dc650dSSadaf Ebrahimi register specified by the reg argument.
1849*22dc650dSSadaf Ebrahimi
1850*22dc650dSSadaf Ebrahimi type must be between SLJIT_MOV and SLJIT_MOV_P and can be
1851*22dc650dSSadaf Ebrahimi combined (or'ed) with SLJIT_MEM_* flags
1852*22dc650dSSadaf Ebrahimi reg is the source or destination register of the operation
1853*22dc650dSSadaf Ebrahimi mem must be a memory operand
1854*22dc650dSSadaf Ebrahimi
1855*22dc650dSSadaf Ebrahimi Flags: - (does not modify flags) */
1856*22dc650dSSadaf Ebrahimi
1857*22dc650dSSadaf Ebrahimi SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_mem_update(struct sljit_compiler *compiler, sljit_s32 type,
1858*22dc650dSSadaf Ebrahimi sljit_s32 reg,
1859*22dc650dSSadaf Ebrahimi sljit_s32 mem, sljit_sw memw);
1860*22dc650dSSadaf Ebrahimi
1861*22dc650dSSadaf Ebrahimi /* Same as sljit_emit_mem except the followings:
1862*22dc650dSSadaf Ebrahimi
1863*22dc650dSSadaf Ebrahimi Loading or storing a pair of registers is not supported.
1864*22dc650dSSadaf Ebrahimi
1865*22dc650dSSadaf Ebrahimi type must be SLJIT_MOV_F64 or SLJIT_MOV_F32 and can be
1866*22dc650dSSadaf Ebrahimi combined (or'ed) with SLJIT_MEM_* flags.
1867*22dc650dSSadaf Ebrahimi freg is the source or destination floating point register
1868*22dc650dSSadaf Ebrahimi of the operation
1869*22dc650dSSadaf Ebrahimi mem must be a memory operand
1870*22dc650dSSadaf Ebrahimi
1871*22dc650dSSadaf Ebrahimi Flags: - (does not modify flags) */
1872*22dc650dSSadaf Ebrahimi
1873*22dc650dSSadaf Ebrahimi SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fmem(struct sljit_compiler *compiler, sljit_s32 type,
1874*22dc650dSSadaf Ebrahimi sljit_s32 freg,
1875*22dc650dSSadaf Ebrahimi sljit_s32 mem, sljit_sw memw);
1876*22dc650dSSadaf Ebrahimi
1877*22dc650dSSadaf Ebrahimi /* Same as sljit_emit_mem_update except the followings:
1878*22dc650dSSadaf Ebrahimi
1879*22dc650dSSadaf Ebrahimi type must be SLJIT_MOV_F64 or SLJIT_MOV_F32 and can be
1880*22dc650dSSadaf Ebrahimi combined (or'ed) with SLJIT_MEM_* flags
1881*22dc650dSSadaf Ebrahimi freg is the source or destination floating point register
1882*22dc650dSSadaf Ebrahimi of the operation
1883*22dc650dSSadaf Ebrahimi mem must be a memory operand
1884*22dc650dSSadaf Ebrahimi
1885*22dc650dSSadaf Ebrahimi Flags: - (does not modify flags) */
1886*22dc650dSSadaf Ebrahimi
1887*22dc650dSSadaf Ebrahimi SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fmem_update(struct sljit_compiler *compiler, sljit_s32 type,
1888*22dc650dSSadaf Ebrahimi sljit_s32 freg,
1889*22dc650dSSadaf Ebrahimi sljit_s32 mem, sljit_sw memw);
1890*22dc650dSSadaf Ebrahimi
1891*22dc650dSSadaf Ebrahimi /* The following options are used by several simd operations. */
1892*22dc650dSSadaf Ebrahimi
1893*22dc650dSSadaf Ebrahimi /* Load data into a simd register, this is the default */
1894*22dc650dSSadaf Ebrahimi #define SLJIT_SIMD_LOAD 0x000000
1895*22dc650dSSadaf Ebrahimi /* Store data from a simd register */
1896*22dc650dSSadaf Ebrahimi #define SLJIT_SIMD_STORE 0x000001
1897*22dc650dSSadaf Ebrahimi /* The simd register contains floating point values */
1898*22dc650dSSadaf Ebrahimi #define SLJIT_SIMD_FLOAT 0x000400
1899*22dc650dSSadaf Ebrahimi /* Tests whether the operation is available */
1900*22dc650dSSadaf Ebrahimi #define SLJIT_SIMD_TEST 0x000800
1901*22dc650dSSadaf Ebrahimi /* Move data to/from a 64 bit (8 byte) long SIMD register */
1902*22dc650dSSadaf Ebrahimi #define SLJIT_SIMD_REG_64 (3 << 12)
1903*22dc650dSSadaf Ebrahimi /* Move data to/from a 128 bit (16 byte) long SIMD register */
1904*22dc650dSSadaf Ebrahimi #define SLJIT_SIMD_REG_128 (4 << 12)
1905*22dc650dSSadaf Ebrahimi /* Move data to/from a 256 bit (32 byte) long SIMD register */
1906*22dc650dSSadaf Ebrahimi #define SLJIT_SIMD_REG_256 (5 << 12)
1907*22dc650dSSadaf Ebrahimi /* Move data to/from a 512 bit (64 byte) long SIMD register */
1908*22dc650dSSadaf Ebrahimi #define SLJIT_SIMD_REG_512 (6 << 12)
1909*22dc650dSSadaf Ebrahimi /* Element size is 8 bit long (this is the default), usually cannot be combined with SLJIT_SIMD_FLOAT */
1910*22dc650dSSadaf Ebrahimi #define SLJIT_SIMD_ELEM_8 (0 << 18)
1911*22dc650dSSadaf Ebrahimi /* Element size is 16 bit long, usually cannot be combined with SLJIT_SIMD_FLOAT */
1912*22dc650dSSadaf Ebrahimi #define SLJIT_SIMD_ELEM_16 (1 << 18)
1913*22dc650dSSadaf Ebrahimi /* Element size is 32 bit long */
1914*22dc650dSSadaf Ebrahimi #define SLJIT_SIMD_ELEM_32 (2 << 18)
1915*22dc650dSSadaf Ebrahimi /* Element size is 64 bit long */
1916*22dc650dSSadaf Ebrahimi #define SLJIT_SIMD_ELEM_64 (3 << 18)
1917*22dc650dSSadaf Ebrahimi /* Element size is 128 bit long */
1918*22dc650dSSadaf Ebrahimi #define SLJIT_SIMD_ELEM_128 (4 << 18)
1919*22dc650dSSadaf Ebrahimi /* Element size is 256 bit long */
1920*22dc650dSSadaf Ebrahimi #define SLJIT_SIMD_ELEM_256 (5 << 18)
1921*22dc650dSSadaf Ebrahimi
1922*22dc650dSSadaf Ebrahimi /* The following options are used by sljit_emit_simd_mov(). */
1923*22dc650dSSadaf Ebrahimi
1924*22dc650dSSadaf Ebrahimi /* Memory address is unaligned (this is the default) */
1925*22dc650dSSadaf Ebrahimi #define SLJIT_SIMD_MEM_UNALIGNED (0 << 24)
1926*22dc650dSSadaf Ebrahimi /* Memory address is 16 bit aligned */
1927*22dc650dSSadaf Ebrahimi #define SLJIT_SIMD_MEM_ALIGNED_16 (1 << 24)
1928*22dc650dSSadaf Ebrahimi /* Memory address is 32 bit aligned */
1929*22dc650dSSadaf Ebrahimi #define SLJIT_SIMD_MEM_ALIGNED_32 (2 << 24)
1930*22dc650dSSadaf Ebrahimi /* Memory address is 64 bit aligned */
1931*22dc650dSSadaf Ebrahimi #define SLJIT_SIMD_MEM_ALIGNED_64 (3 << 24)
1932*22dc650dSSadaf Ebrahimi /* Memory address is 128 bit aligned */
1933*22dc650dSSadaf Ebrahimi #define SLJIT_SIMD_MEM_ALIGNED_128 (4 << 24)
1934*22dc650dSSadaf Ebrahimi /* Memory address is 256 bit aligned */
1935*22dc650dSSadaf Ebrahimi #define SLJIT_SIMD_MEM_ALIGNED_256 (5 << 24)
1936*22dc650dSSadaf Ebrahimi /* Memory address is 512 bit aligned */
1937*22dc650dSSadaf Ebrahimi #define SLJIT_SIMD_MEM_ALIGNED_512 (6 << 24)
1938*22dc650dSSadaf Ebrahimi
1939*22dc650dSSadaf Ebrahimi /* Moves data between a simd register and memory.
1940*22dc650dSSadaf Ebrahimi
1941*22dc650dSSadaf Ebrahimi If the operation is not supported, it returns with
1942*22dc650dSSadaf Ebrahimi SLJIT_ERR_UNSUPPORTED. If SLJIT_SIMD_TEST is passed,
1943*22dc650dSSadaf Ebrahimi it does not emit any instructions.
1944*22dc650dSSadaf Ebrahimi
1945*22dc650dSSadaf Ebrahimi type must be a combination of SLJIT_SIMD_* and
1946*22dc650dSSadaf Ebrahimi SLJIT_SIMD_MEM_* options
1947*22dc650dSSadaf Ebrahimi freg is the source or destination simd register
1948*22dc650dSSadaf Ebrahimi of the operation
1949*22dc650dSSadaf Ebrahimi srcdst must be a memory operand or a simd register
1950*22dc650dSSadaf Ebrahimi
1951*22dc650dSSadaf Ebrahimi Note:
1952*22dc650dSSadaf Ebrahimi The alignment and element size must be
1953*22dc650dSSadaf Ebrahimi less or equal than simd register size.
1954*22dc650dSSadaf Ebrahimi
1955*22dc650dSSadaf Ebrahimi Flags: - (does not modify flags) */
1956*22dc650dSSadaf Ebrahimi
1957*22dc650dSSadaf Ebrahimi SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_mov(struct sljit_compiler *compiler, sljit_s32 type,
1958*22dc650dSSadaf Ebrahimi sljit_s32 freg,
1959*22dc650dSSadaf Ebrahimi sljit_s32 srcdst, sljit_sw srcdstw);
1960*22dc650dSSadaf Ebrahimi
1961*22dc650dSSadaf Ebrahimi /* Replicates a scalar value to all lanes of a simd
1962*22dc650dSSadaf Ebrahimi register.
1963*22dc650dSSadaf Ebrahimi
1964*22dc650dSSadaf Ebrahimi If the operation is not supported, it returns with
1965*22dc650dSSadaf Ebrahimi SLJIT_ERR_UNSUPPORTED. If SLJIT_SIMD_TEST is passed,
1966*22dc650dSSadaf Ebrahimi it does not emit any instructions.
1967*22dc650dSSadaf Ebrahimi
1968*22dc650dSSadaf Ebrahimi type must be a combination of SLJIT_SIMD_* options
1969*22dc650dSSadaf Ebrahimi except SLJIT_SIMD_STORE.
1970*22dc650dSSadaf Ebrahimi freg is the destination simd register of the operation
1971*22dc650dSSadaf Ebrahimi src is the value which is replicated
1972*22dc650dSSadaf Ebrahimi
1973*22dc650dSSadaf Ebrahimi Note:
1974*22dc650dSSadaf Ebrahimi The src == SLJIT_IMM and srcw == 0 can be used to
1975*22dc650dSSadaf Ebrahimi clear a register even when SLJIT_SIMD_FLOAT is set.
1976*22dc650dSSadaf Ebrahimi
1977*22dc650dSSadaf Ebrahimi Flags: - (does not modify flags) */
1978*22dc650dSSadaf Ebrahimi
1979*22dc650dSSadaf Ebrahimi SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_replicate(struct sljit_compiler *compiler, sljit_s32 type,
1980*22dc650dSSadaf Ebrahimi sljit_s32 freg,
1981*22dc650dSSadaf Ebrahimi sljit_s32 src, sljit_sw srcw);
1982*22dc650dSSadaf Ebrahimi
1983*22dc650dSSadaf Ebrahimi /* The following options are used by sljit_emit_simd_lane_mov(). */
1984*22dc650dSSadaf Ebrahimi
1985*22dc650dSSadaf Ebrahimi /* Clear all bits of the simd register before loading the lane. */
1986*22dc650dSSadaf Ebrahimi #define SLJIT_SIMD_LANE_ZERO 0x000002
1987*22dc650dSSadaf Ebrahimi /* Sign extend the integer value stored from the lane. */
1988*22dc650dSSadaf Ebrahimi #define SLJIT_SIMD_LANE_SIGNED 0x000004
1989*22dc650dSSadaf Ebrahimi
1990*22dc650dSSadaf Ebrahimi /* Moves data between a simd register lane and a register or
1991*22dc650dSSadaf Ebrahimi memory. If the srcdst argument is a register, it must be
1992*22dc650dSSadaf Ebrahimi a floating point register when SLJIT_SIMD_FLOAT is specified,
1993*22dc650dSSadaf Ebrahimi or a general purpose register otherwise.
1994*22dc650dSSadaf Ebrahimi
1995*22dc650dSSadaf Ebrahimi If the operation is not supported, it returns with
1996*22dc650dSSadaf Ebrahimi SLJIT_ERR_UNSUPPORTED. If SLJIT_SIMD_TEST is passed,
1997*22dc650dSSadaf Ebrahimi it does not emit any instructions.
1998*22dc650dSSadaf Ebrahimi
1999*22dc650dSSadaf Ebrahimi type must be a combination of SLJIT_SIMD_* options
2000*22dc650dSSadaf Ebrahimi Further options:
2001*22dc650dSSadaf Ebrahimi SLJIT_32 - when SLJIT_SIMD_FLOAT is not set
2002*22dc650dSSadaf Ebrahimi SLJIT_SIMD_LANE_SIGNED - when SLJIT_SIMD_STORE
2003*22dc650dSSadaf Ebrahimi is set and SLJIT_SIMD_FLOAT is not set
2004*22dc650dSSadaf Ebrahimi SLJIT_SIMD_LANE_ZERO - when SLJIT_SIMD_LOAD
2005*22dc650dSSadaf Ebrahimi is specified
2006*22dc650dSSadaf Ebrahimi freg is the source or destination simd register
2007*22dc650dSSadaf Ebrahimi of the operation
2008*22dc650dSSadaf Ebrahimi lane_index is the index of the lane
2009*22dc650dSSadaf Ebrahimi srcdst is the destination operand for loads, and
2010*22dc650dSSadaf Ebrahimi source operand for stores
2011*22dc650dSSadaf Ebrahimi
2012*22dc650dSSadaf Ebrahimi Note:
2013*22dc650dSSadaf Ebrahimi The elem size must be lower than register size.
2014*22dc650dSSadaf Ebrahimi
2015*22dc650dSSadaf Ebrahimi Flags: - (does not modify flags) */
2016*22dc650dSSadaf Ebrahimi
2017*22dc650dSSadaf Ebrahimi SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_lane_mov(struct sljit_compiler *compiler, sljit_s32 type,
2018*22dc650dSSadaf Ebrahimi sljit_s32 freg, sljit_s32 lane_index,
2019*22dc650dSSadaf Ebrahimi sljit_s32 srcdst, sljit_sw srcdstw);
2020*22dc650dSSadaf Ebrahimi
2021*22dc650dSSadaf Ebrahimi /* Replicates a scalar value from a lane to all lanes
2022*22dc650dSSadaf Ebrahimi of a simd register.
2023*22dc650dSSadaf Ebrahimi
2024*22dc650dSSadaf Ebrahimi If the operation is not supported, it returns with
2025*22dc650dSSadaf Ebrahimi SLJIT_ERR_UNSUPPORTED. If SLJIT_SIMD_TEST is passed,
2026*22dc650dSSadaf Ebrahimi it does not emit any instructions.
2027*22dc650dSSadaf Ebrahimi
2028*22dc650dSSadaf Ebrahimi type must be a combination of SLJIT_SIMD_* options
2029*22dc650dSSadaf Ebrahimi except SLJIT_SIMD_STORE.
2030*22dc650dSSadaf Ebrahimi freg is the destination simd register of the operation
2031*22dc650dSSadaf Ebrahimi src is the simd register which lane is replicated
2032*22dc650dSSadaf Ebrahimi src_lane_index is the lane index of the src register
2033*22dc650dSSadaf Ebrahimi
2034*22dc650dSSadaf Ebrahimi Flags: - (does not modify flags) */
2035*22dc650dSSadaf Ebrahimi
2036*22dc650dSSadaf Ebrahimi SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_lane_replicate(struct sljit_compiler *compiler, sljit_s32 type,
2037*22dc650dSSadaf Ebrahimi sljit_s32 freg,
2038*22dc650dSSadaf Ebrahimi sljit_s32 src, sljit_s32 src_lane_index);
2039*22dc650dSSadaf Ebrahimi
2040*22dc650dSSadaf Ebrahimi /* The following options are used by sljit_emit_simd_load_extend(). */
2041*22dc650dSSadaf Ebrahimi
2042*22dc650dSSadaf Ebrahimi /* Sign extend the integer elements */
2043*22dc650dSSadaf Ebrahimi #define SLJIT_SIMD_EXTEND_SIGNED 0x000002
2044*22dc650dSSadaf Ebrahimi /* Extend data to 16 bit */
2045*22dc650dSSadaf Ebrahimi #define SLJIT_SIMD_EXTEND_16 (1 << 24)
2046*22dc650dSSadaf Ebrahimi /* Extend data to 32 bit */
2047*22dc650dSSadaf Ebrahimi #define SLJIT_SIMD_EXTEND_32 (2 << 24)
2048*22dc650dSSadaf Ebrahimi /* Extend data to 64 bit */
2049*22dc650dSSadaf Ebrahimi #define SLJIT_SIMD_EXTEND_64 (3 << 24)
2050*22dc650dSSadaf Ebrahimi
2051*22dc650dSSadaf Ebrahimi /* Extend elements and stores them in a simd register.
2052*22dc650dSSadaf Ebrahimi The extension operation increases the size of the
2053*22dc650dSSadaf Ebrahimi elements (e.g. from 16 bit to 64 bit). For integer
2054*22dc650dSSadaf Ebrahimi values, the extension can be signed or unsigned.
2055*22dc650dSSadaf Ebrahimi
2056*22dc650dSSadaf Ebrahimi If the operation is not supported, it returns with
2057*22dc650dSSadaf Ebrahimi SLJIT_ERR_UNSUPPORTED. If SLJIT_SIMD_TEST is passed,
2058*22dc650dSSadaf Ebrahimi it does not emit any instructions.
2059*22dc650dSSadaf Ebrahimi
2060*22dc650dSSadaf Ebrahimi type must be a combination of SLJIT_SIMD_*, and
2061*22dc650dSSadaf Ebrahimi SLJIT_SIMD_EXTEND_* options except SLJIT_SIMD_STORE
2062*22dc650dSSadaf Ebrahimi freg is the destination simd register of the operation
2063*22dc650dSSadaf Ebrahimi src must be a memory operand or a simd register.
2064*22dc650dSSadaf Ebrahimi In the latter case, the source elements are stored
2065*22dc650dSSadaf Ebrahimi in the lower half of the register.
2066*22dc650dSSadaf Ebrahimi
2067*22dc650dSSadaf Ebrahimi Flags: - (does not modify flags) */
2068*22dc650dSSadaf Ebrahimi
2069*22dc650dSSadaf Ebrahimi SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_extend(struct sljit_compiler *compiler, sljit_s32 type,
2070*22dc650dSSadaf Ebrahimi sljit_s32 freg,
2071*22dc650dSSadaf Ebrahimi sljit_s32 src, sljit_sw srcw);
2072*22dc650dSSadaf Ebrahimi
2073*22dc650dSSadaf Ebrahimi /* Extract the highest bit (usually the sign bit) from
2074*22dc650dSSadaf Ebrahimi each elements of a vector.
2075*22dc650dSSadaf Ebrahimi
2076*22dc650dSSadaf Ebrahimi If the operation is not supported, it returns with
2077*22dc650dSSadaf Ebrahimi SLJIT_ERR_UNSUPPORTED. If SLJIT_SIMD_TEST is passed,
2078*22dc650dSSadaf Ebrahimi it does not emit any instructions.
2079*22dc650dSSadaf Ebrahimi
2080*22dc650dSSadaf Ebrahimi type must be a combination of SLJIT_SIMD_* and SLJIT_32
2081*22dc650dSSadaf Ebrahimi options except SLJIT_SIMD_LOAD
2082*22dc650dSSadaf Ebrahimi freg is the source simd register of the operation
2083*22dc650dSSadaf Ebrahimi dst is the destination operand
2084*22dc650dSSadaf Ebrahimi
2085*22dc650dSSadaf Ebrahimi Flags: - (does not modify flags) */
2086*22dc650dSSadaf Ebrahimi
2087*22dc650dSSadaf Ebrahimi SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_sign(struct sljit_compiler *compiler, sljit_s32 type,
2088*22dc650dSSadaf Ebrahimi sljit_s32 freg,
2089*22dc650dSSadaf Ebrahimi sljit_s32 dst, sljit_sw dstw);
2090*22dc650dSSadaf Ebrahimi
2091*22dc650dSSadaf Ebrahimi /* The following options are used by sljit_emit_simd_op2(). */
2092*22dc650dSSadaf Ebrahimi
2093*22dc650dSSadaf Ebrahimi /* Binary 'and' operation */
2094*22dc650dSSadaf Ebrahimi #define SLJIT_SIMD_OP2_AND 0x000001
2095*22dc650dSSadaf Ebrahimi /* Binary 'or' operation */
2096*22dc650dSSadaf Ebrahimi #define SLJIT_SIMD_OP2_OR 0x000002
2097*22dc650dSSadaf Ebrahimi /* Binary 'xor' operation */
2098*22dc650dSSadaf Ebrahimi #define SLJIT_SIMD_OP2_XOR 0x000003
2099*22dc650dSSadaf Ebrahimi
2100*22dc650dSSadaf Ebrahimi /* Perform simd operations using simd registers.
2101*22dc650dSSadaf Ebrahimi
2102*22dc650dSSadaf Ebrahimi If the operation is not supported, it returns with
2103*22dc650dSSadaf Ebrahimi SLJIT_ERR_UNSUPPORTED. If SLJIT_SIMD_TEST is passed,
2104*22dc650dSSadaf Ebrahimi it does not emit any instructions.
2105*22dc650dSSadaf Ebrahimi
2106*22dc650dSSadaf Ebrahimi type must be a combination of SLJIT_SIMD_* and SLJIT_SIMD_OP2_
2107*22dc650dSSadaf Ebrahimi options except SLJIT_SIMD_LOAD and SLJIT_SIMD_STORE
2108*22dc650dSSadaf Ebrahimi dst_freg is the destination register of the operation
2109*22dc650dSSadaf Ebrahimi src1_freg is the first source register of the operation
2110*22dc650dSSadaf Ebrahimi src1_freg is the second source register of the operation
2111*22dc650dSSadaf Ebrahimi
2112*22dc650dSSadaf Ebrahimi Flags: - (does not modify flags) */
2113*22dc650dSSadaf Ebrahimi
2114*22dc650dSSadaf Ebrahimi SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_op2(struct sljit_compiler *compiler, sljit_s32 type,
2115*22dc650dSSadaf Ebrahimi sljit_s32 dst_freg, sljit_s32 src1_freg, sljit_s32 src2_freg);
2116*22dc650dSSadaf Ebrahimi
2117*22dc650dSSadaf Ebrahimi /* The sljit_emit_atomic_load and sljit_emit_atomic_store operation pair
2118*22dc650dSSadaf Ebrahimi can perform an atomic read-modify-write operation. First, an unsigned
2119*22dc650dSSadaf Ebrahimi value must be loaded from memory using sljit_emit_atomic_load. Then,
2120*22dc650dSSadaf Ebrahimi the updated value must be written back to the same memory location by
2121*22dc650dSSadaf Ebrahimi sljit_emit_atomic_store. A thread can only perform a single atomic
2122*22dc650dSSadaf Ebrahimi operation at a time.
2123*22dc650dSSadaf Ebrahimi
2124*22dc650dSSadaf Ebrahimi Note: atomic operations are experimental, and not implemented
2125*22dc650dSSadaf Ebrahimi for all cpus.
2126*22dc650dSSadaf Ebrahimi
2127*22dc650dSSadaf Ebrahimi The following conditions must be satisfied, or the operation
2128*22dc650dSSadaf Ebrahimi is undefined:
2129*22dc650dSSadaf Ebrahimi - the address provided in mem_reg must be divisible by the size of
2130*22dc650dSSadaf Ebrahimi the value (only naturally aligned updates are supported)
2131*22dc650dSSadaf Ebrahimi - no memory writes are allowed between the load and store operations
2132*22dc650dSSadaf Ebrahimi regardless of its target address (currently read operations are
2133*22dc650dSSadaf Ebrahimi allowed, but this might change in the future)
2134*22dc650dSSadaf Ebrahimi - the memory operation (op) and the base address (stored in mem_reg)
2135*22dc650dSSadaf Ebrahimi passed to the load/store operations must be the same (the mem_reg
2136*22dc650dSSadaf Ebrahimi can be a different register, only its value must be the same)
2137*22dc650dSSadaf Ebrahimi - an store must always follow a load for the same transaction.
2138*22dc650dSSadaf Ebrahimi
2139*22dc650dSSadaf Ebrahimi op must be between SLJIT_MOV and SLJIT_MOV_P, excluding all
2140*22dc650dSSadaf Ebrahimi signed loads such as SLJIT_MOV32_S16
2141*22dc650dSSadaf Ebrahimi dst_reg is the register where the data will be loaded into
2142*22dc650dSSadaf Ebrahimi mem_reg is the base address of the memory load (it cannot be
2143*22dc650dSSadaf Ebrahimi SLJIT_SP or a virtual register on x86-32)
2144*22dc650dSSadaf Ebrahimi
2145*22dc650dSSadaf Ebrahimi Flags: - (does not modify flags) */
2146*22dc650dSSadaf Ebrahimi SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_atomic_load(struct sljit_compiler *compiler, sljit_s32 op,
2147*22dc650dSSadaf Ebrahimi sljit_s32 dst_reg,
2148*22dc650dSSadaf Ebrahimi sljit_s32 mem_reg);
2149*22dc650dSSadaf Ebrahimi
2150*22dc650dSSadaf Ebrahimi /* The sljit_emit_atomic_load and sljit_emit_atomic_store operations
2151*22dc650dSSadaf Ebrahimi allows performing an atomic read-modify-write operation. See the
2152*22dc650dSSadaf Ebrahimi description of sljit_emit_atomic_load.
2153*22dc650dSSadaf Ebrahimi
2154*22dc650dSSadaf Ebrahimi op must be between SLJIT_MOV and SLJIT_MOV_P, excluding all signed
2155*22dc650dSSadaf Ebrahimi loads such as SLJIT_MOV32_S16
2156*22dc650dSSadaf Ebrahimi src_reg is the register which value is stored into the memory
2157*22dc650dSSadaf Ebrahimi mem_reg is the base address of the memory store (it cannot be
2158*22dc650dSSadaf Ebrahimi SLJIT_SP or a virtual register on x86-32)
2159*22dc650dSSadaf Ebrahimi temp_reg is a not preserved scratch register, which must be
2160*22dc650dSSadaf Ebrahimi initialized with the value loaded into the dst_reg during the
2161*22dc650dSSadaf Ebrahimi corresponding sljit_emit_atomic_load operation, or the operation
2162*22dc650dSSadaf Ebrahimi is undefined
2163*22dc650dSSadaf Ebrahimi
2164*22dc650dSSadaf Ebrahimi Flags: ATOMIC_STORED is set if the operation is successful,
2165*22dc650dSSadaf Ebrahimi otherwise the memory remains unchanged. */
2166*22dc650dSSadaf Ebrahimi SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_atomic_store(struct sljit_compiler *compiler, sljit_s32 op,
2167*22dc650dSSadaf Ebrahimi sljit_s32 src_reg,
2168*22dc650dSSadaf Ebrahimi sljit_s32 mem_reg,
2169*22dc650dSSadaf Ebrahimi sljit_s32 temp_reg);
2170*22dc650dSSadaf Ebrahimi
2171*22dc650dSSadaf Ebrahimi /* Copies the base address of SLJIT_SP + offset to dst. The offset can
2172*22dc650dSSadaf Ebrahimi represent the starting address of a value in the local data (stack).
2173*22dc650dSSadaf Ebrahimi The offset is not limited by the local data limits, it can be any value.
2174*22dc650dSSadaf Ebrahimi For example if an array of bytes are stored on the stack from
2175*22dc650dSSadaf Ebrahimi offset 0x40, and R0 contains the offset of an array item plus 0x120,
2176*22dc650dSSadaf Ebrahimi this item can be changed by two SLJIT instructions:
2177*22dc650dSSadaf Ebrahimi
2178*22dc650dSSadaf Ebrahimi sljit_get_local_base(compiler, SLJIT_R1, 0, 0x40 - 0x120);
2179*22dc650dSSadaf Ebrahimi sljit_emit_op1(compiler, SLJIT_MOV_U8, SLJIT_MEM2(SLJIT_R1, SLJIT_R0), 0, SLJIT_IMM, 0x5);
2180*22dc650dSSadaf Ebrahimi
2181*22dc650dSSadaf Ebrahimi Flags: - (may destroy flags) */
2182*22dc650dSSadaf Ebrahimi SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_get_local_base(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw dstw, sljit_sw offset);
2183*22dc650dSSadaf Ebrahimi
2184*22dc650dSSadaf Ebrahimi /* Store a value that can be changed runtime (see: sljit_get_const_addr / sljit_set_const)
2185*22dc650dSSadaf Ebrahimi Flags: - (does not modify flags) */
2186*22dc650dSSadaf Ebrahimi SLJIT_API_FUNC_ATTRIBUTE struct sljit_const* sljit_emit_const(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw dstw, sljit_sw init_value);
2187*22dc650dSSadaf Ebrahimi
2188*22dc650dSSadaf Ebrahimi /* Store the value of a label (see: sljit_set_label / sljit_set_target)
2189*22dc650dSSadaf Ebrahimi Flags: - (does not modify flags) */
2190*22dc650dSSadaf Ebrahimi SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_mov_addr(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw dstw);
2191*22dc650dSSadaf Ebrahimi
2192*22dc650dSSadaf Ebrahimi /* Provides the address of label, jump and const instructions after sljit_generate_code
2193*22dc650dSSadaf Ebrahimi is called. The returned value is unspecified before the sljit_generate_code call.
2194*22dc650dSSadaf Ebrahimi Since these structures are freed by sljit_free_compiler, the addresses must be
2195*22dc650dSSadaf Ebrahimi preserved by the user program elsewere. */
sljit_get_label_addr(struct sljit_label * label)2196*22dc650dSSadaf Ebrahimi static SLJIT_INLINE sljit_uw sljit_get_label_addr(struct sljit_label *label) { return label->u.addr; }
sljit_get_jump_addr(struct sljit_jump * jump)2197*22dc650dSSadaf Ebrahimi static SLJIT_INLINE sljit_uw sljit_get_jump_addr(struct sljit_jump *jump) { return jump->addr; }
sljit_get_const_addr(struct sljit_const * const_)2198*22dc650dSSadaf Ebrahimi static SLJIT_INLINE sljit_uw sljit_get_const_addr(struct sljit_const *const_) { return const_->addr; }
2199*22dc650dSSadaf Ebrahimi
2200*22dc650dSSadaf Ebrahimi /* Only the address and executable offset are required to perform dynamic
2201*22dc650dSSadaf Ebrahimi code modifications. See sljit_get_executable_offset function. */
2202*22dc650dSSadaf Ebrahimi SLJIT_API_FUNC_ATTRIBUTE void sljit_set_jump_addr(sljit_uw addr, sljit_uw new_target, sljit_sw executable_offset);
2203*22dc650dSSadaf Ebrahimi SLJIT_API_FUNC_ATTRIBUTE void sljit_set_const(sljit_uw addr, sljit_sw new_constant, sljit_sw executable_offset);
2204*22dc650dSSadaf Ebrahimi
2205*22dc650dSSadaf Ebrahimi /* --------------------------------------------------------------------- */
2206*22dc650dSSadaf Ebrahimi /* CPU specific functions */
2207*22dc650dSSadaf Ebrahimi /* --------------------------------------------------------------------- */
2208*22dc650dSSadaf Ebrahimi
2209*22dc650dSSadaf Ebrahimi /* Types for sljit_get_register_index */
2210*22dc650dSSadaf Ebrahimi
2211*22dc650dSSadaf Ebrahimi /* General purpose (integer) registers. */
2212*22dc650dSSadaf Ebrahimi #define SLJIT_GP_REGISTER 0
2213*22dc650dSSadaf Ebrahimi /* Floating point registers. */
2214*22dc650dSSadaf Ebrahimi #define SLJIT_FLOAT_REGISTER 1
2215*22dc650dSSadaf Ebrahimi
2216*22dc650dSSadaf Ebrahimi /* The following function is a helper function for sljit_emit_op_custom.
2217*22dc650dSSadaf Ebrahimi It returns with the real machine register index ( >=0 ) of any registers.
2218*22dc650dSSadaf Ebrahimi
2219*22dc650dSSadaf Ebrahimi When type is SLJIT_GP_REGISTER:
2220*22dc650dSSadaf Ebrahimi reg must be an SLJIT_R(i), SLJIT_S(i), or SLJIT_SP register
2221*22dc650dSSadaf Ebrahimi
2222*22dc650dSSadaf Ebrahimi When type is SLJIT_FLOAT_REGISTER:
2223*22dc650dSSadaf Ebrahimi reg must be an SLJIT_FR(i) or SLJIT_FS(i) register
2224*22dc650dSSadaf Ebrahimi
2225*22dc650dSSadaf Ebrahimi When type is SLJIT_SIMD_REG_64 / 128 / 256 / 512 :
2226*22dc650dSSadaf Ebrahimi reg must be an SLJIT_FR(i) or SLJIT_FS(i) register
2227*22dc650dSSadaf Ebrahimi
2228*22dc650dSSadaf Ebrahimi Note: it returns with -1 for unknown registers, such as virtual
2229*22dc650dSSadaf Ebrahimi registers on x86-32 or unsupported simd registers. */
2230*22dc650dSSadaf Ebrahimi
2231*22dc650dSSadaf Ebrahimi SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_get_register_index(sljit_s32 type, sljit_s32 reg);
2232*22dc650dSSadaf Ebrahimi
2233*22dc650dSSadaf Ebrahimi /* Any instruction can be inserted into the instruction stream by
2234*22dc650dSSadaf Ebrahimi sljit_emit_op_custom. It has a similar purpose as inline assembly.
2235*22dc650dSSadaf Ebrahimi The size parameter must match to the instruction size of the target
2236*22dc650dSSadaf Ebrahimi architecture:
2237*22dc650dSSadaf Ebrahimi
2238*22dc650dSSadaf Ebrahimi x86: 0 < size <= 15, the instruction argument can be byte aligned.
2239*22dc650dSSadaf Ebrahimi Thumb2: if size == 2, the instruction argument must be 2 byte aligned.
2240*22dc650dSSadaf Ebrahimi if size == 4, the instruction argument must be 4 byte aligned.
2241*22dc650dSSadaf Ebrahimi s390x: size can be 2, 4, or 6, the instruction argument can be byte aligned.
2242*22dc650dSSadaf Ebrahimi Otherwise: size must be 4 and instruction argument must be 4 byte aligned. */
2243*22dc650dSSadaf Ebrahimi
2244*22dc650dSSadaf Ebrahimi SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_custom(struct sljit_compiler *compiler,
2245*22dc650dSSadaf Ebrahimi void *instruction, sljit_u32 size);
2246*22dc650dSSadaf Ebrahimi
2247*22dc650dSSadaf Ebrahimi /* Flags were set by a 32 bit operation. */
2248*22dc650dSSadaf Ebrahimi #define SLJIT_CURRENT_FLAGS_32 SLJIT_32
2249*22dc650dSSadaf Ebrahimi
2250*22dc650dSSadaf Ebrahimi /* Flags were set by an ADD or ADDC operations. */
2251*22dc650dSSadaf Ebrahimi #define SLJIT_CURRENT_FLAGS_ADD 0x01
2252*22dc650dSSadaf Ebrahimi /* Flags were set by a SUB, SUBC, or NEG operation. */
2253*22dc650dSSadaf Ebrahimi #define SLJIT_CURRENT_FLAGS_SUB 0x02
2254*22dc650dSSadaf Ebrahimi
2255*22dc650dSSadaf Ebrahimi /* Flags were set by sljit_emit_op2u with SLJIT_SUB opcode.
2256*22dc650dSSadaf Ebrahimi Must be combined with SLJIT_CURRENT_FLAGS_SUB. */
2257*22dc650dSSadaf Ebrahimi #define SLJIT_CURRENT_FLAGS_COMPARE 0x04
2258*22dc650dSSadaf Ebrahimi
2259*22dc650dSSadaf Ebrahimi /* Define the currently available CPU status flags. It is usually used after
2260*22dc650dSSadaf Ebrahimi an sljit_emit_label or sljit_emit_op_custom operations to define which CPU
2261*22dc650dSSadaf Ebrahimi status flags are available.
2262*22dc650dSSadaf Ebrahimi
2263*22dc650dSSadaf Ebrahimi The current_flags must be a valid combination of SLJIT_SET_* and
2264*22dc650dSSadaf Ebrahimi SLJIT_CURRENT_FLAGS_* constants. */
2265*22dc650dSSadaf Ebrahimi
2266*22dc650dSSadaf Ebrahimi SLJIT_API_FUNC_ATTRIBUTE void sljit_set_current_flags(struct sljit_compiler *compiler,
2267*22dc650dSSadaf Ebrahimi sljit_s32 current_flags);
2268*22dc650dSSadaf Ebrahimi
2269*22dc650dSSadaf Ebrahimi /* --------------------------------------------------------------------- */
2270*22dc650dSSadaf Ebrahimi /* Serialization functions */
2271*22dc650dSSadaf Ebrahimi /* --------------------------------------------------------------------- */
2272*22dc650dSSadaf Ebrahimi
2273*22dc650dSSadaf Ebrahimi /* Label/jump/const enumeration functions. The items in each group
2274*22dc650dSSadaf Ebrahimi are enumerated in creation order. Serialization / deserialization
2275*22dc650dSSadaf Ebrahimi preserves this order for each group. For example the fifth label
2276*22dc650dSSadaf Ebrahimi after deserialization refers to the same machine code location as
2277*22dc650dSSadaf Ebrahimi the fifth label before the serialization. */
sljit_get_first_label(struct sljit_compiler * compiler)2278*22dc650dSSadaf Ebrahimi static SLJIT_INLINE struct sljit_label *sljit_get_first_label(struct sljit_compiler *compiler) { return compiler->labels; }
sljit_get_first_jump(struct sljit_compiler * compiler)2279*22dc650dSSadaf Ebrahimi static SLJIT_INLINE struct sljit_jump *sljit_get_first_jump(struct sljit_compiler *compiler) { return compiler->jumps; }
sljit_get_first_const(struct sljit_compiler * compiler)2280*22dc650dSSadaf Ebrahimi static SLJIT_INLINE struct sljit_const *sljit_get_first_const(struct sljit_compiler *compiler) { return compiler->consts; }
2281*22dc650dSSadaf Ebrahimi
sljit_get_next_label(struct sljit_label * label)2282*22dc650dSSadaf Ebrahimi static SLJIT_INLINE struct sljit_label *sljit_get_next_label(struct sljit_label *label) { return label->next; }
sljit_get_next_jump(struct sljit_jump * jump)2283*22dc650dSSadaf Ebrahimi static SLJIT_INLINE struct sljit_jump *sljit_get_next_jump(struct sljit_jump *jump) { return jump->next; }
sljit_get_next_const(struct sljit_const * const_)2284*22dc650dSSadaf Ebrahimi static SLJIT_INLINE struct sljit_const *sljit_get_next_const(struct sljit_const *const_) { return const_->next; }
2285*22dc650dSSadaf Ebrahimi
2286*22dc650dSSadaf Ebrahimi /* A number starting from 0 is assigned to each label, which
2287*22dc650dSSadaf Ebrahimi represents its creation index. The first label created by the
2288*22dc650dSSadaf Ebrahimi compiler has index 0, the second has index 1, the third has
2289*22dc650dSSadaf Ebrahimi index 2, and so on. The returned value is unspecified after
2290*22dc650dSSadaf Ebrahimi sljit_generate_code() is called. */
sljit_get_label_index(struct sljit_label * label)2291*22dc650dSSadaf Ebrahimi static SLJIT_INLINE sljit_uw sljit_get_label_index(struct sljit_label *label) { return label->u.index; }
2292*22dc650dSSadaf Ebrahimi
2293*22dc650dSSadaf Ebrahimi /* The sljit_jump_has_label() and sljit_jump_has_target() functions
2294*22dc650dSSadaf Ebrahimi returns non-zero value if a label or target is set for the jump
2295*22dc650dSSadaf Ebrahimi respectively. Both may return with a zero value. The other two
2296*22dc650dSSadaf Ebrahimi functions return the value assigned to the jump. */
2297*22dc650dSSadaf Ebrahimi SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_jump_has_label(struct sljit_jump *jump);
sljit_jump_get_label(struct sljit_jump * jump)2298*22dc650dSSadaf Ebrahimi static SLJIT_INLINE struct sljit_label *sljit_jump_get_label(struct sljit_jump *jump) { return jump->u.label; }
2299*22dc650dSSadaf Ebrahimi SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_jump_has_target(struct sljit_jump *jump);
sljit_jump_get_target(struct sljit_jump * jump)2300*22dc650dSSadaf Ebrahimi static SLJIT_INLINE sljit_uw sljit_jump_get_target(struct sljit_jump *jump) { return jump->u.target; }
2301*22dc650dSSadaf Ebrahimi SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_jump_is_mov_addr(struct sljit_jump *jump);
2302*22dc650dSSadaf Ebrahimi
2303*22dc650dSSadaf Ebrahimi /* Option bits for sljit_serialize_compiler. */
2304*22dc650dSSadaf Ebrahimi
2305*22dc650dSSadaf Ebrahimi /* When debugging is enabled, the serialized buffer contains
2306*22dc650dSSadaf Ebrahimi debugging information unless this option is specified. */
2307*22dc650dSSadaf Ebrahimi #define SLJIT_SERIALIZE_IGNORE_DEBUG 0x1
2308*22dc650dSSadaf Ebrahimi
2309*22dc650dSSadaf Ebrahimi /* Serialize the internal structure of the compiler into a buffer.
2310*22dc650dSSadaf Ebrahimi If the serialization is successful, the returned value is a newly
2311*22dc650dSSadaf Ebrahimi allocated buffer which is allocated by the memory allocator assigned
2312*22dc650dSSadaf Ebrahimi to the compiler. Otherwise the returned value is NULL. Unlike
2313*22dc650dSSadaf Ebrahimi sljit_generate_code(), serialization does not modify the internal
2314*22dc650dSSadaf Ebrahimi state of the compiler, so the code generation can be continued.
2315*22dc650dSSadaf Ebrahimi
2316*22dc650dSSadaf Ebrahimi options must be the combination of SLJIT_SERIALIZE_* option bits
2317*22dc650dSSadaf Ebrahimi size is an output argument, which is set to the byte size of
2318*22dc650dSSadaf Ebrahimi the result buffer if the operation is successful
2319*22dc650dSSadaf Ebrahimi
2320*22dc650dSSadaf Ebrahimi Notes:
2321*22dc650dSSadaf Ebrahimi - This function is useful for ahead-of-time compilation (AOT).
2322*22dc650dSSadaf Ebrahimi - The returned buffer must be freed later by the caller.
2323*22dc650dSSadaf Ebrahimi The SLJIT_FREE() macro is suitable for this purpose:
2324*22dc650dSSadaf Ebrahimi SLJIT_FREE(returned_buffer, sljit_get_allocator_data(compiler))
2325*22dc650dSSadaf Ebrahimi - Memory allocated by sljit_alloc_memory() is not serialized.
2326*22dc650dSSadaf Ebrahimi - The type of the returned buffer is sljit_uw* to emphasize that
2327*22dc650dSSadaf Ebrahimi the buffer is word aligned. However, the 'size' output argument
2328*22dc650dSSadaf Ebrahimi contains the byte size, so this value is always divisible by
2329*22dc650dSSadaf Ebrahimi sizeof(sljit_uw).
2330*22dc650dSSadaf Ebrahimi */
2331*22dc650dSSadaf Ebrahimi SLJIT_API_FUNC_ATTRIBUTE sljit_uw* sljit_serialize_compiler(struct sljit_compiler *compiler,
2332*22dc650dSSadaf Ebrahimi sljit_s32 options, sljit_uw *size);
2333*22dc650dSSadaf Ebrahimi
2334*22dc650dSSadaf Ebrahimi /* Construct a new compiler instance from a buffer produced by
2335*22dc650dSSadaf Ebrahimi sljit_serialize_compiler(). If the operation is successful, the new
2336*22dc650dSSadaf Ebrahimi compiler instance is returned. Otherwise the returned value is NULL.
2337*22dc650dSSadaf Ebrahimi
2338*22dc650dSSadaf Ebrahimi buffer points to a word aligned memory data which was
2339*22dc650dSSadaf Ebrahimi created by sljit_serialize_compiler()
2340*22dc650dSSadaf Ebrahimi size is the byte size of the buffer
2341*22dc650dSSadaf Ebrahimi options must be 0
2342*22dc650dSSadaf Ebrahimi allocator_data specify an allocator specific data, see
2343*22dc650dSSadaf Ebrahimi sljit_create_compiler() for further details
2344*22dc650dSSadaf Ebrahimi
2345*22dc650dSSadaf Ebrahimi Notes:
2346*22dc650dSSadaf Ebrahimi - Labels assigned to jumps are restored with their
2347*22dc650dSSadaf Ebrahimi corresponding label in the label set created by
2348*22dc650dSSadaf Ebrahimi the deserializer. Target addresses assigned to
2349*22dc650dSSadaf Ebrahimi jumps are also restored. Uninitialized jumps
2350*22dc650dSSadaf Ebrahimi remain uninitialized.
2351*22dc650dSSadaf Ebrahimi - After the deserialization, sljit_generate_code() does
2352*22dc650dSSadaf Ebrahimi not need to be the next operation on the returned
2353*22dc650dSSadaf Ebrahimi compiler, the code generation can be continued.
2354*22dc650dSSadaf Ebrahimi Even sljit_serialize_compiler() can be called again.
2355*22dc650dSSadaf Ebrahimi - When debugging is enabled, a buffers without debug
2356*22dc650dSSadaf Ebrahimi information cannot be deserialized.
2357*22dc650dSSadaf Ebrahimi */
2358*22dc650dSSadaf Ebrahimi SLJIT_API_FUNC_ATTRIBUTE struct sljit_compiler *sljit_deserialize_compiler(sljit_uw* buffer, sljit_uw size,
2359*22dc650dSSadaf Ebrahimi sljit_s32 options, void *allocator_data);
2360*22dc650dSSadaf Ebrahimi
2361*22dc650dSSadaf Ebrahimi /* --------------------------------------------------------------------- */
2362*22dc650dSSadaf Ebrahimi /* Miscellaneous utility functions */
2363*22dc650dSSadaf Ebrahimi /* --------------------------------------------------------------------- */
2364*22dc650dSSadaf Ebrahimi
2365*22dc650dSSadaf Ebrahimi /* Get the human readable name of the platform. Can be useful on platforms
2366*22dc650dSSadaf Ebrahimi like ARM, where ARM and Thumb2 functions can be mixed, and it is useful
2367*22dc650dSSadaf Ebrahimi to know the type of the code generator. */
2368*22dc650dSSadaf Ebrahimi SLJIT_API_FUNC_ATTRIBUTE const char* sljit_get_platform_name(void);
2369*22dc650dSSadaf Ebrahimi
2370*22dc650dSSadaf Ebrahimi /* Portable helper function to get an offset of a member.
2371*22dc650dSSadaf Ebrahimi Same as offsetof() macro defined in stddef.h */
2372*22dc650dSSadaf Ebrahimi #define SLJIT_OFFSETOF(base, member) ((sljit_sw)(&((base*)0x10)->member) - 0x10)
2373*22dc650dSSadaf Ebrahimi
2374*22dc650dSSadaf Ebrahimi #if (defined SLJIT_UTIL_STACK && SLJIT_UTIL_STACK)
2375*22dc650dSSadaf Ebrahimi
2376*22dc650dSSadaf Ebrahimi /* The sljit_stack structure and its manipulation functions provides
2377*22dc650dSSadaf Ebrahimi an implementation for a top-down stack. The stack top is stored
2378*22dc650dSSadaf Ebrahimi in the end field of the sljit_stack structure and the stack goes
2379*22dc650dSSadaf Ebrahimi down to the min_start field, so the memory region reserved for
2380*22dc650dSSadaf Ebrahimi this stack is between min_start (inclusive) and end (exclusive)
2381*22dc650dSSadaf Ebrahimi fields. However the application can only use the region between
2382*22dc650dSSadaf Ebrahimi start (inclusive) and end (exclusive) fields. The sljit_stack_resize
2383*22dc650dSSadaf Ebrahimi function can be used to extend this region up to min_start.
2384*22dc650dSSadaf Ebrahimi
2385*22dc650dSSadaf Ebrahimi This feature uses the "address space reserve" feature of modern
2386*22dc650dSSadaf Ebrahimi operating systems. Instead of allocating a large memory block
2387*22dc650dSSadaf Ebrahimi applications can allocate a small memory region and extend it
2388*22dc650dSSadaf Ebrahimi later without moving the content of the memory area. Therefore
2389*22dc650dSSadaf Ebrahimi after a successful resize by sljit_stack_resize all pointers into
2390*22dc650dSSadaf Ebrahimi this region are still valid.
2391*22dc650dSSadaf Ebrahimi
2392*22dc650dSSadaf Ebrahimi Note:
2393*22dc650dSSadaf Ebrahimi this structure may not be supported by all operating systems.
2394*22dc650dSSadaf Ebrahimi end and max_limit fields are aligned to PAGE_SIZE bytes (usually
2395*22dc650dSSadaf Ebrahimi 4 Kbyte or more).
2396*22dc650dSSadaf Ebrahimi stack should grow in larger steps, e.g. 4Kbyte, 16Kbyte or more. */
2397*22dc650dSSadaf Ebrahimi
2398*22dc650dSSadaf Ebrahimi struct sljit_stack {
2399*22dc650dSSadaf Ebrahimi /* User data, anything can be stored here.
2400*22dc650dSSadaf Ebrahimi Initialized to the same value as the end field. */
2401*22dc650dSSadaf Ebrahimi sljit_u8 *top;
2402*22dc650dSSadaf Ebrahimi /* These members are read only. */
2403*22dc650dSSadaf Ebrahimi /* End address of the stack */
2404*22dc650dSSadaf Ebrahimi sljit_u8 *end;
2405*22dc650dSSadaf Ebrahimi /* Current start address of the stack. */
2406*22dc650dSSadaf Ebrahimi sljit_u8 *start;
2407*22dc650dSSadaf Ebrahimi /* Lowest start address of the stack. */
2408*22dc650dSSadaf Ebrahimi sljit_u8 *min_start;
2409*22dc650dSSadaf Ebrahimi };
2410*22dc650dSSadaf Ebrahimi
2411*22dc650dSSadaf Ebrahimi /* Allocates a new stack. Returns NULL if unsuccessful.
2412*22dc650dSSadaf Ebrahimi Note: see sljit_create_compiler for the explanation of allocator_data. */
2413*22dc650dSSadaf Ebrahimi SLJIT_API_FUNC_ATTRIBUTE struct sljit_stack* SLJIT_FUNC sljit_allocate_stack(sljit_uw start_size, sljit_uw max_size, void *allocator_data);
2414*22dc650dSSadaf Ebrahimi SLJIT_API_FUNC_ATTRIBUTE void SLJIT_FUNC sljit_free_stack(struct sljit_stack *stack, void *allocator_data);
2415*22dc650dSSadaf Ebrahimi
2416*22dc650dSSadaf Ebrahimi /* Can be used to increase (extend) or decrease (shrink) the stack
2417*22dc650dSSadaf Ebrahimi memory area. Returns with new_start if successful and NULL otherwise.
2418*22dc650dSSadaf Ebrahimi It always fails if new_start is less than min_start or greater or equal
2419*22dc650dSSadaf Ebrahimi than end fields. The fields of the stack are not changed if the returned
2420*22dc650dSSadaf Ebrahimi value is NULL (the current memory content is never lost). */
2421*22dc650dSSadaf Ebrahimi SLJIT_API_FUNC_ATTRIBUTE sljit_u8 *SLJIT_FUNC sljit_stack_resize(struct sljit_stack *stack, sljit_u8 *new_start);
2422*22dc650dSSadaf Ebrahimi
2423*22dc650dSSadaf Ebrahimi #endif /* (defined SLJIT_UTIL_STACK && SLJIT_UTIL_STACK) */
2424*22dc650dSSadaf Ebrahimi
2425*22dc650dSSadaf Ebrahimi #if !(defined SLJIT_INDIRECT_CALL && SLJIT_INDIRECT_CALL)
2426*22dc650dSSadaf Ebrahimi
2427*22dc650dSSadaf Ebrahimi /* Get the entry address of a given function (signed, unsigned result). */
2428*22dc650dSSadaf Ebrahimi #define SLJIT_FUNC_ADDR(func_name) ((sljit_sw)func_name)
2429*22dc650dSSadaf Ebrahimi #define SLJIT_FUNC_UADDR(func_name) ((sljit_uw)func_name)
2430*22dc650dSSadaf Ebrahimi
2431*22dc650dSSadaf Ebrahimi #else /* !(defined SLJIT_INDIRECT_CALL && SLJIT_INDIRECT_CALL) */
2432*22dc650dSSadaf Ebrahimi
2433*22dc650dSSadaf Ebrahimi /* All JIT related code should be placed in the same context (library, binary, etc.). */
2434*22dc650dSSadaf Ebrahimi
2435*22dc650dSSadaf Ebrahimi /* Get the entry address of a given function (signed, unsigned result). */
2436*22dc650dSSadaf Ebrahimi #define SLJIT_FUNC_ADDR(func_name) (*(sljit_sw*)(void*)func_name)
2437*22dc650dSSadaf Ebrahimi #define SLJIT_FUNC_UADDR(func_name) (*(sljit_uw*)(void*)func_name)
2438*22dc650dSSadaf Ebrahimi
2439*22dc650dSSadaf Ebrahimi /* For powerpc64, the function pointers point to a context descriptor. */
2440*22dc650dSSadaf Ebrahimi struct sljit_function_context {
2441*22dc650dSSadaf Ebrahimi sljit_uw addr;
2442*22dc650dSSadaf Ebrahimi sljit_uw r2;
2443*22dc650dSSadaf Ebrahimi sljit_uw r11;
2444*22dc650dSSadaf Ebrahimi };
2445*22dc650dSSadaf Ebrahimi
2446*22dc650dSSadaf Ebrahimi /* Fill the context arguments using the addr and the function.
2447*22dc650dSSadaf Ebrahimi If func_ptr is NULL, it will not be set to the address of context
2448*22dc650dSSadaf Ebrahimi If addr is NULL, the function address also comes from the func pointer. */
2449*22dc650dSSadaf Ebrahimi SLJIT_API_FUNC_ATTRIBUTE void sljit_set_function_context(void** func_ptr, struct sljit_function_context* context, sljit_uw addr, void* func);
2450*22dc650dSSadaf Ebrahimi
2451*22dc650dSSadaf Ebrahimi #endif /* !(defined SLJIT_INDIRECT_CALL && SLJIT_INDIRECT_CALL) */
2452*22dc650dSSadaf Ebrahimi
2453*22dc650dSSadaf Ebrahimi #if (defined SLJIT_EXECUTABLE_ALLOCATOR && SLJIT_EXECUTABLE_ALLOCATOR)
2454*22dc650dSSadaf Ebrahimi /* Free unused executable memory. The allocator keeps some free memory
2455*22dc650dSSadaf Ebrahimi around to reduce the number of OS executable memory allocations.
2456*22dc650dSSadaf Ebrahimi This improves performance since these calls are costly. However
2457*22dc650dSSadaf Ebrahimi it is sometimes desired to free all unused memory regions, e.g.
2458*22dc650dSSadaf Ebrahimi before the application terminates. */
2459*22dc650dSSadaf Ebrahimi SLJIT_API_FUNC_ATTRIBUTE void sljit_free_unused_memory_exec(void);
2460*22dc650dSSadaf Ebrahimi #endif
2461*22dc650dSSadaf Ebrahimi
2462*22dc650dSSadaf Ebrahimi #ifdef __cplusplus
2463*22dc650dSSadaf Ebrahimi } /* extern "C" */
2464*22dc650dSSadaf Ebrahimi #endif
2465*22dc650dSSadaf Ebrahimi
2466*22dc650dSSadaf Ebrahimi #endif /* SLJIT_LIR_H_ */
2467