sljitLir.h revision 1.2 1 1.2 alnsn /* $NetBSD: sljitLir.h,v 1.2 2014/06/17 19:36:45 alnsn Exp $ */
2 1.2 alnsn
3 1.1 alnsn /*
4 1.1 alnsn * Stack-less Just-In-Time compiler
5 1.1 alnsn *
6 1.1 alnsn * Copyright 2009-2012 Zoltan Herczeg (hzmester (at) freemail.hu). All rights reserved.
7 1.1 alnsn *
8 1.1 alnsn * Redistribution and use in source and binary forms, with or without modification, are
9 1.1 alnsn * permitted provided that the following conditions are met:
10 1.1 alnsn *
11 1.1 alnsn * 1. Redistributions of source code must retain the above copyright notice, this list of
12 1.1 alnsn * conditions and the following disclaimer.
13 1.1 alnsn *
14 1.1 alnsn * 2. Redistributions in binary form must reproduce the above copyright notice, this list
15 1.1 alnsn * of conditions and the following disclaimer in the documentation and/or other materials
16 1.1 alnsn * provided with the distribution.
17 1.1 alnsn *
18 1.1 alnsn * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) AND CONTRIBUTORS ``AS IS'' AND ANY
19 1.1 alnsn * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
20 1.1 alnsn * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
21 1.1 alnsn * SHALL THE COPYRIGHT HOLDER(S) OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
22 1.1 alnsn * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
23 1.1 alnsn * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
24 1.1 alnsn * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
25 1.1 alnsn * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
26 1.1 alnsn * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 1.1 alnsn */
28 1.1 alnsn
29 1.1 alnsn #ifndef _SLJIT_LIR_H_
30 1.1 alnsn #define _SLJIT_LIR_H_
31 1.1 alnsn
32 1.1 alnsn /*
33 1.1 alnsn ------------------------------------------------------------------------
34 1.1 alnsn Stack-Less JIT compiler for multiple architectures (x86, ARM, PowerPC)
35 1.1 alnsn ------------------------------------------------------------------------
36 1.1 alnsn
37 1.1 alnsn Short description
38 1.1 alnsn Advantages:
39 1.2 alnsn - The execution can be continued from any LIR instruction. In other
40 1.2 alnsn words, it is possible to jump to any label from anywhere, even from
41 1.2 alnsn a code fragment, which is compiled later, if both compiled code
42 1.2 alnsn shares the same context. See sljit_emit_enter for more details
43 1.2 alnsn - Supports self modifying code: target of (conditional) jump and call
44 1.2 alnsn instructions and some constant values can be dynamically modified
45 1.2 alnsn during runtime
46 1.1 alnsn - although it is not suggested to do it frequently
47 1.2 alnsn - can be used for inline caching: save an important value once
48 1.2 alnsn in the instruction stream
49 1.2 alnsn - since this feature limits the optimization possibilities, a
50 1.2 alnsn special flag must be passed at compile time when these
51 1.2 alnsn instructions are emitted
52 1.1 alnsn - A fixed stack space can be allocated for local variables
53 1.1 alnsn - The compiler is thread-safe
54 1.1 alnsn - The compiler is highly configurable through preprocessor macros.
55 1.1 alnsn You can disable unneeded features (multithreading in single
56 1.1 alnsn threaded applications), and you can use your own system functions
57 1.1 alnsn (including memory allocators). See sljitConfig.h
58 1.1 alnsn Disadvantages:
59 1.2 alnsn - No automatic register allocation, and temporary results are
60 1.2 alnsn not stored on the stack. (hence the name comes)
61 1.1 alnsn - Limited number of registers (only 6+4 integer registers, max 3+2
62 1.2 alnsn scratch, max 3+2 saved and 6 floating point registers)
63 1.1 alnsn In practice:
64 1.1 alnsn - This approach is very effective for interpreters
65 1.1 alnsn - One of the saved registers typically points to a stack interface
66 1.2 alnsn - It can jump to any exception handler anytime (even if it belongs
67 1.2 alnsn to another function)
68 1.2 alnsn - Hot paths can be modified during runtime reflecting the changes
69 1.1 alnsn of the fastest execution path of the dynamic language
70 1.1 alnsn - SLJIT supports complex memory addressing modes
71 1.2 alnsn - mainly position and context independent code (except some cases)
72 1.1 alnsn
73 1.1 alnsn For valgrind users:
74 1.1 alnsn - pass --smc-check=all argument to valgrind, since JIT is a "self-modifying code"
75 1.1 alnsn */
76 1.1 alnsn
77 1.1 alnsn #if !(defined SLJIT_NO_DEFAULT_CONFIG && SLJIT_NO_DEFAULT_CONFIG)
78 1.1 alnsn #include "sljitConfig.h"
79 1.1 alnsn #endif
80 1.1 alnsn
81 1.1 alnsn /* The following header file defines useful macros for fine tuning
82 1.2 alnsn sljit based code generators. They are listed in the beginning
83 1.1 alnsn of sljitConfigInternal.h */
84 1.1 alnsn
85 1.1 alnsn #include "sljitConfigInternal.h"
86 1.1 alnsn
87 1.1 alnsn /* --------------------------------------------------------------------- */
88 1.1 alnsn /* Error codes */
89 1.1 alnsn /* --------------------------------------------------------------------- */
90 1.1 alnsn
91 1.1 alnsn /* Indicates no error. */
92 1.1 alnsn #define SLJIT_SUCCESS 0
93 1.1 alnsn /* After the call of sljit_generate_code(), the error code of the compiler
94 1.1 alnsn is set to this value to avoid future sljit calls (in debug mode at least).
95 1.1 alnsn The complier should be freed after sljit_generate_code(). */
96 1.1 alnsn #define SLJIT_ERR_COMPILED 1
97 1.1 alnsn /* Cannot allocate non executable memory. */
98 1.1 alnsn #define SLJIT_ERR_ALLOC_FAILED 2
99 1.1 alnsn /* Cannot allocate executable memory.
100 1.1 alnsn Only for sljit_generate_code() */
101 1.1 alnsn #define SLJIT_ERR_EX_ALLOC_FAILED 3
102 1.1 alnsn /* return value for SLJIT_CONFIG_UNSUPPORTED empty architecture. */
103 1.1 alnsn #define SLJIT_ERR_UNSUPPORTED 4
104 1.1 alnsn
105 1.1 alnsn /* --------------------------------------------------------------------- */
106 1.1 alnsn /* Registers */
107 1.1 alnsn /* --------------------------------------------------------------------- */
108 1.1 alnsn
109 1.1 alnsn #define SLJIT_UNUSED 0
110 1.1 alnsn
111 1.2 alnsn /* Scratch (temporary) registers whose may not preserve their values
112 1.2 alnsn across function calls. */
113 1.2 alnsn #define SLJIT_SCRATCH_REG1 1
114 1.2 alnsn #define SLJIT_SCRATCH_REG2 2
115 1.2 alnsn #define SLJIT_SCRATCH_REG3 3
116 1.2 alnsn /* Note: extra registers cannot be used for memory addressing. */
117 1.2 alnsn /* Note: on x86-32, these registers are emulated (using stack
118 1.2 alnsn loads & stores). */
119 1.1 alnsn #define SLJIT_TEMPORARY_EREG1 4
120 1.1 alnsn #define SLJIT_TEMPORARY_EREG2 5
121 1.1 alnsn
122 1.1 alnsn /* Saved registers whose preserve their values across function calls. */
123 1.1 alnsn #define SLJIT_SAVED_REG1 6
124 1.1 alnsn #define SLJIT_SAVED_REG2 7
125 1.1 alnsn #define SLJIT_SAVED_REG3 8
126 1.2 alnsn /* Note: extra registers cannot be used for memory addressing. */
127 1.2 alnsn /* Note: on x86-32, these registers are emulated (using stack
128 1.2 alnsn loads & stores). */
129 1.1 alnsn #define SLJIT_SAVED_EREG1 9
130 1.1 alnsn #define SLJIT_SAVED_EREG2 10
131 1.1 alnsn
132 1.1 alnsn /* Read-only register (cannot be the destination of an operation).
133 1.1 alnsn Only SLJIT_MEM1(SLJIT_LOCALS_REG) addressing mode is allowed since
134 1.1 alnsn several ABIs has certain limitations about the stack layout. However
135 1.2 alnsn sljit_get_local_base() can be used to obtain the offset of a value
136 1.2 alnsn on the stack. */
137 1.1 alnsn #define SLJIT_LOCALS_REG 11
138 1.1 alnsn
139 1.1 alnsn /* Number of registers. */
140 1.1 alnsn #define SLJIT_NO_TMP_REGISTERS 5
141 1.1 alnsn #define SLJIT_NO_GEN_REGISTERS 5
142 1.1 alnsn #define SLJIT_NO_REGISTERS 11
143 1.1 alnsn
144 1.1 alnsn /* Return with machine word. */
145 1.1 alnsn
146 1.2 alnsn #define SLJIT_RETURN_REG SLJIT_SCRATCH_REG1
147 1.1 alnsn
148 1.1 alnsn /* x86 prefers specific registers for special purposes. In case of shift
149 1.2 alnsn by register it supports only SLJIT_SCRATCH_REG3 for shift argument
150 1.1 alnsn (which is the src2 argument of sljit_emit_op2). If another register is
151 1.1 alnsn used, sljit must exchange data between registers which cause a minor
152 1.1 alnsn slowdown. Other architectures has no such limitation. */
153 1.1 alnsn
154 1.2 alnsn #define SLJIT_PREF_SHIFT_REG SLJIT_SCRATCH_REG3
155 1.1 alnsn
156 1.1 alnsn /* --------------------------------------------------------------------- */
157 1.1 alnsn /* Floating point registers */
158 1.1 alnsn /* --------------------------------------------------------------------- */
159 1.1 alnsn
160 1.1 alnsn /* Note: SLJIT_UNUSED as destination is not valid for floating point
161 1.1 alnsn operations, since they cannot be used for setting flags. */
162 1.1 alnsn
163 1.2 alnsn /* Floating point operations are performed on double or
164 1.2 alnsn single precision values. */
165 1.2 alnsn
166 1.2 alnsn #define SLJIT_FLOAT_REG1 1
167 1.2 alnsn #define SLJIT_FLOAT_REG2 2
168 1.2 alnsn #define SLJIT_FLOAT_REG3 3
169 1.2 alnsn #define SLJIT_FLOAT_REG4 4
170 1.2 alnsn #define SLJIT_FLOAT_REG5 5
171 1.2 alnsn #define SLJIT_FLOAT_REG6 6
172 1.1 alnsn
173 1.2 alnsn #define SLJIT_NO_FLOAT_REGISTERS 6
174 1.1 alnsn
175 1.1 alnsn /* --------------------------------------------------------------------- */
176 1.1 alnsn /* Main structures and functions */
177 1.1 alnsn /* --------------------------------------------------------------------- */
178 1.1 alnsn
179 1.1 alnsn struct sljit_memory_fragment {
180 1.1 alnsn struct sljit_memory_fragment *next;
181 1.1 alnsn sljit_uw used_size;
182 1.2 alnsn /* Must be aligned to sljit_sw. */
183 1.1 alnsn sljit_ub memory[1];
184 1.1 alnsn };
185 1.1 alnsn
186 1.1 alnsn struct sljit_label {
187 1.1 alnsn struct sljit_label *next;
188 1.1 alnsn sljit_uw addr;
189 1.1 alnsn /* The maximum size difference. */
190 1.1 alnsn sljit_uw size;
191 1.1 alnsn };
192 1.1 alnsn
193 1.1 alnsn struct sljit_jump {
194 1.1 alnsn struct sljit_jump *next;
195 1.1 alnsn sljit_uw addr;
196 1.2 alnsn sljit_sw flags;
197 1.1 alnsn union {
198 1.1 alnsn sljit_uw target;
199 1.1 alnsn struct sljit_label* label;
200 1.1 alnsn } u;
201 1.1 alnsn };
202 1.1 alnsn
203 1.1 alnsn struct sljit_const {
204 1.1 alnsn struct sljit_const *next;
205 1.1 alnsn sljit_uw addr;
206 1.1 alnsn };
207 1.1 alnsn
208 1.1 alnsn struct sljit_compiler {
209 1.2 alnsn sljit_si error;
210 1.1 alnsn
211 1.1 alnsn struct sljit_label *labels;
212 1.1 alnsn struct sljit_jump *jumps;
213 1.1 alnsn struct sljit_const *consts;
214 1.1 alnsn struct sljit_label *last_label;
215 1.1 alnsn struct sljit_jump *last_jump;
216 1.1 alnsn struct sljit_const *last_const;
217 1.1 alnsn
218 1.1 alnsn struct sljit_memory_fragment *buf;
219 1.1 alnsn struct sljit_memory_fragment *abuf;
220 1.1 alnsn
221 1.1 alnsn /* Used local registers. */
222 1.2 alnsn sljit_si scratches;
223 1.1 alnsn /* Used saved registers. */
224 1.2 alnsn sljit_si saveds;
225 1.1 alnsn /* Local stack size. */
226 1.2 alnsn sljit_si local_size;
227 1.1 alnsn /* Code size. */
228 1.1 alnsn sljit_uw size;
229 1.1 alnsn /* For statistical purposes. */
230 1.1 alnsn sljit_uw executable_size;
231 1.1 alnsn
232 1.1 alnsn #if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
233 1.2 alnsn sljit_si args;
234 1.2 alnsn sljit_si locals_offset;
235 1.2 alnsn sljit_si scratches_start;
236 1.2 alnsn sljit_si saveds_start;
237 1.1 alnsn #endif
238 1.1 alnsn
239 1.1 alnsn #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
240 1.2 alnsn sljit_si mode32;
241 1.1 alnsn #endif
242 1.1 alnsn
243 1.1 alnsn #if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) || (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
244 1.2 alnsn sljit_si flags_saved;
245 1.1 alnsn #endif
246 1.1 alnsn
247 1.1 alnsn #if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5)
248 1.1 alnsn /* Constant pool handling. */
249 1.1 alnsn sljit_uw *cpool;
250 1.1 alnsn sljit_ub *cpool_unique;
251 1.1 alnsn sljit_uw cpool_diff;
252 1.1 alnsn sljit_uw cpool_fill;
253 1.1 alnsn /* Other members. */
254 1.1 alnsn /* Contains pointer, "ldr pc, [...]" pairs. */
255 1.1 alnsn sljit_uw patches;
256 1.1 alnsn #endif
257 1.1 alnsn
258 1.1 alnsn #if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5) || (defined SLJIT_CONFIG_ARM_V7 && SLJIT_CONFIG_ARM_V7)
259 1.1 alnsn /* Temporary fields. */
260 1.1 alnsn sljit_uw shift_imm;
261 1.2 alnsn sljit_si cache_arg;
262 1.2 alnsn sljit_sw cache_argw;
263 1.1 alnsn #endif
264 1.1 alnsn
265 1.1 alnsn #if (defined SLJIT_CONFIG_ARM_THUMB2 && SLJIT_CONFIG_ARM_THUMB2)
266 1.2 alnsn sljit_si cache_arg;
267 1.2 alnsn sljit_sw cache_argw;
268 1.2 alnsn #endif
269 1.2 alnsn
270 1.2 alnsn #if (defined SLJIT_CONFIG_ARM_64 && SLJIT_CONFIG_ARM_64)
271 1.2 alnsn sljit_si locals_offset;
272 1.2 alnsn sljit_si cache_arg;
273 1.2 alnsn sljit_sw cache_argw;
274 1.1 alnsn #endif
275 1.1 alnsn
276 1.1 alnsn #if (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32) || (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
277 1.2 alnsn sljit_sw imm;
278 1.2 alnsn sljit_si cache_arg;
279 1.2 alnsn sljit_sw cache_argw;
280 1.2 alnsn #endif
281 1.2 alnsn
282 1.2 alnsn #if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32) || (defined SLJIT_CONFIG_MIPS_64 && SLJIT_CONFIG_MIPS_64)
283 1.2 alnsn sljit_si delay_slot;
284 1.2 alnsn sljit_si cache_arg;
285 1.2 alnsn sljit_sw cache_argw;
286 1.2 alnsn #endif
287 1.2 alnsn
288 1.2 alnsn #if (defined SLJIT_CONFIG_SPARC_32 && SLJIT_CONFIG_SPARC_32)
289 1.2 alnsn sljit_si delay_slot;
290 1.2 alnsn sljit_si cache_arg;
291 1.2 alnsn sljit_sw cache_argw;
292 1.1 alnsn #endif
293 1.1 alnsn
294 1.2 alnsn #if (defined SLJIT_CONFIG_TILEGX && SLJIT_CONFIG_TILEGX)
295 1.2 alnsn sljit_si cache_arg;
296 1.2 alnsn sljit_sw cache_argw;
297 1.1 alnsn #endif
298 1.1 alnsn
299 1.1 alnsn #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
300 1.1 alnsn FILE* verbose;
301 1.1 alnsn #endif
302 1.1 alnsn
303 1.1 alnsn #if (defined SLJIT_DEBUG && SLJIT_DEBUG)
304 1.1 alnsn /* Local size passed to the functions. */
305 1.2 alnsn sljit_si logical_local_size;
306 1.1 alnsn #endif
307 1.1 alnsn
308 1.1 alnsn #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) || (defined SLJIT_DEBUG && SLJIT_DEBUG)
309 1.2 alnsn sljit_si skip_checks;
310 1.1 alnsn #endif
311 1.1 alnsn };
312 1.1 alnsn
313 1.1 alnsn /* --------------------------------------------------------------------- */
314 1.1 alnsn /* Main functions */
315 1.1 alnsn /* --------------------------------------------------------------------- */
316 1.1 alnsn
317 1.1 alnsn /* Creates an sljit compiler.
318 1.1 alnsn Returns NULL if failed. */
319 1.1 alnsn SLJIT_API_FUNC_ATTRIBUTE struct sljit_compiler* sljit_create_compiler(void);
320 1.2 alnsn
321 1.2 alnsn /* Free everything except the compiled machine code. */
322 1.1 alnsn SLJIT_API_FUNC_ATTRIBUTE void sljit_free_compiler(struct sljit_compiler *compiler);
323 1.1 alnsn
324 1.2 alnsn /* Returns the current error code. If an error is occurred, future sljit
325 1.2 alnsn calls which uses the same compiler argument returns early with the same
326 1.2 alnsn error code. Thus there is no need for checking the error after every
327 1.2 alnsn call, it is enough to do it before the code is compiled. Removing
328 1.2 alnsn these checks increases the performance of the compiling process. */
329 1.2 alnsn static SLJIT_INLINE sljit_si sljit_get_compiler_error(struct sljit_compiler *compiler) { return compiler->error; }
330 1.1 alnsn
331 1.1 alnsn /*
332 1.1 alnsn Allocate a small amount of memory. The size must be <= 64 bytes on 32 bit,
333 1.2 alnsn and <= 128 bytes on 64 bit architectures. The memory area is owned by the
334 1.2 alnsn compiler, and freed by sljit_free_compiler. The returned pointer is
335 1.2 alnsn sizeof(sljit_sw) aligned. Excellent for allocating small blocks during
336 1.2 alnsn the compiling, and no need to worry about freeing them. The size is
337 1.2 alnsn enough to contain at most 16 pointers. If the size is outside of the range,
338 1.2 alnsn the function will return with NULL. However, this return value does not
339 1.2 alnsn indicate that there is no more memory (does not set the current error code
340 1.2 alnsn of the compiler to out-of-memory status).
341 1.1 alnsn */
342 1.2 alnsn SLJIT_API_FUNC_ATTRIBUTE void* sljit_alloc_memory(struct sljit_compiler *compiler, sljit_si size);
343 1.1 alnsn
344 1.1 alnsn #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
345 1.1 alnsn /* Passing NULL disables verbose. */
346 1.1 alnsn SLJIT_API_FUNC_ATTRIBUTE void sljit_compiler_verbose(struct sljit_compiler *compiler, FILE* verbose);
347 1.1 alnsn #endif
348 1.1 alnsn
349 1.1 alnsn SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compiler);
350 1.1 alnsn SLJIT_API_FUNC_ATTRIBUTE void sljit_free_code(void* code);
351 1.1 alnsn
352 1.1 alnsn /*
353 1.2 alnsn After the machine code generation is finished we can retrieve the allocated
354 1.2 alnsn executable memory size, although this area may not be fully filled with
355 1.2 alnsn instructions depending on some optimizations. This function is useful only
356 1.2 alnsn for statistical purposes.
357 1.1 alnsn
358 1.1 alnsn Before a successful code generation, this function returns with 0.
359 1.1 alnsn */
360 1.1 alnsn static SLJIT_INLINE sljit_uw sljit_get_generated_code_size(struct sljit_compiler *compiler) { return compiler->executable_size; }
361 1.1 alnsn
362 1.2 alnsn /* Instruction generation. Returns with any error code. If there is no
363 1.2 alnsn error, they return with SLJIT_SUCCESS. */
364 1.1 alnsn
365 1.1 alnsn /*
366 1.1 alnsn The executable code is basically a function call from the viewpoint of
367 1.1 alnsn the C language. The function calls must obey to the ABI (Application
368 1.1 alnsn Binary Interface) of the platform, which specify the purpose of machine
369 1.1 alnsn registers and stack handling among other things. The sljit_emit_enter
370 1.1 alnsn function emits the necessary instructions for setting up a new context
371 1.1 alnsn for the executable code and moves function arguments to the saved
372 1.1 alnsn registers. The number of arguments are specified in the "args"
373 1.1 alnsn parameter and the first argument goes to SLJIT_SAVED_REG1, the second
374 1.2 alnsn goes to SLJIT_SAVED_REG2 and so on. The number of scratch and
375 1.2 alnsn saved registers are passed in "scratches" and "saveds" arguments
376 1.1 alnsn respectively. Since the saved registers contains the arguments,
377 1.1 alnsn "args" must be less or equal than "saveds". The sljit_emit_enter
378 1.1 alnsn is also capable of allocating a stack space for local variables. The
379 1.1 alnsn "local_size" argument contains the size in bytes of this local area
380 1.1 alnsn and its staring address is stored in SLJIT_LOCALS_REG. However
381 1.1 alnsn the SLJIT_LOCALS_REG is not necessary the machine stack pointer.
382 1.1 alnsn The memory bytes between SLJIT_LOCALS_REG (inclusive) and
383 1.1 alnsn SLJIT_LOCALS_REG + local_size (exclusive) can be modified freely
384 1.1 alnsn until the function returns. The stack space is uninitialized.
385 1.1 alnsn
386 1.2 alnsn Note: every call of sljit_emit_enter and sljit_set_context
387 1.2 alnsn overwrites the previous context. */
388 1.1 alnsn
389 1.1 alnsn #define SLJIT_MAX_LOCAL_SIZE 65536
390 1.1 alnsn
391 1.2 alnsn SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_enter(struct sljit_compiler *compiler,
392 1.2 alnsn sljit_si args, sljit_si scratches, sljit_si saveds, sljit_si local_size);
393 1.1 alnsn
394 1.1 alnsn /* The machine code has a context (which contains the local stack space size,
395 1.1 alnsn number of used registers, etc.) which initialized by sljit_emit_enter. Several
396 1.1 alnsn functions (like sljit_emit_return) requres this context to be able to generate
397 1.1 alnsn the appropriate code. However, some code fragments (like inline cache) may have
398 1.1 alnsn no normal entry point so their context is unknown for the compiler. Using the
399 1.2 alnsn function below we can specify their context.
400 1.1 alnsn
401 1.1 alnsn Note: every call of sljit_emit_enter and sljit_set_context overwrites
402 1.1 alnsn the previous context. */
403 1.1 alnsn
404 1.1 alnsn SLJIT_API_FUNC_ATTRIBUTE void sljit_set_context(struct sljit_compiler *compiler,
405 1.2 alnsn sljit_si args, sljit_si scratches, sljit_si saveds, sljit_si local_size);
406 1.1 alnsn
407 1.1 alnsn /* Return from machine code. The op argument can be SLJIT_UNUSED which means the
408 1.1 alnsn function does not return with anything or any opcode between SLJIT_MOV and
409 1.2 alnsn SLJIT_MOV_P (see sljit_emit_op1). As for src and srcw they must be 0 if op
410 1.1 alnsn is SLJIT_UNUSED, otherwise see below the description about source and
411 1.1 alnsn destination arguments. */
412 1.1 alnsn
413 1.2 alnsn SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_return(struct sljit_compiler *compiler, sljit_si op,
414 1.2 alnsn sljit_si src, sljit_sw srcw);
415 1.2 alnsn
416 1.2 alnsn /* Fast calling mechanism for utility functions (see SLJIT_FAST_CALL). All registers and
417 1.2 alnsn even the stack frame is passed to the callee. The return address is preserved in
418 1.2 alnsn dst/dstw by sljit_emit_fast_enter (the type of the value stored by this function
419 1.2 alnsn is sljit_p), and sljit_emit_fast_return can use this as a return value later. */
420 1.2 alnsn
421 1.2 alnsn /* Note: only for sljit specific, non ABI compilant calls. Fast, since only a few machine
422 1.2 alnsn instructions are needed. Excellent for small uility functions, where saving registers
423 1.2 alnsn and setting up a new stack frame would cost too much performance. However, it is still
424 1.2 alnsn possible to return to the address of the caller (or anywhere else). */
425 1.1 alnsn
426 1.1 alnsn /* Note: flags are not changed (unlike sljit_emit_enter / sljit_emit_return). */
427 1.1 alnsn
428 1.1 alnsn /* Note: although sljit_emit_fast_return could be replaced by an ijump, it is not suggested,
429 1.1 alnsn since many architectures do clever branch prediction on call / return instruction pairs. */
430 1.1 alnsn
431 1.2 alnsn SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fast_enter(struct sljit_compiler *compiler, sljit_si dst, sljit_sw dstw);
432 1.2 alnsn SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fast_return(struct sljit_compiler *compiler, sljit_si src, sljit_sw srcw);
433 1.1 alnsn
434 1.1 alnsn /*
435 1.1 alnsn Source and destination values for arithmetical instructions
436 1.1 alnsn imm - a simple immediate value (cannot be used as a destination)
437 1.1 alnsn reg - any of the registers (immediate argument must be 0)
438 1.1 alnsn [imm] - absolute immediate memory address
439 1.1 alnsn [reg+imm] - indirect memory address
440 1.1 alnsn [reg+(reg<<imm)] - indirect indexed memory address (shift must be between 0 and 3)
441 1.2 alnsn useful for (byte, half, int, sljit_sw) array access
442 1.1 alnsn (fully supported by both x86 and ARM architectures, and cheap operation on others)
443 1.1 alnsn */
444 1.1 alnsn
445 1.1 alnsn /*
446 1.1 alnsn IMPORATNT NOTE: memory access MUST be naturally aligned except
447 1.1 alnsn SLJIT_UNALIGNED macro is defined and its value is 1.
448 1.1 alnsn
449 1.1 alnsn length | alignment
450 1.1 alnsn ---------+-----------
451 1.2 alnsn byte | 1 byte (any physical_address is accepted)
452 1.2 alnsn half | 2 byte (physical_address & 0x1 == 0)
453 1.2 alnsn int | 4 byte (physical_address & 0x3 == 0)
454 1.2 alnsn word | 4 byte if SLJIT_32BIT_ARCHITECTURE is defined and its value is 1
455 1.1 alnsn | 8 byte if SLJIT_64BIT_ARCHITECTURE is defined and its value is 1
456 1.2 alnsn pointer | size of sljit_p type (4 byte on 32 bit machines, 4 or 8 byte
457 1.2 alnsn | on 64 bit machines)
458 1.1 alnsn
459 1.2 alnsn Note: Different architectures have different addressing limitations.
460 1.2 alnsn A single instruction is enough for the following addressing
461 1.2 alnsn modes. Other adrressing modes are emulated by instruction
462 1.2 alnsn sequences. This information could help to improve those code
463 1.2 alnsn generators which focuses only a few architectures.
464 1.2 alnsn
465 1.2 alnsn x86: [reg+imm], -2^32+1 <= imm <= 2^32-1 (full address space on x86-32)
466 1.2 alnsn [reg+(reg<<imm)] is supported
467 1.2 alnsn [imm], -2^32+1 <= imm <= 2^32-1 is supported
468 1.2 alnsn Write-back is not supported
469 1.2 alnsn arm: [reg+imm], -4095 <= imm <= 4095 or -255 <= imm <= 255 for signed
470 1.2 alnsn bytes, any halfs or floating point values)
471 1.2 alnsn [reg+(reg<<imm)] is supported
472 1.2 alnsn Write-back is supported
473 1.2 alnsn arm-t2: [reg+imm], -255 <= imm <= 4095
474 1.2 alnsn [reg+(reg<<imm)] is supported
475 1.2 alnsn Write back is supported only for [reg+imm], where -255 <= imm <= 255
476 1.2 alnsn ppc: [reg+imm], -65536 <= imm <= 65535. 64 bit loads/stores and 32 bit
477 1.2 alnsn signed load on 64 bit requires immediates divisible by 4.
478 1.2 alnsn [reg+imm] is not supported for signed 8 bit values.
479 1.2 alnsn [reg+reg] is supported
480 1.2 alnsn Write-back is supported except for one instruction: 32 bit signed
481 1.2 alnsn load with [reg+imm] addressing mode on 64 bit.
482 1.2 alnsn mips: [reg+imm], -65536 <= imm <= 65535
483 1.2 alnsn sparc: [reg+imm], -4096 <= imm <= 4095
484 1.2 alnsn [reg+reg] is supported
485 1.1 alnsn */
486 1.1 alnsn
487 1.1 alnsn /* Register output: simply the name of the register.
488 1.1 alnsn For destination, you can use SLJIT_UNUSED as well. */
489 1.2 alnsn #define SLJIT_MEM 0x80
490 1.1 alnsn #define SLJIT_MEM0() (SLJIT_MEM)
491 1.1 alnsn #define SLJIT_MEM1(r1) (SLJIT_MEM | (r1))
492 1.2 alnsn #define SLJIT_MEM2(r1, r2) (SLJIT_MEM | (r1) | ((r2) << 8))
493 1.2 alnsn #define SLJIT_IMM 0x40
494 1.1 alnsn
495 1.1 alnsn /* Set 32 bit operation mode (I) on 64 bit CPUs. The flag is totally ignored on
496 1.2 alnsn 32 bit CPUs. If this flag is set for an arithmetic operation, it uses only the
497 1.2 alnsn lower 32 bit of the input register(s), and set the CPU status flags according
498 1.2 alnsn to the 32 bit result. The higher 32 bits are undefined for both the input and
499 1.2 alnsn output. However, the CPU might not ignore those higher 32 bits, like MIPS, which
500 1.2 alnsn expects it to be the sign extension of the lower 32 bit. All 32 bit operations
501 1.2 alnsn are undefined, if this condition is not fulfilled. Therefore, when SLJIT_INT_OP
502 1.2 alnsn is specified, all register arguments must be the result of other operations with
503 1.2 alnsn the same SLJIT_INT_OP flag. In other words, although a register can hold either
504 1.2 alnsn a 64 or 32 bit value, these values cannot be mixed. The only exceptions are
505 1.2 alnsn SLJIT_IMOV and SLJIT_IMOVU (SLJIT_MOV_SI/SLJIT_MOVU_SI with SLJIT_INT_OP flag)
506 1.2 alnsn which can convert any source argument to SLJIT_INT_OP compatible result. This
507 1.2 alnsn conversion might be unnecessary on some CPUs like x86-64, since the upper 32
508 1.2 alnsn bit is always ignored. In this case SLJIT is clever enough to not generate any
509 1.2 alnsn instructions if the source and destination operands are the same registers.
510 1.2 alnsn Affects sljit_emit_op0, sljit_emit_op1 and sljit_emit_op2. */
511 1.1 alnsn #define SLJIT_INT_OP 0x100
512 1.1 alnsn
513 1.2 alnsn /* Single precision mode (SP). This flag is similar to SLJIT_INT_OP, just
514 1.2 alnsn it applies to floating point registers (it is even the same bit). When
515 1.2 alnsn this flag is passed, the CPU performs single precision floating point
516 1.2 alnsn operations. Similar to SLJIT_INT_OP, all register arguments must be the
517 1.2 alnsn result of other floating point operations with this flag. Affects
518 1.2 alnsn sljit_emit_fop1, sljit_emit_fop2 and sljit_emit_fcmp. */
519 1.2 alnsn #define SLJIT_SINGLE_OP 0x100
520 1.2 alnsn
521 1.1 alnsn /* Common CPU status flags for all architectures (x86, ARM, PPC)
522 1.1 alnsn - carry flag
523 1.1 alnsn - overflow flag
524 1.1 alnsn - zero flag
525 1.1 alnsn - negative/positive flag (depends on arc)
526 1.1 alnsn On mips, these flags are emulated by software. */
527 1.1 alnsn
528 1.1 alnsn /* By default, the instructions may, or may not set the CPU status flags.
529 1.1 alnsn Forcing to set or keep status flags can be done with the following flags: */
530 1.1 alnsn
531 1.1 alnsn /* Note: sljit tries to emit the minimum number of instructions. Using these
532 1.1 alnsn flags can increase them, so use them wisely to avoid unnecessary code generation. */
533 1.1 alnsn
534 1.1 alnsn /* Set Equal (Zero) status flag (E). */
535 1.1 alnsn #define SLJIT_SET_E 0x0200
536 1.2 alnsn /* Set unsigned status flag (U). */
537 1.2 alnsn #define SLJIT_SET_U 0x0400
538 1.1 alnsn /* Set signed status flag (S). */
539 1.2 alnsn #define SLJIT_SET_S 0x0800
540 1.1 alnsn /* Set signed overflow flag (O). */
541 1.1 alnsn #define SLJIT_SET_O 0x1000
542 1.1 alnsn /* Set carry flag (C).
543 1.1 alnsn Note: Kinda unsigned overflow, but behaves differently on various cpus. */
544 1.1 alnsn #define SLJIT_SET_C 0x2000
545 1.1 alnsn /* Do not modify the flags (K).
546 1.1 alnsn Note: This flag cannot be combined with any other SLJIT_SET_* flag. */
547 1.1 alnsn #define SLJIT_KEEP_FLAGS 0x4000
548 1.1 alnsn
549 1.1 alnsn /* Notes:
550 1.1 alnsn - you cannot postpone conditional jump instructions except if noted that
551 1.1 alnsn the instruction does not set flags (See: SLJIT_KEEP_FLAGS).
552 1.1 alnsn - flag combinations: '|' means 'logical or'. */
553 1.1 alnsn
554 1.1 alnsn /* Flags: - (never set any flags)
555 1.1 alnsn Note: breakpoint instruction is not supported by all architectures (namely ppc)
556 1.1 alnsn It falls back to SLJIT_NOP in those cases. */
557 1.1 alnsn #define SLJIT_BREAKPOINT 0
558 1.1 alnsn /* Flags: - (never set any flags)
559 1.1 alnsn Note: may or may not cause an extra cycle wait
560 1.1 alnsn it can even decrease the runtime in a few cases. */
561 1.1 alnsn #define SLJIT_NOP 1
562 1.2 alnsn /* Flags: - (may destroy flags)
563 1.2 alnsn Unsigned multiplication of SLJIT_SCRATCH_REG1 and SLJIT_SCRATCH_REG2.
564 1.2 alnsn Result goes to SLJIT_SCRATCH_REG2:SLJIT_SCRATCH_REG1 (high:low) word */
565 1.1 alnsn #define SLJIT_UMUL 2
566 1.2 alnsn /* Flags: - (may destroy flags)
567 1.2 alnsn Signed multiplication of SLJIT_SCRATCH_REG1 and SLJIT_SCRATCH_REG2.
568 1.2 alnsn Result goes to SLJIT_SCRATCH_REG2:SLJIT_SCRATCH_REG1 (high:low) word */
569 1.1 alnsn #define SLJIT_SMUL 3
570 1.2 alnsn /* Flags: I - (may destroy flags)
571 1.2 alnsn Unsigned divide of the value in SLJIT_SCRATCH_REG1 by the value in SLJIT_SCRATCH_REG2.
572 1.2 alnsn The result is placed in SLJIT_SCRATCH_REG1 and the remainder goes to SLJIT_SCRATCH_REG2.
573 1.2 alnsn Note: if SLJIT_SCRATCH_REG2 contains 0, the behaviour is undefined. */
574 1.1 alnsn #define SLJIT_UDIV 4
575 1.2 alnsn #define SLJIT_IUDIV (SLJIT_UDIV | SLJIT_INT_OP)
576 1.2 alnsn /* Flags: I - (may destroy flags)
577 1.2 alnsn Signed divide of the value in SLJIT_SCRATCH_REG1 by the value in SLJIT_SCRATCH_REG2.
578 1.2 alnsn The result is placed in SLJIT_SCRATCH_REG1 and the remainder goes to SLJIT_SCRATCH_REG2.
579 1.2 alnsn Note: if SLJIT_SCRATCH_REG2 contains 0, the behaviour is undefined. */
580 1.1 alnsn #define SLJIT_SDIV 5
581 1.2 alnsn #define SLJIT_ISDIV (SLJIT_SDIV | SLJIT_INT_OP)
582 1.1 alnsn
583 1.2 alnsn SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op0(struct sljit_compiler *compiler, sljit_si op);
584 1.1 alnsn
585 1.1 alnsn /* Notes for MOV instructions:
586 1.2 alnsn U = Mov with update (pre form). If source or destination defined as SLJIT_MEM1(r1)
587 1.1 alnsn or SLJIT_MEM2(r1, r2), r1 is increased by the sum of r2 and the constant argument
588 1.1 alnsn UB = unsigned byte (8 bit)
589 1.1 alnsn SB = signed byte (8 bit)
590 1.2 alnsn UH = unsigned half (16 bit)
591 1.2 alnsn SH = signed half (16 bit)
592 1.2 alnsn UI = unsigned int (32 bit)
593 1.2 alnsn SI = signed int (32 bit)
594 1.2 alnsn P = pointer (sljit_p) size */
595 1.1 alnsn
596 1.1 alnsn /* Flags: - (never set any flags) */
597 1.1 alnsn #define SLJIT_MOV 6
598 1.2 alnsn /* Flags: I - (never set any flags) */
599 1.1 alnsn #define SLJIT_MOV_UB 7
600 1.2 alnsn #define SLJIT_IMOV_UB (SLJIT_MOV_UB | SLJIT_INT_OP)
601 1.2 alnsn /* Flags: I - (never set any flags) */
602 1.1 alnsn #define SLJIT_MOV_SB 8
603 1.2 alnsn #define SLJIT_IMOV_SB (SLJIT_MOV_SB | SLJIT_INT_OP)
604 1.2 alnsn /* Flags: I - (never set any flags) */
605 1.1 alnsn #define SLJIT_MOV_UH 9
606 1.2 alnsn #define SLJIT_IMOV_UH (SLJIT_MOV_UH | SLJIT_INT_OP)
607 1.2 alnsn /* Flags: I - (never set any flags) */
608 1.1 alnsn #define SLJIT_MOV_SH 10
609 1.2 alnsn #define SLJIT_IMOV_SH (SLJIT_MOV_SH | SLJIT_INT_OP)
610 1.2 alnsn /* Flags: I - (never set any flags)
611 1.2 alnsn Note: see SLJIT_INT_OP for further details. */
612 1.1 alnsn #define SLJIT_MOV_UI 11
613 1.2 alnsn /* No SLJIT_INT_OP form, since it is the same as SLJIT_IMOV. */
614 1.2 alnsn /* Flags: I - (never set any flags)
615 1.2 alnsn Note: see SLJIT_INT_OP for further details. */
616 1.1 alnsn #define SLJIT_MOV_SI 12
617 1.2 alnsn #define SLJIT_IMOV (SLJIT_MOV_SI | SLJIT_INT_OP)
618 1.1 alnsn /* Flags: - (never set any flags) */
619 1.2 alnsn #define SLJIT_MOV_P 13
620 1.1 alnsn /* Flags: - (never set any flags) */
621 1.2 alnsn #define SLJIT_MOVU 14
622 1.2 alnsn /* Flags: I - (never set any flags) */
623 1.2 alnsn #define SLJIT_MOVU_UB 15
624 1.2 alnsn #define SLJIT_IMOVU_UB (SLJIT_MOVU_UB | SLJIT_INT_OP)
625 1.2 alnsn /* Flags: I - (never set any flags) */
626 1.2 alnsn #define SLJIT_MOVU_SB 16
627 1.2 alnsn #define SLJIT_IMOVU_SB (SLJIT_MOVU_SB | SLJIT_INT_OP)
628 1.2 alnsn /* Flags: I - (never set any flags) */
629 1.2 alnsn #define SLJIT_MOVU_UH 17
630 1.2 alnsn #define SLJIT_IMOVU_UH (SLJIT_MOVU_UH | SLJIT_INT_OP)
631 1.2 alnsn /* Flags: I - (never set any flags) */
632 1.2 alnsn #define SLJIT_MOVU_SH 18
633 1.2 alnsn #define SLJIT_IMOVU_SH (SLJIT_MOVU_SH | SLJIT_INT_OP)
634 1.2 alnsn /* Flags: I - (never set any flags)
635 1.2 alnsn Note: see SLJIT_INT_OP for further details. */
636 1.2 alnsn #define SLJIT_MOVU_UI 19
637 1.2 alnsn /* No SLJIT_INT_OP form, since it is the same as SLJIT_IMOVU. */
638 1.2 alnsn /* Flags: I - (never set any flags)
639 1.2 alnsn Note: see SLJIT_INT_OP for further details. */
640 1.2 alnsn #define SLJIT_MOVU_SI 20
641 1.2 alnsn #define SLJIT_IMOVU (SLJIT_MOVU_SI | SLJIT_INT_OP)
642 1.1 alnsn /* Flags: - (never set any flags) */
643 1.2 alnsn #define SLJIT_MOVU_P 21
644 1.1 alnsn /* Flags: I | E | K */
645 1.2 alnsn #define SLJIT_NOT 22
646 1.2 alnsn #define SLJIT_INOT (SLJIT_NOT | SLJIT_INT_OP)
647 1.1 alnsn /* Flags: I | E | O | K */
648 1.2 alnsn #define SLJIT_NEG 23
649 1.2 alnsn #define SLJIT_INEG (SLJIT_NEG | SLJIT_INT_OP)
650 1.1 alnsn /* Count leading zeroes
651 1.2 alnsn Flags: I | E | K
652 1.2 alnsn Important note! Sparc 32 does not support K flag, since
653 1.2 alnsn the required popc instruction is introduced only in sparc 64. */
654 1.2 alnsn #define SLJIT_CLZ 24
655 1.2 alnsn #define SLJIT_ICLZ (SLJIT_CLZ | SLJIT_INT_OP)
656 1.2 alnsn
657 1.2 alnsn SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op1(struct sljit_compiler *compiler, sljit_si op,
658 1.2 alnsn sljit_si dst, sljit_sw dstw,
659 1.2 alnsn sljit_si src, sljit_sw srcw);
660 1.1 alnsn
661 1.1 alnsn /* Flags: I | E | O | C | K */
662 1.2 alnsn #define SLJIT_ADD 25
663 1.2 alnsn #define SLJIT_IADD (SLJIT_ADD | SLJIT_INT_OP)
664 1.1 alnsn /* Flags: I | C | K */
665 1.2 alnsn #define SLJIT_ADDC 26
666 1.2 alnsn #define SLJIT_IADDC (SLJIT_ADDC | SLJIT_INT_OP)
667 1.2 alnsn /* Flags: I | E | U | S | O | C | K */
668 1.2 alnsn #define SLJIT_SUB 27
669 1.2 alnsn #define SLJIT_ISUB (SLJIT_SUB | SLJIT_INT_OP)
670 1.1 alnsn /* Flags: I | C | K */
671 1.2 alnsn #define SLJIT_SUBC 28
672 1.2 alnsn #define SLJIT_ISUBC (SLJIT_SUBC | SLJIT_INT_OP)
673 1.1 alnsn /* Note: integer mul
674 1.1 alnsn Flags: I | O (see SLJIT_C_MUL_*) | K */
675 1.2 alnsn #define SLJIT_MUL 29
676 1.2 alnsn #define SLJIT_IMUL (SLJIT_MUL | SLJIT_INT_OP)
677 1.1 alnsn /* Flags: I | E | K */
678 1.2 alnsn #define SLJIT_AND 30
679 1.2 alnsn #define SLJIT_IAND (SLJIT_AND | SLJIT_INT_OP)
680 1.1 alnsn /* Flags: I | E | K */
681 1.2 alnsn #define SLJIT_OR 31
682 1.2 alnsn #define SLJIT_IOR (SLJIT_OR | SLJIT_INT_OP)
683 1.1 alnsn /* Flags: I | E | K */
684 1.2 alnsn #define SLJIT_XOR 32
685 1.2 alnsn #define SLJIT_IXOR (SLJIT_XOR | SLJIT_INT_OP)
686 1.1 alnsn /* Flags: I | E | K
687 1.1 alnsn Let bit_length be the length of the shift operation: 32 or 64.
688 1.1 alnsn If src2 is immediate, src2w is masked by (bit_length - 1).
689 1.1 alnsn Otherwise, if the content of src2 is outside the range from 0
690 1.1 alnsn to bit_length - 1, the operation is undefined. */
691 1.2 alnsn #define SLJIT_SHL 33
692 1.2 alnsn #define SLJIT_ISHL (SLJIT_SHL | SLJIT_INT_OP)
693 1.1 alnsn /* Flags: I | E | K
694 1.1 alnsn Let bit_length be the length of the shift operation: 32 or 64.
695 1.1 alnsn If src2 is immediate, src2w is masked by (bit_length - 1).
696 1.1 alnsn Otherwise, if the content of src2 is outside the range from 0
697 1.1 alnsn to bit_length - 1, the operation is undefined. */
698 1.2 alnsn #define SLJIT_LSHR 34
699 1.2 alnsn #define SLJIT_ILSHR (SLJIT_LSHR | SLJIT_INT_OP)
700 1.1 alnsn /* Flags: I | E | K
701 1.1 alnsn Let bit_length be the length of the shift operation: 32 or 64.
702 1.1 alnsn If src2 is immediate, src2w is masked by (bit_length - 1).
703 1.1 alnsn Otherwise, if the content of src2 is outside the range from 0
704 1.1 alnsn to bit_length - 1, the operation is undefined. */
705 1.2 alnsn #define SLJIT_ASHR 35
706 1.2 alnsn #define SLJIT_IASHR (SLJIT_ASHR | SLJIT_INT_OP)
707 1.1 alnsn
708 1.2 alnsn SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op2(struct sljit_compiler *compiler, sljit_si op,
709 1.2 alnsn sljit_si dst, sljit_sw dstw,
710 1.2 alnsn sljit_si src1, sljit_sw src1w,
711 1.2 alnsn sljit_si src2, sljit_sw src2w);
712 1.1 alnsn
713 1.1 alnsn /* The following function is a helper function for sljit_emit_op_custom.
714 1.2 alnsn It returns with the real machine register index of any SLJIT_SCRATCH
715 1.1 alnsn SLJIT_SAVED or SLJIT_LOCALS register.
716 1.2 alnsn Note: it returns with -1 for virtual registers (all EREGs on x86-32). */
717 1.1 alnsn
718 1.2 alnsn SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_get_register_index(sljit_si reg);
719 1.2 alnsn
720 1.2 alnsn /* The following function is a helper function for sljit_emit_op_custom.
721 1.2 alnsn It returns with the real machine register index of any SLJIT_FLOAT register.
722 1.2 alnsn Note: the index is divided by 2 on ARM 32 bit architectures. */
723 1.2 alnsn
724 1.2 alnsn SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_get_float_register_index(sljit_si reg);
725 1.1 alnsn
726 1.1 alnsn /* Any instruction can be inserted into the instruction stream by
727 1.1 alnsn sljit_emit_op_custom. It has a similar purpose as inline assembly.
728 1.1 alnsn The size parameter must match to the instruction size of the target
729 1.1 alnsn architecture:
730 1.1 alnsn
731 1.1 alnsn x86: 0 < size <= 15. The instruction argument can be byte aligned.
732 1.1 alnsn Thumb2: if size == 2, the instruction argument must be 2 byte aligned.
733 1.1 alnsn if size == 4, the instruction argument must be 4 byte aligned.
734 1.1 alnsn Otherwise: size must be 4 and instruction argument must be 4 byte aligned. */
735 1.1 alnsn
736 1.2 alnsn SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op_custom(struct sljit_compiler *compiler,
737 1.2 alnsn void *instruction, sljit_si size);
738 1.1 alnsn
739 1.1 alnsn /* Returns with non-zero if fpu is available. */
740 1.1 alnsn
741 1.2 alnsn SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_is_fpu_available(void);
742 1.1 alnsn
743 1.1 alnsn /* Note: dst is the left and src is the right operand for SLJIT_FCMP.
744 1.2 alnsn Note: NaN check is always performed. If SLJIT_C_FLOAT_UNORDERED is set,
745 1.1 alnsn the comparison result is unpredictable.
746 1.2 alnsn Flags: SP | E | S (see SLJIT_C_FLOAT_*) */
747 1.2 alnsn #define SLJIT_CMPD 36
748 1.2 alnsn #define SLJIT_CMPS (SLJIT_CMPD | SLJIT_SINGLE_OP)
749 1.2 alnsn /* Flags: SP - (never set any flags) */
750 1.2 alnsn #define SLJIT_MOVD 37
751 1.2 alnsn #define SLJIT_MOVS (SLJIT_MOVD | SLJIT_SINGLE_OP)
752 1.2 alnsn /* Flags: SP - (never set any flags) */
753 1.2 alnsn #define SLJIT_NEGD 38
754 1.2 alnsn #define SLJIT_NEGS (SLJIT_NEGD | SLJIT_SINGLE_OP)
755 1.2 alnsn /* Flags: SP - (never set any flags) */
756 1.2 alnsn #define SLJIT_ABSD 39
757 1.2 alnsn #define SLJIT_ABSS (SLJIT_ABSD | SLJIT_SINGLE_OP)
758 1.2 alnsn
759 1.2 alnsn SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fop1(struct sljit_compiler *compiler, sljit_si op,
760 1.2 alnsn sljit_si dst, sljit_sw dstw,
761 1.2 alnsn sljit_si src, sljit_sw srcw);
762 1.2 alnsn
763 1.2 alnsn /* Flags: SP - (never set any flags) */
764 1.2 alnsn #define SLJIT_ADDD 40
765 1.2 alnsn #define SLJIT_ADDS (SLJIT_ADDD | SLJIT_SINGLE_OP)
766 1.2 alnsn /* Flags: SP - (never set any flags) */
767 1.2 alnsn #define SLJIT_SUBD 41
768 1.2 alnsn #define SLJIT_SUBS (SLJIT_SUBD | SLJIT_SINGLE_OP)
769 1.2 alnsn /* Flags: SP - (never set any flags) */
770 1.2 alnsn #define SLJIT_MULD 42
771 1.2 alnsn #define SLJIT_MULS (SLJIT_MULD | SLJIT_SINGLE_OP)
772 1.2 alnsn /* Flags: SP - (never set any flags) */
773 1.2 alnsn #define SLJIT_DIVD 43
774 1.2 alnsn #define SLJIT_DIVS (SLJIT_DIVD | SLJIT_SINGLE_OP)
775 1.2 alnsn
776 1.2 alnsn SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fop2(struct sljit_compiler *compiler, sljit_si op,
777 1.2 alnsn sljit_si dst, sljit_sw dstw,
778 1.2 alnsn sljit_si src1, sljit_sw src1w,
779 1.2 alnsn sljit_si src2, sljit_sw src2w);
780 1.1 alnsn
781 1.1 alnsn /* Label and jump instructions. */
782 1.1 alnsn
783 1.1 alnsn SLJIT_API_FUNC_ATTRIBUTE struct sljit_label* sljit_emit_label(struct sljit_compiler *compiler);
784 1.1 alnsn
785 1.1 alnsn /* Invert conditional instruction: xor (^) with 0x1 */
786 1.1 alnsn #define SLJIT_C_EQUAL 0
787 1.1 alnsn #define SLJIT_C_ZERO 0
788 1.1 alnsn #define SLJIT_C_NOT_EQUAL 1
789 1.1 alnsn #define SLJIT_C_NOT_ZERO 1
790 1.1 alnsn
791 1.1 alnsn #define SLJIT_C_LESS 2
792 1.1 alnsn #define SLJIT_C_GREATER_EQUAL 3
793 1.1 alnsn #define SLJIT_C_GREATER 4
794 1.1 alnsn #define SLJIT_C_LESS_EQUAL 5
795 1.1 alnsn #define SLJIT_C_SIG_LESS 6
796 1.1 alnsn #define SLJIT_C_SIG_GREATER_EQUAL 7
797 1.1 alnsn #define SLJIT_C_SIG_GREATER 8
798 1.1 alnsn #define SLJIT_C_SIG_LESS_EQUAL 9
799 1.1 alnsn
800 1.1 alnsn #define SLJIT_C_OVERFLOW 10
801 1.1 alnsn #define SLJIT_C_NOT_OVERFLOW 11
802 1.1 alnsn
803 1.1 alnsn #define SLJIT_C_MUL_OVERFLOW 12
804 1.1 alnsn #define SLJIT_C_MUL_NOT_OVERFLOW 13
805 1.1 alnsn
806 1.1 alnsn #define SLJIT_C_FLOAT_EQUAL 14
807 1.1 alnsn #define SLJIT_C_FLOAT_NOT_EQUAL 15
808 1.1 alnsn #define SLJIT_C_FLOAT_LESS 16
809 1.1 alnsn #define SLJIT_C_FLOAT_GREATER_EQUAL 17
810 1.1 alnsn #define SLJIT_C_FLOAT_GREATER 18
811 1.1 alnsn #define SLJIT_C_FLOAT_LESS_EQUAL 19
812 1.2 alnsn #define SLJIT_C_FLOAT_UNORDERED 20
813 1.2 alnsn #define SLJIT_C_FLOAT_ORDERED 21
814 1.1 alnsn
815 1.1 alnsn #define SLJIT_JUMP 22
816 1.1 alnsn #define SLJIT_FAST_CALL 23
817 1.1 alnsn #define SLJIT_CALL0 24
818 1.1 alnsn #define SLJIT_CALL1 25
819 1.1 alnsn #define SLJIT_CALL2 26
820 1.1 alnsn #define SLJIT_CALL3 27
821 1.1 alnsn
822 1.1 alnsn /* Fast calling method. See sljit_emit_fast_enter / sljit_emit_fast_return. */
823 1.1 alnsn
824 1.1 alnsn /* The target can be changed during runtime (see: sljit_set_jump_addr). */
825 1.1 alnsn #define SLJIT_REWRITABLE_JUMP 0x1000
826 1.1 alnsn
827 1.1 alnsn /* Emit a jump instruction. The destination is not set, only the type of the jump.
828 1.1 alnsn type must be between SLJIT_C_EQUAL and SLJIT_CALL3
829 1.1 alnsn type can be combined (or'ed) with SLJIT_REWRITABLE_JUMP
830 1.1 alnsn Flags: - (never set any flags) for both conditional and unconditional jumps.
831 1.1 alnsn Flags: destroy all flags for calls. */
832 1.2 alnsn SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_jump(struct sljit_compiler *compiler, sljit_si type);
833 1.1 alnsn
834 1.1 alnsn /* Basic arithmetic comparison. In most architectures it is implemented as
835 1.1 alnsn an SLJIT_SUB operation (with SLJIT_UNUSED destination and setting
836 1.1 alnsn appropriate flags) followed by a sljit_emit_jump. However some
837 1.1 alnsn architectures (i.e: MIPS) may employ special optimizations here. It is
838 1.1 alnsn suggested to use this comparison form when appropriate.
839 1.1 alnsn type must be between SLJIT_C_EQUAL and SLJIT_C_SIG_LESS_EQUAL
840 1.1 alnsn type can be combined (or'ed) with SLJIT_REWRITABLE_JUMP or SLJIT_INT_OP
841 1.1 alnsn Flags: destroy flags. */
842 1.2 alnsn SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_cmp(struct sljit_compiler *compiler, sljit_si type,
843 1.2 alnsn sljit_si src1, sljit_sw src1w,
844 1.2 alnsn sljit_si src2, sljit_sw src2w);
845 1.1 alnsn
846 1.1 alnsn /* Basic floating point comparison. In most architectures it is implemented as
847 1.1 alnsn an SLJIT_FCMP operation (setting appropriate flags) followed by a
848 1.1 alnsn sljit_emit_jump. However some architectures (i.e: MIPS) may employ
849 1.1 alnsn special optimizations here. It is suggested to use this comparison form
850 1.1 alnsn when appropriate.
851 1.2 alnsn type must be between SLJIT_C_FLOAT_EQUAL and SLJIT_C_FLOAT_ORDERED
852 1.2 alnsn type can be combined (or'ed) with SLJIT_REWRITABLE_JUMP and SLJIT_SINGLE_OP
853 1.1 alnsn Flags: destroy flags.
854 1.1 alnsn Note: if either operand is NaN, the behaviour is undefined for
855 1.1 alnsn type <= SLJIT_C_FLOAT_LESS_EQUAL. */
856 1.2 alnsn SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_fcmp(struct sljit_compiler *compiler, sljit_si type,
857 1.2 alnsn sljit_si src1, sljit_sw src1w,
858 1.2 alnsn sljit_si src2, sljit_sw src2w);
859 1.1 alnsn
860 1.1 alnsn /* Set the destination of the jump to this label. */
861 1.1 alnsn SLJIT_API_FUNC_ATTRIBUTE void sljit_set_label(struct sljit_jump *jump, struct sljit_label* label);
862 1.2 alnsn /* Set the destination address of the jump to this label. */
863 1.1 alnsn SLJIT_API_FUNC_ATTRIBUTE void sljit_set_target(struct sljit_jump *jump, sljit_uw target);
864 1.1 alnsn
865 1.1 alnsn /* Call function or jump anywhere. Both direct and indirect form
866 1.1 alnsn type must be between SLJIT_JUMP and SLJIT_CALL3
867 1.1 alnsn Direct form: set src to SLJIT_IMM() and srcw to the address
868 1.1 alnsn Indirect form: any other valid addressing mode
869 1.1 alnsn Flags: - (never set any flags) for unconditional jumps.
870 1.1 alnsn Flags: destroy all flags for calls. */
871 1.2 alnsn SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_ijump(struct sljit_compiler *compiler, sljit_si type, sljit_si src, sljit_sw srcw);
872 1.1 alnsn
873 1.2 alnsn /* Perform the operation using the conditional flags as the second argument.
874 1.2 alnsn Type must always be between SLJIT_C_EQUAL and SLJIT_C_FLOAT_ORDERED. The
875 1.2 alnsn value represented by the type is 1, if the condition represented by the type
876 1.2 alnsn is fulfilled, and 0 otherwise.
877 1.2 alnsn
878 1.2 alnsn If op == SLJIT_MOV, SLJIT_MOV_SI, SLJIT_MOV_UI:
879 1.2 alnsn Set dst to the value represented by the type (0 or 1).
880 1.2 alnsn Src must be SLJIT_UNUSED, and srcw must be 0
881 1.1 alnsn Flags: - (never set any flags)
882 1.2 alnsn If op == SLJIT_OR, op == SLJIT_AND, op == SLJIT_XOR
883 1.2 alnsn Performs the binary operation using src as the first, and the value
884 1.2 alnsn represented by type as the second argument.
885 1.2 alnsn Important note: only dst=src and dstw=srcw is supported at the moment!
886 1.2 alnsn Flags: I | E | K
887 1.2 alnsn Note: sljit_emit_op_flags does nothing, if dst is SLJIT_UNUSED (regardless of op). */
888 1.2 alnsn SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op_flags(struct sljit_compiler *compiler, sljit_si op,
889 1.2 alnsn sljit_si dst, sljit_sw dstw,
890 1.2 alnsn sljit_si src, sljit_sw srcw,
891 1.2 alnsn sljit_si type);
892 1.1 alnsn
893 1.2 alnsn /* Copies the base address of SLJIT_LOCALS_REG+offset to dst.
894 1.1 alnsn Flags: - (never set any flags) */
895 1.2 alnsn SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_get_local_base(struct sljit_compiler *compiler, sljit_si dst, sljit_sw dstw, sljit_sw offset);
896 1.1 alnsn
897 1.1 alnsn /* The constant can be changed runtime (see: sljit_set_const)
898 1.1 alnsn Flags: - (never set any flags) */
899 1.2 alnsn SLJIT_API_FUNC_ATTRIBUTE struct sljit_const* sljit_emit_const(struct sljit_compiler *compiler, sljit_si dst, sljit_sw dstw, sljit_sw init_value);
900 1.1 alnsn
901 1.1 alnsn /* After the code generation the address for label, jump and const instructions
902 1.2 alnsn are computed. Since these structures are freed by sljit_free_compiler, the
903 1.1 alnsn addresses must be preserved by the user program elsewere. */
904 1.1 alnsn static SLJIT_INLINE sljit_uw sljit_get_label_addr(struct sljit_label *label) { return label->addr; }
905 1.1 alnsn static SLJIT_INLINE sljit_uw sljit_get_jump_addr(struct sljit_jump *jump) { return jump->addr; }
906 1.1 alnsn static SLJIT_INLINE sljit_uw sljit_get_const_addr(struct sljit_const *const_) { return const_->addr; }
907 1.1 alnsn
908 1.1 alnsn /* Only the address is required to rewrite the code. */
909 1.1 alnsn SLJIT_API_FUNC_ATTRIBUTE void sljit_set_jump_addr(sljit_uw addr, sljit_uw new_addr);
910 1.2 alnsn SLJIT_API_FUNC_ATTRIBUTE void sljit_set_const(sljit_uw addr, sljit_sw new_constant);
911 1.1 alnsn
912 1.1 alnsn /* --------------------------------------------------------------------- */
913 1.1 alnsn /* Miscellaneous utility functions */
914 1.1 alnsn /* --------------------------------------------------------------------- */
915 1.1 alnsn
916 1.1 alnsn #define SLJIT_MAJOR_VERSION 0
917 1.2 alnsn #define SLJIT_MINOR_VERSION 91
918 1.1 alnsn
919 1.2 alnsn /* Get the human readable name of the platform. Can be useful on platforms
920 1.2 alnsn like ARM, where ARM and Thumb2 functions can be mixed, and
921 1.2 alnsn it is useful to know the type of the code generator. */
922 1.1 alnsn SLJIT_API_FUNC_ATTRIBUTE SLJIT_CONST char* sljit_get_platform_name(void);
923 1.1 alnsn
924 1.2 alnsn /* Portable helper function to get an offset of a member. */
925 1.2 alnsn #define SLJIT_OFFSETOF(base, member) ((sljit_sw)(&((base*)0x10)->member) - 0x10)
926 1.1 alnsn
927 1.1 alnsn #if (defined SLJIT_UTIL_GLOBAL_LOCK && SLJIT_UTIL_GLOBAL_LOCK)
928 1.1 alnsn /* This global lock is useful to compile common functions. */
929 1.1 alnsn SLJIT_API_FUNC_ATTRIBUTE void SLJIT_CALL sljit_grab_lock(void);
930 1.1 alnsn SLJIT_API_FUNC_ATTRIBUTE void SLJIT_CALL sljit_release_lock(void);
931 1.1 alnsn #endif
932 1.1 alnsn
933 1.1 alnsn #if (defined SLJIT_UTIL_STACK && SLJIT_UTIL_STACK)
934 1.1 alnsn
935 1.1 alnsn /* The sljit_stack is a utiliy feature of sljit, which allocates a
936 1.1 alnsn writable memory region between base (inclusive) and limit (exclusive).
937 1.1 alnsn Both base and limit is a pointer, and base is always <= than limit.
938 1.1 alnsn This feature uses the "address space reserve" feature
939 1.1 alnsn of modern operating systems. Basically we don't need to allocate a
940 1.1 alnsn huge memory block in one step for the worst case, we can start with
941 1.1 alnsn a smaller chunk and extend it later. Since the address space is
942 1.1 alnsn reserved, the data never copied to other regions, thus it is safe
943 1.1 alnsn to store pointers here. */
944 1.1 alnsn
945 1.1 alnsn /* Note: The base field is aligned to PAGE_SIZE bytes (usually 4k or more).
946 1.1 alnsn Note: stack growing should not happen in small steps: 4k, 16k or even
947 1.1 alnsn bigger growth is better.
948 1.1 alnsn Note: this structure may not be supported by all operating systems.
949 1.1 alnsn Some kind of fallback mechanism is suggested when SLJIT_UTIL_STACK
950 1.1 alnsn is not defined. */
951 1.1 alnsn
952 1.1 alnsn struct sljit_stack {
953 1.1 alnsn /* User data, anything can be stored here.
954 1.1 alnsn Starting with the same value as base. */
955 1.1 alnsn sljit_uw top;
956 1.1 alnsn /* These members are read only. */
957 1.1 alnsn sljit_uw base;
958 1.1 alnsn sljit_uw limit;
959 1.1 alnsn sljit_uw max_limit;
960 1.1 alnsn };
961 1.1 alnsn
962 1.1 alnsn /* Returns NULL if unsuccessful.
963 1.1 alnsn Note: limit and max_limit contains the size for stack allocation
964 1.1 alnsn Note: the top field is initialized to base. */
965 1.1 alnsn SLJIT_API_FUNC_ATTRIBUTE struct sljit_stack* SLJIT_CALL sljit_allocate_stack(sljit_uw limit, sljit_uw max_limit);
966 1.1 alnsn SLJIT_API_FUNC_ATTRIBUTE void SLJIT_CALL sljit_free_stack(struct sljit_stack* stack);
967 1.1 alnsn
968 1.1 alnsn /* Can be used to increase (allocate) or decrease (free) the memory area.
969 1.1 alnsn Returns with a non-zero value if unsuccessful. If new_limit is greater than
970 1.1 alnsn max_limit, it will fail. It is very easy to implement a stack data structure,
971 1.1 alnsn since the growth ratio can be added to the current limit, and sljit_stack_resize
972 1.1 alnsn will do all the necessary checks. The fields of the stack are not changed if
973 1.1 alnsn sljit_stack_resize fails. */
974 1.2 alnsn SLJIT_API_FUNC_ATTRIBUTE sljit_sw SLJIT_CALL sljit_stack_resize(struct sljit_stack* stack, sljit_uw new_limit);
975 1.1 alnsn
976 1.1 alnsn #endif /* (defined SLJIT_UTIL_STACK && SLJIT_UTIL_STACK) */
977 1.1 alnsn
978 1.1 alnsn #if !(defined SLJIT_INDIRECT_CALL && SLJIT_INDIRECT_CALL)
979 1.1 alnsn
980 1.1 alnsn /* Get the entry address of a given function. */
981 1.2 alnsn #define SLJIT_FUNC_OFFSET(func_name) ((sljit_sw)func_name)
982 1.1 alnsn
983 1.1 alnsn #else /* !(defined SLJIT_INDIRECT_CALL && SLJIT_INDIRECT_CALL) */
984 1.1 alnsn
985 1.1 alnsn /* All JIT related code should be placed in the same context (library, binary, etc.). */
986 1.1 alnsn
987 1.2 alnsn #define SLJIT_FUNC_OFFSET(func_name) (*(sljit_sw*)(void*)func_name)
988 1.1 alnsn
989 1.1 alnsn /* For powerpc64, the function pointers point to a context descriptor. */
990 1.1 alnsn struct sljit_function_context {
991 1.2 alnsn sljit_sw addr;
992 1.2 alnsn sljit_sw r2;
993 1.2 alnsn sljit_sw r11;
994 1.1 alnsn };
995 1.1 alnsn
996 1.1 alnsn /* Fill the context arguments using the addr and the function.
997 1.1 alnsn If func_ptr is NULL, it will not be set to the address of context
998 1.1 alnsn If addr is NULL, the function address also comes from the func pointer. */
999 1.2 alnsn SLJIT_API_FUNC_ATTRIBUTE void sljit_set_function_context(void** func_ptr, struct sljit_function_context* context, sljit_sw addr, void* func);
1000 1.1 alnsn
1001 1.1 alnsn #endif /* !(defined SLJIT_INDIRECT_CALL && SLJIT_INDIRECT_CALL) */
1002 1.1 alnsn
1003 1.1 alnsn #endif /* _SLJIT_LIR_H_ */
1004