2 * Stack-less Just-In-Time compiler
4 * Copyright 2009-2012 Zoltan Herczeg (hzmester@freemail.hu). All rights reserved.
6 * Redistribution and use in source and binary forms, with or without modification, are
7 * permitted provided that the following conditions are met:
9 * 1. Redistributions of source code must retain the above copyright notice, this list of
10 * conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright notice, this list
13 * of conditions and the following disclaimer in the documentation and/or other materials
14 * provided with the distribution.
16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) AND CONTRIBUTORS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
18 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
19 * SHALL THE COPYRIGHT HOLDER(S) OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
20 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
21 * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
22 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
23 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
24 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 #define CHECK_ERROR() \
31 if (SLJIT_UNLIKELY(compiler->error)) \
32 return compiler->error; \
35 #define CHECK_ERROR_PTR() \
37 if (SLJIT_UNLIKELY(compiler->error)) \
41 #define CHECK_ERROR_VOID() \
43 if (SLJIT_UNLIKELY(compiler->error)) \
47 #define FAIL_IF(expr) \
49 if (SLJIT_UNLIKELY(expr)) \
50 return compiler->error; \
53 #define PTR_FAIL_IF(expr) \
55 if (SLJIT_UNLIKELY(expr)) \
59 #define FAIL_IF_NULL(ptr) \
61 if (SLJIT_UNLIKELY(!(ptr))) { \
62 compiler->error = SLJIT_ERR_ALLOC_FAILED; \
63 return SLJIT_ERR_ALLOC_FAILED; \
67 #define PTR_FAIL_IF_NULL(ptr) \
69 if (SLJIT_UNLIKELY(!(ptr))) { \
70 compiler->error = SLJIT_ERR_ALLOC_FAILED; \
75 #define PTR_FAIL_WITH_EXEC_IF(ptr) \
77 if (SLJIT_UNLIKELY(!(ptr))) { \
78 compiler->error = SLJIT_ERR_EX_ALLOC_FAILED; \
83 #if !(defined SLJIT_CONFIG_UNSUPPORTED && SLJIT_CONFIG_UNSUPPORTED)
85 #define GET_OPCODE(op) \
86 ((op) & ~(SLJIT_INT_OP | SLJIT_SET_E | SLJIT_SET_U | SLJIT_SET_S | SLJIT_SET_O | SLJIT_SET_C | SLJIT_KEEP_FLAGS))
88 #define GET_FLAGS(op) \
89 ((op) & (SLJIT_SET_E | SLJIT_SET_U | SLJIT_SET_S | SLJIT_SET_O | SLJIT_SET_C))
91 #define GET_ALL_FLAGS(op) \
92 ((op) & (SLJIT_INT_OP | SLJIT_SET_E | SLJIT_SET_U | SLJIT_SET_S | SLJIT_SET_O | SLJIT_SET_C | SLJIT_KEEP_FLAGS))
94 #define TYPE_CAST_NEEDED(op) \
95 (((op) >= SLJIT_MOV_UB && (op) <= SLJIT_MOV_SH) || ((op) >= SLJIT_MOVU_UB && (op) <= SLJIT_MOVU_SH))
99 #if (defined SLJIT_32BIT_ARCHITECTURE && SLJIT_32BIT_ARCHITECTURE)
100 #define ABUF_SIZE 2048
102 #define ABUF_SIZE 4096
105 /* Parameter parsing. */
106 #define REG_MASK 0x3f
107 #define OFFS_REG(reg) (((reg) >> 8) & REG_MASK)
108 #define OFFS_REG_MASK (REG_MASK << 8)
109 #define TO_OFFS_REG(reg) ((reg) << 8)
110 /* When reg cannot be unused. */
111 #define FAST_IS_REG(reg) ((reg) <= REG_MASK)
112 /* When reg can be unused. */
113 #define SLOW_IS_REG(reg) ((reg) > 0 && (reg) <= REG_MASK)
116 #define JUMP_LABEL 0x1
117 #define JUMP_ADDR 0x2
118 /* SLJIT_REWRITABLE_JUMP is 0x1000. */
120 #if (defined SLJIT_CONFIG_X86 && SLJIT_CONFIG_X86)
121 # define PATCH_MB 0x4
122 # define PATCH_MW 0x8
123 #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
124 # define PATCH_MD 0x10
128 #if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5) || (defined SLJIT_CONFIG_ARM_V7 && SLJIT_CONFIG_ARM_V7)
133 #if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5)
134 # define CPOOL_SIZE 512
137 #if (defined SLJIT_CONFIG_ARM_THUMB2 && SLJIT_CONFIG_ARM_THUMB2)
138 # define IS_COND 0x04
140 /* conditional + imm8 */
141 # define PATCH_TYPE1 0x10
142 /* conditional + imm20 */
143 # define PATCH_TYPE2 0x20
145 # define PATCH_TYPE3 0x30
147 # define PATCH_TYPE4 0x40
149 # define PATCH_TYPE5 0x50
151 # define PATCH_BL 0x60
152 /* 0xf00 cc code for branches */
155 #if (defined SLJIT_CONFIG_ARM_64 && SLJIT_CONFIG_ARM_64)
156 # define IS_COND 0x004
157 # define IS_CBZ 0x008
159 # define PATCH_B 0x020
160 # define PATCH_COND 0x040
161 # define PATCH_ABS48 0x080
162 # define PATCH_ABS64 0x100
165 #if (defined SLJIT_CONFIG_PPC && SLJIT_CONFIG_PPC)
166 # define IS_COND 0x004
167 # define IS_CALL 0x008
168 # define PATCH_B 0x010
169 # define PATCH_ABS_B 0x020
170 #if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
171 # define PATCH_ABS32 0x040
172 # define PATCH_ABS48 0x080
174 # define REMOVE_COND 0x100
177 #if (defined SLJIT_CONFIG_MIPS && SLJIT_CONFIG_MIPS)
178 # define IS_MOVABLE 0x004
179 # define IS_JAL 0x008
180 # define IS_CALL 0x010
181 # define IS_BIT26_COND 0x020
182 # define IS_BIT16_COND 0x040
184 # define IS_COND (IS_BIT26_COND | IS_BIT16_COND)
186 # define PATCH_B 0x080
187 # define PATCH_J 0x100
189 #if (defined SLJIT_CONFIG_MIPS_64 && SLJIT_CONFIG_MIPS_64)
190 # define PATCH_ABS32 0x200
191 # define PATCH_ABS48 0x400
194 /* instruction types */
195 # define MOVABLE_INS 0
196 /* 1 - 31 last destination register */
197 /* no destination (i.e: store) */
198 # define UNMOVABLE_INS 32
199 /* FPU status register */
203 #if (defined SLJIT_CONFIG_TILEGX && SLJIT_CONFIG_TILEGX)
205 # define IS_COND 0x08
207 # define PATCH_B 0x10
208 # define PATCH_J 0x20
211 #if (defined SLJIT_CONFIG_SPARC_32 && SLJIT_CONFIG_SPARC_32)
212 # define IS_MOVABLE 0x04
213 # define IS_COND 0x08
214 # define IS_CALL 0x10
216 # define PATCH_B 0x20
217 # define PATCH_CALL 0x40
219 /* instruction types */
220 # define MOVABLE_INS 0
221 /* 1 - 31 last destination register */
222 /* no destination (i.e: store) */
223 # define UNMOVABLE_INS 32
225 # define DST_INS_MASK 0xff
227 /* ICC_SET is the same as SET_FLAGS. */
228 # define ICC_IS_SET (1 << 23)
229 # define FCC_IS_SET (1 << 24)
232 #if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
233 #define SLJIT_HAS_VARIABLE_LOCALS_OFFSET 1
234 #if !(defined SLJIT_X86_32_FASTCALL && SLJIT_X86_32_FASTCALL)
235 #define FIXED_LOCALS_OFFSET (3 * sizeof(sljit_sw))
239 #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
240 #define SLJIT_HAS_FIXED_LOCALS_OFFSET 1
242 #define FIXED_LOCALS_OFFSET ((4 + 2) * sizeof(sljit_sw))
244 #define FIXED_LOCALS_OFFSET (sizeof(sljit_sw))
248 #if (defined SLJIT_CONFIG_ARM_64 && SLJIT_CONFIG_ARM_64)
249 #define SLJIT_HAS_VARIABLE_LOCALS_OFFSET 1
252 #if (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32)
253 #define SLJIT_HAS_FIXED_LOCALS_OFFSET 1
255 #define FIXED_LOCALS_OFFSET ((6 + 8) * sizeof(sljit_sw))
257 #define FIXED_LOCALS_OFFSET (3 * sizeof(sljit_sw))
261 #if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
262 #define SLJIT_HAS_FIXED_LOCALS_OFFSET 1
263 #define FIXED_LOCALS_OFFSET ((6 + 8) * sizeof(sljit_sw))
266 #if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
267 #define SLJIT_HAS_FIXED_LOCALS_OFFSET 1
268 #define FIXED_LOCALS_OFFSET (4 * sizeof(sljit_sw))
271 #if (defined SLJIT_CONFIG_MIPS_64 && SLJIT_CONFIG_MIPS_64)
272 #define SLJIT_HAS_FIXED_LOCALS_OFFSET 1
273 #define FIXED_LOCALS_OFFSET 0
276 #if (defined SLJIT_CONFIG_SPARC_32 && SLJIT_CONFIG_SPARC_32)
277 #define SLJIT_HAS_FIXED_LOCALS_OFFSET 1
278 #define FIXED_LOCALS_OFFSET (23 * sizeof(sljit_sw))
281 #if (defined SLJIT_HAS_VARIABLE_LOCALS_OFFSET && SLJIT_HAS_VARIABLE_LOCALS_OFFSET)
283 #define ADJUST_LOCAL_OFFSET(p, i) \
284 if ((p) == (SLJIT_MEM1(SLJIT_LOCALS_REG))) \
285 (i) += compiler->locals_offset;
287 #elif (defined SLJIT_HAS_FIXED_LOCALS_OFFSET && SLJIT_HAS_FIXED_LOCALS_OFFSET)
289 #define ADJUST_LOCAL_OFFSET(p, i) \
290 if ((p) == (SLJIT_MEM1(SLJIT_LOCALS_REG))) \
291 (i) += FIXED_LOCALS_OFFSET;
295 #define ADJUST_LOCAL_OFFSET(p, i)
299 #endif /* !(defined SLJIT_CONFIG_UNSUPPORTED && SLJIT_CONFIG_UNSUPPORTED) */
301 /* Utils can still be used even if SLJIT_CONFIG_UNSUPPORTED is set. */
302 #include "sljitUtils.c"
304 #if !(defined SLJIT_CONFIG_UNSUPPORTED && SLJIT_CONFIG_UNSUPPORTED)
306 #if (defined SLJIT_EXECUTABLE_ALLOCATOR && SLJIT_EXECUTABLE_ALLOCATOR)
307 #include "sljitExecAllocator.c"
310 /* --------------------------------------------------------------------- */
311 /* Public functions */
312 /* --------------------------------------------------------------------- */
314 #if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5) || (defined SLJIT_CONFIG_X86 && SLJIT_CONFIG_X86)
315 #define SLJIT_NEEDS_COMPILER_INIT 1
316 static sljit_si compiler_initialized
= 0;
317 /* A thread safe initialization. */
318 static void init_compiler(void);
321 SLJIT_API_FUNC_ATTRIBUTE
struct sljit_compiler
* sljit_create_compiler(void)
323 struct sljit_compiler
*compiler
= (struct sljit_compiler
*)SLJIT_MALLOC(sizeof(struct sljit_compiler
));
326 SLJIT_ZEROMEM(compiler
, sizeof(struct sljit_compiler
));
328 SLJIT_COMPILE_ASSERT(
329 sizeof(sljit_sb
) == 1 && sizeof(sljit_ub
) == 1
330 && sizeof(sljit_sh
) == 2 && sizeof(sljit_uh
) == 2
331 && sizeof(sljit_si
) == 4 && sizeof(sljit_ui
) == 4
332 && (sizeof(sljit_p
) == 4 || sizeof(sljit_p
) == 8)
333 && sizeof(sljit_p
) <= sizeof(sljit_sw
)
334 && (sizeof(sljit_sw
) == 4 || sizeof(sljit_sw
) == 8)
335 && (sizeof(sljit_uw
) == 4 || sizeof(sljit_uw
) == 8),
336 invalid_integer_types
);
337 SLJIT_COMPILE_ASSERT(SLJIT_INT_OP
== SLJIT_SINGLE_OP
,
338 int_op_and_single_op_must_be_the_same
);
339 SLJIT_COMPILE_ASSERT(SLJIT_REWRITABLE_JUMP
!= SLJIT_SINGLE_OP
,
340 rewritable_jump_and_single_op_must_not_be_the_same
);
342 /* Only the non-zero members must be set. */
343 compiler
->error
= SLJIT_SUCCESS
;
345 compiler
->buf
= (struct sljit_memory_fragment
*)SLJIT_MALLOC(BUF_SIZE
);
346 compiler
->abuf
= (struct sljit_memory_fragment
*)SLJIT_MALLOC(ABUF_SIZE
);
348 if (!compiler
->buf
|| !compiler
->abuf
) {
350 SLJIT_FREE(compiler
->buf
);
352 SLJIT_FREE(compiler
->abuf
);
353 SLJIT_FREE(compiler
);
357 compiler
->buf
->next
= NULL
;
358 compiler
->buf
->used_size
= 0;
359 compiler
->abuf
->next
= NULL
;
360 compiler
->abuf
->used_size
= 0;
362 compiler
->scratches
= -1;
363 compiler
->saveds
= -1;
365 #if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
369 #if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5)
370 compiler
->cpool
= (sljit_uw
*)SLJIT_MALLOC(CPOOL_SIZE
* sizeof(sljit_uw
) + CPOOL_SIZE
* sizeof(sljit_ub
));
371 if (!compiler
->cpool
) {
372 SLJIT_FREE(compiler
->buf
);
373 SLJIT_FREE(compiler
->abuf
);
374 SLJIT_FREE(compiler
);
377 compiler
->cpool_unique
= (sljit_ub
*)(compiler
->cpool
+ CPOOL_SIZE
);
378 compiler
->cpool_diff
= 0xffffffff;
381 #if (defined SLJIT_CONFIG_MIPS && SLJIT_CONFIG_MIPS)
382 compiler
->delay_slot
= UNMOVABLE_INS
;
385 #if (defined SLJIT_CONFIG_SPARC_32 && SLJIT_CONFIG_SPARC_32)
386 compiler
->delay_slot
= UNMOVABLE_INS
;
389 #if (defined SLJIT_NEEDS_COMPILER_INIT && SLJIT_NEEDS_COMPILER_INIT)
390 if (!compiler_initialized
) {
392 compiler_initialized
= 1;
399 SLJIT_API_FUNC_ATTRIBUTE
void sljit_free_compiler(struct sljit_compiler
*compiler
)
401 struct sljit_memory_fragment
*buf
;
402 struct sljit_memory_fragment
*curr
;
411 buf
= compiler
->abuf
;
418 #if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5)
419 SLJIT_FREE(compiler
->cpool
);
421 SLJIT_FREE(compiler
);
424 #if (defined SLJIT_CONFIG_ARM_THUMB2 && SLJIT_CONFIG_ARM_THUMB2)
425 SLJIT_API_FUNC_ATTRIBUTE
void sljit_free_code(void* code
)
427 /* Remove thumb mode flag. */
428 SLJIT_FREE_EXEC((void*)((sljit_uw
)code
& ~0x1));
430 #elif (defined SLJIT_INDIRECT_CALL && SLJIT_INDIRECT_CALL)
431 SLJIT_API_FUNC_ATTRIBUTE
void sljit_free_code(void* code
)
433 /* Resolve indirection. */
434 code
= (void*)(*(sljit_uw
*)code
);
435 SLJIT_FREE_EXEC(code
);
438 SLJIT_API_FUNC_ATTRIBUTE
void sljit_free_code(void* code
)
440 SLJIT_FREE_EXEC(code
);
444 SLJIT_API_FUNC_ATTRIBUTE
void sljit_set_label(struct sljit_jump
*jump
, struct sljit_label
* label
)
446 if (SLJIT_LIKELY(!!jump
) && SLJIT_LIKELY(!!label
)) {
447 jump
->flags
&= ~JUMP_ADDR
;
448 jump
->flags
|= JUMP_LABEL
;
449 jump
->u
.label
= label
;
453 SLJIT_API_FUNC_ATTRIBUTE
void sljit_set_target(struct sljit_jump
*jump
, sljit_uw target
)
455 if (SLJIT_LIKELY(!!jump
)) {
456 jump
->flags
&= ~JUMP_LABEL
;
457 jump
->flags
|= JUMP_ADDR
;
458 jump
->u
.target
= target
;
462 /* --------------------------------------------------------------------- */
463 /* Private functions */
464 /* --------------------------------------------------------------------- */
466 static void* ensure_buf(struct sljit_compiler
*compiler
, sljit_uw size
)
469 struct sljit_memory_fragment
*new_frag
;
471 SLJIT_ASSERT(size
<= 256);
472 if (compiler
->buf
->used_size
+ size
<= (BUF_SIZE
- (sljit_uw
)SLJIT_OFFSETOF(struct sljit_memory_fragment
, memory
))) {
473 ret
= compiler
->buf
->memory
+ compiler
->buf
->used_size
;
474 compiler
->buf
->used_size
+= size
;
477 new_frag
= (struct sljit_memory_fragment
*)SLJIT_MALLOC(BUF_SIZE
);
478 PTR_FAIL_IF_NULL(new_frag
);
479 new_frag
->next
= compiler
->buf
;
480 compiler
->buf
= new_frag
;
481 new_frag
->used_size
= size
;
482 return new_frag
->memory
;
485 static void* ensure_abuf(struct sljit_compiler
*compiler
, sljit_uw size
)
488 struct sljit_memory_fragment
*new_frag
;
490 SLJIT_ASSERT(size
<= 256);
491 if (compiler
->abuf
->used_size
+ size
<= (ABUF_SIZE
- (sljit_uw
)SLJIT_OFFSETOF(struct sljit_memory_fragment
, memory
))) {
492 ret
= compiler
->abuf
->memory
+ compiler
->abuf
->used_size
;
493 compiler
->abuf
->used_size
+= size
;
496 new_frag
= (struct sljit_memory_fragment
*)SLJIT_MALLOC(ABUF_SIZE
);
497 PTR_FAIL_IF_NULL(new_frag
);
498 new_frag
->next
= compiler
->abuf
;
499 compiler
->abuf
= new_frag
;
500 new_frag
->used_size
= size
;
501 return new_frag
->memory
;
504 SLJIT_API_FUNC_ATTRIBUTE
void* sljit_alloc_memory(struct sljit_compiler
*compiler
, sljit_si size
)
508 #if (defined SLJIT_64BIT_ARCHITECTURE && SLJIT_64BIT_ARCHITECTURE)
509 if (size
<= 0 || size
> 128)
511 size
= (size
+ 7) & ~7;
513 if (size
<= 0 || size
> 64)
515 size
= (size
+ 3) & ~3;
517 return ensure_abuf(compiler
, size
);
520 static SLJIT_INLINE
void reverse_buf(struct sljit_compiler
*compiler
)
522 struct sljit_memory_fragment
*buf
= compiler
->buf
;
523 struct sljit_memory_fragment
*prev
= NULL
;
524 struct sljit_memory_fragment
*tmp
;
531 } while (buf
!= NULL
);
533 compiler
->buf
= prev
;
536 static SLJIT_INLINE
void set_label(struct sljit_label
*label
, struct sljit_compiler
*compiler
)
539 label
->size
= compiler
->size
;
540 if (compiler
->last_label
)
541 compiler
->last_label
->next
= label
;
543 compiler
->labels
= label
;
544 compiler
->last_label
= label
;
547 static SLJIT_INLINE
void set_jump(struct sljit_jump
*jump
, struct sljit_compiler
*compiler
, sljit_si flags
)
551 if (compiler
->last_jump
)
552 compiler
->last_jump
->next
= jump
;
554 compiler
->jumps
= jump
;
555 compiler
->last_jump
= jump
;
558 static SLJIT_INLINE
void set_const(struct sljit_const
*const_
, struct sljit_compiler
*compiler
)
561 const_
->addr
= compiler
->size
;
562 if (compiler
->last_const
)
563 compiler
->last_const
->next
= const_
;
565 compiler
->consts
= const_
;
566 compiler
->last_const
= const_
;
569 #define ADDRESSING_DEPENDS_ON(exp, reg) \
570 (((exp) & SLJIT_MEM) && (((exp) & REG_MASK) == reg || OFFS_REG(exp) == reg))
572 #if (defined SLJIT_DEBUG && SLJIT_DEBUG)
573 #define FUNCTION_CHECK_OP() \
574 SLJIT_ASSERT(!GET_FLAGS(op) || !(op & SLJIT_KEEP_FLAGS)); \
575 switch (GET_OPCODE(op)) { \
584 SLJIT_ASSERT(!(op & (SLJIT_SET_U | SLJIT_SET_S | SLJIT_SET_O | SLJIT_SET_C))); \
587 SLJIT_ASSERT(!(op & (SLJIT_SET_U | SLJIT_SET_S | SLJIT_SET_C))); \
590 SLJIT_ASSERT(!(op & (SLJIT_SET_E | SLJIT_SET_U | SLJIT_SET_S | SLJIT_SET_C))); \
593 SLJIT_ASSERT(!(op & (SLJIT_SET_U | SLJIT_SET_S))); \
599 SLJIT_ASSERT(!(op & (SLJIT_SET_E | SLJIT_SET_U | SLJIT_SET_S | SLJIT_SET_O))); \
601 case SLJIT_BREAKPOINT: \
609 case SLJIT_MOVU_UI: \
611 /* Nothing allowed */ \
612 SLJIT_ASSERT(!(op & (SLJIT_INT_OP | SLJIT_SET_E | SLJIT_SET_U | SLJIT_SET_S | SLJIT_SET_O | SLJIT_SET_C | SLJIT_KEEP_FLAGS))); \
615 /* Only SLJIT_INT_OP or SLJIT_SINGLE_OP is allowed. */ \
616 SLJIT_ASSERT(!(op & (SLJIT_SET_E | SLJIT_SET_U | SLJIT_SET_S | SLJIT_SET_O | SLJIT_SET_C | SLJIT_KEEP_FLAGS))); \
620 #define FUNCTION_CHECK_FOP() \
621 SLJIT_ASSERT(!GET_FLAGS(op) || !(op & SLJIT_KEEP_FLAGS)); \
622 switch (GET_OPCODE(op)) { \
624 SLJIT_ASSERT(!(op & (SLJIT_SET_U | SLJIT_SET_O | SLJIT_SET_C | SLJIT_KEEP_FLAGS))); \
625 SLJIT_ASSERT((op & (SLJIT_SET_E | SLJIT_SET_S))); \
628 /* Only SLJIT_INT_OP or SLJIT_SINGLE_OP is allowed. */ \
629 SLJIT_ASSERT(!(op & (SLJIT_SET_E | SLJIT_SET_U | SLJIT_SET_S | SLJIT_SET_O | SLJIT_SET_C | SLJIT_KEEP_FLAGS))); \
633 #define FUNCTION_CHECK_IS_REG(r) \
634 ((r) == SLJIT_UNUSED || \
635 ((r) >= SLJIT_SCRATCH_REG1 && (r) <= SLJIT_SCRATCH_REG1 - 1 + compiler->scratches) || \
636 ((r) >= SLJIT_SAVED_REG1 && (r) <= SLJIT_SAVED_REG1 - 1 + compiler->saveds))
638 #define FUNCTION_CHECK_SRC(p, i) \
639 SLJIT_ASSERT(compiler->scratches != -1 && compiler->saveds != -1); \
640 if (FUNCTION_CHECK_IS_REG(p)) \
641 SLJIT_ASSERT((i) == 0 && (p) != SLJIT_UNUSED); \
642 else if ((p) == SLJIT_IMM) \
644 else if ((p) == (SLJIT_MEM1(SLJIT_LOCALS_REG))) \
645 SLJIT_ASSERT((i) >= 0 && (i) < compiler->logical_local_size); \
646 else if ((p) & SLJIT_MEM) { \
647 SLJIT_ASSERT(FUNCTION_CHECK_IS_REG((p) & REG_MASK)); \
648 if ((p) & OFFS_REG_MASK) { \
649 SLJIT_ASSERT(FUNCTION_CHECK_IS_REG(OFFS_REG(p))); \
650 SLJIT_ASSERT(!((i) & ~0x3)); \
652 SLJIT_ASSERT(!((p) & ~(SLJIT_MEM | SLJIT_IMM | REG_MASK | OFFS_REG_MASK))); \
657 #define FUNCTION_CHECK_DST(p, i) \
658 SLJIT_ASSERT(compiler->scratches != -1 && compiler->saveds != -1); \
659 if (FUNCTION_CHECK_IS_REG(p)) \
660 SLJIT_ASSERT((i) == 0); \
661 else if ((p) == (SLJIT_MEM1(SLJIT_LOCALS_REG))) \
662 SLJIT_ASSERT((i) >= 0 && (i) < compiler->logical_local_size); \
663 else if ((p) & SLJIT_MEM) { \
664 SLJIT_ASSERT(FUNCTION_CHECK_IS_REG((p) & REG_MASK)); \
665 if ((p) & OFFS_REG_MASK) { \
666 SLJIT_ASSERT(FUNCTION_CHECK_IS_REG(OFFS_REG(p))); \
667 SLJIT_ASSERT(!((i) & ~0x3)); \
669 SLJIT_ASSERT(!((p) & ~(SLJIT_MEM | SLJIT_IMM | REG_MASK | OFFS_REG_MASK))); \
674 #define FUNCTION_FCHECK(p, i) \
675 if ((p) >= SLJIT_FLOAT_REG1 && (p) <= SLJIT_FLOAT_REG6) \
676 SLJIT_ASSERT(i == 0); \
677 else if ((p) == (SLJIT_MEM1(SLJIT_LOCALS_REG))) \
678 SLJIT_ASSERT((i) >= 0 && (i) < compiler->logical_local_size); \
679 else if ((p) & SLJIT_MEM) { \
680 SLJIT_ASSERT(FUNCTION_CHECK_IS_REG((p) & REG_MASK)); \
681 if ((p) & OFFS_REG_MASK) { \
682 SLJIT_ASSERT(FUNCTION_CHECK_IS_REG(OFFS_REG(p))); \
683 SLJIT_ASSERT(((p) & OFFS_REG_MASK) != TO_OFFS_REG(SLJIT_LOCALS_REG) && !(i & ~0x3)); \
685 SLJIT_ASSERT(OFFS_REG(p) == 0); \
686 SLJIT_ASSERT(!((p) & ~(SLJIT_MEM | SLJIT_IMM | REG_MASK | OFFS_REG_MASK))); \
691 #define FUNCTION_CHECK_OP1() \
692 if (GET_OPCODE(op) >= SLJIT_MOVU && GET_OPCODE(op) <= SLJIT_MOVU_P) { \
693 SLJIT_ASSERT(!(src & SLJIT_MEM) || (src & REG_MASK) != SLJIT_LOCALS_REG); \
694 SLJIT_ASSERT(!(dst & SLJIT_MEM) || (dst & REG_MASK) != SLJIT_LOCALS_REG); \
695 if ((src & SLJIT_MEM) && (src & REG_MASK)) \
696 SLJIT_ASSERT((dst & REG_MASK) != (src & REG_MASK) && OFFS_REG(dst) != (src & REG_MASK)); \
701 #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
703 SLJIT_API_FUNC_ATTRIBUTE
void sljit_compiler_verbose(struct sljit_compiler
*compiler
, FILE* verbose
)
705 compiler
->verbose
= verbose
;
708 static char* reg_names
[] = {
709 (char*)"unused", (char*)"s1", (char*)"s2", (char*)"s3",
710 (char*)"se1", (char*)"se2", (char*)"p1", (char*)"p2",
711 (char*)"p3", (char*)"pe1", (char*)"pe2", (char*)"lc"
714 static char* freg_names
[] = {
715 (char*)"unused", (char*)"f1", (char*)"f2", (char*)"f3",
716 (char*)"f4", (char*)"f5", (char*)"f6"
719 #if (defined SLJIT_64BIT_ARCHITECTURE && SLJIT_64BIT_ARCHITECTURE)
721 # define SLJIT_PRINT_D "I64"
723 # define SLJIT_PRINT_D "l"
726 # define SLJIT_PRINT_D ""
729 #define sljit_verbose_param(p, i) \
730 if ((p) & SLJIT_IMM) \
731 fprintf(compiler->verbose, "#%" SLJIT_PRINT_D "d", (i)); \
732 else if ((p) & SLJIT_MEM) { \
733 if ((p) & REG_MASK) { \
735 if ((p) & OFFS_REG_MASK) \
736 fprintf(compiler->verbose, "[%s + %s * %d]", reg_names[(p) & REG_MASK], reg_names[OFFS_REG(p)], 1 << (i)); \
738 fprintf(compiler->verbose, "[%s + #%" SLJIT_PRINT_D "d]", reg_names[(p) & REG_MASK], (i)); \
741 if ((p) & OFFS_REG_MASK) \
742 fprintf(compiler->verbose, "[%s + %s]", reg_names[(p) & REG_MASK], reg_names[OFFS_REG(p)]); \
744 fprintf(compiler->verbose, "[%s]", reg_names[(p) & REG_MASK]); \
748 fprintf(compiler->verbose, "[#%" SLJIT_PRINT_D "d]", (i)); \
750 fprintf(compiler->verbose, "%s", reg_names[p]);
751 #define sljit_verbose_fparam(p, i) \
752 if ((p) & SLJIT_MEM) { \
753 if ((p) & REG_MASK) { \
755 if ((p) & OFFS_REG_MASK) \
756 fprintf(compiler->verbose, "[%s + %s * %d]", reg_names[(p) & REG_MASK], reg_names[OFFS_REG(p)], 1 << (i)); \
758 fprintf(compiler->verbose, "[%s + #%" SLJIT_PRINT_D "d]", reg_names[(p) & REG_MASK], (i)); \
761 if ((p) & OFFS_REG_MASK) \
762 fprintf(compiler->verbose, "[%s + %s]", reg_names[(p) & REG_MASK], reg_names[OFFS_REG(p)]); \
764 fprintf(compiler->verbose, "[%s]", reg_names[(p) & REG_MASK]); \
768 fprintf(compiler->verbose, "[#%" SLJIT_PRINT_D "d]", (i)); \
770 fprintf(compiler->verbose, "%s", freg_names[p]);
772 static SLJIT_CONST
char* op_names
[] = {
774 (char*)"breakpoint", (char*)"nop",
775 (char*)"umul", (char*)"smul", (char*)"udiv", (char*)"sdiv",
777 (char*)"mov", (char*)"mov.ub", (char*)"mov.sb", (char*)"mov.uh",
778 (char*)"mov.sh", (char*)"mov.ui", (char*)"mov.si", (char*)"mov.p",
779 (char*)"movu", (char*)"movu.ub", (char*)"movu.sb", (char*)"movu.uh",
780 (char*)"movu.sh", (char*)"movu.ui", (char*)"movu.si", (char*)"movu.p",
781 (char*)"not", (char*)"neg", (char*)"clz",
783 (char*)"add", (char*)"addc", (char*)"sub", (char*)"subc",
784 (char*)"mul", (char*)"and", (char*)"or", (char*)"xor",
785 (char*)"shl", (char*)"lshr", (char*)"ashr",
787 (char*)"mov", (char*)"neg", (char*)"abs", (char*)"conv",
788 (char*)"conv", (char*)"conv", (char*)"conv", (char*)"conv",
791 (char*)"add", (char*)"sub", (char*)"mul", (char*)"div"
794 static char* jump_names
[] = {
795 (char*)"equal", (char*)"not_equal",
796 (char*)"less", (char*)"greater_equal",
797 (char*)"greater", (char*)"less_equal",
798 (char*)"sig_less", (char*)"sig_greater_equal",
799 (char*)"sig_greater", (char*)"sig_less_equal",
800 (char*)"overflow", (char*)"not_overflow",
801 (char*)"mul_overflow", (char*)"mul_not_overflow",
802 (char*)"float_equal", (char*)"float_not_equal",
803 (char*)"float_less", (char*)"float_greater_equal",
804 (char*)"float_greater", (char*)"float_less_equal",
805 (char*)"float_unordered", (char*)"float_ordered",
806 (char*)"jump", (char*)"fast_call",
807 (char*)"call0", (char*)"call1", (char*)"call2", (char*)"call3"
812 /* --------------------------------------------------------------------- */
814 /* --------------------------------------------------------------------- */
816 static SLJIT_INLINE
void check_sljit_generate_code(struct sljit_compiler
*compiler
)
818 #if (defined SLJIT_DEBUG && SLJIT_DEBUG)
819 struct sljit_jump
*jump
;
821 /* If debug and verbose are disabled, all arguments are unused. */
822 SLJIT_UNUSED_ARG(compiler
);
824 SLJIT_ASSERT(compiler
->size
> 0);
825 #if (defined SLJIT_DEBUG && SLJIT_DEBUG)
826 jump
= compiler
->jumps
;
828 /* All jumps have target. */
829 SLJIT_ASSERT(jump
->flags
& (JUMP_LABEL
| JUMP_ADDR
));
835 static SLJIT_INLINE
void check_sljit_emit_enter(struct sljit_compiler
*compiler
, sljit_si args
, sljit_si scratches
, sljit_si saveds
, sljit_si local_size
)
837 /* If debug and verbose are disabled, all arguments are unused. */
838 SLJIT_UNUSED_ARG(compiler
);
839 SLJIT_UNUSED_ARG(args
);
840 SLJIT_UNUSED_ARG(scratches
);
841 SLJIT_UNUSED_ARG(saveds
);
842 SLJIT_UNUSED_ARG(local_size
);
844 SLJIT_ASSERT(args
>= 0 && args
<= 3);
845 SLJIT_ASSERT(scratches
>= 0 && scratches
<= SLJIT_NO_TMP_REGISTERS
);
846 SLJIT_ASSERT(saveds
>= 0 && saveds
<= SLJIT_NO_GEN_REGISTERS
);
847 SLJIT_ASSERT(args
<= saveds
);
848 SLJIT_ASSERT(local_size
>= 0 && local_size
<= SLJIT_MAX_LOCAL_SIZE
);
849 #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
850 if (SLJIT_UNLIKELY(!!compiler
->verbose
))
851 fprintf(compiler
->verbose
, " enter args=%d scratches=%d saveds=%d local_size=%d\n", args
, scratches
, saveds
, local_size
);
855 static SLJIT_INLINE
void check_sljit_set_context(struct sljit_compiler
*compiler
, sljit_si args
, sljit_si scratches
, sljit_si saveds
, sljit_si local_size
)
857 /* If debug and verbose are disabled, all arguments are unused. */
858 SLJIT_UNUSED_ARG(compiler
);
859 SLJIT_UNUSED_ARG(args
);
860 SLJIT_UNUSED_ARG(scratches
);
861 SLJIT_UNUSED_ARG(saveds
);
862 SLJIT_UNUSED_ARG(local_size
);
864 #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) || (defined SLJIT_DEBUG && SLJIT_DEBUG)
865 if (SLJIT_UNLIKELY(compiler
->skip_checks
)) {
866 compiler
->skip_checks
= 0;
871 SLJIT_ASSERT(args
>= 0 && args
<= 3);
872 SLJIT_ASSERT(scratches
>= 0 && scratches
<= SLJIT_NO_TMP_REGISTERS
);
873 SLJIT_ASSERT(saveds
>= 0 && saveds
<= SLJIT_NO_GEN_REGISTERS
);
874 SLJIT_ASSERT(args
<= saveds
);
875 SLJIT_ASSERT(local_size
>= 0 && local_size
<= SLJIT_MAX_LOCAL_SIZE
);
876 #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
877 if (SLJIT_UNLIKELY(!!compiler
->verbose
))
878 fprintf(compiler
->verbose
, " set_context args=%d scratches=%d saveds=%d local_size=%d\n", args
, scratches
, saveds
, local_size
);
882 static SLJIT_INLINE
void check_sljit_emit_return(struct sljit_compiler
*compiler
, sljit_si op
, sljit_si src
, sljit_sw srcw
)
884 /* If debug and verbose are disabled, all arguments are unused. */
885 SLJIT_UNUSED_ARG(compiler
);
886 SLJIT_UNUSED_ARG(op
);
887 SLJIT_UNUSED_ARG(src
);
888 SLJIT_UNUSED_ARG(srcw
);
890 #if (defined SLJIT_DEBUG && SLJIT_DEBUG)
891 if (op
!= SLJIT_UNUSED
) {
892 SLJIT_ASSERT(op
>= SLJIT_MOV
&& op
<= SLJIT_MOV_P
);
893 FUNCTION_CHECK_SRC(src
, srcw
);
896 SLJIT_ASSERT(src
== 0 && srcw
== 0);
898 #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
899 if (SLJIT_UNLIKELY(!!compiler
->verbose
)) {
900 if (op
== SLJIT_UNUSED
)
901 fprintf(compiler
->verbose
, " return\n");
903 fprintf(compiler
->verbose
, " return %s ", op_names
[op
]);
904 sljit_verbose_param(src
, srcw
);
905 fprintf(compiler
->verbose
, "\n");
911 static SLJIT_INLINE
void check_sljit_emit_fast_enter(struct sljit_compiler
*compiler
, sljit_si dst
, sljit_sw dstw
)
913 /* If debug and verbose are disabled, all arguments are unused. */
914 SLJIT_UNUSED_ARG(compiler
);
915 SLJIT_UNUSED_ARG(dst
);
916 SLJIT_UNUSED_ARG(dstw
);
918 #if (defined SLJIT_DEBUG && SLJIT_DEBUG)
919 FUNCTION_CHECK_DST(dst
, dstw
);
921 #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
922 if (SLJIT_UNLIKELY(!!compiler
->verbose
)) {
923 fprintf(compiler
->verbose
, " fast_enter ");
924 sljit_verbose_param(dst
, dstw
);
925 fprintf(compiler
->verbose
, "\n");
930 static SLJIT_INLINE
void check_sljit_emit_fast_return(struct sljit_compiler
*compiler
, sljit_si src
, sljit_sw srcw
)
932 /* If debug and verbose are disabled, all arguments are unused. */
933 SLJIT_UNUSED_ARG(compiler
);
934 SLJIT_UNUSED_ARG(src
);
935 SLJIT_UNUSED_ARG(srcw
);
937 #if (defined SLJIT_DEBUG && SLJIT_DEBUG)
938 FUNCTION_CHECK_SRC(src
, srcw
);
940 #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
941 if (SLJIT_UNLIKELY(!!compiler
->verbose
)) {
942 fprintf(compiler
->verbose
, " fast_return ");
943 sljit_verbose_param(src
, srcw
);
944 fprintf(compiler
->verbose
, "\n");
949 static SLJIT_INLINE
void check_sljit_emit_op0(struct sljit_compiler
*compiler
, sljit_si op
)
951 /* If debug and verbose are disabled, all arguments are unused. */
952 SLJIT_UNUSED_ARG(compiler
);
953 SLJIT_UNUSED_ARG(op
);
955 SLJIT_ASSERT((op
>= SLJIT_BREAKPOINT
&& op
<= SLJIT_SMUL
)
956 || ((op
& ~SLJIT_INT_OP
) >= SLJIT_UDIV
&& (op
& ~SLJIT_INT_OP
) <= SLJIT_SDIV
));
957 #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
958 if (SLJIT_UNLIKELY(!!compiler
->verbose
))
959 fprintf(compiler
->verbose
, " %s%s\n", !(op
& SLJIT_INT_OP
) ? "" : "i", op_names
[GET_OPCODE(op
)]);
963 static SLJIT_INLINE
void check_sljit_emit_op1(struct sljit_compiler
*compiler
, sljit_si op
,
964 sljit_si dst
, sljit_sw dstw
,
965 sljit_si src
, sljit_sw srcw
)
967 /* If debug and verbose are disabled, all arguments are unused. */
968 SLJIT_UNUSED_ARG(compiler
);
969 SLJIT_UNUSED_ARG(op
);
970 SLJIT_UNUSED_ARG(dst
);
971 SLJIT_UNUSED_ARG(dstw
);
972 SLJIT_UNUSED_ARG(src
);
973 SLJIT_UNUSED_ARG(srcw
);
975 #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) || (defined SLJIT_DEBUG && SLJIT_DEBUG)
976 if (SLJIT_UNLIKELY(compiler
->skip_checks
)) {
977 compiler
->skip_checks
= 0;
982 SLJIT_ASSERT(GET_OPCODE(op
) >= SLJIT_MOV
&& GET_OPCODE(op
) <= SLJIT_CLZ
);
983 #if (defined SLJIT_DEBUG && SLJIT_DEBUG)
985 FUNCTION_CHECK_SRC(src
, srcw
);
986 FUNCTION_CHECK_DST(dst
, dstw
);
987 FUNCTION_CHECK_OP1();
989 #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
990 if (SLJIT_UNLIKELY(!!compiler
->verbose
)) {
991 fprintf(compiler
->verbose
, " %s%s%s%s%s%s%s%s ", !(op
& SLJIT_INT_OP
) ? "" : "i", op_names
[GET_OPCODE(op
)],
992 !(op
& SLJIT_SET_E
) ? "" : ".e", !(op
& SLJIT_SET_U
) ? "" : ".u", !(op
& SLJIT_SET_S
) ? "" : ".s",
993 !(op
& SLJIT_SET_O
) ? "" : ".o", !(op
& SLJIT_SET_C
) ? "" : ".c", !(op
& SLJIT_KEEP_FLAGS
) ? "" : ".k");
994 sljit_verbose_param(dst
, dstw
);
995 fprintf(compiler
->verbose
, ", ");
996 sljit_verbose_param(src
, srcw
);
997 fprintf(compiler
->verbose
, "\n");
1002 static SLJIT_INLINE
void check_sljit_emit_op2(struct sljit_compiler
*compiler
, sljit_si op
,
1003 sljit_si dst
, sljit_sw dstw
,
1004 sljit_si src1
, sljit_sw src1w
,
1005 sljit_si src2
, sljit_sw src2w
)
1007 /* If debug and verbose are disabled, all arguments are unused. */
1008 SLJIT_UNUSED_ARG(compiler
);
1009 SLJIT_UNUSED_ARG(op
);
1010 SLJIT_UNUSED_ARG(dst
);
1011 SLJIT_UNUSED_ARG(dstw
);
1012 SLJIT_UNUSED_ARG(src1
);
1013 SLJIT_UNUSED_ARG(src1w
);
1014 SLJIT_UNUSED_ARG(src2
);
1015 SLJIT_UNUSED_ARG(src2w
);
1017 #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) || (defined SLJIT_DEBUG && SLJIT_DEBUG)
1018 if (SLJIT_UNLIKELY(compiler
->skip_checks
)) {
1019 compiler
->skip_checks
= 0;
1024 SLJIT_ASSERT(GET_OPCODE(op
) >= SLJIT_ADD
&& GET_OPCODE(op
) <= SLJIT_ASHR
);
1025 #if (defined SLJIT_DEBUG && SLJIT_DEBUG)
1026 FUNCTION_CHECK_OP();
1027 FUNCTION_CHECK_SRC(src1
, src1w
);
1028 FUNCTION_CHECK_SRC(src2
, src2w
);
1029 FUNCTION_CHECK_DST(dst
, dstw
);
1031 #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
1032 if (SLJIT_UNLIKELY(!!compiler
->verbose
)) {
1033 fprintf(compiler
->verbose
, " %s%s%s%s%s%s%s%s ", !(op
& SLJIT_INT_OP
) ? "" : "i", op_names
[GET_OPCODE(op
)],
1034 !(op
& SLJIT_SET_E
) ? "" : ".e", !(op
& SLJIT_SET_U
) ? "" : ".u", !(op
& SLJIT_SET_S
) ? "" : ".s",
1035 !(op
& SLJIT_SET_O
) ? "" : ".o", !(op
& SLJIT_SET_C
) ? "" : ".c", !(op
& SLJIT_KEEP_FLAGS
) ? "" : ".k");
1036 sljit_verbose_param(dst
, dstw
);
1037 fprintf(compiler
->verbose
, ", ");
1038 sljit_verbose_param(src1
, src1w
);
1039 fprintf(compiler
->verbose
, ", ");
1040 sljit_verbose_param(src2
, src2w
);
1041 fprintf(compiler
->verbose
, "\n");
1046 static SLJIT_INLINE
void check_sljit_get_register_index(sljit_si reg
)
1048 SLJIT_UNUSED_ARG(reg
);
1049 SLJIT_ASSERT(reg
> 0 && reg
<= SLJIT_NO_REGISTERS
);
1052 static SLJIT_INLINE
void check_sljit_get_float_register_index(sljit_si reg
)
1054 SLJIT_UNUSED_ARG(reg
);
1055 SLJIT_ASSERT(reg
> 0 && reg
<= SLJIT_NO_FLOAT_REGISTERS
);
1058 static SLJIT_INLINE
void check_sljit_emit_op_custom(struct sljit_compiler
*compiler
,
1059 void *instruction
, sljit_si size
)
1061 SLJIT_UNUSED_ARG(compiler
);
1062 SLJIT_UNUSED_ARG(instruction
);
1063 SLJIT_UNUSED_ARG(size
);
1064 SLJIT_ASSERT(instruction
);
1067 #define SELECT_FOP1_OPERATION_WITH_CHECKS(compiler, op, dst, dstw, src, srcw) \
1068 SLJIT_ASSERT(sljit_is_fpu_available()); \
1069 SLJIT_COMPILE_ASSERT(!(SLJIT_CONVW_FROMD & 0x1) && !(SLJIT_CONVD_FROMW & 0x1) && (SLJIT_MOVD < SLJIT_CONVW_FROMD), \
1070 invalid_float_opcodes); \
1071 if (GET_OPCODE(op) >= SLJIT_CONVW_FROMD) { \
1072 if (GET_OPCODE(op) == SLJIT_CMPD) { \
1073 check_sljit_emit_fop1_cmp(compiler, op, dst, dstw, src, srcw); \
1074 ADJUST_LOCAL_OFFSET(dst, dstw); \
1075 ADJUST_LOCAL_OFFSET(src, srcw); \
1076 return sljit_emit_fop1_cmp(compiler, op, dst, dstw, src, srcw); \
1078 if ((GET_OPCODE(op) | 0x1) == SLJIT_CONVI_FROMD) { \
1079 check_sljit_emit_fop1_convw_fromd(compiler, op, dst, dstw, src, srcw); \
1080 ADJUST_LOCAL_OFFSET(dst, dstw); \
1081 ADJUST_LOCAL_OFFSET(src, srcw); \
1082 return sljit_emit_fop1_convw_fromd(compiler, op, dst, dstw, src, srcw); \
1084 check_sljit_emit_fop1_convd_fromw(compiler, op, dst, dstw, src, srcw); \
1085 ADJUST_LOCAL_OFFSET(dst, dstw); \
1086 ADJUST_LOCAL_OFFSET(src, srcw); \
1087 return sljit_emit_fop1_convd_fromw(compiler, op, dst, dstw, src, srcw); \
1089 check_sljit_emit_fop1(compiler, op, dst, dstw, src, srcw); \
1090 ADJUST_LOCAL_OFFSET(dst, dstw); \
1091 ADJUST_LOCAL_OFFSET(src, srcw);
1093 static SLJIT_INLINE
void check_sljit_emit_fop1(struct sljit_compiler
*compiler
, sljit_si op
,
1094 sljit_si dst
, sljit_sw dstw
,
1095 sljit_si src
, sljit_sw srcw
)
1097 /* If debug and verbose are disabled, all arguments are unused. */
1098 SLJIT_UNUSED_ARG(compiler
);
1099 SLJIT_UNUSED_ARG(op
);
1100 SLJIT_UNUSED_ARG(dst
);
1101 SLJIT_UNUSED_ARG(dstw
);
1102 SLJIT_UNUSED_ARG(src
);
1103 SLJIT_UNUSED_ARG(srcw
);
1105 #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) || (defined SLJIT_DEBUG && SLJIT_DEBUG)
1106 if (SLJIT_UNLIKELY(compiler
->skip_checks
)) {
1107 compiler
->skip_checks
= 0;
1112 SLJIT_ASSERT(GET_OPCODE(op
) >= SLJIT_MOVD
&& GET_OPCODE(op
) <= SLJIT_CONVD_FROMS
);
1113 #if (defined SLJIT_DEBUG && SLJIT_DEBUG)
1114 FUNCTION_CHECK_FOP();
1115 FUNCTION_FCHECK(src
, srcw
);
1116 FUNCTION_FCHECK(dst
, dstw
);
1118 #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
1119 if (SLJIT_UNLIKELY(!!compiler
->verbose
)) {
1120 fprintf(compiler
->verbose
, " %s%s ", op_names
[GET_OPCODE(op
)],
1121 (GET_OPCODE(op
) == SLJIT_CONVD_FROMS
)
1122 ? ((op
& SLJIT_SINGLE_OP
) ? "s.fromd" : "d.froms")
1123 : ((op
& SLJIT_SINGLE_OP
) ? "s" : "d"));
1124 sljit_verbose_fparam(dst
, dstw
);
1125 fprintf(compiler
->verbose
, ", ");
1126 sljit_verbose_fparam(src
, srcw
);
1127 fprintf(compiler
->verbose
, "\n");
1132 static SLJIT_INLINE
void check_sljit_emit_fop1_cmp(struct sljit_compiler
*compiler
, sljit_si op
,
1133 sljit_si src1
, sljit_sw src1w
,
1134 sljit_si src2
, sljit_sw src2w
)
1136 /* If debug and verbose are disabled, all arguments are unused. */
1137 SLJIT_UNUSED_ARG(compiler
);
1138 SLJIT_UNUSED_ARG(op
);
1139 SLJIT_UNUSED_ARG(src1
);
1140 SLJIT_UNUSED_ARG(src1w
);
1141 SLJIT_UNUSED_ARG(src2
);
1142 SLJIT_UNUSED_ARG(src2w
);
1144 #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) || (defined SLJIT_DEBUG && SLJIT_DEBUG)
1145 if (SLJIT_UNLIKELY(compiler
->skip_checks
)) {
1146 compiler
->skip_checks
= 0;
1151 SLJIT_ASSERT(GET_OPCODE(op
) == SLJIT_CMPD
);
1152 #if (defined SLJIT_DEBUG && SLJIT_DEBUG)
1153 FUNCTION_CHECK_FOP();
1154 FUNCTION_FCHECK(src1
, src1w
);
1155 FUNCTION_FCHECK(src2
, src2w
);
1157 #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
1158 if (SLJIT_UNLIKELY(!!compiler
->verbose
)) {
1159 fprintf(compiler
->verbose
, " %s%s%s%s ", op_names
[GET_OPCODE(op
)], (op
& SLJIT_SINGLE_OP
) ? "s" : "d",
1160 !(op
& SLJIT_SET_E
) ? "" : ".e", !(op
& SLJIT_SET_S
) ? "" : ".s");
1161 sljit_verbose_fparam(src1
, src1w
);
1162 fprintf(compiler
->verbose
, ", ");
1163 sljit_verbose_fparam(src2
, src2w
);
1164 fprintf(compiler
->verbose
, "\n");
1169 static SLJIT_INLINE
void check_sljit_emit_fop1_convw_fromd(struct sljit_compiler
*compiler
, sljit_si op
,
1170 sljit_si dst
, sljit_sw dstw
,
1171 sljit_si src
, sljit_sw srcw
)
1173 /* If debug and verbose are disabled, all arguments are unused. */
1174 SLJIT_UNUSED_ARG(compiler
);
1175 SLJIT_UNUSED_ARG(op
);
1176 SLJIT_UNUSED_ARG(dst
);
1177 SLJIT_UNUSED_ARG(dstw
);
1178 SLJIT_UNUSED_ARG(src
);
1179 SLJIT_UNUSED_ARG(srcw
);
1181 #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) || (defined SLJIT_DEBUG && SLJIT_DEBUG)
1182 if (SLJIT_UNLIKELY(compiler
->skip_checks
)) {
1183 compiler
->skip_checks
= 0;
1188 SLJIT_ASSERT(GET_OPCODE(op
) >= SLJIT_CONVW_FROMD
&& GET_OPCODE(op
) <= SLJIT_CONVI_FROMD
);
1189 #if (defined SLJIT_DEBUG && SLJIT_DEBUG)
1190 FUNCTION_CHECK_FOP();
1191 FUNCTION_FCHECK(src
, srcw
);
1192 FUNCTION_CHECK_DST(dst
, dstw
);
1194 #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
1195 if (SLJIT_UNLIKELY(!!compiler
->verbose
)) {
1196 fprintf(compiler
->verbose
, " %s%s.from%s ", op_names
[GET_OPCODE(op
)],
1197 (GET_OPCODE(op
) == SLJIT_CONVI_FROMD
) ? "i" : "w",
1198 (op
& SLJIT_SINGLE_OP
) ? "s" : "d");
1199 sljit_verbose_param(dst
, dstw
);
1200 fprintf(compiler
->verbose
, ", ");
1201 sljit_verbose_fparam(src
, srcw
);
1202 fprintf(compiler
->verbose
, "\n");
1207 static SLJIT_INLINE
void check_sljit_emit_fop1_convd_fromw(struct sljit_compiler
*compiler
, sljit_si op
,
1208 sljit_si dst
, sljit_sw dstw
,
1209 sljit_si src
, sljit_sw srcw
)
1211 /* If debug and verbose are disabled, all arguments are unused. */
1212 SLJIT_UNUSED_ARG(compiler
);
1213 SLJIT_UNUSED_ARG(op
);
1214 SLJIT_UNUSED_ARG(dst
);
1215 SLJIT_UNUSED_ARG(dstw
);
1216 SLJIT_UNUSED_ARG(src
);
1217 SLJIT_UNUSED_ARG(srcw
);
1219 #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) || (defined SLJIT_DEBUG && SLJIT_DEBUG)
1220 if (SLJIT_UNLIKELY(compiler
->skip_checks
)) {
1221 compiler
->skip_checks
= 0;
1226 SLJIT_ASSERT(GET_OPCODE(op
) >= SLJIT_CONVD_FROMW
&& GET_OPCODE(op
) <= SLJIT_CONVD_FROMI
);
1227 #if (defined SLJIT_DEBUG && SLJIT_DEBUG)
1228 FUNCTION_CHECK_FOP();
1229 FUNCTION_CHECK_SRC(src
, srcw
);
1230 FUNCTION_FCHECK(dst
, dstw
);
1232 #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
1233 if (SLJIT_UNLIKELY(!!compiler
->verbose
)) {
1234 fprintf(compiler
->verbose
, " %s%s.from%s ", op_names
[GET_OPCODE(op
)],
1235 (op
& SLJIT_SINGLE_OP
) ? "s" : "d",
1236 (GET_OPCODE(op
) == SLJIT_CONVD_FROMI
) ? "i" : "w");
1237 sljit_verbose_fparam(dst
, dstw
);
1238 fprintf(compiler
->verbose
, ", ");
1239 sljit_verbose_param(src
, srcw
);
1240 fprintf(compiler
->verbose
, "\n");
1245 static SLJIT_INLINE
void check_sljit_emit_fop2(struct sljit_compiler
*compiler
, sljit_si op
,
1246 sljit_si dst
, sljit_sw dstw
,
1247 sljit_si src1
, sljit_sw src1w
,
1248 sljit_si src2
, sljit_sw src2w
)
1250 /* If debug and verbose are disabled, all arguments are unused. */
1251 SLJIT_UNUSED_ARG(compiler
);
1252 SLJIT_UNUSED_ARG(op
);
1253 SLJIT_UNUSED_ARG(dst
);
1254 SLJIT_UNUSED_ARG(dstw
);
1255 SLJIT_UNUSED_ARG(src1
);
1256 SLJIT_UNUSED_ARG(src1w
);
1257 SLJIT_UNUSED_ARG(src2
);
1258 SLJIT_UNUSED_ARG(src2w
);
1260 SLJIT_ASSERT(sljit_is_fpu_available());
1261 SLJIT_ASSERT(GET_OPCODE(op
) >= SLJIT_ADDD
&& GET_OPCODE(op
) <= SLJIT_DIVD
);
1262 #if (defined SLJIT_DEBUG && SLJIT_DEBUG)
1263 FUNCTION_CHECK_FOP();
1264 FUNCTION_FCHECK(src1
, src1w
);
1265 FUNCTION_FCHECK(src2
, src2w
);
1266 FUNCTION_FCHECK(dst
, dstw
);
1268 #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
1269 if (SLJIT_UNLIKELY(!!compiler
->verbose
)) {
1270 fprintf(compiler
->verbose
, " %s%s ", op_names
[GET_OPCODE(op
)], (op
& SLJIT_SINGLE_OP
) ? "s" : "d");
1271 sljit_verbose_fparam(dst
, dstw
);
1272 fprintf(compiler
->verbose
, ", ");
1273 sljit_verbose_fparam(src1
, src1w
);
1274 fprintf(compiler
->verbose
, ", ");
1275 sljit_verbose_fparam(src2
, src2w
);
1276 fprintf(compiler
->verbose
, "\n");
1281 static SLJIT_INLINE
void check_sljit_emit_label(struct sljit_compiler
*compiler
)
1283 /* If debug and verbose are disabled, all arguments are unused. */
1284 SLJIT_UNUSED_ARG(compiler
);
1286 #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
1287 if (SLJIT_UNLIKELY(!!compiler
->verbose
))
1288 fprintf(compiler
->verbose
, "label:\n");
1292 static SLJIT_INLINE
void check_sljit_emit_jump(struct sljit_compiler
*compiler
, sljit_si type
)
1294 /* If debug and verbose are disabled, all arguments are unused. */
1295 SLJIT_UNUSED_ARG(compiler
);
1296 SLJIT_UNUSED_ARG(type
);
1298 #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) || (defined SLJIT_DEBUG && SLJIT_DEBUG)
1299 if (SLJIT_UNLIKELY(compiler
->skip_checks
)) {
1300 compiler
->skip_checks
= 0;
1305 SLJIT_ASSERT(!(type
& ~(0xff | SLJIT_REWRITABLE_JUMP
)));
1306 SLJIT_ASSERT((type
& 0xff) >= SLJIT_C_EQUAL
&& (type
& 0xff) <= SLJIT_CALL3
);
1307 #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
1308 if (SLJIT_UNLIKELY(!!compiler
->verbose
))
1309 fprintf(compiler
->verbose
, " jump%s.%s\n", !(type
& SLJIT_REWRITABLE_JUMP
) ? "" : ".r", jump_names
[type
& 0xff]);
1313 static SLJIT_INLINE
void check_sljit_emit_cmp(struct sljit_compiler
*compiler
, sljit_si type
,
1314 sljit_si src1
, sljit_sw src1w
,
1315 sljit_si src2
, sljit_sw src2w
)
1317 SLJIT_UNUSED_ARG(compiler
);
1318 SLJIT_UNUSED_ARG(type
);
1319 SLJIT_UNUSED_ARG(src1
);
1320 SLJIT_UNUSED_ARG(src1w
);
1321 SLJIT_UNUSED_ARG(src2
);
1322 SLJIT_UNUSED_ARG(src2w
);
1324 SLJIT_ASSERT(!(type
& ~(0xff | SLJIT_REWRITABLE_JUMP
| SLJIT_INT_OP
)));
1325 SLJIT_ASSERT((type
& 0xff) >= SLJIT_C_EQUAL
&& (type
& 0xff) <= SLJIT_C_SIG_LESS_EQUAL
);
1326 #if (defined SLJIT_DEBUG && SLJIT_DEBUG)
1327 FUNCTION_CHECK_SRC(src1
, src1w
);
1328 FUNCTION_CHECK_SRC(src2
, src2w
);
1330 #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
1331 if (SLJIT_UNLIKELY(!!compiler
->verbose
)) {
1332 fprintf(compiler
->verbose
, " %scmp%s.%s ", !(type
& SLJIT_INT_OP
) ? "" : "i", !(type
& SLJIT_REWRITABLE_JUMP
) ? "" : ".r", jump_names
[type
& 0xff]);
1333 sljit_verbose_param(src1
, src1w
);
1334 fprintf(compiler
->verbose
, ", ");
1335 sljit_verbose_param(src2
, src2w
);
1336 fprintf(compiler
->verbose
, "\n");
1341 static SLJIT_INLINE
void check_sljit_emit_fcmp(struct sljit_compiler
*compiler
, sljit_si type
,
1342 sljit_si src1
, sljit_sw src1w
,
1343 sljit_si src2
, sljit_sw src2w
)
1345 SLJIT_UNUSED_ARG(compiler
);
1346 SLJIT_UNUSED_ARG(type
);
1347 SLJIT_UNUSED_ARG(src1
);
1348 SLJIT_UNUSED_ARG(src1w
);
1349 SLJIT_UNUSED_ARG(src2
);
1350 SLJIT_UNUSED_ARG(src2w
);
1352 SLJIT_ASSERT(sljit_is_fpu_available());
1353 SLJIT_ASSERT(!(type
& ~(0xff | SLJIT_REWRITABLE_JUMP
| SLJIT_SINGLE_OP
)));
1354 SLJIT_ASSERT((type
& 0xff) >= SLJIT_C_FLOAT_EQUAL
&& (type
& 0xff) <= SLJIT_C_FLOAT_ORDERED
);
1355 #if (defined SLJIT_DEBUG && SLJIT_DEBUG)
1356 FUNCTION_FCHECK(src1
, src1w
);
1357 FUNCTION_FCHECK(src2
, src2w
);
1359 #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
1360 if (SLJIT_UNLIKELY(!!compiler
->verbose
)) {
1361 fprintf(compiler
->verbose
, " %scmp%s.%s ", (type
& SLJIT_SINGLE_OP
) ? "s" : "d",
1362 !(type
& SLJIT_REWRITABLE_JUMP
) ? "" : ".r", jump_names
[type
& 0xff]);
1363 sljit_verbose_fparam(src1
, src1w
);
1364 fprintf(compiler
->verbose
, ", ");
1365 sljit_verbose_fparam(src2
, src2w
);
1366 fprintf(compiler
->verbose
, "\n");
1371 static SLJIT_INLINE
void check_sljit_emit_ijump(struct sljit_compiler
*compiler
, sljit_si type
, sljit_si src
, sljit_sw srcw
)
1373 /* If debug and verbose are disabled, all arguments are unused. */
1374 SLJIT_UNUSED_ARG(compiler
);
1375 SLJIT_UNUSED_ARG(type
);
1376 SLJIT_UNUSED_ARG(src
);
1377 SLJIT_UNUSED_ARG(srcw
);
1379 #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) || (defined SLJIT_DEBUG && SLJIT_DEBUG)
1380 if (SLJIT_UNLIKELY(compiler
->skip_checks
)) {
1381 compiler
->skip_checks
= 0;
1386 SLJIT_ASSERT(type
>= SLJIT_JUMP
&& type
<= SLJIT_CALL3
);
1387 #if (defined SLJIT_DEBUG && SLJIT_DEBUG)
1388 FUNCTION_CHECK_SRC(src
, srcw
);
1390 #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
1391 if (SLJIT_UNLIKELY(!!compiler
->verbose
)) {
1392 fprintf(compiler
->verbose
, " ijump.%s ", jump_names
[type
]);
1393 sljit_verbose_param(src
, srcw
);
1394 fprintf(compiler
->verbose
, "\n");
1399 static SLJIT_INLINE
void check_sljit_emit_op_flags(struct sljit_compiler
*compiler
, sljit_si op
,
1400 sljit_si dst
, sljit_sw dstw
,
1401 sljit_si src
, sljit_sw srcw
,
1404 /* If debug and verbose are disabled, all arguments are unused. */
1405 SLJIT_UNUSED_ARG(compiler
);
1406 SLJIT_UNUSED_ARG(op
);
1407 SLJIT_UNUSED_ARG(dst
);
1408 SLJIT_UNUSED_ARG(dstw
);
1409 SLJIT_UNUSED_ARG(src
);
1410 SLJIT_UNUSED_ARG(srcw
);
1411 SLJIT_UNUSED_ARG(type
);
1413 SLJIT_ASSERT(type
>= SLJIT_C_EQUAL
&& type
< SLJIT_JUMP
);
1414 SLJIT_ASSERT(op
== SLJIT_MOV
|| GET_OPCODE(op
) == SLJIT_MOV_UI
|| GET_OPCODE(op
) == SLJIT_MOV_SI
1415 || (GET_OPCODE(op
) >= SLJIT_AND
&& GET_OPCODE(op
) <= SLJIT_XOR
));
1416 SLJIT_ASSERT((op
& (SLJIT_SET_U
| SLJIT_SET_S
| SLJIT_SET_O
| SLJIT_SET_C
)) == 0);
1417 SLJIT_ASSERT((op
& (SLJIT_SET_E
| SLJIT_KEEP_FLAGS
)) != (SLJIT_SET_E
| SLJIT_KEEP_FLAGS
));
1418 #if (defined SLJIT_DEBUG && SLJIT_DEBUG)
1419 if (GET_OPCODE(op
) < SLJIT_ADD
) {
1420 SLJIT_ASSERT(src
== SLJIT_UNUSED
&& srcw
== 0);
1422 SLJIT_ASSERT(src
== dst
&& srcw
== dstw
);
1424 FUNCTION_CHECK_DST(dst
, dstw
);
1426 #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
1427 if (SLJIT_UNLIKELY(!!compiler
->verbose
)) {
1428 fprintf(compiler
->verbose
, " %sflags.%s%s%s ", !(op
& SLJIT_INT_OP
) ? "" : "i",
1429 op_names
[GET_OPCODE(op
)], !(op
& SLJIT_SET_E
) ? "" : ".e", !(op
& SLJIT_KEEP_FLAGS
) ? "" : ".k");
1430 sljit_verbose_param(dst
, dstw
);
1431 if (src
!= SLJIT_UNUSED
) {
1432 fprintf(compiler
->verbose
, ", ");
1433 sljit_verbose_param(src
, srcw
);
1435 fprintf(compiler
->verbose
, ", %s\n", jump_names
[type
]);
1440 static SLJIT_INLINE
void check_sljit_get_local_base(struct sljit_compiler
*compiler
, sljit_si dst
, sljit_sw dstw
, sljit_sw offset
)
1442 SLJIT_UNUSED_ARG(compiler
);
1443 SLJIT_UNUSED_ARG(dst
);
1444 SLJIT_UNUSED_ARG(dstw
);
1445 SLJIT_UNUSED_ARG(offset
);
1447 #if (defined SLJIT_DEBUG && SLJIT_DEBUG)
1448 FUNCTION_CHECK_DST(dst
, dstw
);
1450 #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
1451 if (SLJIT_UNLIKELY(!!compiler
->verbose
)) {
1452 fprintf(compiler
->verbose
, " local_base ");
1453 sljit_verbose_param(dst
, dstw
);
1454 fprintf(compiler
->verbose
, ", #%" SLJIT_PRINT_D
"d\n", offset
);
1459 static SLJIT_INLINE
void check_sljit_emit_const(struct sljit_compiler
*compiler
, sljit_si dst
, sljit_sw dstw
, sljit_sw init_value
)
1461 /* If debug and verbose are disabled, all arguments are unused. */
1462 SLJIT_UNUSED_ARG(compiler
);
1463 SLJIT_UNUSED_ARG(dst
);
1464 SLJIT_UNUSED_ARG(dstw
);
1465 SLJIT_UNUSED_ARG(init_value
);
1467 #if (defined SLJIT_DEBUG && SLJIT_DEBUG)
1468 FUNCTION_CHECK_DST(dst
, dstw
);
1470 #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
1471 if (SLJIT_UNLIKELY(!!compiler
->verbose
)) {
1472 fprintf(compiler
->verbose
, " const ");
1473 sljit_verbose_param(dst
, dstw
);
1474 fprintf(compiler
->verbose
, ", #%" SLJIT_PRINT_D
"d\n", init_value
);
1479 static SLJIT_INLINE sljit_si
emit_mov_before_return(struct sljit_compiler
*compiler
, sljit_si op
, sljit_si src
, sljit_sw srcw
)
1481 /* Return if don't need to do anything. */
1482 if (op
== SLJIT_UNUSED
)
1483 return SLJIT_SUCCESS
;
1485 #if (defined SLJIT_64BIT_ARCHITECTURE && SLJIT_64BIT_ARCHITECTURE)
1486 /* At the moment the pointer size is always equal to sljit_sw. May be changed in the future. */
1487 if (src
== SLJIT_RETURN_REG
&& (op
== SLJIT_MOV
|| op
== SLJIT_MOV_P
))
1488 return SLJIT_SUCCESS
;
1490 if (src
== SLJIT_RETURN_REG
&& (op
== SLJIT_MOV
|| op
== SLJIT_MOV_UI
|| op
== SLJIT_MOV_SI
|| op
== SLJIT_MOV_P
))
1491 return SLJIT_SUCCESS
;
1494 #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) || (defined SLJIT_DEBUG && SLJIT_DEBUG)
1495 compiler
->skip_checks
= 1;
1497 return sljit_emit_op1(compiler
, op
, SLJIT_RETURN_REG
, 0, src
, srcw
);
1500 /* CPU description section */
1502 #if (defined SLJIT_32BIT_ARCHITECTURE && SLJIT_32BIT_ARCHITECTURE)
1503 #define SLJIT_CPUINFO_PART1 " 32bit ("
1504 #elif (defined SLJIT_64BIT_ARCHITECTURE && SLJIT_64BIT_ARCHITECTURE)
1505 #define SLJIT_CPUINFO_PART1 " 64bit ("
1507 #error "Internal error: CPU type info missing"
1510 #if (defined SLJIT_LITTLE_ENDIAN && SLJIT_LITTLE_ENDIAN)
1511 #define SLJIT_CPUINFO_PART2 "little endian + "
1512 #elif (defined SLJIT_BIG_ENDIAN && SLJIT_BIG_ENDIAN)
1513 #define SLJIT_CPUINFO_PART2 "big endian + "
1515 #error "Internal error: CPU type info missing"
1518 #if (defined SLJIT_UNALIGNED && SLJIT_UNALIGNED)
1519 #define SLJIT_CPUINFO_PART3 "unaligned)"
1521 #define SLJIT_CPUINFO_PART3 "aligned)"
1524 #define SLJIT_CPUINFO SLJIT_CPUINFO_PART1 SLJIT_CPUINFO_PART2 SLJIT_CPUINFO_PART3
1526 #if (defined SLJIT_CONFIG_X86 && SLJIT_CONFIG_X86)
1527 # include "sljitNativeX86_common.c"
1528 #elif (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5)
1529 # include "sljitNativeARM_32.c"
1530 #elif (defined SLJIT_CONFIG_ARM_V7 && SLJIT_CONFIG_ARM_V7)
1531 # include "sljitNativeARM_32.c"
1532 #elif (defined SLJIT_CONFIG_ARM_THUMB2 && SLJIT_CONFIG_ARM_THUMB2)
1533 # include "sljitNativeARM_T2_32.c"
1534 #elif (defined SLJIT_CONFIG_ARM_64 && SLJIT_CONFIG_ARM_64)
1535 # include "sljitNativeARM_64.c"
1536 #elif (defined SLJIT_CONFIG_PPC && SLJIT_CONFIG_PPC)
1537 # include "sljitNativePPC_common.c"
1538 #elif (defined SLJIT_CONFIG_MIPS && SLJIT_CONFIG_MIPS)
1539 # include "sljitNativeMIPS_common.c"
1540 #elif (defined SLJIT_CONFIG_SPARC && SLJIT_CONFIG_SPARC)
1541 # include "sljitNativeSPARC_common.c"
1542 #elif (defined SLJIT_CONFIG_TILEGX && SLJIT_CONFIG_TILEGX)
1543 # include "sljitNativeTILEGX_64.c"
1546 #if !(defined SLJIT_CONFIG_MIPS && SLJIT_CONFIG_MIPS)
1548 SLJIT_API_FUNC_ATTRIBUTE
struct sljit_jump
* sljit_emit_cmp(struct sljit_compiler
*compiler
, sljit_si type
,
1549 sljit_si src1
, sljit_sw src1w
,
1550 sljit_si src2
, sljit_sw src2w
)
1552 /* Default compare for most architectures. */
1553 sljit_si flags
, tmp_src
, condition
;
1557 check_sljit_emit_cmp(compiler
, type
, src1
, src1w
, src2
, src2w
);
1559 condition
= type
& 0xff;
1560 #if (defined SLJIT_CONFIG_ARM_64 && SLJIT_CONFIG_ARM_64)
1561 if ((condition
== SLJIT_C_EQUAL
|| condition
== SLJIT_C_NOT_EQUAL
)) {
1562 if ((src1
& SLJIT_IMM
) && !src1w
) {
1568 if ((src2
& SLJIT_IMM
) && !src2w
)
1569 return emit_cmp_to0(compiler
, type
, src1
, src1w
);
1573 if (SLJIT_UNLIKELY((src1
& SLJIT_IMM
) && !(src2
& SLJIT_IMM
))) {
1574 /* Immediate is prefered as second argument by most architectures. */
1575 switch (condition
) {
1577 condition
= SLJIT_C_GREATER
;
1579 case SLJIT_C_GREATER_EQUAL
:
1580 condition
= SLJIT_C_LESS_EQUAL
;
1582 case SLJIT_C_GREATER
:
1583 condition
= SLJIT_C_LESS
;
1585 case SLJIT_C_LESS_EQUAL
:
1586 condition
= SLJIT_C_GREATER_EQUAL
;
1588 case SLJIT_C_SIG_LESS
:
1589 condition
= SLJIT_C_SIG_GREATER
;
1591 case SLJIT_C_SIG_GREATER_EQUAL
:
1592 condition
= SLJIT_C_SIG_LESS_EQUAL
;
1594 case SLJIT_C_SIG_GREATER
:
1595 condition
= SLJIT_C_SIG_LESS
;
1597 case SLJIT_C_SIG_LESS_EQUAL
:
1598 condition
= SLJIT_C_SIG_GREATER_EQUAL
;
1601 type
= condition
| (type
& (SLJIT_INT_OP
| SLJIT_REWRITABLE_JUMP
));
1610 if (condition
<= SLJIT_C_NOT_ZERO
)
1611 flags
= SLJIT_SET_E
;
1612 else if (condition
<= SLJIT_C_LESS_EQUAL
)
1613 flags
= SLJIT_SET_U
;
1615 flags
= SLJIT_SET_S
;
1617 #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) || (defined SLJIT_DEBUG && SLJIT_DEBUG)
1618 compiler
->skip_checks
= 1;
1620 PTR_FAIL_IF(sljit_emit_op2(compiler
, SLJIT_SUB
| flags
| (type
& SLJIT_INT_OP
),
1621 SLJIT_UNUSED
, 0, src1
, src1w
, src2
, src2w
));
1622 #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) || (defined SLJIT_DEBUG && SLJIT_DEBUG)
1623 compiler
->skip_checks
= 1;
1625 return sljit_emit_jump(compiler
, condition
| (type
& SLJIT_REWRITABLE_JUMP
));
1628 SLJIT_API_FUNC_ATTRIBUTE
struct sljit_jump
* sljit_emit_fcmp(struct sljit_compiler
*compiler
, sljit_si type
,
1629 sljit_si src1
, sljit_sw src1w
,
1630 sljit_si src2
, sljit_sw src2w
)
1632 sljit_si flags
, condition
;
1634 check_sljit_emit_fcmp(compiler
, type
, src1
, src1w
, src2
, src2w
);
1636 condition
= type
& 0xff;
1637 flags
= (condition
<= SLJIT_C_FLOAT_NOT_EQUAL
) ? SLJIT_SET_E
: SLJIT_SET_S
;
1638 if (type
& SLJIT_SINGLE_OP
)
1639 flags
|= SLJIT_SINGLE_OP
;
1641 #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) || (defined SLJIT_DEBUG && SLJIT_DEBUG)
1642 compiler
->skip_checks
= 1;
1644 sljit_emit_fop1(compiler
, SLJIT_CMPD
| flags
, src1
, src1w
, src2
, src2w
);
1646 #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) || (defined SLJIT_DEBUG && SLJIT_DEBUG)
1647 compiler
->skip_checks
= 1;
1649 return sljit_emit_jump(compiler
, condition
| (type
& SLJIT_REWRITABLE_JUMP
));
1654 #if !(defined SLJIT_CONFIG_X86 && SLJIT_CONFIG_X86)
1656 SLJIT_API_FUNC_ATTRIBUTE sljit_si
sljit_get_local_base(struct sljit_compiler
*compiler
, sljit_si dst
, sljit_sw dstw
, sljit_sw offset
)
1659 check_sljit_get_local_base(compiler
, dst
, dstw
, offset
);
1661 ADJUST_LOCAL_OFFSET(SLJIT_MEM1(SLJIT_LOCALS_REG
), offset
);
1662 #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) || (defined SLJIT_DEBUG && SLJIT_DEBUG)
1663 compiler
->skip_checks
= 1;
1666 return sljit_emit_op2(compiler
, SLJIT_ADD
| SLJIT_KEEP_FLAGS
, dst
, dstw
, SLJIT_LOCALS_REG
, 0, SLJIT_IMM
, offset
);
1667 return sljit_emit_op1(compiler
, SLJIT_MOV
, dst
, dstw
, SLJIT_LOCALS_REG
, 0);
1672 #else /* SLJIT_CONFIG_UNSUPPORTED */
1674 /* Empty function bodies for those machines, which are not (yet) supported. */
1676 SLJIT_API_FUNC_ATTRIBUTE SLJIT_CONST
char* sljit_get_platform_name(void)
1678 return "unsupported";
1681 SLJIT_API_FUNC_ATTRIBUTE
struct sljit_compiler
* sljit_create_compiler(void)
1683 SLJIT_ASSERT_STOP();
1687 SLJIT_API_FUNC_ATTRIBUTE
void sljit_free_compiler(struct sljit_compiler
*compiler
)
1689 SLJIT_UNUSED_ARG(compiler
);
1690 SLJIT_ASSERT_STOP();
1693 SLJIT_API_FUNC_ATTRIBUTE
void* sljit_alloc_memory(struct sljit_compiler
*compiler
, sljit_si size
)
1695 SLJIT_UNUSED_ARG(compiler
);
1696 SLJIT_UNUSED_ARG(size
);
1697 SLJIT_ASSERT_STOP();
1701 #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
1702 SLJIT_API_FUNC_ATTRIBUTE
void sljit_compiler_verbose(struct sljit_compiler
*compiler
, FILE* verbose
)
1704 SLJIT_UNUSED_ARG(compiler
);
1705 SLJIT_UNUSED_ARG(verbose
);
1706 SLJIT_ASSERT_STOP();
1710 SLJIT_API_FUNC_ATTRIBUTE
void* sljit_generate_code(struct sljit_compiler
*compiler
)
1712 SLJIT_UNUSED_ARG(compiler
);
1713 SLJIT_ASSERT_STOP();
1717 SLJIT_API_FUNC_ATTRIBUTE
void sljit_free_code(void* code
)
1719 SLJIT_UNUSED_ARG(code
);
1720 SLJIT_ASSERT_STOP();
1723 SLJIT_API_FUNC_ATTRIBUTE sljit_si
sljit_emit_enter(struct sljit_compiler
*compiler
, sljit_si args
, sljit_si scratches
, sljit_si saveds
, sljit_si local_size
)
1725 SLJIT_UNUSED_ARG(compiler
);
1726 SLJIT_UNUSED_ARG(args
);
1727 SLJIT_UNUSED_ARG(scratches
);
1728 SLJIT_UNUSED_ARG(saveds
);
1729 SLJIT_UNUSED_ARG(local_size
);
1730 SLJIT_ASSERT_STOP();
1731 return SLJIT_ERR_UNSUPPORTED
;
1734 SLJIT_API_FUNC_ATTRIBUTE
void sljit_set_context(struct sljit_compiler
*compiler
, sljit_si args
, sljit_si scratches
, sljit_si saveds
, sljit_si local_size
)
1736 SLJIT_UNUSED_ARG(compiler
);
1737 SLJIT_UNUSED_ARG(args
);
1738 SLJIT_UNUSED_ARG(scratches
);
1739 SLJIT_UNUSED_ARG(saveds
);
1740 SLJIT_UNUSED_ARG(local_size
);
1741 SLJIT_ASSERT_STOP();
1744 SLJIT_API_FUNC_ATTRIBUTE sljit_si
sljit_emit_return(struct sljit_compiler
*compiler
, sljit_si op
, sljit_si src
, sljit_sw srcw
)
1746 SLJIT_UNUSED_ARG(compiler
);
1747 SLJIT_UNUSED_ARG(op
);
1748 SLJIT_UNUSED_ARG(src
);
1749 SLJIT_UNUSED_ARG(srcw
);
1750 SLJIT_ASSERT_STOP();
1751 return SLJIT_ERR_UNSUPPORTED
;
1754 SLJIT_API_FUNC_ATTRIBUTE sljit_si
sljit_emit_fast_enter(struct sljit_compiler
*compiler
, sljit_si dst
, sljit_sw dstw
)
1756 SLJIT_UNUSED_ARG(compiler
);
1757 SLJIT_UNUSED_ARG(dst
);
1758 SLJIT_UNUSED_ARG(dstw
);
1759 SLJIT_ASSERT_STOP();
1760 return SLJIT_ERR_UNSUPPORTED
;
1763 SLJIT_API_FUNC_ATTRIBUTE sljit_si
sljit_emit_fast_return(struct sljit_compiler
*compiler
, sljit_si src
, sljit_sw srcw
)
1765 SLJIT_UNUSED_ARG(compiler
);
1766 SLJIT_UNUSED_ARG(src
);
1767 SLJIT_UNUSED_ARG(srcw
);
1768 SLJIT_ASSERT_STOP();
1769 return SLJIT_ERR_UNSUPPORTED
;
1772 SLJIT_API_FUNC_ATTRIBUTE sljit_si
sljit_emit_op0(struct sljit_compiler
*compiler
, sljit_si op
)
1774 SLJIT_UNUSED_ARG(compiler
);
1775 SLJIT_UNUSED_ARG(op
);
1776 SLJIT_ASSERT_STOP();
1777 return SLJIT_ERR_UNSUPPORTED
;
1780 SLJIT_API_FUNC_ATTRIBUTE sljit_si
sljit_emit_op1(struct sljit_compiler
*compiler
, sljit_si op
,
1781 sljit_si dst
, sljit_sw dstw
,
1782 sljit_si src
, sljit_sw srcw
)
1784 SLJIT_UNUSED_ARG(compiler
);
1785 SLJIT_UNUSED_ARG(op
);
1786 SLJIT_UNUSED_ARG(dst
);
1787 SLJIT_UNUSED_ARG(dstw
);
1788 SLJIT_UNUSED_ARG(src
);
1789 SLJIT_UNUSED_ARG(srcw
);
1790 SLJIT_ASSERT_STOP();
1791 return SLJIT_ERR_UNSUPPORTED
;
1794 SLJIT_API_FUNC_ATTRIBUTE sljit_si
sljit_emit_op2(struct sljit_compiler
*compiler
, sljit_si op
,
1795 sljit_si dst
, sljit_sw dstw
,
1796 sljit_si src1
, sljit_sw src1w
,
1797 sljit_si src2
, sljit_sw src2w
)
1799 SLJIT_UNUSED_ARG(compiler
);
1800 SLJIT_UNUSED_ARG(op
);
1801 SLJIT_UNUSED_ARG(dst
);
1802 SLJIT_UNUSED_ARG(dstw
);
1803 SLJIT_UNUSED_ARG(src1
);
1804 SLJIT_UNUSED_ARG(src1w
);
1805 SLJIT_UNUSED_ARG(src2
);
1806 SLJIT_UNUSED_ARG(src2w
);
1807 SLJIT_ASSERT_STOP();
1808 return SLJIT_ERR_UNSUPPORTED
;
1811 SLJIT_API_FUNC_ATTRIBUTE sljit_si
sljit_get_register_index(sljit_si reg
)
1813 SLJIT_ASSERT_STOP();
1817 SLJIT_API_FUNC_ATTRIBUTE sljit_si
sljit_emit_op_custom(struct sljit_compiler
*compiler
,
1818 void *instruction
, sljit_si size
)
1820 SLJIT_UNUSED_ARG(compiler
);
1821 SLJIT_UNUSED_ARG(instruction
);
1822 SLJIT_UNUSED_ARG(size
);
1823 SLJIT_ASSERT_STOP();
1824 return SLJIT_ERR_UNSUPPORTED
;
1827 SLJIT_API_FUNC_ATTRIBUTE sljit_si
sljit_is_fpu_available(void)
1829 SLJIT_ASSERT_STOP();
1833 SLJIT_API_FUNC_ATTRIBUTE sljit_si
sljit_emit_fop1(struct sljit_compiler
*compiler
, sljit_si op
,
1834 sljit_si dst
, sljit_sw dstw
,
1835 sljit_si src
, sljit_sw srcw
)
1837 SLJIT_UNUSED_ARG(compiler
);
1838 SLJIT_UNUSED_ARG(op
);
1839 SLJIT_UNUSED_ARG(dst
);
1840 SLJIT_UNUSED_ARG(dstw
);
1841 SLJIT_UNUSED_ARG(src
);
1842 SLJIT_UNUSED_ARG(srcw
);
1843 SLJIT_ASSERT_STOP();
1844 return SLJIT_ERR_UNSUPPORTED
;
1847 SLJIT_API_FUNC_ATTRIBUTE sljit_si
sljit_emit_fop2(struct sljit_compiler
*compiler
, sljit_si op
,
1848 sljit_si dst
, sljit_sw dstw
,
1849 sljit_si src1
, sljit_sw src1w
,
1850 sljit_si src2
, sljit_sw src2w
)
1852 SLJIT_UNUSED_ARG(compiler
);
1853 SLJIT_UNUSED_ARG(op
);
1854 SLJIT_UNUSED_ARG(dst
);
1855 SLJIT_UNUSED_ARG(dstw
);
1856 SLJIT_UNUSED_ARG(src1
);
1857 SLJIT_UNUSED_ARG(src1w
);
1858 SLJIT_UNUSED_ARG(src2
);
1859 SLJIT_UNUSED_ARG(src2w
);
1860 SLJIT_ASSERT_STOP();
1861 return SLJIT_ERR_UNSUPPORTED
;
1864 SLJIT_API_FUNC_ATTRIBUTE
struct sljit_label
* sljit_emit_label(struct sljit_compiler
*compiler
)
1866 SLJIT_UNUSED_ARG(compiler
);
1867 SLJIT_ASSERT_STOP();
1871 SLJIT_API_FUNC_ATTRIBUTE
struct sljit_jump
* sljit_emit_jump(struct sljit_compiler
*compiler
, sljit_si type
)
1873 SLJIT_UNUSED_ARG(compiler
);
1874 SLJIT_UNUSED_ARG(type
);
1875 SLJIT_ASSERT_STOP();
1879 SLJIT_API_FUNC_ATTRIBUTE
struct sljit_jump
* sljit_emit_cmp(struct sljit_compiler
*compiler
, sljit_si type
,
1880 sljit_si src1
, sljit_sw src1w
,
1881 sljit_si src2
, sljit_sw src2w
)
1883 SLJIT_UNUSED_ARG(compiler
);
1884 SLJIT_UNUSED_ARG(type
);
1885 SLJIT_UNUSED_ARG(src1
);
1886 SLJIT_UNUSED_ARG(src1w
);
1887 SLJIT_UNUSED_ARG(src2
);
1888 SLJIT_UNUSED_ARG(src2w
);
1889 SLJIT_ASSERT_STOP();
1893 SLJIT_API_FUNC_ATTRIBUTE
struct sljit_jump
* sljit_emit_fcmp(struct sljit_compiler
*compiler
, sljit_si type
,
1894 sljit_si src1
, sljit_sw src1w
,
1895 sljit_si src2
, sljit_sw src2w
)
1897 SLJIT_UNUSED_ARG(compiler
);
1898 SLJIT_UNUSED_ARG(type
);
1899 SLJIT_UNUSED_ARG(src1
);
1900 SLJIT_UNUSED_ARG(src1w
);
1901 SLJIT_UNUSED_ARG(src2
);
1902 SLJIT_UNUSED_ARG(src2w
);
1903 SLJIT_ASSERT_STOP();
1907 SLJIT_API_FUNC_ATTRIBUTE
void sljit_set_label(struct sljit_jump
*jump
, struct sljit_label
* label
)
1909 SLJIT_UNUSED_ARG(jump
);
1910 SLJIT_UNUSED_ARG(label
);
1911 SLJIT_ASSERT_STOP();
1914 SLJIT_API_FUNC_ATTRIBUTE
void sljit_set_target(struct sljit_jump
*jump
, sljit_uw target
)
1916 SLJIT_UNUSED_ARG(jump
);
1917 SLJIT_UNUSED_ARG(target
);
1918 SLJIT_ASSERT_STOP();
1921 SLJIT_API_FUNC_ATTRIBUTE sljit_si
sljit_emit_ijump(struct sljit_compiler
*compiler
, sljit_si type
, sljit_si src
, sljit_sw srcw
)
1923 SLJIT_UNUSED_ARG(compiler
);
1924 SLJIT_UNUSED_ARG(type
);
1925 SLJIT_UNUSED_ARG(src
);
1926 SLJIT_UNUSED_ARG(srcw
);
1927 SLJIT_ASSERT_STOP();
1928 return SLJIT_ERR_UNSUPPORTED
;
1931 SLJIT_API_FUNC_ATTRIBUTE sljit_si
sljit_emit_op_flags(struct sljit_compiler
*compiler
, sljit_si op
,
1932 sljit_si dst
, sljit_sw dstw
,
1933 sljit_si src
, sljit_sw srcw
,
1936 SLJIT_UNUSED_ARG(compiler
);
1937 SLJIT_UNUSED_ARG(op
);
1938 SLJIT_UNUSED_ARG(dst
);
1939 SLJIT_UNUSED_ARG(dstw
);
1940 SLJIT_UNUSED_ARG(src
);
1941 SLJIT_UNUSED_ARG(srcw
);
1942 SLJIT_UNUSED_ARG(type
);
1943 SLJIT_ASSERT_STOP();
1944 return SLJIT_ERR_UNSUPPORTED
;
1947 SLJIT_API_FUNC_ATTRIBUTE sljit_si
sljit_get_local_base(struct sljit_compiler
*compiler
, sljit_si dst
, sljit_sw dstw
, sljit_sw offset
)
1949 SLJIT_UNUSED_ARG(compiler
);
1950 SLJIT_UNUSED_ARG(dst
);
1951 SLJIT_UNUSED_ARG(dstw
);
1952 SLJIT_UNUSED_ARG(offset
);
1953 SLJIT_ASSERT_STOP();
1954 return SLJIT_ERR_UNSUPPORTED
;
1957 SLJIT_API_FUNC_ATTRIBUTE
struct sljit_const
* sljit_emit_const(struct sljit_compiler
*compiler
, sljit_si dst
, sljit_sw dstw
, sljit_sw initval
)
1959 SLJIT_UNUSED_ARG(compiler
);
1960 SLJIT_UNUSED_ARG(dst
);
1961 SLJIT_UNUSED_ARG(dstw
);
1962 SLJIT_UNUSED_ARG(initval
);
1963 SLJIT_ASSERT_STOP();
1967 SLJIT_API_FUNC_ATTRIBUTE
void sljit_set_jump_addr(sljit_uw addr
, sljit_uw new_addr
)
1969 SLJIT_UNUSED_ARG(addr
);
1970 SLJIT_UNUSED_ARG(new_addr
);
1971 SLJIT_ASSERT_STOP();
1974 SLJIT_API_FUNC_ATTRIBUTE
void sljit_set_const(sljit_uw addr
, sljit_sw new_constant
)
1976 SLJIT_UNUSED_ARG(addr
);
1977 SLJIT_UNUSED_ARG(new_constant
);
1978 SLJIT_ASSERT_STOP();