1 /*
2 * Stack-less Just-In-Time compiler
3 *
4 * Copyright Zoltan Herczeg ([email protected]). All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without modification, are
7 * permitted provided that the following conditions are met:
8 *
9 * 1. Redistributions of source code must retain the above copyright notice, this list of
10 * conditions and the following disclaimer.
11 *
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.
15 *
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.
25 */
26
27 #include "sljitLir.h"
28
29 #ifdef _WIN32
30
31 #include <windows.h>
32
33 #endif /* _WIN32 */
34
35 #if !(defined SLJIT_STD_MACROS_DEFINED && SLJIT_STD_MACROS_DEFINED)
36
37 /* These libraries are needed for the macros below. */
38 #include <stdlib.h>
39 #include <string.h>
40
41 #endif /* SLJIT_STD_MACROS_DEFINED */
42
43 #define CHECK_ERROR() \
44 do { \
45 if (SLJIT_UNLIKELY(compiler->error)) \
46 return compiler->error; \
47 } while (0)
48
49 #define CHECK_ERROR_PTR() \
50 do { \
51 if (SLJIT_UNLIKELY(compiler->error)) \
52 return NULL; \
53 } while (0)
54
55 #define FAIL_IF(expr) \
56 do { \
57 if (SLJIT_UNLIKELY(expr)) \
58 return compiler->error; \
59 } while (0)
60
61 #define PTR_FAIL_IF(expr) \
62 do { \
63 if (SLJIT_UNLIKELY(expr)) \
64 return NULL; \
65 } while (0)
66
67 #define FAIL_IF_NULL(ptr) \
68 do { \
69 if (SLJIT_UNLIKELY(!(ptr))) { \
70 compiler->error = SLJIT_ERR_ALLOC_FAILED; \
71 return SLJIT_ERR_ALLOC_FAILED; \
72 } \
73 } while (0)
74
75 #define PTR_FAIL_IF_NULL(ptr) \
76 do { \
77 if (SLJIT_UNLIKELY(!(ptr))) { \
78 compiler->error = SLJIT_ERR_ALLOC_FAILED; \
79 return NULL; \
80 } \
81 } while (0)
82
83 #define PTR_FAIL_WITH_EXEC_IF(ptr) \
84 do { \
85 if (SLJIT_UNLIKELY(!(ptr))) { \
86 compiler->error = SLJIT_ERR_EX_ALLOC_FAILED; \
87 return NULL; \
88 } \
89 } while (0)
90
91 #if !(defined SLJIT_CONFIG_UNSUPPORTED && SLJIT_CONFIG_UNSUPPORTED)
92
93 #define SSIZE_OF(type) ((sljit_s32)sizeof(sljit_ ## type))
94
95 #define VARIABLE_FLAG_SHIFT (10)
96 /* All variable flags are even. */
97 #define VARIABLE_FLAG_MASK (0x3e << VARIABLE_FLAG_SHIFT)
98 #define GET_FLAG_TYPE(op) ((op) >> VARIABLE_FLAG_SHIFT)
99
100 #define GET_OPCODE(op) \
101 ((op) & ~(SLJIT_32 | SLJIT_SET_Z | VARIABLE_FLAG_MASK))
102
103 #define HAS_FLAGS(op) \
104 ((op) & (SLJIT_SET_Z | VARIABLE_FLAG_MASK))
105
106 #define GET_ALL_FLAGS(op) \
107 ((op) & (SLJIT_32 | SLJIT_SET_Z | VARIABLE_FLAG_MASK))
108
109 #if (defined SLJIT_64BIT_ARCHITECTURE && SLJIT_64BIT_ARCHITECTURE)
110 #define TYPE_CAST_NEEDED(op) \
111 ((op) >= SLJIT_MOV_U8 && (op) <= SLJIT_MOV_S32)
112 #else /* !SLJIT_64BIT_ARCHITECTURE */
113 #define TYPE_CAST_NEEDED(op) \
114 ((op) >= SLJIT_MOV_U8 && (op) <= SLJIT_MOV_S16)
115 #endif /* SLJIT_64BIT_ARCHITECTURE */
116
117 #define BUF_SIZE 4096
118
119 #if (defined SLJIT_32BIT_ARCHITECTURE && SLJIT_32BIT_ARCHITECTURE)
120 #define ABUF_SIZE 2048
121 #else
122 #define ABUF_SIZE 4096
123 #endif
124
125 /* Parameter parsing. */
126 #define REG_MASK 0x7f
127 #define OFFS_REG(reg) (((reg) >> 8) & REG_MASK)
128 #define OFFS_REG_MASK (REG_MASK << 8)
129 #define TO_OFFS_REG(reg) ((reg) << 8)
130 #define FAST_IS_REG(reg) ((reg) < REG_MASK)
131
132 /* Mask for argument types. */
133 #define SLJIT_ARG_MASK 0x7
134 #define SLJIT_ARG_FULL_MASK (SLJIT_ARG_MASK | SLJIT_ARG_TYPE_SCRATCH_REG)
135
136 /* Mask for register pairs. */
137 #define REG_PAIR_MASK 0x7f00
138 #define REG_PAIR_FIRST(reg) ((reg) & 0x7f)
139 #define REG_PAIR_SECOND(reg) ((reg) >> 8)
140
141 /* Mask for sljit_emit_enter. */
142 #define SLJIT_KEPT_SAVEDS_COUNT(options) ((options) & 0x3)
143
144 /* Getters for simd operations, which returns with log2(size). */
145 #define SLJIT_SIMD_GET_OPCODE(type) ((type) & 0xff)
146 #define SLJIT_SIMD_GET_REG_SIZE(type) (((type) >> 12) & 0x3f)
147 #define SLJIT_SIMD_GET_ELEM_SIZE(type) (((type) >> 18) & 0x3f)
148 #define SLJIT_SIMD_GET_ELEM2_SIZE(type) (((type) >> 24) & 0x3f)
149
150 #define SLJIT_SIMD_CHECK_REG(type) (((type) & 0x3f000) >= SLJIT_SIMD_REG_64 && ((type) & 0x3f000) <= SLJIT_SIMD_REG_512)
151 #define SLJIT_SIMD_TYPE_MASK(m) ((sljit_s32)0xff000fff & ~(SLJIT_SIMD_FLOAT | SLJIT_SIMD_TEST | (m)))
152 #define SLJIT_SIMD_TYPE_MASK2(m) ((sljit_s32)0xc0000fff & ~(SLJIT_SIMD_FLOAT | SLJIT_SIMD_TEST | (m)))
153
154 /* Jump flags. */
155 #define JUMP_ADDR 0x1
156 #define JUMP_MOV_ADDR 0x2
157 /* SLJIT_REWRITABLE_JUMP is 0x1000. */
158
159 #if (defined SLJIT_CONFIG_X86 && SLJIT_CONFIG_X86)
160 # define PATCH_MB 0x04
161 # define PATCH_MW 0x08
162 #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
163 # define PATCH_MD 0x10
164 # define MOV_ADDR_HI 0x20
165 # define JUMP_MAX_SIZE ((sljit_uw)(10 + 3))
166 # define CJUMP_MAX_SIZE ((sljit_uw)(2 + 10 + 3))
167 #else /* !SLJIT_CONFIG_X86_64 */
168 # define JUMP_MAX_SIZE ((sljit_uw)5)
169 # define CJUMP_MAX_SIZE ((sljit_uw)6)
170 #endif /* SLJIT_CONFIG_X86_64 */
171 # define TYPE_SHIFT 13
172 #if (defined SLJIT_DEBUG && SLJIT_DEBUG)
173 /* Bits 7..12 is for debug jump size, SLJIT_REWRITABLE_JUMP is 0x1000 */
174 # define JUMP_SIZE_SHIFT 7
175 #endif /* SLJIT_DEBUG */
176 #endif /* SLJIT_CONFIG_X86 */
177
178 #if (defined SLJIT_CONFIG_ARM_V6 && SLJIT_CONFIG_ARM_V6) || (defined SLJIT_CONFIG_ARM_V7 && SLJIT_CONFIG_ARM_V7)
179 # define IS_BL 0x04
180 # define PATCH_B 0x08
181 #endif /* SLJIT_CONFIG_ARM_V6 || SLJIT_CONFIG_ARM_V7 */
182
183 #if (defined SLJIT_CONFIG_ARM_V6 && SLJIT_CONFIG_ARM_V6)
184 # define CPOOL_SIZE 512
185 #endif /* SLJIT_CONFIG_ARM_V6 */
186
187 #if (defined SLJIT_CONFIG_ARM_V7 && SLJIT_CONFIG_ARM_V7)
188 # define JUMP_SIZE_SHIFT 26
189 # define JUMP_MAX_SIZE ((sljit_uw)3)
190 #endif /* SLJIT_CONFIG_ARM_V7 */
191
192 #if (defined SLJIT_CONFIG_ARM_THUMB2 && SLJIT_CONFIG_ARM_THUMB2)
193 # define IS_COND 0x04
194 # define IS_BL 0x08
195 /* conditional + imm8 */
196 # define PATCH_TYPE1 0x10
197 /* conditional + imm20 */
198 # define PATCH_TYPE2 0x20
199 /* imm11 */
200 # define PATCH_TYPE3 0x30
201 /* imm24 */
202 # define PATCH_TYPE4 0x40
203 /* BL + imm24 */
204 # define PATCH_TYPE5 0x50
205 /* addwi/subwi */
206 # define PATCH_TYPE6 0x60
207 /* 0xf00 cc code for branches */
208 # define JUMP_SIZE_SHIFT 26
209 # define JUMP_MAX_SIZE ((sljit_uw)5)
210 #endif /* SLJIT_CONFIG_ARM_THUMB2 */
211
212 #if (defined SLJIT_CONFIG_ARM_64 && SLJIT_CONFIG_ARM_64)
213 # define IS_COND 0x004
214 # define IS_CBZ 0x008
215 # define IS_BL 0x010
216 # define PATCH_COND 0x020
217 # define PATCH_B 0x040
218 # define PATCH_B32 0x080
219 # define PATCH_ABS48 0x100
220 # define PATCH_ABS64 0x200
221 # define JUMP_SIZE_SHIFT 58
222 # define JUMP_MAX_SIZE ((sljit_uw)5)
223 #endif /* SLJIT_CONFIG_ARM_64 */
224
225 #if (defined SLJIT_CONFIG_PPC && SLJIT_CONFIG_PPC)
226 # define IS_COND 0x004
227 # define IS_CALL 0x008
228 # define PATCH_B 0x010
229 # define PATCH_ABS_B 0x020
230 #if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
231 # define PATCH_ABS32 0x040
232 # define PATCH_ABS48 0x080
233 # define JUMP_SIZE_SHIFT 58
234 # define JUMP_MAX_SIZE ((sljit_uw)7)
235 #else /* !SLJIT_CONFIG_PPC_64 */
236 # define JUMP_SIZE_SHIFT 26
237 # define JUMP_MAX_SIZE ((sljit_uw)4)
238 #endif /* SLJIT_CONFIG_PPC_64 */
239 #endif /* SLJIT_CONFIG_PPC */
240
241 #if (defined SLJIT_CONFIG_MIPS && SLJIT_CONFIG_MIPS)
242 # define IS_MOVABLE 0x004
243 # define IS_JAL 0x008
244 # define IS_CALL 0x010
245 # define IS_BIT26_COND 0x020
246 # define IS_BIT16_COND 0x040
247 # define IS_BIT23_COND 0x080
248
249 # define IS_COND (IS_BIT26_COND | IS_BIT16_COND | IS_BIT23_COND)
250
251 # define PATCH_B 0x100
252 # define PATCH_J 0x200
253
254 #if (defined SLJIT_CONFIG_MIPS_64 && SLJIT_CONFIG_MIPS_64)
255 # define PATCH_ABS32 0x400
256 # define PATCH_ABS48 0x800
257 #endif /* SLJIT_CONFIG_MIPS_64 */
258
259 /* instruction types */
260 # define MOVABLE_INS 0
261 /* 1 - 31 last destination register */
262 /* no destination (i.e: store) */
263 # define UNMOVABLE_INS 32
264 /* FPU status register */
265 # define FCSR_FCC 33
266 #endif /* SLJIT_CONFIG_MIPS */
267
268 #if (defined SLJIT_CONFIG_RISCV && SLJIT_CONFIG_RISCV)
269 # define IS_COND 0x004
270 # define IS_CALL 0x008
271
272 # define PATCH_B 0x010
273 # define PATCH_J 0x020
274
275 #if (defined SLJIT_CONFIG_RISCV_64 && SLJIT_CONFIG_RISCV_64)
276 # define PATCH_REL32 0x040
277 # define PATCH_ABS32 0x080
278 # define PATCH_ABS44 0x100
279 # define PATCH_ABS52 0x200
280 # define JUMP_SIZE_SHIFT 58
281 # define JUMP_MAX_SIZE ((sljit_uw)6)
282 #else /* !SLJIT_CONFIG_RISCV_64 */
283 # define JUMP_SIZE_SHIFT 26
284 # define JUMP_MAX_SIZE ((sljit_uw)2)
285 #endif /* SLJIT_CONFIG_RISCV_64 */
286 #endif /* SLJIT_CONFIG_RISCV */
287
288 #if (defined SLJIT_CONFIG_LOONGARCH && SLJIT_CONFIG_LOONGARCH)
289 # define IS_COND 0x004
290 # define IS_CALL 0x008
291
292 # define PATCH_B 0x010
293 # define PATCH_J 0x020
294
295 # define PATCH_REL32 0x040
296 # define PATCH_ABS32 0x080
297 # define PATCH_ABS52 0x100
298 # define JUMP_SIZE_SHIFT 58
299 # define JUMP_MAX_SIZE ((sljit_uw)4)
300
301 #endif /* SLJIT_CONFIG_LOONGARCH */
302 /* Stack management. */
303
304 #define GET_SAVED_REGISTERS_SIZE(scratches, saveds, extra) \
305 (((scratches < SLJIT_NUMBER_OF_SCRATCH_REGISTERS ? 0 : (scratches - SLJIT_NUMBER_OF_SCRATCH_REGISTERS)) + \
306 (saveds) + (sljit_s32)(extra)) * (sljit_s32)sizeof(sljit_sw))
307
308 #define GET_SAVED_FLOAT_REGISTERS_SIZE(fscratches, fsaveds, type) \
309 (((fscratches < SLJIT_NUMBER_OF_SCRATCH_FLOAT_REGISTERS ? 0 : (fscratches - SLJIT_NUMBER_OF_SCRATCH_FLOAT_REGISTERS)) + \
310 (fsaveds)) * SSIZE_OF(type))
311
312 #define ADJUST_LOCAL_OFFSET(p, i) \
313 if ((p) == (SLJIT_MEM1(SLJIT_SP))) \
314 (i) += SLJIT_LOCALS_OFFSET;
315
316 #endif /* !(defined SLJIT_CONFIG_UNSUPPORTED && SLJIT_CONFIG_UNSUPPORTED) */
317
318 /* Utils can still be used even if SLJIT_CONFIG_UNSUPPORTED is set. */
319 #include "sljitUtils.c"
320
321 #if (defined SLJIT_CONFIG_ARM_THUMB2 && SLJIT_CONFIG_ARM_THUMB2)
322 #define SLJIT_CODE_TO_PTR(code) ((void*)((sljit_up)(code) & ~(sljit_up)0x1))
323 #elif (defined SLJIT_INDIRECT_CALL && SLJIT_INDIRECT_CALL)
324 #define SLJIT_CODE_TO_PTR(code) ((void*)(*(sljit_up*)code))
325 #else /* !SLJIT_CONFIG_ARM_THUMB2 && !SLJIT_INDIRECT_CALL */
326 #define SLJIT_CODE_TO_PTR(code) ((void*)(code))
327 #endif /* SLJIT_CONFIG_ARM_THUMB2 || SLJIT_INDIRECT_CALL */
328
329 #if !(defined SLJIT_CONFIG_UNSUPPORTED && SLJIT_CONFIG_UNSUPPORTED)
330
331 #if (defined SLJIT_EXECUTABLE_ALLOCATOR && SLJIT_EXECUTABLE_ALLOCATOR)
332
333 #if (defined SLJIT_PROT_EXECUTABLE_ALLOCATOR && SLJIT_PROT_EXECUTABLE_ALLOCATOR)
334
335 #if defined(__NetBSD__)
336 #include "allocator_src/sljitProtExecAllocatorNetBSD.c"
337 #else
338 #include "allocator_src/sljitProtExecAllocatorPosix.c"
339 #endif
340
341 #elif (defined SLJIT_WX_EXECUTABLE_ALLOCATOR && SLJIT_WX_EXECUTABLE_ALLOCATOR)
342
343 #if defined(_WIN32)
344 #include "allocator_src/sljitWXExecAllocatorWindows.c"
345 #else
346 #include "allocator_src/sljitWXExecAllocatorPosix.c"
347 #endif
348
349 #else
350
351 #if defined(_WIN32)
352 #include "allocator_src/sljitExecAllocatorWindows.c"
353 #elif defined(__APPLE__)
354 #include "allocator_src/sljitExecAllocatorApple.c"
355 #elif defined(__FreeBSD__)
356 #include "allocator_src/sljitExecAllocatorFreeBSD.c"
357 #else
358 #include "allocator_src/sljitExecAllocatorPosix.c"
359 #endif
360
361 #endif
362
363 #else /* !SLJIT_EXECUTABLE_ALLOCATOR */
364
365 #ifndef SLJIT_UPDATE_WX_FLAGS
366 #define SLJIT_UPDATE_WX_FLAGS(from, to, enable_exec)
367 #endif
368
369 #endif /* SLJIT_EXECUTABLE_ALLOCATOR */
370
371 #if (defined SLJIT_PROT_EXECUTABLE_ALLOCATOR && SLJIT_PROT_EXECUTABLE_ALLOCATOR)
372 #define SLJIT_ADD_EXEC_OFFSET(ptr, exec_offset) ((sljit_u8 *)(ptr) + (exec_offset))
373 #else
374 #define SLJIT_ADD_EXEC_OFFSET(ptr, exec_offset) ((sljit_u8 *)(ptr))
375 #endif
376
377 /* Argument checking features. */
378
379 #if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
380
381 /* Returns with error when an invalid argument is passed. */
382
383 #define CHECK_ARGUMENT(x) \
384 do { \
385 if (SLJIT_UNLIKELY(!(x))) \
386 return 1; \
387 } while (0)
388
389 #define CHECK_RETURN_TYPE sljit_s32
390 #define CHECK_RETURN_OK return 0
391
392 #define CHECK(x) \
393 do { \
394 if (SLJIT_UNLIKELY(x)) { \
395 compiler->error = SLJIT_ERR_BAD_ARGUMENT; \
396 return SLJIT_ERR_BAD_ARGUMENT; \
397 } \
398 } while (0)
399
400 #define CHECK_PTR(x) \
401 do { \
402 if (SLJIT_UNLIKELY(x)) { \
403 compiler->error = SLJIT_ERR_BAD_ARGUMENT; \
404 return NULL; \
405 } \
406 } while (0)
407
408 #define CHECK_REG_INDEX(x) \
409 do { \
410 if (SLJIT_UNLIKELY(x)) { \
411 return -2; \
412 } \
413 } while (0)
414
415 #elif (defined SLJIT_DEBUG && SLJIT_DEBUG)
416
417 /* Assertion failure occures if an invalid argument is passed. */
418 #undef SLJIT_ARGUMENT_CHECKS
419 #define SLJIT_ARGUMENT_CHECKS 1
420
421 #define CHECK_ARGUMENT(x) SLJIT_ASSERT(x)
422 #define CHECK_RETURN_TYPE void
423 #define CHECK_RETURN_OK return
424 #define CHECK(x) x
425 #define CHECK_PTR(x) x
426 #define CHECK_REG_INDEX(x) x
427
428 #elif (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
429
430 /* Arguments are not checked. */
431 #define CHECK_RETURN_TYPE void
432 #define CHECK_RETURN_OK return
433 #define CHECK(x) x
434 #define CHECK_PTR(x) x
435 #define CHECK_REG_INDEX(x) x
436
437 #else
438
439 /* Arguments are not checked. */
440 #define CHECK(x)
441 #define CHECK_PTR(x)
442 #define CHECK_REG_INDEX(x)
443
444 #endif /* SLJIT_ARGUMENT_CHECKS */
445
446 /* --------------------------------------------------------------------- */
447 /* Public functions */
448 /* --------------------------------------------------------------------- */
449
450 #if (defined SLJIT_CONFIG_X86 && SLJIT_CONFIG_X86)
451 #define SLJIT_NEEDS_COMPILER_INIT 1
452 static sljit_s32 compiler_initialized = 0;
453 /* A thread safe initialization. */
454 static void init_compiler(void);
455 #endif
456
sljit_create_compiler(void * allocator_data)457 SLJIT_API_FUNC_ATTRIBUTE struct sljit_compiler* sljit_create_compiler(void *allocator_data)
458 {
459 struct sljit_compiler *compiler = (struct sljit_compiler*)SLJIT_MALLOC(sizeof(struct sljit_compiler), allocator_data);
460 if (!compiler)
461 return NULL;
462 SLJIT_ZEROMEM(compiler, sizeof(struct sljit_compiler));
463
464 SLJIT_COMPILE_ASSERT(
465 sizeof(sljit_s8) == 1 && sizeof(sljit_u8) == 1
466 && sizeof(sljit_s16) == 2 && sizeof(sljit_u16) == 2
467 && sizeof(sljit_s32) == 4 && sizeof(sljit_u32) == 4
468 && (sizeof(sljit_up) == 4 || sizeof(sljit_up) == 8)
469 && sizeof(sljit_up) <= sizeof(sljit_sw)
470 && sizeof(sljit_up) == sizeof(sljit_sp)
471 && (sizeof(sljit_sw) == 4 || sizeof(sljit_sw) == 8)
472 && (sizeof(sljit_uw) == sizeof(sljit_sw)),
473 invalid_integer_types);
474 SLJIT_COMPILE_ASSERT(SLJIT_REWRITABLE_JUMP != SLJIT_32,
475 rewritable_jump_and_single_op_must_not_be_the_same);
476 SLJIT_COMPILE_ASSERT(!(SLJIT_EQUAL & 0x1) && !(SLJIT_LESS & 0x1) && !(SLJIT_F_EQUAL & 0x1) && !(SLJIT_JUMP & 0x1),
477 conditional_flags_must_be_even_numbers);
478
479 /* Only the non-zero members must be set. */
480 compiler->error = SLJIT_SUCCESS;
481
482 compiler->allocator_data = allocator_data;
483 compiler->buf = (struct sljit_memory_fragment*)SLJIT_MALLOC(BUF_SIZE, allocator_data);
484 compiler->abuf = (struct sljit_memory_fragment*)SLJIT_MALLOC(ABUF_SIZE, allocator_data);
485
486 if (!compiler->buf || !compiler->abuf) {
487 if (compiler->buf)
488 SLJIT_FREE(compiler->buf, allocator_data);
489 if (compiler->abuf)
490 SLJIT_FREE(compiler->abuf, allocator_data);
491 SLJIT_FREE(compiler, allocator_data);
492 return NULL;
493 }
494
495 compiler->buf->next = NULL;
496 compiler->buf->used_size = 0;
497 compiler->abuf->next = NULL;
498 compiler->abuf->used_size = 0;
499
500 compiler->scratches = -1;
501 compiler->saveds = -1;
502 compiler->fscratches = -1;
503 compiler->fsaveds = -1;
504 compiler->local_size = -1;
505
506 #if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
507 compiler->args_size = -1;
508 #endif /* SLJIT_CONFIG_X86_32 */
509
510 #if (defined SLJIT_CONFIG_ARM_V6 && SLJIT_CONFIG_ARM_V6)
511 compiler->cpool = (sljit_uw*)SLJIT_MALLOC(CPOOL_SIZE * sizeof(sljit_uw)
512 + CPOOL_SIZE * sizeof(sljit_u8), allocator_data);
513 if (!compiler->cpool) {
514 SLJIT_FREE(compiler->buf, allocator_data);
515 SLJIT_FREE(compiler->abuf, allocator_data);
516 SLJIT_FREE(compiler, allocator_data);
517 return NULL;
518 }
519 compiler->cpool_unique = (sljit_u8*)(compiler->cpool + CPOOL_SIZE);
520 compiler->cpool_diff = 0xffffffff;
521 #endif /* SLJIT_CONFIG_ARM_V6 */
522
523 #if (defined SLJIT_CONFIG_MIPS && SLJIT_CONFIG_MIPS)
524 compiler->delay_slot = UNMOVABLE_INS;
525 #endif /* SLJIT_CONFIG_MIPS */
526
527 #if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS) \
528 || (defined SLJIT_DEBUG && SLJIT_DEBUG)
529 compiler->last_flags = 0;
530 compiler->last_return = -1;
531 compiler->logical_local_size = 0;
532 #endif /* SLJIT_ARGUMENT_CHECKS || SLJIT_DEBUG */
533
534 #if (defined SLJIT_NEEDS_COMPILER_INIT && SLJIT_NEEDS_COMPILER_INIT)
535 if (!compiler_initialized) {
536 init_compiler();
537 compiler_initialized = 1;
538 }
539 #endif
540
541 return compiler;
542 }
543
sljit_free_compiler(struct sljit_compiler * compiler)544 SLJIT_API_FUNC_ATTRIBUTE void sljit_free_compiler(struct sljit_compiler *compiler)
545 {
546 struct sljit_memory_fragment *buf;
547 struct sljit_memory_fragment *curr;
548 void *allocator_data = compiler->allocator_data;
549 SLJIT_UNUSED_ARG(allocator_data);
550
551 buf = compiler->buf;
552 while (buf) {
553 curr = buf;
554 buf = buf->next;
555 SLJIT_FREE(curr, allocator_data);
556 }
557
558 buf = compiler->abuf;
559 while (buf) {
560 curr = buf;
561 buf = buf->next;
562 SLJIT_FREE(curr, allocator_data);
563 }
564
565 #if (defined SLJIT_CONFIG_ARM_V6 && SLJIT_CONFIG_ARM_V6)
566 SLJIT_FREE(compiler->cpool, allocator_data);
567 #endif
568 SLJIT_FREE(compiler, allocator_data);
569 }
570
sljit_set_compiler_memory_error(struct sljit_compiler * compiler)571 SLJIT_API_FUNC_ATTRIBUTE void sljit_set_compiler_memory_error(struct sljit_compiler *compiler)
572 {
573 if (compiler->error == SLJIT_SUCCESS)
574 compiler->error = SLJIT_ERR_ALLOC_FAILED;
575 }
576
sljit_free_code(void * code,void * exec_allocator_data)577 SLJIT_API_FUNC_ATTRIBUTE void sljit_free_code(void* code, void *exec_allocator_data)
578 {
579 SLJIT_UNUSED_ARG(exec_allocator_data);
580
581 SLJIT_FREE_EXEC(SLJIT_CODE_TO_PTR(code), exec_allocator_data);
582 }
583
sljit_set_label(struct sljit_jump * jump,struct sljit_label * label)584 SLJIT_API_FUNC_ATTRIBUTE void sljit_set_label(struct sljit_jump *jump, struct sljit_label* label)
585 {
586 if (SLJIT_LIKELY(!!jump) && SLJIT_LIKELY(!!label)) {
587 jump->flags &= (sljit_uw)~JUMP_ADDR;
588 jump->u.label = label;
589 }
590 }
591
sljit_set_target(struct sljit_jump * jump,sljit_uw target)592 SLJIT_API_FUNC_ATTRIBUTE void sljit_set_target(struct sljit_jump *jump, sljit_uw target)
593 {
594 if (SLJIT_LIKELY(!!jump)) {
595 jump->flags |= JUMP_ADDR;
596 jump->u.target = target;
597 }
598 }
599
600 #define SLJIT_CURRENT_FLAGS_ALL \
601 (SLJIT_CURRENT_FLAGS_32 | SLJIT_CURRENT_FLAGS_ADD | SLJIT_CURRENT_FLAGS_SUB | SLJIT_CURRENT_FLAGS_COMPARE)
602
sljit_set_current_flags(struct sljit_compiler * compiler,sljit_s32 current_flags)603 SLJIT_API_FUNC_ATTRIBUTE void sljit_set_current_flags(struct sljit_compiler *compiler, sljit_s32 current_flags)
604 {
605 SLJIT_UNUSED_ARG(compiler);
606 SLJIT_UNUSED_ARG(current_flags);
607
608 #if (defined SLJIT_HAS_STATUS_FLAGS_STATE && SLJIT_HAS_STATUS_FLAGS_STATE)
609 compiler->status_flags_state = current_flags;
610 #endif
611
612 #if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
613 compiler->last_flags = 0;
614 if ((current_flags & ~(VARIABLE_FLAG_MASK | SLJIT_SET_Z | SLJIT_CURRENT_FLAGS_ALL)) == 0) {
615 compiler->last_flags = GET_FLAG_TYPE(current_flags) | (current_flags & (SLJIT_32 | SLJIT_SET_Z));
616 }
617 #endif
618 }
619
620 /* --------------------------------------------------------------------- */
621 /* Private functions */
622 /* --------------------------------------------------------------------- */
623
ensure_buf(struct sljit_compiler * compiler,sljit_uw size)624 static void* ensure_buf(struct sljit_compiler *compiler, sljit_uw size)
625 {
626 sljit_u8 *ret;
627 struct sljit_memory_fragment *new_frag;
628
629 SLJIT_ASSERT(size <= 256);
630 if (compiler->buf->used_size + size <= (BUF_SIZE - (sljit_uw)SLJIT_OFFSETOF(struct sljit_memory_fragment, memory))) {
631 ret = compiler->buf->memory + compiler->buf->used_size;
632 compiler->buf->used_size += size;
633 return ret;
634 }
635 new_frag = (struct sljit_memory_fragment*)SLJIT_MALLOC(BUF_SIZE, compiler->allocator_data);
636 PTR_FAIL_IF_NULL(new_frag);
637 new_frag->next = compiler->buf;
638 compiler->buf = new_frag;
639 new_frag->used_size = size;
640 return new_frag->memory;
641 }
642
ensure_abuf(struct sljit_compiler * compiler,sljit_uw size)643 static void* ensure_abuf(struct sljit_compiler *compiler, sljit_uw size)
644 {
645 sljit_u8 *ret;
646 struct sljit_memory_fragment *new_frag;
647
648 SLJIT_ASSERT(size <= 256);
649 if (compiler->abuf->used_size + size <= (ABUF_SIZE - (sljit_uw)SLJIT_OFFSETOF(struct sljit_memory_fragment, memory))) {
650 ret = compiler->abuf->memory + compiler->abuf->used_size;
651 compiler->abuf->used_size += size;
652 return ret;
653 }
654 new_frag = (struct sljit_memory_fragment*)SLJIT_MALLOC(ABUF_SIZE, compiler->allocator_data);
655 PTR_FAIL_IF_NULL(new_frag);
656 new_frag->next = compiler->abuf;
657 compiler->abuf = new_frag;
658 new_frag->used_size = size;
659 return new_frag->memory;
660 }
661
sljit_alloc_memory(struct sljit_compiler * compiler,sljit_s32 size)662 SLJIT_API_FUNC_ATTRIBUTE void* sljit_alloc_memory(struct sljit_compiler *compiler, sljit_s32 size)
663 {
664 CHECK_ERROR_PTR();
665
666 #if (defined SLJIT_64BIT_ARCHITECTURE && SLJIT_64BIT_ARCHITECTURE)
667 if (size <= 0 || size > 128)
668 return NULL;
669 size = (size + 7) & ~7;
670 #else
671 if (size <= 0 || size > 64)
672 return NULL;
673 size = (size + 3) & ~3;
674 #endif
675 return ensure_abuf(compiler, (sljit_uw)size);
676 }
677
reverse_buf(struct sljit_compiler * compiler)678 static SLJIT_INLINE void reverse_buf(struct sljit_compiler *compiler)
679 {
680 struct sljit_memory_fragment *buf = compiler->buf;
681 struct sljit_memory_fragment *prev = NULL;
682 struct sljit_memory_fragment *tmp;
683
684 do {
685 tmp = buf->next;
686 buf->next = prev;
687 prev = buf;
688 buf = tmp;
689 } while (buf != NULL);
690
691 compiler->buf = prev;
692 }
693
allocate_executable_memory(sljit_uw size,sljit_s32 options,void * exec_allocator_data,sljit_sw * executable_offset)694 static SLJIT_INLINE void* allocate_executable_memory(sljit_uw size, sljit_s32 options,
695 void *exec_allocator_data, sljit_sw *executable_offset)
696 {
697 void *code;
698 struct sljit_generate_code_buffer *buffer;
699
700 if (SLJIT_LIKELY(!(options & SLJIT_GENERATE_CODE_BUFFER))) {
701 code = SLJIT_MALLOC_EXEC(size, exec_allocator_data);
702 *executable_offset = SLJIT_EXEC_OFFSET(code);
703 return code;
704 }
705
706 buffer = (struct sljit_generate_code_buffer*)exec_allocator_data;
707
708 if (size <= buffer->size) {
709 *executable_offset = buffer->executable_offset;
710 return buffer->buffer;
711 }
712
713 return NULL;
714 }
715
716 #define SLJIT_MAX_ADDRESS ~(sljit_uw)0
717
718 #define SLJIT_GET_NEXT_SIZE(ptr) (ptr != NULL) ? ((ptr)->size) : SLJIT_MAX_ADDRESS
719 #define SLJIT_GET_NEXT_ADDRESS(ptr) (ptr != NULL) ? ((ptr)->addr) : SLJIT_MAX_ADDRESS
720
721 #if !(defined SLJIT_CONFIG_X86 && SLJIT_CONFIG_X86)
722
723 #define SLJIT_NEXT_DEFINE_TYPES \
724 sljit_uw next_label_size; \
725 sljit_uw next_jump_addr; \
726 sljit_uw next_const_addr; \
727 sljit_uw next_min_addr
728
729 #define SLJIT_NEXT_INIT_TYPES() \
730 next_label_size = SLJIT_GET_NEXT_SIZE(label); \
731 next_jump_addr = SLJIT_GET_NEXT_ADDRESS(jump); \
732 next_const_addr = SLJIT_GET_NEXT_ADDRESS(const_);
733
734 #define SLJIT_GET_NEXT_MIN() \
735 next_min_addr = sljit_get_next_min(next_label_size, next_jump_addr, next_const_addr);
736
sljit_get_next_min(sljit_uw next_label_size,sljit_uw next_jump_addr,sljit_uw next_const_addr)737 static SLJIT_INLINE sljit_uw sljit_get_next_min(sljit_uw next_label_size,
738 sljit_uw next_jump_addr, sljit_uw next_const_addr)
739 {
740 sljit_uw result = next_jump_addr;
741
742 SLJIT_ASSERT(result == SLJIT_MAX_ADDRESS || result != next_const_addr);
743
744 if (next_const_addr < result)
745 result = next_const_addr;
746
747 if (next_label_size < result)
748 result = next_label_size;
749
750 return result;
751 }
752
753 #endif /* !SLJIT_CONFIG_X86 */
754
set_emit_enter(struct sljit_compiler * compiler,sljit_s32 options,sljit_s32 args,sljit_s32 scratches,sljit_s32 saveds,sljit_s32 fscratches,sljit_s32 fsaveds,sljit_s32 local_size)755 static SLJIT_INLINE void set_emit_enter(struct sljit_compiler *compiler,
756 sljit_s32 options, sljit_s32 args, sljit_s32 scratches, sljit_s32 saveds,
757 sljit_s32 fscratches, sljit_s32 fsaveds, sljit_s32 local_size)
758 {
759 SLJIT_UNUSED_ARG(args);
760 SLJIT_UNUSED_ARG(local_size);
761
762 compiler->options = options;
763 compiler->scratches = scratches;
764 compiler->saveds = saveds;
765 compiler->fscratches = fscratches;
766 compiler->fsaveds = fsaveds;
767 #if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
768 compiler->last_return = args & SLJIT_ARG_MASK;
769 compiler->logical_local_size = local_size;
770 #endif
771 }
772
set_set_context(struct sljit_compiler * compiler,sljit_s32 options,sljit_s32 args,sljit_s32 scratches,sljit_s32 saveds,sljit_s32 fscratches,sljit_s32 fsaveds,sljit_s32 local_size)773 static SLJIT_INLINE void set_set_context(struct sljit_compiler *compiler,
774 sljit_s32 options, sljit_s32 args, sljit_s32 scratches, sljit_s32 saveds,
775 sljit_s32 fscratches, sljit_s32 fsaveds, sljit_s32 local_size)
776 {
777 SLJIT_UNUSED_ARG(args);
778 SLJIT_UNUSED_ARG(local_size);
779
780 compiler->options = options;
781 compiler->scratches = scratches;
782 compiler->saveds = saveds;
783 compiler->fscratches = fscratches;
784 compiler->fsaveds = fsaveds;
785 #if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
786 compiler->last_return = args & SLJIT_ARG_MASK;
787 compiler->logical_local_size = local_size;
788 #endif
789 }
790
set_label(struct sljit_label * label,struct sljit_compiler * compiler)791 static SLJIT_INLINE void set_label(struct sljit_label *label, struct sljit_compiler *compiler)
792 {
793 label->next = NULL;
794 label->u.index = compiler->label_count++;
795 label->size = compiler->size;
796 if (compiler->last_label != NULL)
797 compiler->last_label->next = label;
798 else
799 compiler->labels = label;
800 compiler->last_label = label;
801 }
802
set_jump(struct sljit_jump * jump,struct sljit_compiler * compiler,sljit_u32 flags)803 static SLJIT_INLINE void set_jump(struct sljit_jump *jump, struct sljit_compiler *compiler, sljit_u32 flags)
804 {
805 jump->next = NULL;
806 jump->flags = flags;
807 jump->u.label = NULL;
808 if (compiler->last_jump != NULL)
809 compiler->last_jump->next = jump;
810 else
811 compiler->jumps = jump;
812 compiler->last_jump = jump;
813 }
814
set_mov_addr(struct sljit_jump * jump,struct sljit_compiler * compiler,sljit_uw offset)815 static SLJIT_INLINE void set_mov_addr(struct sljit_jump *jump, struct sljit_compiler *compiler, sljit_uw offset)
816 {
817 jump->next = NULL;
818 jump->addr = compiler->size - offset;
819 jump->flags = JUMP_MOV_ADDR;
820 jump->u.label = NULL;
821 if (compiler->last_jump != NULL)
822 compiler->last_jump->next = jump;
823 else
824 compiler->jumps = jump;
825 compiler->last_jump = jump;
826 }
827
set_const(struct sljit_const * const_,struct sljit_compiler * compiler)828 static SLJIT_INLINE void set_const(struct sljit_const *const_, struct sljit_compiler *compiler)
829 {
830 const_->next = NULL;
831 const_->addr = compiler->size;
832 if (compiler->last_const != NULL)
833 compiler->last_const->next = const_;
834 else
835 compiler->consts = const_;
836 compiler->last_const = const_;
837 }
838
839 #define ADDRESSING_DEPENDS_ON(exp, reg) \
840 (((exp) & SLJIT_MEM) && (((exp) & REG_MASK) == reg || OFFS_REG(exp) == reg))
841
842 #if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
843
function_check_arguments(sljit_s32 arg_types,sljit_s32 scratches,sljit_s32 saveds,sljit_s32 fscratches)844 static sljit_s32 function_check_arguments(sljit_s32 arg_types, sljit_s32 scratches, sljit_s32 saveds, sljit_s32 fscratches)
845 {
846 sljit_s32 word_arg_count, scratch_arg_end, saved_arg_count, float_arg_count, curr_type;
847
848 curr_type = (arg_types & SLJIT_ARG_FULL_MASK);
849
850 if (curr_type >= SLJIT_ARG_TYPE_F64) {
851 if (curr_type > SLJIT_ARG_TYPE_F32 || fscratches == 0)
852 return 0;
853 } else if (curr_type >= SLJIT_ARG_TYPE_W) {
854 if (scratches == 0)
855 return 0;
856 }
857
858 arg_types >>= SLJIT_ARG_SHIFT;
859
860 word_arg_count = 0;
861 scratch_arg_end = 0;
862 saved_arg_count = 0;
863 float_arg_count = 0;
864 while (arg_types != 0) {
865 if (word_arg_count + float_arg_count >= 4)
866 return 0;
867
868 curr_type = (arg_types & SLJIT_ARG_MASK);
869
870 if (arg_types & SLJIT_ARG_TYPE_SCRATCH_REG) {
871 if (saveds == -1 || curr_type < SLJIT_ARG_TYPE_W || curr_type > SLJIT_ARG_TYPE_P)
872 return 0;
873
874 word_arg_count++;
875 scratch_arg_end = word_arg_count;
876 } else {
877 if (curr_type < SLJIT_ARG_TYPE_W || curr_type > SLJIT_ARG_TYPE_F32)
878 return 0;
879
880 if (curr_type < SLJIT_ARG_TYPE_F64) {
881 word_arg_count++;
882 saved_arg_count++;
883 } else
884 float_arg_count++;
885 }
886
887 arg_types >>= SLJIT_ARG_SHIFT;
888 }
889
890 if (saveds == -1)
891 return (word_arg_count <= scratches && float_arg_count <= fscratches);
892
893 return (saved_arg_count <= saveds && scratch_arg_end <= scratches && float_arg_count <= fscratches);
894 }
895
896 #define FUNCTION_CHECK_IS_REG(r) \
897 (((r) >= SLJIT_R0 && (r) < (SLJIT_R0 + compiler->scratches)) \
898 || ((r) > (SLJIT_S0 - compiler->saveds) && (r) <= SLJIT_S0) \
899 || ((r) >= SLJIT_TMP_REGISTER_BASE && (r) < (SLJIT_TMP_REGISTER_BASE + SLJIT_NUMBER_OF_TEMPORARY_REGISTERS)))
900
901 #if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
902 #define CHECK_IF_VIRTUAL_REGISTER(p) ((p) <= SLJIT_S3 && (p) >= SLJIT_S8)
903 #else
904 #define CHECK_IF_VIRTUAL_REGISTER(p) 0
905 #endif
906
function_check_src_mem(struct sljit_compiler * compiler,sljit_s32 p,sljit_sw i)907 static sljit_s32 function_check_src_mem(struct sljit_compiler *compiler, sljit_s32 p, sljit_sw i)
908 {
909 if (compiler->scratches == -1)
910 return 0;
911
912 if (!(p & SLJIT_MEM))
913 return 0;
914
915 if (p == SLJIT_MEM1(SLJIT_SP))
916 return (i >= 0 && i < compiler->logical_local_size);
917
918 if (!(!(p & REG_MASK) || FUNCTION_CHECK_IS_REG(p & REG_MASK)))
919 return 0;
920
921 if (CHECK_IF_VIRTUAL_REGISTER(p & REG_MASK))
922 return 0;
923
924 if (p & OFFS_REG_MASK) {
925 if (!(p & REG_MASK))
926 return 0;
927
928 if (!(FUNCTION_CHECK_IS_REG(OFFS_REG(p))))
929 return 0;
930
931 if (CHECK_IF_VIRTUAL_REGISTER(OFFS_REG(p)))
932 return 0;
933
934 if ((i & ~0x3) != 0)
935 return 0;
936 }
937
938 return (p & ~(SLJIT_MEM | REG_MASK | OFFS_REG_MASK)) == 0;
939 }
940
941 #define FUNCTION_CHECK_SRC_MEM(p, i) \
942 CHECK_ARGUMENT(function_check_src_mem(compiler, p, i));
943
function_check_src(struct sljit_compiler * compiler,sljit_s32 p,sljit_sw i)944 static sljit_s32 function_check_src(struct sljit_compiler *compiler, sljit_s32 p, sljit_sw i)
945 {
946 if (compiler->scratches == -1)
947 return 0;
948
949 if (FUNCTION_CHECK_IS_REG(p))
950 return (i == 0);
951
952 if (p == SLJIT_IMM)
953 return 1;
954
955 return function_check_src_mem(compiler, p, i);
956 }
957
958 #define FUNCTION_CHECK_SRC(p, i) \
959 CHECK_ARGUMENT(function_check_src(compiler, p, i));
960
function_check_dst(struct sljit_compiler * compiler,sljit_s32 p,sljit_sw i)961 static sljit_s32 function_check_dst(struct sljit_compiler *compiler, sljit_s32 p, sljit_sw i)
962 {
963 if (compiler->scratches == -1)
964 return 0;
965
966 if (FUNCTION_CHECK_IS_REG(p))
967 return (i == 0);
968
969 return function_check_src_mem(compiler, p, i);
970 }
971
972 #define FUNCTION_CHECK_DST(p, i) \
973 CHECK_ARGUMENT(function_check_dst(compiler, p, i));
974
975 #if (defined SLJIT_CONFIG_ARM_32 && SLJIT_CONFIG_ARM_32) \
976 || (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
977
978 #define FUNCTION_CHECK_IS_FREG(fr, is_32) \
979 function_check_is_freg(compiler, (fr), (is_32))
980
981 static sljit_s32 function_check_is_freg(struct sljit_compiler *compiler, sljit_s32 fr, sljit_s32 is_32);
982
983 #define FUNCTION_FCHECK(p, i, is_32) \
984 CHECK_ARGUMENT(function_fcheck(compiler, (p), (i), (is_32)));
985
function_fcheck(struct sljit_compiler * compiler,sljit_s32 p,sljit_sw i,sljit_s32 is_32)986 static sljit_s32 function_fcheck(struct sljit_compiler *compiler, sljit_s32 p, sljit_sw i, sljit_s32 is_32)
987 {
988 if (compiler->scratches == -1)
989 return 0;
990
991 if (FUNCTION_CHECK_IS_FREG(p, is_32))
992 return (i == 0);
993
994 return function_check_src_mem(compiler, p, i);
995 }
996
997 #else /* !SLJIT_CONFIG_ARM_32 && !SLJIT_CONFIG_MIPS_32 */
998 #define FUNCTION_CHECK_IS_FREG(fr, is_32) \
999 function_check_is_freg(compiler, (fr))
1000
function_check_is_freg(struct sljit_compiler * compiler,sljit_s32 fr)1001 static sljit_s32 function_check_is_freg(struct sljit_compiler *compiler, sljit_s32 fr)
1002 {
1003 if (compiler->scratches == -1)
1004 return 0;
1005
1006 return (fr >= SLJIT_FR0 && fr < (SLJIT_FR0 + compiler->fscratches))
1007 || (fr > (SLJIT_FS0 - compiler->fsaveds) && fr <= SLJIT_FS0)
1008 || (fr >= SLJIT_TMP_FREGISTER_BASE && fr < (SLJIT_TMP_FREGISTER_BASE + SLJIT_NUMBER_OF_TEMPORARY_FLOAT_REGISTERS));
1009 }
1010
1011 #define FUNCTION_FCHECK(p, i, is_32) \
1012 CHECK_ARGUMENT(function_fcheck(compiler, (p), (i)));
1013
function_fcheck(struct sljit_compiler * compiler,sljit_s32 p,sljit_sw i)1014 static sljit_s32 function_fcheck(struct sljit_compiler *compiler, sljit_s32 p, sljit_sw i)
1015 {
1016 if (compiler->scratches == -1)
1017 return 0;
1018
1019 if ((p >= SLJIT_FR0 && p < (SLJIT_FR0 + compiler->fscratches))
1020 || (p > (SLJIT_FS0 - compiler->fsaveds) && p <= SLJIT_FS0)
1021 || (p >= SLJIT_TMP_FREGISTER_BASE && p < (SLJIT_TMP_FREGISTER_BASE + SLJIT_NUMBER_OF_TEMPORARY_FLOAT_REGISTERS)))
1022 return (i == 0);
1023
1024 return function_check_src_mem(compiler, p, i);
1025 }
1026
1027 #endif /* SLJIT_CONFIG_ARM_32 || SLJIT_CONFIG_MIPS_32 */
1028
1029 #endif /* SLJIT_ARGUMENT_CHECKS */
1030
1031 #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
1032
sljit_compiler_verbose(struct sljit_compiler * compiler,FILE * verbose)1033 SLJIT_API_FUNC_ATTRIBUTE void sljit_compiler_verbose(struct sljit_compiler *compiler, FILE* verbose)
1034 {
1035 compiler->verbose = verbose;
1036 }
1037
1038 #if (defined SLJIT_64BIT_ARCHITECTURE && SLJIT_64BIT_ARCHITECTURE)
1039 #ifdef _WIN64
1040 #ifdef __GNUC__
1041 # define SLJIT_PRINT_D "ll"
1042 #else
1043 # define SLJIT_PRINT_D "I64"
1044 #endif
1045 #else
1046 # define SLJIT_PRINT_D "l"
1047 #endif
1048 #else
1049 # define SLJIT_PRINT_D ""
1050 #endif
1051
sljit_verbose_reg(struct sljit_compiler * compiler,sljit_s32 r)1052 static void sljit_verbose_reg(struct sljit_compiler *compiler, sljit_s32 r)
1053 {
1054 if (r < (SLJIT_R0 + compiler->scratches))
1055 fprintf(compiler->verbose, "r%d", r - SLJIT_R0);
1056 else if (r < SLJIT_SP)
1057 fprintf(compiler->verbose, "s%d", SLJIT_NUMBER_OF_REGISTERS - r);
1058 else if (r == SLJIT_SP)
1059 fprintf(compiler->verbose, "sp");
1060 else
1061 fprintf(compiler->verbose, "t%d", r - SLJIT_TMP_REGISTER_BASE);
1062 }
1063
sljit_verbose_freg(struct sljit_compiler * compiler,sljit_s32 r)1064 static void sljit_verbose_freg(struct sljit_compiler *compiler, sljit_s32 r)
1065 {
1066 #if (defined SLJIT_CONFIG_ARM_32 && SLJIT_CONFIG_ARM_32) \
1067 || (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
1068 if (r >= SLJIT_F64_SECOND(SLJIT_FR0)) {
1069 fprintf(compiler->verbose, "^");
1070 r -= SLJIT_F64_SECOND(0);
1071 }
1072 #endif /* SLJIT_CONFIG_ARM_32 || SLJIT_CONFIG_MIPS_32 */
1073
1074 if (r < (SLJIT_FR0 + compiler->fscratches))
1075 fprintf(compiler->verbose, "fr%d", r - SLJIT_FR0);
1076 else if (r < SLJIT_TMP_FREGISTER_BASE)
1077 fprintf(compiler->verbose, "fs%d", SLJIT_NUMBER_OF_FLOAT_REGISTERS - r);
1078 else
1079 fprintf(compiler->verbose, "ft%d", r - SLJIT_TMP_FREGISTER_BASE);
1080 }
1081
sljit_verbose_param(struct sljit_compiler * compiler,sljit_s32 p,sljit_sw i)1082 static void sljit_verbose_param(struct sljit_compiler *compiler, sljit_s32 p, sljit_sw i)
1083 {
1084 if ((p) == SLJIT_IMM)
1085 fprintf(compiler->verbose, "#%" SLJIT_PRINT_D "d", (i));
1086 else if ((p) & SLJIT_MEM) {
1087 if ((p) & REG_MASK) {
1088 fputc('[', compiler->verbose);
1089 sljit_verbose_reg(compiler, (p) & REG_MASK);
1090 if ((p) & OFFS_REG_MASK) {
1091 fprintf(compiler->verbose, " + ");
1092 sljit_verbose_reg(compiler, OFFS_REG(p));
1093 if (i)
1094 fprintf(compiler->verbose, " * %d", 1 << (i));
1095 }
1096 else if (i)
1097 fprintf(compiler->verbose, " + %" SLJIT_PRINT_D "d", (i));
1098 fputc(']', compiler->verbose);
1099 }
1100 else
1101 fprintf(compiler->verbose, "[#%" SLJIT_PRINT_D "d]", (i));
1102 } else
1103 sljit_verbose_reg(compiler, p);
1104 }
1105
sljit_verbose_fparam(struct sljit_compiler * compiler,sljit_s32 p,sljit_sw i)1106 static void sljit_verbose_fparam(struct sljit_compiler *compiler, sljit_s32 p, sljit_sw i)
1107 {
1108 if ((p) & SLJIT_MEM) {
1109 if ((p) & REG_MASK) {
1110 fputc('[', compiler->verbose);
1111 sljit_verbose_reg(compiler, (p) & REG_MASK);
1112 if ((p) & OFFS_REG_MASK) {
1113 fprintf(compiler->verbose, " + ");
1114 sljit_verbose_reg(compiler, OFFS_REG(p));
1115 if (i)
1116 fprintf(compiler->verbose, "%d", 1 << (i));
1117 }
1118 else if (i)
1119 fprintf(compiler->verbose, " + %" SLJIT_PRINT_D "d", (i));
1120 fputc(']', compiler->verbose);
1121 }
1122 else
1123 fprintf(compiler->verbose, "[#%" SLJIT_PRINT_D "d]", (i));
1124 }
1125 else
1126 sljit_verbose_freg(compiler, p);
1127 }
1128
1129 static const char* op0_names[] = {
1130 "breakpoint", "nop", "lmul.uw", "lmul.sw",
1131 "divmod.u", "divmod.s", "div.u", "div.s",
1132 "endbr", "skip_frames_before_return"
1133 };
1134
1135 static const char* op1_names[] = {
1136 "mov", "mov", "mov", "mov",
1137 "mov", "mov", "mov", "mov",
1138 "mov", "clz", "ctz", "rev",
1139 "rev", "rev", "rev", "rev"
1140 };
1141
1142 static const char* op1_types[] = {
1143 "", ".u8", ".s8", ".u16",
1144 ".s16", ".u32", ".s32", "32",
1145 ".p", "", "", "",
1146 ".u16", ".s16", ".u32", ".s32"
1147 };
1148
1149 static const char* op2_names[] = {
1150 "add", "addc", "sub", "subc",
1151 "mul", "and", "or", "xor",
1152 "shl", "mshl", "lshr", "mlshr",
1153 "ashr", "mashr", "rotl", "rotr"
1154 };
1155
1156 static const char* op2r_names[] = {
1157 "muladd"
1158 };
1159
1160 static const char* op_src_dst_names[] = {
1161 "fast_return", "skip_frames_before_fast_return",
1162 "prefetch_l1", "prefetch_l2",
1163 "prefetch_l3", "prefetch_once",
1164 "fast_enter", "get_return_address"
1165 };
1166
1167 static const char* fop1_names[] = {
1168 "mov", "conv", "conv", "conv",
1169 "conv", "conv", "conv", "conv",
1170 "cmp", "neg", "abs",
1171 };
1172
1173 static const char* fop1_conv_types[] = {
1174 "sw", "s32", "sw", "s32",
1175 "uw", "u32"
1176 };
1177
1178 static const char* fop2_names[] = {
1179 "add", "sub", "mul", "div"
1180 };
1181
1182 static const char* fop2r_names[] = {
1183 "copysign"
1184 };
1185
1186 static const char* simd_op2_names[] = {
1187 "and", "or", "xor"
1188 };
1189
1190 static const char* jump_names[] = {
1191 "equal", "not_equal",
1192 "less", "greater_equal",
1193 "greater", "less_equal",
1194 "sig_less", "sig_greater_equal",
1195 "sig_greater", "sig_less_equal",
1196 "overflow", "not_overflow",
1197 "carry", "not_carry",
1198 "atomic_stored", "atomic_not_stored",
1199 "f_equal", "f_not_equal",
1200 "f_less", "f_greater_equal",
1201 "f_greater", "f_less_equal",
1202 "unordered", "ordered",
1203 "ordered_equal", "unordered_or_not_equal",
1204 "ordered_less", "unordered_or_greater_equal",
1205 "ordered_greater", "unordered_or_less_equal",
1206 "unordered_or_equal", "ordered_not_equal",
1207 "unordered_or_less", "ordered_greater_equal",
1208 "unordered_or_greater", "ordered_less_equal",
1209 "jump", "fast_call",
1210 "call", "call_reg_arg"
1211 };
1212
1213 static const char* call_arg_names[] = {
1214 "void", "w", "32", "p", "f64", "f32"
1215 };
1216
1217 #endif /* SLJIT_VERBOSE */
1218
1219 /* --------------------------------------------------------------------- */
1220 /* Arch dependent */
1221 /* --------------------------------------------------------------------- */
1222
1223 #if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS) \
1224 || (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
1225
1226 #define SLJIT_SKIP_CHECKS(compiler) (compiler)->skip_checks = 1
1227
check_sljit_generate_code(struct sljit_compiler * compiler)1228 static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_generate_code(struct sljit_compiler *compiler)
1229 {
1230 #if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
1231 struct sljit_jump *jump;
1232 #endif
1233
1234 SLJIT_UNUSED_ARG(compiler);
1235
1236 #if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
1237 CHECK_ARGUMENT(compiler->size > 0);
1238 jump = compiler->jumps;
1239 while (jump) {
1240 /* All jumps have target. */
1241 CHECK_ARGUMENT((jump->flags & JUMP_ADDR) || jump->u.label != NULL);
1242 jump = jump->next;
1243 }
1244 #endif
1245 CHECK_RETURN_OK;
1246 }
1247
1248 #if (defined SLJIT_CONFIG_X86 && SLJIT_CONFIG_X86)
1249 #define SLJIT_ENTER_CPU_SPECIFIC_OPTIONS (SLJIT_ENTER_USE_VEX)
1250 #else /* !SLJIT_CONFIG_X86 */
1251 #define SLJIT_ENTER_CPU_SPECIFIC_OPTIONS (0)
1252 #endif /* !SLJIT_CONFIG_X86 */
1253
check_sljit_emit_enter(struct sljit_compiler * compiler,sljit_s32 options,sljit_s32 arg_types,sljit_s32 scratches,sljit_s32 saveds,sljit_s32 fscratches,sljit_s32 fsaveds,sljit_s32 local_size)1254 static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_enter(struct sljit_compiler *compiler,
1255 sljit_s32 options, sljit_s32 arg_types, sljit_s32 scratches, sljit_s32 saveds,
1256 sljit_s32 fscratches, sljit_s32 fsaveds, sljit_s32 local_size)
1257 {
1258 SLJIT_UNUSED_ARG(compiler);
1259
1260 #if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
1261 if (options & SLJIT_ENTER_REG_ARG) {
1262 CHECK_ARGUMENT(!(options & ~(0x3 | SLJIT_ENTER_REG_ARG | SLJIT_ENTER_CPU_SPECIFIC_OPTIONS)));
1263 } else {
1264 CHECK_ARGUMENT((options & ~SLJIT_ENTER_CPU_SPECIFIC_OPTIONS) == 0);
1265 }
1266 CHECK_ARGUMENT(SLJIT_KEPT_SAVEDS_COUNT(options) <= 3 && SLJIT_KEPT_SAVEDS_COUNT(options) <= saveds);
1267 CHECK_ARGUMENT(scratches >= 0 && scratches <= SLJIT_NUMBER_OF_REGISTERS);
1268 CHECK_ARGUMENT(saveds >= 0 && saveds <= SLJIT_NUMBER_OF_SAVED_REGISTERS);
1269 CHECK_ARGUMENT(scratches + saveds <= SLJIT_NUMBER_OF_REGISTERS);
1270 CHECK_ARGUMENT(fscratches >= 0 && fscratches <= SLJIT_NUMBER_OF_FLOAT_REGISTERS);
1271 CHECK_ARGUMENT(fsaveds >= 0 && fsaveds <= SLJIT_NUMBER_OF_SAVED_FLOAT_REGISTERS);
1272 CHECK_ARGUMENT(fscratches + fsaveds <= SLJIT_NUMBER_OF_FLOAT_REGISTERS);
1273 CHECK_ARGUMENT(local_size >= 0 && local_size <= SLJIT_MAX_LOCAL_SIZE);
1274 CHECK_ARGUMENT((arg_types & SLJIT_ARG_FULL_MASK) <= SLJIT_ARG_TYPE_F32);
1275 CHECK_ARGUMENT(function_check_arguments(arg_types, scratches, (options & SLJIT_ENTER_REG_ARG) ? 0 : saveds, fscratches));
1276
1277 compiler->last_flags = 0;
1278 #endif
1279 #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
1280 if (SLJIT_UNLIKELY(!!compiler->verbose)) {
1281 fprintf(compiler->verbose, " enter ret[%s", call_arg_names[arg_types & SLJIT_ARG_MASK]);
1282
1283 arg_types >>= SLJIT_ARG_SHIFT;
1284 if (arg_types) {
1285 fprintf(compiler->verbose, "], args[");
1286 do {
1287 fprintf(compiler->verbose, "%s%s", call_arg_names[arg_types & SLJIT_ARG_MASK],
1288 (arg_types & SLJIT_ARG_TYPE_SCRATCH_REG) ? "_r" : "");
1289 arg_types >>= SLJIT_ARG_SHIFT;
1290 if (arg_types)
1291 fprintf(compiler->verbose, ",");
1292 } while (arg_types);
1293 }
1294
1295 fprintf(compiler->verbose, "],");
1296
1297 if (options & SLJIT_ENTER_REG_ARG) {
1298 if (SLJIT_KEPT_SAVEDS_COUNT(options) > 0)
1299 fprintf(compiler->verbose, " opt:reg_arg(%d),", SLJIT_KEPT_SAVEDS_COUNT(options));
1300 else
1301 fprintf(compiler->verbose, " opt:reg_arg,");
1302 }
1303
1304 #if (defined SLJIT_CONFIG_X86 && SLJIT_CONFIG_X86)
1305 if (options & SLJIT_ENTER_USE_VEX) {
1306 fprintf(compiler->verbose, " opt:use_vex,");
1307 }
1308 #endif /* !SLJIT_CONFIG_X86 */
1309
1310 fprintf(compiler->verbose, " scratches:%d, saveds:%d, fscratches:%d, fsaveds:%d, local_size:%d\n",
1311 scratches, saveds, fscratches, fsaveds, local_size);
1312 }
1313 #endif
1314 CHECK_RETURN_OK;
1315 }
1316
check_sljit_set_context(struct sljit_compiler * compiler,sljit_s32 options,sljit_s32 arg_types,sljit_s32 scratches,sljit_s32 saveds,sljit_s32 fscratches,sljit_s32 fsaveds,sljit_s32 local_size)1317 static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_set_context(struct sljit_compiler *compiler,
1318 sljit_s32 options, sljit_s32 arg_types, sljit_s32 scratches, sljit_s32 saveds,
1319 sljit_s32 fscratches, sljit_s32 fsaveds, sljit_s32 local_size)
1320 {
1321 SLJIT_UNUSED_ARG(compiler);
1322
1323 #if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
1324 if (options & SLJIT_ENTER_REG_ARG) {
1325 CHECK_ARGUMENT(!(options & ~(0x3 | SLJIT_ENTER_REG_ARG | SLJIT_ENTER_CPU_SPECIFIC_OPTIONS)));
1326 } else {
1327 CHECK_ARGUMENT((options & ~SLJIT_ENTER_CPU_SPECIFIC_OPTIONS) == 0);
1328 }
1329 CHECK_ARGUMENT(SLJIT_KEPT_SAVEDS_COUNT(options) <= 3 && SLJIT_KEPT_SAVEDS_COUNT(options) <= saveds);
1330 CHECK_ARGUMENT(scratches >= 0 && scratches <= SLJIT_NUMBER_OF_REGISTERS);
1331 CHECK_ARGUMENT(saveds >= 0 && saveds <= SLJIT_NUMBER_OF_SAVED_REGISTERS);
1332 CHECK_ARGUMENT(scratches + saveds <= SLJIT_NUMBER_OF_REGISTERS);
1333 CHECK_ARGUMENT(fscratches >= 0 && fscratches <= SLJIT_NUMBER_OF_FLOAT_REGISTERS);
1334 CHECK_ARGUMENT(fsaveds >= 0 && fsaveds <= SLJIT_NUMBER_OF_SAVED_FLOAT_REGISTERS);
1335 CHECK_ARGUMENT(fscratches + fsaveds <= SLJIT_NUMBER_OF_FLOAT_REGISTERS);
1336 CHECK_ARGUMENT(local_size >= 0 && local_size <= SLJIT_MAX_LOCAL_SIZE);
1337 CHECK_ARGUMENT((arg_types & SLJIT_ARG_FULL_MASK) < SLJIT_ARG_TYPE_F64);
1338 CHECK_ARGUMENT(function_check_arguments(arg_types, scratches, (options & SLJIT_ENTER_REG_ARG) ? 0 : saveds, fscratches));
1339
1340 compiler->last_flags = 0;
1341 #endif
1342 #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
1343 if (SLJIT_UNLIKELY(!!compiler->verbose)) {
1344 fprintf(compiler->verbose, " set_context ret[%s", call_arg_names[arg_types & SLJIT_ARG_MASK]);
1345
1346 arg_types >>= SLJIT_ARG_SHIFT;
1347 if (arg_types) {
1348 fprintf(compiler->verbose, "], args[");
1349 do {
1350 fprintf(compiler->verbose, "%s%s", call_arg_names[arg_types & SLJIT_ARG_MASK],
1351 (arg_types & SLJIT_ARG_TYPE_SCRATCH_REG) ? "_r" : "");
1352 arg_types >>= SLJIT_ARG_SHIFT;
1353 if (arg_types)
1354 fprintf(compiler->verbose, ",");
1355 } while (arg_types);
1356 }
1357
1358 fprintf(compiler->verbose, "],");
1359
1360 if (options & SLJIT_ENTER_REG_ARG) {
1361 if (SLJIT_KEPT_SAVEDS_COUNT(options) > 0)
1362 fprintf(compiler->verbose, " opt:reg_arg(%d),", SLJIT_KEPT_SAVEDS_COUNT(options));
1363 else
1364 fprintf(compiler->verbose, " opt:reg_arg,");
1365 }
1366
1367 #if (defined SLJIT_CONFIG_X86 && SLJIT_CONFIG_X86)
1368 if (options & SLJIT_ENTER_USE_VEX) {
1369 fprintf(compiler->verbose, " opt:use_vex,");
1370 }
1371 #endif /* !SLJIT_CONFIG_X86 */
1372
1373 fprintf(compiler->verbose, " scratches:%d, saveds:%d, fscratches:%d, fsaveds:%d, local_size:%d\n",
1374 scratches, saveds, fscratches, fsaveds, local_size);
1375 }
1376 #endif
1377 CHECK_RETURN_OK;
1378 }
1379
1380 #undef SLJIT_ENTER_CPU_SPECIFIC_OPTIONS
1381
check_sljit_emit_return_void(struct sljit_compiler * compiler)1382 static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_return_void(struct sljit_compiler *compiler)
1383 {
1384 if (SLJIT_UNLIKELY(compiler->skip_checks)) {
1385 compiler->skip_checks = 0;
1386 CHECK_RETURN_OK;
1387 }
1388
1389 #if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
1390 CHECK_ARGUMENT(compiler->last_return == SLJIT_ARG_TYPE_RET_VOID);
1391 #endif
1392
1393 #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
1394 if (SLJIT_UNLIKELY(!!compiler->verbose)) {
1395 fprintf(compiler->verbose, " return_void\n");
1396 }
1397 #endif
1398 CHECK_RETURN_OK;
1399 }
1400
check_sljit_emit_return(struct sljit_compiler * compiler,sljit_s32 op,sljit_s32 src,sljit_sw srcw)1401 static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_return(struct sljit_compiler *compiler, sljit_s32 op, sljit_s32 src, sljit_sw srcw)
1402 {
1403 #if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
1404 CHECK_ARGUMENT(compiler->scratches >= 0);
1405
1406 switch (compiler->last_return) {
1407 case SLJIT_ARG_TYPE_W:
1408 CHECK_ARGUMENT(op >= SLJIT_MOV && op <= SLJIT_MOV_S32);
1409 break;
1410 case SLJIT_ARG_TYPE_32:
1411 CHECK_ARGUMENT(op == SLJIT_MOV32 || (op >= SLJIT_MOV32_U8 && op <= SLJIT_MOV32_S16));
1412 break;
1413 case SLJIT_ARG_TYPE_P:
1414 CHECK_ARGUMENT(op == SLJIT_MOV_P);
1415 break;
1416 case SLJIT_ARG_TYPE_F64:
1417 CHECK_ARGUMENT(sljit_has_cpu_feature(SLJIT_HAS_FPU));
1418 CHECK_ARGUMENT(op == SLJIT_MOV_F64);
1419 break;
1420 case SLJIT_ARG_TYPE_F32:
1421 CHECK_ARGUMENT(sljit_has_cpu_feature(SLJIT_HAS_FPU));
1422 CHECK_ARGUMENT(op == SLJIT_MOV_F32);
1423 break;
1424 default:
1425 /* Context not initialized, void, etc. */
1426 CHECK_ARGUMENT(0);
1427 break;
1428 }
1429
1430 if (GET_OPCODE(op) < SLJIT_MOV_F64) {
1431 FUNCTION_CHECK_SRC(src, srcw);
1432 } else {
1433 FUNCTION_FCHECK(src, srcw, op & SLJIT_32);
1434 }
1435 compiler->last_flags = 0;
1436 #endif
1437 #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
1438 if (SLJIT_UNLIKELY(!!compiler->verbose)) {
1439 if (GET_OPCODE(op) < SLJIT_MOV_F64) {
1440 fprintf(compiler->verbose, " return%s%s ", !(op & SLJIT_32) ? "" : "32",
1441 op1_types[GET_OPCODE(op) - SLJIT_OP1_BASE]);
1442 sljit_verbose_param(compiler, src, srcw);
1443 } else {
1444 fprintf(compiler->verbose, " return%s ", !(op & SLJIT_32) ? ".f64" : ".f32");
1445 sljit_verbose_fparam(compiler, src, srcw);
1446 }
1447 fprintf(compiler->verbose, "\n");
1448 }
1449 #endif
1450 CHECK_RETURN_OK;
1451 }
1452
check_sljit_emit_return_to(struct sljit_compiler * compiler,sljit_s32 src,sljit_sw srcw)1453 static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_return_to(struct sljit_compiler *compiler,
1454 sljit_s32 src, sljit_sw srcw)
1455 {
1456 #if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
1457 FUNCTION_CHECK_SRC(src, srcw);
1458 #endif
1459 #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
1460 if (SLJIT_UNLIKELY(!!compiler->verbose)) {
1461 fprintf(compiler->verbose, " return_to ");
1462 sljit_verbose_param(compiler, src, srcw);
1463 fprintf(compiler->verbose, "\n");
1464 }
1465 #endif
1466 CHECK_RETURN_OK;
1467 }
1468
check_sljit_emit_op0(struct sljit_compiler * compiler,sljit_s32 op)1469 static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_op0(struct sljit_compiler *compiler, sljit_s32 op)
1470 {
1471 #if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
1472 CHECK_ARGUMENT((op >= SLJIT_BREAKPOINT && op <= SLJIT_LMUL_SW)
1473 || ((op & ~SLJIT_32) >= SLJIT_DIVMOD_UW && (op & ~SLJIT_32) <= SLJIT_DIV_SW)
1474 || (op >= SLJIT_ENDBR && op <= SLJIT_SKIP_FRAMES_BEFORE_RETURN));
1475 CHECK_ARGUMENT(GET_OPCODE(op) < SLJIT_LMUL_UW || GET_OPCODE(op) >= SLJIT_ENDBR || compiler->scratches >= 2);
1476 if ((GET_OPCODE(op) >= SLJIT_LMUL_UW && GET_OPCODE(op) <= SLJIT_DIV_SW) || op == SLJIT_SKIP_FRAMES_BEFORE_RETURN)
1477 compiler->last_flags = 0;
1478 #endif
1479 #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
1480 if (SLJIT_UNLIKELY(!!compiler->verbose))
1481 {
1482 fprintf(compiler->verbose, " %s", op0_names[GET_OPCODE(op) - SLJIT_OP0_BASE]);
1483 if (GET_OPCODE(op) >= SLJIT_DIVMOD_UW && GET_OPCODE(op) <= SLJIT_DIV_SW) {
1484 fprintf(compiler->verbose, (op & SLJIT_32) ? "32" : "w");
1485 }
1486 fprintf(compiler->verbose, "\n");
1487 }
1488 #endif
1489 CHECK_RETURN_OK;
1490 }
1491
check_sljit_emit_op1(struct sljit_compiler * compiler,sljit_s32 op,sljit_s32 dst,sljit_sw dstw,sljit_s32 src,sljit_sw srcw)1492 static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_op1(struct sljit_compiler *compiler, sljit_s32 op,
1493 sljit_s32 dst, sljit_sw dstw,
1494 sljit_s32 src, sljit_sw srcw)
1495 {
1496 if (SLJIT_UNLIKELY(compiler->skip_checks)) {
1497 compiler->skip_checks = 0;
1498 CHECK_RETURN_OK;
1499 }
1500
1501 #if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
1502 CHECK_ARGUMENT(GET_OPCODE(op) >= SLJIT_MOV && GET_OPCODE(op) <= SLJIT_REV_S32);
1503
1504 switch (GET_OPCODE(op)) {
1505 case SLJIT_MOV:
1506 case SLJIT_MOV_U32:
1507 case SLJIT_MOV_S32:
1508 case SLJIT_MOV32:
1509 case SLJIT_MOV_P:
1510 case SLJIT_REV_U32:
1511 case SLJIT_REV_S32:
1512 /* Nothing allowed */
1513 CHECK_ARGUMENT(!(op & (SLJIT_32 | SLJIT_SET_Z | VARIABLE_FLAG_MASK)));
1514 break;
1515 default:
1516 /* Only SLJIT_32 is allowed. */
1517 CHECK_ARGUMENT(!(op & (SLJIT_SET_Z | VARIABLE_FLAG_MASK)));
1518 break;
1519 }
1520
1521 FUNCTION_CHECK_DST(dst, dstw);
1522 FUNCTION_CHECK_SRC(src, srcw);
1523 #endif
1524 #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
1525 if (SLJIT_UNLIKELY(!!compiler->verbose)) {
1526 fprintf(compiler->verbose, " %s%s%s ", op1_names[GET_OPCODE(op) - SLJIT_OP1_BASE],
1527 !(op & SLJIT_32) ? "" : "32", op1_types[GET_OPCODE(op) - SLJIT_OP1_BASE]);
1528
1529 sljit_verbose_param(compiler, dst, dstw);
1530 fprintf(compiler->verbose, ", ");
1531 sljit_verbose_param(compiler, src, srcw);
1532 fprintf(compiler->verbose, "\n");
1533 }
1534 #endif
1535 CHECK_RETURN_OK;
1536 }
1537
check_sljit_emit_atomic_load(struct sljit_compiler * compiler,sljit_s32 op,sljit_s32 dst_reg,sljit_s32 mem_reg)1538 static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_atomic_load(struct sljit_compiler *compiler, sljit_s32 op,
1539 sljit_s32 dst_reg,
1540 sljit_s32 mem_reg)
1541 {
1542 if (SLJIT_UNLIKELY(compiler->skip_checks)) {
1543 compiler->skip_checks = 0;
1544 CHECK_RETURN_OK;
1545 }
1546
1547 #if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
1548 CHECK_ARGUMENT(sljit_has_cpu_feature(SLJIT_HAS_ATOMIC));
1549 CHECK_ARGUMENT(GET_OPCODE(op) >= SLJIT_MOV && GET_OPCODE(op) <= SLJIT_MOV_P);
1550 CHECK_ARGUMENT(GET_OPCODE(op) != SLJIT_MOV_S8 && GET_OPCODE(op) != SLJIT_MOV_S16 && GET_OPCODE(op) != SLJIT_MOV_S32);
1551
1552 /* All arguments must be valid registers. */
1553 CHECK_ARGUMENT(FUNCTION_CHECK_IS_REG(dst_reg));
1554 CHECK_ARGUMENT(FUNCTION_CHECK_IS_REG(mem_reg) && !CHECK_IF_VIRTUAL_REGISTER(mem_reg));
1555
1556 if (op == SLJIT_MOV32_U8 || op == SLJIT_MOV32_U16) {
1557 /* Only SLJIT_32 is allowed. */
1558 CHECK_ARGUMENT(!(op & (VARIABLE_FLAG_MASK | SLJIT_SET_Z)));
1559 } else {
1560 /* Nothing allowed. */
1561 CHECK_ARGUMENT(!(op & (SLJIT_32 | SLJIT_SET_Z | VARIABLE_FLAG_MASK)));
1562 }
1563
1564 compiler->last_flags = 0;
1565 #endif /* SLJIT_ARGUMENT_CHECKS */
1566 #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
1567 if (SLJIT_UNLIKELY(!!compiler->verbose)) {
1568 fprintf(compiler->verbose, " atomic_load%s%s ", !(op & SLJIT_32) ? "" : "32",
1569 op1_types[GET_OPCODE(op) - SLJIT_OP1_BASE]);
1570 sljit_verbose_reg(compiler, dst_reg);
1571 fprintf(compiler->verbose, ", [");
1572 sljit_verbose_reg(compiler, mem_reg);
1573 fprintf(compiler->verbose, "]\n");
1574 }
1575 #endif /* SLJIT_VERBOSE */
1576 CHECK_RETURN_OK;
1577 }
1578
check_sljit_emit_atomic_store(struct sljit_compiler * compiler,sljit_s32 op,sljit_s32 src_reg,sljit_s32 mem_reg,sljit_s32 temp_reg)1579 static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_atomic_store(struct sljit_compiler *compiler, sljit_s32 op,
1580 sljit_s32 src_reg,
1581 sljit_s32 mem_reg,
1582 sljit_s32 temp_reg)
1583 {
1584 if (SLJIT_UNLIKELY(compiler->skip_checks)) {
1585 compiler->skip_checks = 0;
1586 CHECK_RETURN_OK;
1587 }
1588
1589 #if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
1590 CHECK_ARGUMENT(sljit_has_cpu_feature(SLJIT_HAS_ATOMIC));
1591 CHECK_ARGUMENT(GET_OPCODE(op) >= SLJIT_MOV && GET_OPCODE(op) <= SLJIT_MOV_P);
1592 CHECK_ARGUMENT(GET_OPCODE(op) != SLJIT_MOV_S8 && GET_OPCODE(op) != SLJIT_MOV_S16 && GET_OPCODE(op) != SLJIT_MOV_S32);
1593
1594 /* All arguments must be valid registers. */
1595 CHECK_ARGUMENT(FUNCTION_CHECK_IS_REG(src_reg));
1596 CHECK_ARGUMENT(FUNCTION_CHECK_IS_REG(mem_reg) && !CHECK_IF_VIRTUAL_REGISTER(mem_reg));
1597 CHECK_ARGUMENT(FUNCTION_CHECK_IS_REG(temp_reg) && src_reg != temp_reg);
1598
1599 CHECK_ARGUMENT(!(op & VARIABLE_FLAG_MASK) || GET_FLAG_TYPE(op) == SLJIT_ATOMIC_STORED);
1600
1601 if (GET_OPCODE(op) == SLJIT_MOV_U8 || GET_OPCODE(op) == SLJIT_MOV_U16) {
1602 /* Only SLJIT_32, SLJIT_ATOMIC_STORED are allowed. */
1603 CHECK_ARGUMENT(!(op & SLJIT_SET_Z));
1604 } else {
1605 /* Only SLJIT_ATOMIC_STORED is allowed. */
1606 CHECK_ARGUMENT(!(op & (SLJIT_32 | SLJIT_SET_Z)));
1607 }
1608
1609 compiler->last_flags = GET_FLAG_TYPE(op) | (op & SLJIT_32);
1610 #endif /* SLJIT_ARGUMENT_CHECKS */
1611 #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
1612 if (SLJIT_UNLIKELY(!!compiler->verbose)) {
1613 fprintf(compiler->verbose, " atomic_store%s%s%s ", !(op & SLJIT_32) ? "" : "32",
1614 op1_types[GET_OPCODE(op) - SLJIT_OP1_BASE], !(op & VARIABLE_FLAG_MASK) ? "" : ".stored");
1615 sljit_verbose_reg(compiler, src_reg);
1616 fprintf(compiler->verbose, ", [");
1617 sljit_verbose_reg(compiler, mem_reg);
1618 fprintf(compiler->verbose, "], ");
1619 sljit_verbose_reg(compiler, temp_reg);
1620 fprintf(compiler->verbose, "\n");
1621 }
1622 #endif /* SLJIT_VERBOSE */
1623 CHECK_RETURN_OK;
1624 }
1625
check_sljit_emit_op2(struct sljit_compiler * compiler,sljit_s32 op,sljit_s32 unset,sljit_s32 dst,sljit_sw dstw,sljit_s32 src1,sljit_sw src1w,sljit_s32 src2,sljit_sw src2w)1626 static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_op2(struct sljit_compiler *compiler, sljit_s32 op, sljit_s32 unset,
1627 sljit_s32 dst, sljit_sw dstw,
1628 sljit_s32 src1, sljit_sw src1w,
1629 sljit_s32 src2, sljit_sw src2w)
1630 {
1631 if (SLJIT_UNLIKELY(compiler->skip_checks)) {
1632 compiler->skip_checks = 0;
1633 CHECK_RETURN_OK;
1634 }
1635
1636 #if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
1637 CHECK_ARGUMENT(GET_OPCODE(op) >= SLJIT_ADD && GET_OPCODE(op) <= SLJIT_ROTR);
1638
1639 switch (GET_OPCODE(op)) {
1640 case SLJIT_AND:
1641 case SLJIT_OR:
1642 case SLJIT_XOR:
1643 case SLJIT_SHL:
1644 case SLJIT_MSHL:
1645 case SLJIT_LSHR:
1646 case SLJIT_MLSHR:
1647 case SLJIT_ASHR:
1648 case SLJIT_MASHR:
1649 CHECK_ARGUMENT(!(op & VARIABLE_FLAG_MASK));
1650 break;
1651 case SLJIT_MUL:
1652 CHECK_ARGUMENT(!(op & SLJIT_SET_Z));
1653 CHECK_ARGUMENT(!(op & VARIABLE_FLAG_MASK)
1654 || GET_FLAG_TYPE(op) == SLJIT_OVERFLOW);
1655 break;
1656 case SLJIT_ADD:
1657 CHECK_ARGUMENT(!(op & VARIABLE_FLAG_MASK)
1658 || GET_FLAG_TYPE(op) == GET_FLAG_TYPE(SLJIT_SET_CARRY)
1659 || GET_FLAG_TYPE(op) == SLJIT_OVERFLOW);
1660 break;
1661 case SLJIT_SUB:
1662 CHECK_ARGUMENT(!(op & VARIABLE_FLAG_MASK)
1663 || (GET_FLAG_TYPE(op) >= SLJIT_LESS && GET_FLAG_TYPE(op) <= SLJIT_OVERFLOW)
1664 || GET_FLAG_TYPE(op) == GET_FLAG_TYPE(SLJIT_SET_CARRY));
1665 break;
1666 case SLJIT_ADDC:
1667 case SLJIT_SUBC:
1668 CHECK_ARGUMENT(!(op & VARIABLE_FLAG_MASK)
1669 || GET_FLAG_TYPE(op) == GET_FLAG_TYPE(SLJIT_SET_CARRY));
1670 CHECK_ARGUMENT((compiler->last_flags & 0xff) == GET_FLAG_TYPE(SLJIT_SET_CARRY));
1671 CHECK_ARGUMENT((op & SLJIT_32) == (compiler->last_flags & SLJIT_32));
1672 break;
1673 case SLJIT_ROTL:
1674 case SLJIT_ROTR:
1675 CHECK_ARGUMENT(!(op & (SLJIT_SET_Z | VARIABLE_FLAG_MASK)));
1676 break;
1677 default:
1678 SLJIT_UNREACHABLE();
1679 break;
1680 }
1681
1682 if (unset) {
1683 CHECK_ARGUMENT(HAS_FLAGS(op));
1684 } else {
1685 FUNCTION_CHECK_DST(dst, dstw);
1686 }
1687 FUNCTION_CHECK_SRC(src1, src1w);
1688 FUNCTION_CHECK_SRC(src2, src2w);
1689 compiler->last_flags = GET_FLAG_TYPE(op) | (op & (SLJIT_32 | SLJIT_SET_Z));
1690 #endif
1691 #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
1692 if (SLJIT_UNLIKELY(!!compiler->verbose)) {
1693 fprintf(compiler->verbose, " %s%s%s%s%s ", op2_names[GET_OPCODE(op) - SLJIT_OP2_BASE], !(op & SLJIT_32) ? "" : "32",
1694 !(op & SLJIT_SET_Z) ? "" : ".z", !(op & VARIABLE_FLAG_MASK) ? "" : ".",
1695 !(op & VARIABLE_FLAG_MASK) ? "" : jump_names[GET_FLAG_TYPE(op)]);
1696 if (unset)
1697 fprintf(compiler->verbose, "unset");
1698 else
1699 sljit_verbose_param(compiler, dst, dstw);
1700 fprintf(compiler->verbose, ", ");
1701 sljit_verbose_param(compiler, src1, src1w);
1702 fprintf(compiler->verbose, ", ");
1703 sljit_verbose_param(compiler, src2, src2w);
1704 fprintf(compiler->verbose, "\n");
1705 }
1706 #endif
1707 CHECK_RETURN_OK;
1708 }
1709
check_sljit_emit_op2r(struct sljit_compiler * compiler,sljit_s32 op,sljit_s32 dst_reg,sljit_s32 src1,sljit_sw src1w,sljit_s32 src2,sljit_sw src2w)1710 static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_op2r(struct sljit_compiler *compiler, sljit_s32 op,
1711 sljit_s32 dst_reg,
1712 sljit_s32 src1, sljit_sw src1w,
1713 sljit_s32 src2, sljit_sw src2w)
1714 {
1715 #if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
1716 CHECK_ARGUMENT((op | SLJIT_32) == SLJIT_MULADD32);
1717 CHECK_ARGUMENT(FUNCTION_CHECK_IS_REG(dst_reg));
1718 FUNCTION_CHECK_SRC(src1, src1w);
1719 FUNCTION_CHECK_SRC(src2, src2w);
1720 compiler->last_flags = 0;
1721 #endif
1722 #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
1723 if (SLJIT_UNLIKELY(!!compiler->verbose)) {
1724 fprintf(compiler->verbose, " %s%s ", op2r_names[GET_OPCODE(op) - SLJIT_OP2R_BASE], !(op & SLJIT_32) ? "" : "32");
1725
1726 sljit_verbose_reg(compiler, dst_reg);
1727 fprintf(compiler->verbose, ", ");
1728 sljit_verbose_param(compiler, src1, src1w);
1729 fprintf(compiler->verbose, ", ");
1730 sljit_verbose_param(compiler, src2, src2w);
1731 fprintf(compiler->verbose, "\n");
1732 }
1733 #endif
1734 CHECK_RETURN_OK;
1735 }
1736
check_sljit_emit_shift_into(struct sljit_compiler * compiler,sljit_s32 op,sljit_s32 dst_reg,sljit_s32 src1_reg,sljit_s32 src2_reg,sljit_s32 src3,sljit_sw src3w)1737 static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_shift_into(struct sljit_compiler *compiler, sljit_s32 op,
1738 sljit_s32 dst_reg,
1739 sljit_s32 src1_reg,
1740 sljit_s32 src2_reg,
1741 sljit_s32 src3, sljit_sw src3w)
1742 {
1743 #if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
1744 CHECK_ARGUMENT(GET_OPCODE(op) == SLJIT_SHL || GET_OPCODE(op) == SLJIT_LSHR
1745 || GET_OPCODE(op) == SLJIT_MSHL || GET_OPCODE(op) == SLJIT_MLSHR);
1746 CHECK_ARGUMENT((op & ~(0xff | SLJIT_32 | SLJIT_SHIFT_INTO_NON_ZERO)) == 0);
1747 CHECK_ARGUMENT(FUNCTION_CHECK_IS_REG(dst_reg));
1748 CHECK_ARGUMENT(FUNCTION_CHECK_IS_REG(src1_reg));
1749 CHECK_ARGUMENT(FUNCTION_CHECK_IS_REG(src2_reg));
1750 FUNCTION_CHECK_SRC(src3, src3w);
1751 CHECK_ARGUMENT(dst_reg != src2_reg);
1752 #endif
1753 #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
1754 if (SLJIT_UNLIKELY(!!compiler->verbose)) {
1755 fprintf(compiler->verbose, " %s%s.into%s ", op2_names[GET_OPCODE(op) - SLJIT_OP2_BASE], !(op & SLJIT_32) ? "" : "32",
1756 (op & SLJIT_SHIFT_INTO_NON_ZERO) ? ".nz" : "");
1757
1758 sljit_verbose_reg(compiler, dst_reg);
1759 fprintf(compiler->verbose, ", ");
1760 sljit_verbose_reg(compiler, src1_reg);
1761 fprintf(compiler->verbose, ", ");
1762 sljit_verbose_reg(compiler, src2_reg);
1763 fprintf(compiler->verbose, ", ");
1764 sljit_verbose_param(compiler, src3, src3w);
1765 fprintf(compiler->verbose, "\n");
1766 }
1767 #endif
1768 CHECK_RETURN_OK;
1769 }
1770
check_sljit_emit_op_src(struct sljit_compiler * compiler,sljit_s32 op,sljit_s32 src,sljit_sw srcw)1771 static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_op_src(struct sljit_compiler *compiler, sljit_s32 op,
1772 sljit_s32 src, sljit_sw srcw)
1773 {
1774 #if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
1775 CHECK_ARGUMENT(op >= SLJIT_FAST_RETURN && op <= SLJIT_PREFETCH_ONCE);
1776 FUNCTION_CHECK_SRC(src, srcw);
1777
1778 if (op == SLJIT_FAST_RETURN || op == SLJIT_SKIP_FRAMES_BEFORE_FAST_RETURN) {
1779 CHECK_ARGUMENT(src != SLJIT_IMM);
1780 compiler->last_flags = 0;
1781 } else if (op >= SLJIT_PREFETCH_L1 && op <= SLJIT_PREFETCH_ONCE) {
1782 CHECK_ARGUMENT(src & SLJIT_MEM);
1783 }
1784 #endif
1785 #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
1786 if (SLJIT_UNLIKELY(!!compiler->verbose)) {
1787 fprintf(compiler->verbose, " %s ", op_src_dst_names[op - SLJIT_OP_SRC_DST_BASE]);
1788 sljit_verbose_param(compiler, src, srcw);
1789 fprintf(compiler->verbose, "\n");
1790 }
1791 #endif
1792 CHECK_RETURN_OK;
1793 }
1794
check_sljit_emit_op_dst(struct sljit_compiler * compiler,sljit_s32 op,sljit_s32 dst,sljit_sw dstw)1795 static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_op_dst(struct sljit_compiler *compiler, sljit_s32 op,
1796 sljit_s32 dst, sljit_sw dstw)
1797 {
1798 #if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
1799 CHECK_ARGUMENT(op >= SLJIT_FAST_ENTER && op <= SLJIT_GET_RETURN_ADDRESS);
1800 FUNCTION_CHECK_DST(dst, dstw);
1801
1802 if (op == SLJIT_FAST_ENTER)
1803 compiler->last_flags = 0;
1804 #endif
1805 #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
1806 if (SLJIT_UNLIKELY(!!compiler->verbose)) {
1807 fprintf(compiler->verbose, " %s ", op_src_dst_names[op - SLJIT_OP_SRC_DST_BASE]);
1808 sljit_verbose_param(compiler, dst, dstw);
1809 fprintf(compiler->verbose, "\n");
1810 }
1811 #endif
1812 CHECK_RETURN_OK;
1813 }
1814
check_sljit_get_register_index(sljit_s32 type,sljit_s32 reg)1815 static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_get_register_index(sljit_s32 type, sljit_s32 reg)
1816 {
1817 SLJIT_UNUSED_ARG(type);
1818 SLJIT_UNUSED_ARG(reg);
1819 #if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
1820 if (type == SLJIT_GP_REGISTER) {
1821 CHECK_ARGUMENT((reg > 0 && reg <= SLJIT_NUMBER_OF_REGISTERS)
1822 || (reg >= SLJIT_TMP_REGISTER_BASE && reg < (SLJIT_TMP_REGISTER_BASE + SLJIT_NUMBER_OF_TEMPORARY_REGISTERS)));
1823 } else {
1824 CHECK_ARGUMENT(type == SLJIT_FLOAT_REGISTER || ((type >> 12) == 0 || ((type >> 12) >= 3 && (type >> 12) <= 6)));
1825 CHECK_ARGUMENT((reg > 0 && reg <= SLJIT_NUMBER_OF_FLOAT_REGISTERS)
1826 || (reg >= SLJIT_TMP_FREGISTER_BASE && reg < (SLJIT_TMP_FREGISTER_BASE + SLJIT_NUMBER_OF_TEMPORARY_FLOAT_REGISTERS)));
1827 }
1828 #endif
1829 CHECK_RETURN_OK;
1830 }
1831
check_sljit_emit_op_custom(struct sljit_compiler * compiler,void * instruction,sljit_u32 size)1832 static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_op_custom(struct sljit_compiler *compiler,
1833 void *instruction, sljit_u32 size)
1834 {
1835 #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
1836 sljit_u32 i;
1837 #endif
1838
1839 SLJIT_UNUSED_ARG(compiler);
1840
1841 #if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
1842 CHECK_ARGUMENT(instruction);
1843
1844 #if (defined SLJIT_CONFIG_X86 && SLJIT_CONFIG_X86)
1845 CHECK_ARGUMENT(size > 0 && size < 16);
1846 #elif (defined SLJIT_CONFIG_ARM_THUMB2 && SLJIT_CONFIG_ARM_THUMB2)
1847 CHECK_ARGUMENT((size == 2 && (((sljit_sw)instruction) & 0x1) == 0)
1848 || (size == 4 && (((sljit_sw)instruction) & 0x3) == 0));
1849 #elif (defined SLJIT_CONFIG_S390X && SLJIT_CONFIG_S390X)
1850 CHECK_ARGUMENT(size == 2 || size == 4 || size == 6);
1851 #else
1852 CHECK_ARGUMENT(size == 4 && (((sljit_sw)instruction) & 0x3) == 0);
1853 #endif
1854
1855 compiler->last_flags = 0;
1856 #endif
1857 #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
1858 if (SLJIT_UNLIKELY(!!compiler->verbose)) {
1859 fprintf(compiler->verbose, " op_custom");
1860 for (i = 0; i < size; i++)
1861 fprintf(compiler->verbose, " 0x%x", ((sljit_u8*)instruction)[i]);
1862 fprintf(compiler->verbose, "\n");
1863 }
1864 #endif
1865 CHECK_RETURN_OK;
1866 }
1867
check_sljit_emit_fop1(struct sljit_compiler * compiler,sljit_s32 op,sljit_s32 dst,sljit_sw dstw,sljit_s32 src,sljit_sw srcw)1868 static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_fop1(struct sljit_compiler *compiler, sljit_s32 op,
1869 sljit_s32 dst, sljit_sw dstw,
1870 sljit_s32 src, sljit_sw srcw)
1871 {
1872 if (SLJIT_UNLIKELY(compiler->skip_checks)) {
1873 compiler->skip_checks = 0;
1874 CHECK_RETURN_OK;
1875 }
1876
1877 #if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
1878 CHECK_ARGUMENT(sljit_has_cpu_feature(SLJIT_HAS_FPU));
1879 CHECK_ARGUMENT(GET_OPCODE(op) >= SLJIT_MOV_F64 && GET_OPCODE(op) <= SLJIT_ABS_F64);
1880 CHECK_ARGUMENT(!(op & (SLJIT_SET_Z | VARIABLE_FLAG_MASK)));
1881 FUNCTION_FCHECK(src, srcw, op & SLJIT_32);
1882 FUNCTION_FCHECK(dst, dstw, op & SLJIT_32);
1883 #endif
1884 #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
1885 if (SLJIT_UNLIKELY(!!compiler->verbose)) {
1886 if (GET_OPCODE(op) == SLJIT_CONV_F64_FROM_F32)
1887 fprintf(compiler->verbose, " %s%s ", fop1_names[SLJIT_CONV_F64_FROM_F32 - SLJIT_FOP1_BASE],
1888 (op & SLJIT_32) ? ".f32.from.f64" : ".f64.from.f32");
1889 else
1890 fprintf(compiler->verbose, " %s%s ", fop1_names[GET_OPCODE(op) - SLJIT_FOP1_BASE],
1891 (op & SLJIT_32) ? ".f32" : ".f64");
1892
1893 sljit_verbose_fparam(compiler, dst, dstw);
1894 fprintf(compiler->verbose, ", ");
1895 sljit_verbose_fparam(compiler, src, srcw);
1896 fprintf(compiler->verbose, "\n");
1897 }
1898 #endif
1899 CHECK_RETURN_OK;
1900 }
1901
check_sljit_emit_fop1_cmp(struct sljit_compiler * compiler,sljit_s32 op,sljit_s32 src1,sljit_sw src1w,sljit_s32 src2,sljit_sw src2w)1902 static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_fop1_cmp(struct sljit_compiler *compiler, sljit_s32 op,
1903 sljit_s32 src1, sljit_sw src1w,
1904 sljit_s32 src2, sljit_sw src2w)
1905 {
1906 #if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
1907 compiler->last_flags = GET_FLAG_TYPE(op) | (op & SLJIT_32);
1908 #endif
1909
1910 if (SLJIT_UNLIKELY(compiler->skip_checks)) {
1911 compiler->skip_checks = 0;
1912 CHECK_RETURN_OK;
1913 }
1914
1915 #if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
1916 CHECK_ARGUMENT(sljit_has_cpu_feature(SLJIT_HAS_FPU));
1917 CHECK_ARGUMENT(GET_OPCODE(op) == SLJIT_CMP_F64);
1918 CHECK_ARGUMENT(!(op & SLJIT_SET_Z));
1919 CHECK_ARGUMENT((op & VARIABLE_FLAG_MASK)
1920 || (GET_FLAG_TYPE(op) >= SLJIT_F_EQUAL && GET_FLAG_TYPE(op) <= SLJIT_ORDERED_LESS_EQUAL));
1921 FUNCTION_FCHECK(src1, src1w, op & SLJIT_32);
1922 FUNCTION_FCHECK(src2, src2w, op & SLJIT_32);
1923 #endif
1924 #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
1925 if (SLJIT_UNLIKELY(!!compiler->verbose)) {
1926 fprintf(compiler->verbose, " %s%s", fop1_names[SLJIT_CMP_F64 - SLJIT_FOP1_BASE], (op & SLJIT_32) ? ".f32" : ".f64");
1927 if (op & VARIABLE_FLAG_MASK) {
1928 fprintf(compiler->verbose, ".%s", jump_names[GET_FLAG_TYPE(op)]);
1929 }
1930 fprintf(compiler->verbose, " ");
1931 sljit_verbose_fparam(compiler, src1, src1w);
1932 fprintf(compiler->verbose, ", ");
1933 sljit_verbose_fparam(compiler, src2, src2w);
1934 fprintf(compiler->verbose, "\n");
1935 }
1936 #endif
1937 CHECK_RETURN_OK;
1938 }
1939
check_sljit_emit_fop1_conv_sw_from_f64(struct sljit_compiler * compiler,sljit_s32 op,sljit_s32 dst,sljit_sw dstw,sljit_s32 src,sljit_sw srcw)1940 static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_fop1_conv_sw_from_f64(struct sljit_compiler *compiler, sljit_s32 op,
1941 sljit_s32 dst, sljit_sw dstw,
1942 sljit_s32 src, sljit_sw srcw)
1943 {
1944 if (SLJIT_UNLIKELY(compiler->skip_checks)) {
1945 compiler->skip_checks = 0;
1946 CHECK_RETURN_OK;
1947 }
1948
1949 #if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
1950 CHECK_ARGUMENT(sljit_has_cpu_feature(SLJIT_HAS_FPU));
1951 CHECK_ARGUMENT(!(op & (SLJIT_SET_Z | VARIABLE_FLAG_MASK)));
1952 FUNCTION_FCHECK(src, srcw, op & SLJIT_32);
1953 FUNCTION_CHECK_DST(dst, dstw);
1954 #endif
1955 #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
1956 if (SLJIT_UNLIKELY(!!compiler->verbose)) {
1957 fprintf(compiler->verbose, " %s%s.from%s ", fop1_names[GET_OPCODE(op) - SLJIT_FOP1_BASE],
1958 fop1_conv_types[GET_OPCODE(op) - SLJIT_CONV_SW_FROM_F64],
1959 (op & SLJIT_32) ? ".f32" : ".f64");
1960 sljit_verbose_param(compiler, dst, dstw);
1961 fprintf(compiler->verbose, ", ");
1962 sljit_verbose_fparam(compiler, src, srcw);
1963 fprintf(compiler->verbose, "\n");
1964 }
1965 #endif
1966 CHECK_RETURN_OK;
1967 }
1968
check_sljit_emit_fop1_conv_f64_from_w(struct sljit_compiler * compiler,sljit_s32 op,sljit_s32 dst,sljit_sw dstw,sljit_s32 src,sljit_sw srcw)1969 static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_fop1_conv_f64_from_w(struct sljit_compiler *compiler, sljit_s32 op,
1970 sljit_s32 dst, sljit_sw dstw,
1971 sljit_s32 src, sljit_sw srcw)
1972 {
1973 if (SLJIT_UNLIKELY(compiler->skip_checks)) {
1974 compiler->skip_checks = 0;
1975 CHECK_RETURN_OK;
1976 }
1977
1978 #if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
1979 CHECK_ARGUMENT(sljit_has_cpu_feature(SLJIT_HAS_FPU));
1980 CHECK_ARGUMENT(!(op & (SLJIT_SET_Z | VARIABLE_FLAG_MASK)));
1981 FUNCTION_CHECK_SRC(src, srcw);
1982 FUNCTION_FCHECK(dst, dstw, op & SLJIT_32);
1983 #endif
1984 #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
1985 if (SLJIT_UNLIKELY(!!compiler->verbose)) {
1986 fprintf(compiler->verbose, " %s%s.from.%s ", fop1_names[GET_OPCODE(op) - SLJIT_FOP1_BASE],
1987 (op & SLJIT_32) ? ".f32" : ".f64",
1988 fop1_conv_types[GET_OPCODE(op) - SLJIT_CONV_SW_FROM_F64]);
1989 sljit_verbose_fparam(compiler, dst, dstw);
1990 fprintf(compiler->verbose, ", ");
1991 sljit_verbose_param(compiler, src, srcw);
1992 fprintf(compiler->verbose, "\n");
1993 }
1994 #endif
1995 CHECK_RETURN_OK;
1996 }
1997
check_sljit_emit_fop2(struct sljit_compiler * compiler,sljit_s32 op,sljit_s32 dst,sljit_sw dstw,sljit_s32 src1,sljit_sw src1w,sljit_s32 src2,sljit_sw src2w)1998 static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_fop2(struct sljit_compiler *compiler, sljit_s32 op,
1999 sljit_s32 dst, sljit_sw dstw,
2000 sljit_s32 src1, sljit_sw src1w,
2001 sljit_s32 src2, sljit_sw src2w)
2002 {
2003 if (SLJIT_UNLIKELY(compiler->skip_checks)) {
2004 compiler->skip_checks = 0;
2005 CHECK_RETURN_OK;
2006 }
2007
2008 #if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
2009 CHECK_ARGUMENT(sljit_has_cpu_feature(SLJIT_HAS_FPU));
2010 CHECK_ARGUMENT(GET_OPCODE(op) >= SLJIT_ADD_F64 && GET_OPCODE(op) <= SLJIT_DIV_F64);
2011 CHECK_ARGUMENT(!(op & (SLJIT_SET_Z | VARIABLE_FLAG_MASK)));
2012 FUNCTION_FCHECK(src1, src1w, op & SLJIT_32);
2013 FUNCTION_FCHECK(src2, src2w, op & SLJIT_32);
2014 FUNCTION_FCHECK(dst, dstw, op & SLJIT_32);
2015 #endif
2016 #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
2017 if (SLJIT_UNLIKELY(!!compiler->verbose)) {
2018 fprintf(compiler->verbose, " %s%s ", fop2_names[GET_OPCODE(op) - SLJIT_FOP2_BASE], (op & SLJIT_32) ? ".f32" : ".f64");
2019 sljit_verbose_fparam(compiler, dst, dstw);
2020 fprintf(compiler->verbose, ", ");
2021 sljit_verbose_fparam(compiler, src1, src1w);
2022 fprintf(compiler->verbose, ", ");
2023 sljit_verbose_fparam(compiler, src2, src2w);
2024 fprintf(compiler->verbose, "\n");
2025 }
2026 #endif
2027 CHECK_RETURN_OK;
2028 }
2029
check_sljit_emit_fop2r(struct sljit_compiler * compiler,sljit_s32 op,sljit_s32 dst_freg,sljit_s32 src1,sljit_sw src1w,sljit_s32 src2,sljit_sw src2w)2030 static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_fop2r(struct sljit_compiler *compiler, sljit_s32 op,
2031 sljit_s32 dst_freg,
2032 sljit_s32 src1, sljit_sw src1w,
2033 sljit_s32 src2, sljit_sw src2w)
2034 {
2035 #if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
2036 CHECK_ARGUMENT(sljit_has_cpu_feature(SLJIT_HAS_FPU));
2037 CHECK_ARGUMENT(GET_OPCODE(op) == SLJIT_COPYSIGN_F64);
2038 FUNCTION_FCHECK(src1, src1w, op & SLJIT_32);
2039 FUNCTION_FCHECK(src2, src2w, op & SLJIT_32);
2040 CHECK_ARGUMENT(FUNCTION_CHECK_IS_FREG(dst_freg, op & SLJIT_32));
2041 #endif
2042 #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
2043 if (SLJIT_UNLIKELY(!!compiler->verbose)) {
2044 fprintf(compiler->verbose, " %s%s ", fop2r_names[GET_OPCODE(op) - SLJIT_FOP2R_BASE], (op & SLJIT_32) ? ".f32" : ".f64");
2045 sljit_verbose_freg(compiler, dst_freg);
2046 fprintf(compiler->verbose, ", ");
2047 sljit_verbose_fparam(compiler, src1, src1w);
2048 fprintf(compiler->verbose, ", ");
2049 sljit_verbose_fparam(compiler, src2, src2w);
2050 fprintf(compiler->verbose, "\n");
2051 }
2052 #endif
2053 CHECK_RETURN_OK;
2054 }
2055
check_sljit_emit_fset32(struct sljit_compiler * compiler,sljit_s32 freg,sljit_f32 value)2056 static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_fset32(struct sljit_compiler *compiler,
2057 sljit_s32 freg, sljit_f32 value)
2058 {
2059 SLJIT_UNUSED_ARG(value);
2060
2061 if (SLJIT_UNLIKELY(compiler->skip_checks)) {
2062 compiler->skip_checks = 0;
2063 CHECK_RETURN_OK;
2064 }
2065
2066 #if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
2067 CHECK_ARGUMENT(sljit_has_cpu_feature(SLJIT_HAS_FPU));
2068 CHECK_ARGUMENT(FUNCTION_CHECK_IS_FREG(freg, 1));
2069 #endif
2070 #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
2071 if (SLJIT_UNLIKELY(!!compiler->verbose)) {
2072 fprintf(compiler->verbose, " fset32 ");
2073 sljit_verbose_freg(compiler, freg);
2074 fprintf(compiler->verbose, ", %f\n", value);
2075 }
2076 #endif
2077 CHECK_RETURN_OK;
2078 }
2079
check_sljit_emit_fset64(struct sljit_compiler * compiler,sljit_s32 freg,sljit_f64 value)2080 static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_fset64(struct sljit_compiler *compiler,
2081 sljit_s32 freg, sljit_f64 value)
2082 {
2083 SLJIT_UNUSED_ARG(value);
2084
2085 if (SLJIT_UNLIKELY(compiler->skip_checks)) {
2086 compiler->skip_checks = 0;
2087 CHECK_RETURN_OK;
2088 }
2089
2090 #if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
2091 CHECK_ARGUMENT(sljit_has_cpu_feature(SLJIT_HAS_FPU));
2092 CHECK_ARGUMENT(FUNCTION_CHECK_IS_FREG(freg, 0));
2093 #endif
2094 #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
2095 if (SLJIT_UNLIKELY(!!compiler->verbose)) {
2096 fprintf(compiler->verbose, " fset64 ");
2097 sljit_verbose_freg(compiler, freg);
2098 fprintf(compiler->verbose, ", %f\n", value);
2099 }
2100 #endif
2101 CHECK_RETURN_OK;
2102 }
2103
check_sljit_emit_fcopy(struct sljit_compiler * compiler,sljit_s32 op,sljit_s32 freg,sljit_s32 reg)2104 static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_fcopy(struct sljit_compiler *compiler, sljit_s32 op,
2105 sljit_s32 freg, sljit_s32 reg)
2106 {
2107 #if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
2108 CHECK_ARGUMENT(sljit_has_cpu_feature(SLJIT_HAS_FPU));
2109 CHECK_ARGUMENT(GET_OPCODE(op) >= SLJIT_COPY_TO_F64 && GET_OPCODE(op) <= SLJIT_COPY_FROM_F64);
2110 CHECK_ARGUMENT(!(op & (SLJIT_SET_Z | VARIABLE_FLAG_MASK)));
2111 CHECK_ARGUMENT(FUNCTION_CHECK_IS_FREG(freg, op & SLJIT_32));
2112
2113 #if (defined SLJIT_64BIT_ARCHITECTURE && SLJIT_64BIT_ARCHITECTURE)
2114 CHECK_ARGUMENT(FUNCTION_CHECK_IS_REG(reg));
2115 #else /* !SLJIT_64BIT_ARCHITECTURE */
2116 switch (op) {
2117 case SLJIT_COPY32_TO_F32:
2118 case SLJIT_COPY32_FROM_F32:
2119 CHECK_ARGUMENT(FUNCTION_CHECK_IS_REG(reg));
2120 break;
2121 case SLJIT_COPY_TO_F64:
2122 case SLJIT_COPY_FROM_F64:
2123 if (reg & REG_PAIR_MASK) {
2124 CHECK_ARGUMENT(FUNCTION_CHECK_IS_REG(REG_PAIR_FIRST(reg)));
2125 CHECK_ARGUMENT(FUNCTION_CHECK_IS_REG(REG_PAIR_SECOND(reg)));
2126
2127 if (op == SLJIT_COPY_TO_F64)
2128 break;
2129
2130 CHECK_ARGUMENT(REG_PAIR_FIRST(reg) != REG_PAIR_SECOND(reg));
2131 break;
2132 }
2133
2134 CHECK_ARGUMENT(FUNCTION_CHECK_IS_REG(reg));
2135 break;
2136 }
2137 #endif /* SLJIT_64BIT_ARCHITECTURE */
2138 #endif
2139 #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
2140 if (SLJIT_UNLIKELY(!!compiler->verbose)) {
2141 fprintf(compiler->verbose, " copy%s_%s_f%s ", (op & SLJIT_32) ? "32" : "",
2142 GET_OPCODE(op) == SLJIT_COPY_TO_F64 ? "to" : "from", (op & SLJIT_32) ? "32" : "64");
2143
2144 sljit_verbose_freg(compiler, freg);
2145
2146 if (reg & REG_PAIR_MASK) {
2147 fprintf(compiler->verbose, ", {");
2148 sljit_verbose_reg(compiler, REG_PAIR_FIRST(reg));
2149 fprintf(compiler->verbose, ", ");
2150 sljit_verbose_reg(compiler, REG_PAIR_SECOND(reg));
2151 fprintf(compiler->verbose, "}\n");
2152 } else {
2153 fprintf(compiler->verbose, ", ");
2154 sljit_verbose_reg(compiler, reg);
2155 fprintf(compiler->verbose, "\n");
2156 }
2157 }
2158 #endif
2159 CHECK_RETURN_OK;
2160 }
2161
check_sljit_emit_label(struct sljit_compiler * compiler)2162 static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_label(struct sljit_compiler *compiler)
2163 {
2164 SLJIT_UNUSED_ARG(compiler);
2165
2166 if (SLJIT_UNLIKELY(compiler->skip_checks)) {
2167 compiler->skip_checks = 0;
2168 CHECK_RETURN_OK;
2169 }
2170
2171 #if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
2172 compiler->last_flags = 0;
2173 #endif
2174
2175 #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
2176 if (SLJIT_UNLIKELY(!!compiler->verbose))
2177 fprintf(compiler->verbose, "label:\n");
2178 #endif
2179 CHECK_RETURN_OK;
2180 }
2181
2182 #if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
2183 #if (defined SLJIT_CONFIG_X86 && SLJIT_CONFIG_X86) \
2184 || (defined SLJIT_CONFIG_ARM && SLJIT_CONFIG_ARM)
2185 #define CHECK_UNORDERED(type, last_flags) \
2186 ((((type) & 0xfe) == SLJIT_ORDERED) && \
2187 ((last_flags) & 0xff) >= SLJIT_UNORDERED && ((last_flags) & 0xff) <= SLJIT_ORDERED_LESS_EQUAL)
2188 #else
2189 #define CHECK_UNORDERED(type, last_flags) 0
2190 #endif
2191 #endif /* SLJIT_ARGUMENT_CHECKS */
2192
check_sljit_emit_jump(struct sljit_compiler * compiler,sljit_s32 type)2193 static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_jump(struct sljit_compiler *compiler, sljit_s32 type)
2194 {
2195 if (SLJIT_UNLIKELY(compiler->skip_checks)) {
2196 compiler->skip_checks = 0;
2197 CHECK_RETURN_OK;
2198 }
2199
2200 #if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
2201 CHECK_ARGUMENT(!(type & ~(0xff | SLJIT_REWRITABLE_JUMP)));
2202 CHECK_ARGUMENT((type & 0xff) >= SLJIT_EQUAL && (type & 0xff) <= SLJIT_FAST_CALL);
2203
2204 if ((type & 0xff) < SLJIT_JUMP) {
2205 if ((type & 0xff) <= SLJIT_NOT_ZERO)
2206 CHECK_ARGUMENT(compiler->last_flags & SLJIT_SET_Z);
2207 else if ((compiler->last_flags & 0xff) == SLJIT_CARRY) {
2208 CHECK_ARGUMENT((type & 0xfe) == SLJIT_CARRY);
2209 compiler->last_flags = 0;
2210 } else
2211 CHECK_ARGUMENT((type & 0xfe) == (compiler->last_flags & 0xff)
2212 || CHECK_UNORDERED(type, compiler->last_flags));
2213 }
2214 #endif
2215 #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
2216 if (SLJIT_UNLIKELY(!!compiler->verbose))
2217 fprintf(compiler->verbose, " jump%s %s\n", !(type & SLJIT_REWRITABLE_JUMP) ? "" : ".r",
2218 jump_names[type & 0xff]);
2219 #endif
2220 CHECK_RETURN_OK;
2221 }
2222
check_sljit_emit_call(struct sljit_compiler * compiler,sljit_s32 type,sljit_s32 arg_types)2223 static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_call(struct sljit_compiler *compiler, sljit_s32 type,
2224 sljit_s32 arg_types)
2225 {
2226 #if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
2227 CHECK_ARGUMENT(!(type & ~(0xff | SLJIT_REWRITABLE_JUMP | SLJIT_CALL_RETURN)));
2228 CHECK_ARGUMENT((type & 0xff) >= SLJIT_CALL && (type & 0xff) <= SLJIT_CALL_REG_ARG);
2229 CHECK_ARGUMENT(function_check_arguments(arg_types, compiler->scratches, -1, compiler->fscratches));
2230
2231 if (type & SLJIT_CALL_RETURN) {
2232 CHECK_ARGUMENT((arg_types & SLJIT_ARG_MASK) == compiler->last_return);
2233
2234 if (compiler->options & SLJIT_ENTER_REG_ARG) {
2235 CHECK_ARGUMENT((type & 0xff) == SLJIT_CALL_REG_ARG);
2236 } else {
2237 CHECK_ARGUMENT((type & 0xff) != SLJIT_CALL_REG_ARG);
2238 }
2239 }
2240 #endif
2241 #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
2242 if (SLJIT_UNLIKELY(!!compiler->verbose)) {
2243 fprintf(compiler->verbose, " %s%s%s ret[%s", jump_names[type & 0xff],
2244 !(type & SLJIT_REWRITABLE_JUMP) ? "" : ".r",
2245 !(type & SLJIT_CALL_RETURN) ? "" : ".ret",
2246 call_arg_names[arg_types & SLJIT_ARG_MASK]);
2247
2248 arg_types >>= SLJIT_ARG_SHIFT;
2249 if (arg_types) {
2250 fprintf(compiler->verbose, "], args[");
2251 do {
2252 fprintf(compiler->verbose, "%s", call_arg_names[arg_types & SLJIT_ARG_MASK]);
2253 arg_types >>= SLJIT_ARG_SHIFT;
2254 if (arg_types)
2255 fprintf(compiler->verbose, ",");
2256 } while (arg_types);
2257 }
2258 fprintf(compiler->verbose, "]\n");
2259 }
2260 #endif
2261 CHECK_RETURN_OK;
2262 }
2263
check_sljit_emit_cmp(struct sljit_compiler * compiler,sljit_s32 type,sljit_s32 src1,sljit_sw src1w,sljit_s32 src2,sljit_sw src2w)2264 static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_cmp(struct sljit_compiler *compiler, sljit_s32 type,
2265 sljit_s32 src1, sljit_sw src1w,
2266 sljit_s32 src2, sljit_sw src2w)
2267 {
2268 #if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
2269 CHECK_ARGUMENT(!(type & ~(0xff | SLJIT_REWRITABLE_JUMP | SLJIT_32)));
2270 CHECK_ARGUMENT((type & 0xff) >= SLJIT_EQUAL && (type & 0xff) <= SLJIT_SIG_LESS_EQUAL);
2271 FUNCTION_CHECK_SRC(src1, src1w);
2272 FUNCTION_CHECK_SRC(src2, src2w);
2273 compiler->last_flags = 0;
2274 #endif
2275 #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
2276 if (SLJIT_UNLIKELY(!!compiler->verbose)) {
2277 fprintf(compiler->verbose, " cmp%s%s %s, ", (type & SLJIT_32) ? "32" : "",
2278 !(type & SLJIT_REWRITABLE_JUMP) ? "" : ".r", jump_names[type & 0xff]);
2279 sljit_verbose_param(compiler, src1, src1w);
2280 fprintf(compiler->verbose, ", ");
2281 sljit_verbose_param(compiler, src2, src2w);
2282 fprintf(compiler->verbose, "\n");
2283 }
2284 #endif
2285 CHECK_RETURN_OK;
2286 }
2287
check_sljit_emit_fcmp(struct sljit_compiler * compiler,sljit_s32 type,sljit_s32 src1,sljit_sw src1w,sljit_s32 src2,sljit_sw src2w)2288 static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_fcmp(struct sljit_compiler *compiler, sljit_s32 type,
2289 sljit_s32 src1, sljit_sw src1w,
2290 sljit_s32 src2, sljit_sw src2w)
2291 {
2292 #if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
2293 CHECK_ARGUMENT(sljit_has_cpu_feature(SLJIT_HAS_FPU));
2294 CHECK_ARGUMENT(!(type & ~(0xff | SLJIT_REWRITABLE_JUMP | SLJIT_32)));
2295 CHECK_ARGUMENT((type & 0xff) >= SLJIT_F_EQUAL && (type & 0xff) <= SLJIT_ORDERED_LESS_EQUAL);
2296 FUNCTION_FCHECK(src1, src1w, type & SLJIT_32);
2297 FUNCTION_FCHECK(src2, src2w, type & SLJIT_32);
2298 compiler->last_flags = 0;
2299 #endif
2300 #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
2301 if (SLJIT_UNLIKELY(!!compiler->verbose)) {
2302 fprintf(compiler->verbose, " fcmp%s%s %s, ", (type & SLJIT_32) ? ".f32" : ".f64",
2303 !(type & SLJIT_REWRITABLE_JUMP) ? "" : ".r", jump_names[type & 0xff]);
2304 sljit_verbose_fparam(compiler, src1, src1w);
2305 fprintf(compiler->verbose, ", ");
2306 sljit_verbose_fparam(compiler, src2, src2w);
2307 fprintf(compiler->verbose, "\n");
2308 }
2309 #endif
2310 CHECK_RETURN_OK;
2311 }
2312
check_sljit_emit_ijump(struct sljit_compiler * compiler,sljit_s32 type,sljit_s32 src,sljit_sw srcw)2313 static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_ijump(struct sljit_compiler *compiler, sljit_s32 type,
2314 sljit_s32 src, sljit_sw srcw)
2315 {
2316 if (SLJIT_UNLIKELY(compiler->skip_checks)) {
2317 compiler->skip_checks = 0;
2318 CHECK_RETURN_OK;
2319 }
2320
2321 #if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
2322 CHECK_ARGUMENT(type >= SLJIT_JUMP && type <= SLJIT_FAST_CALL);
2323 FUNCTION_CHECK_SRC(src, srcw);
2324 #endif
2325 #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
2326 if (SLJIT_UNLIKELY(!!compiler->verbose)) {
2327 fprintf(compiler->verbose, " ijump.%s ", jump_names[type]);
2328 sljit_verbose_param(compiler, src, srcw);
2329 fprintf(compiler->verbose, "\n");
2330 }
2331 #endif
2332 CHECK_RETURN_OK;
2333 }
2334
check_sljit_emit_icall(struct sljit_compiler * compiler,sljit_s32 type,sljit_s32 arg_types,sljit_s32 src,sljit_sw srcw)2335 static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_icall(struct sljit_compiler *compiler, sljit_s32 type,
2336 sljit_s32 arg_types,
2337 sljit_s32 src, sljit_sw srcw)
2338 {
2339 #if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
2340 CHECK_ARGUMENT(!(type & ~(0xff | SLJIT_CALL_RETURN)));
2341 CHECK_ARGUMENT((type & 0xff) >= SLJIT_CALL && (type & 0xff) <= SLJIT_CALL_REG_ARG);
2342 CHECK_ARGUMENT(function_check_arguments(arg_types, compiler->scratches, -1, compiler->fscratches));
2343 FUNCTION_CHECK_SRC(src, srcw);
2344
2345 if (type & SLJIT_CALL_RETURN) {
2346 CHECK_ARGUMENT((arg_types & SLJIT_ARG_MASK) == compiler->last_return);
2347
2348 if (compiler->options & SLJIT_ENTER_REG_ARG) {
2349 CHECK_ARGUMENT((type & 0xff) == SLJIT_CALL_REG_ARG);
2350 } else {
2351 CHECK_ARGUMENT((type & 0xff) != SLJIT_CALL_REG_ARG);
2352 }
2353 }
2354 #endif
2355 #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
2356 if (SLJIT_UNLIKELY(!!compiler->verbose)) {
2357 fprintf(compiler->verbose, " i%s%s ret[%s", jump_names[type & 0xff],
2358 !(type & SLJIT_CALL_RETURN) ? "" : ".ret",
2359 call_arg_names[arg_types & SLJIT_ARG_MASK]);
2360
2361 arg_types >>= SLJIT_ARG_SHIFT;
2362 if (arg_types) {
2363 fprintf(compiler->verbose, "], args[");
2364 do {
2365 fprintf(compiler->verbose, "%s", call_arg_names[arg_types & SLJIT_ARG_MASK]);
2366 arg_types >>= SLJIT_ARG_SHIFT;
2367 if (arg_types)
2368 fprintf(compiler->verbose, ",");
2369 } while (arg_types);
2370 }
2371 fprintf(compiler->verbose, "], ");
2372 sljit_verbose_param(compiler, src, srcw);
2373 fprintf(compiler->verbose, "\n");
2374 }
2375 #endif
2376 CHECK_RETURN_OK;
2377 }
2378
check_sljit_emit_op_flags(struct sljit_compiler * compiler,sljit_s32 op,sljit_s32 dst,sljit_sw dstw,sljit_s32 type)2379 static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_op_flags(struct sljit_compiler *compiler, sljit_s32 op,
2380 sljit_s32 dst, sljit_sw dstw,
2381 sljit_s32 type)
2382 {
2383 #if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
2384 CHECK_ARGUMENT(type >= SLJIT_EQUAL && type <= SLJIT_ORDERED_LESS_EQUAL);
2385 CHECK_ARGUMENT(op == SLJIT_MOV || op == SLJIT_MOV32
2386 || (GET_OPCODE(op) >= SLJIT_AND && GET_OPCODE(op) <= SLJIT_XOR));
2387 CHECK_ARGUMENT(!(op & VARIABLE_FLAG_MASK));
2388
2389 if (type <= SLJIT_NOT_ZERO)
2390 CHECK_ARGUMENT(compiler->last_flags & SLJIT_SET_Z);
2391 else
2392 CHECK_ARGUMENT((type & 0xfe) == (compiler->last_flags & 0xff)
2393 || CHECK_UNORDERED(type, compiler->last_flags));
2394
2395 FUNCTION_CHECK_DST(dst, dstw);
2396
2397 if (GET_OPCODE(op) >= SLJIT_ADD)
2398 compiler->last_flags = GET_FLAG_TYPE(op) | (op & (SLJIT_32 | SLJIT_SET_Z));
2399 #endif
2400 #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
2401 if (SLJIT_UNLIKELY(!!compiler->verbose)) {
2402 fprintf(compiler->verbose, " flags.%s%s%s ",
2403 GET_OPCODE(op) < SLJIT_OP2_BASE ? "mov" : op2_names[GET_OPCODE(op) - SLJIT_OP2_BASE],
2404 GET_OPCODE(op) < SLJIT_OP2_BASE ? op1_types[GET_OPCODE(op) - SLJIT_OP1_BASE] : ((op & SLJIT_32) ? "32" : ""),
2405 !(op & SLJIT_SET_Z) ? "" : ".z");
2406 sljit_verbose_param(compiler, dst, dstw);
2407 fprintf(compiler->verbose, ", %s\n", jump_names[type]);
2408 }
2409 #endif
2410 CHECK_RETURN_OK;
2411 }
2412
check_sljit_emit_select(struct sljit_compiler * compiler,sljit_s32 type,sljit_s32 dst_reg,sljit_s32 src1,sljit_sw src1w,sljit_s32 src2_reg)2413 static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_select(struct sljit_compiler *compiler, sljit_s32 type,
2414 sljit_s32 dst_reg,
2415 sljit_s32 src1, sljit_sw src1w,
2416 sljit_s32 src2_reg)
2417 {
2418 #if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
2419 sljit_s32 cond = type & ~SLJIT_32;
2420
2421 CHECK_ARGUMENT(cond >= SLJIT_EQUAL && cond <= SLJIT_ORDERED_LESS_EQUAL);
2422
2423 CHECK_ARGUMENT(compiler->scratches != -1 && compiler->saveds != -1);
2424 CHECK_ARGUMENT(FUNCTION_CHECK_IS_REG(dst_reg));
2425 FUNCTION_CHECK_SRC(src1, src1w);
2426 CHECK_ARGUMENT(FUNCTION_CHECK_IS_REG(src2_reg));
2427
2428 if (cond <= SLJIT_NOT_ZERO)
2429 CHECK_ARGUMENT(compiler->last_flags & SLJIT_SET_Z);
2430 else if ((compiler->last_flags & 0xff) == SLJIT_CARRY) {
2431 CHECK_ARGUMENT((type & 0xfe) == SLJIT_CARRY);
2432 compiler->last_flags = 0;
2433 } else
2434 CHECK_ARGUMENT((cond & 0xfe) == (compiler->last_flags & 0xff)
2435 || CHECK_UNORDERED(cond, compiler->last_flags));
2436 #endif
2437 #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
2438 if (SLJIT_UNLIKELY(!!compiler->verbose)) {
2439 fprintf(compiler->verbose, " select%s %s, ",
2440 !(type & SLJIT_32) ? "" : "32",
2441 jump_names[type & ~SLJIT_32]);
2442 sljit_verbose_reg(compiler, dst_reg);
2443 fprintf(compiler->verbose, ", ");
2444 sljit_verbose_param(compiler, src1, src1w);
2445 fprintf(compiler->verbose, ", ");
2446 sljit_verbose_reg(compiler, src2_reg);
2447 fprintf(compiler->verbose, "\n");
2448 }
2449 #endif
2450 CHECK_RETURN_OK;
2451 }
2452
check_sljit_emit_fselect(struct sljit_compiler * compiler,sljit_s32 type,sljit_s32 dst_freg,sljit_s32 src1,sljit_sw src1w,sljit_s32 src2_freg)2453 static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_fselect(struct sljit_compiler *compiler, sljit_s32 type,
2454 sljit_s32 dst_freg,
2455 sljit_s32 src1, sljit_sw src1w,
2456 sljit_s32 src2_freg)
2457 {
2458 #if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
2459 sljit_s32 cond = type & ~SLJIT_32;
2460
2461 CHECK_ARGUMENT(cond >= SLJIT_EQUAL && cond <= SLJIT_ORDERED_LESS_EQUAL);
2462
2463 CHECK_ARGUMENT(compiler->fscratches != -1 && compiler->fsaveds != -1);
2464 CHECK_ARGUMENT(FUNCTION_CHECK_IS_FREG(dst_freg, type & SLJIT_32));
2465 FUNCTION_FCHECK(src1, src1w, type & SLJIT_32);
2466 CHECK_ARGUMENT(FUNCTION_CHECK_IS_FREG(src2_freg, type & SLJIT_32));
2467
2468 if (cond <= SLJIT_NOT_ZERO)
2469 CHECK_ARGUMENT(compiler->last_flags & SLJIT_SET_Z);
2470 else if ((compiler->last_flags & 0xff) == SLJIT_CARRY) {
2471 CHECK_ARGUMENT((type & 0xfe) == SLJIT_CARRY);
2472 compiler->last_flags = 0;
2473 } else
2474 CHECK_ARGUMENT((cond & 0xfe) == (compiler->last_flags & 0xff)
2475 || CHECK_UNORDERED(cond, compiler->last_flags));
2476 #endif
2477 #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
2478 if (SLJIT_UNLIKELY(!!compiler->verbose)) {
2479 fprintf(compiler->verbose, " fselect%s %s, ",
2480 !(type & SLJIT_32) ? "" : "32",
2481 jump_names[type & ~SLJIT_32]);
2482 sljit_verbose_freg(compiler, dst_freg);
2483 fprintf(compiler->verbose, ", ");
2484 sljit_verbose_fparam(compiler, src1, src1w);
2485 fprintf(compiler->verbose, ", ");
2486 sljit_verbose_freg(compiler, src2_freg);
2487 fprintf(compiler->verbose, "\n");
2488 }
2489 #endif
2490 CHECK_RETURN_OK;
2491 }
2492
check_sljit_emit_mem(struct sljit_compiler * compiler,sljit_s32 type,sljit_s32 reg,sljit_s32 mem,sljit_sw memw)2493 static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_mem(struct sljit_compiler *compiler, sljit_s32 type,
2494 sljit_s32 reg,
2495 sljit_s32 mem, sljit_sw memw)
2496 {
2497 #if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
2498 sljit_s32 allowed_flags;
2499 #endif /* SLJIT_ARGUMENT_CHECKS */
2500
2501 if (SLJIT_UNLIKELY(compiler->skip_checks)) {
2502 compiler->skip_checks = 0;
2503 CHECK_RETURN_OK;
2504 }
2505
2506 #if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
2507 if (type & SLJIT_MEM_UNALIGNED) {
2508 CHECK_ARGUMENT(!(type & (SLJIT_MEM_ALIGNED_16 | SLJIT_MEM_ALIGNED_32)));
2509 } else if (type & SLJIT_MEM_ALIGNED_16) {
2510 CHECK_ARGUMENT(!(type & SLJIT_MEM_ALIGNED_32));
2511 } else {
2512 CHECK_ARGUMENT((reg & REG_PAIR_MASK) || (type & SLJIT_MEM_ALIGNED_32));
2513 }
2514
2515 allowed_flags = SLJIT_MEM_UNALIGNED;
2516
2517 switch (type & 0xff) {
2518 case SLJIT_MOV_P:
2519 case SLJIT_MOV:
2520 allowed_flags |= SLJIT_MEM_ALIGNED_32;
2521 /* fallthrough */
2522 case SLJIT_MOV_U32:
2523 case SLJIT_MOV_S32:
2524 case SLJIT_MOV32:
2525 allowed_flags |= SLJIT_MEM_ALIGNED_16;
2526 break;
2527 }
2528
2529 CHECK_ARGUMENT((type & ~(0xff | SLJIT_32 | SLJIT_MEM_STORE | allowed_flags)) == 0);
2530
2531 if (reg & REG_PAIR_MASK) {
2532 CHECK_ARGUMENT((type & 0xff) == SLJIT_MOV);
2533 CHECK_ARGUMENT(FUNCTION_CHECK_IS_REG(REG_PAIR_FIRST(reg)));
2534 CHECK_ARGUMENT(FUNCTION_CHECK_IS_REG(REG_PAIR_SECOND(reg)));
2535 CHECK_ARGUMENT(REG_PAIR_FIRST(reg) != REG_PAIR_SECOND(reg));
2536 } else {
2537 CHECK_ARGUMENT((type & 0xff) >= SLJIT_MOV && (type & 0xff) <= SLJIT_MOV_P);
2538 CHECK_ARGUMENT(!(type & SLJIT_32) || ((type & 0xff) >= SLJIT_MOV_U8 && (type & 0xff) <= SLJIT_MOV_S16));
2539 CHECK_ARGUMENT(FUNCTION_CHECK_IS_REG(reg));
2540 }
2541
2542 FUNCTION_CHECK_SRC_MEM(mem, memw);
2543 #endif
2544 #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
2545 if (SLJIT_UNLIKELY(!!compiler->verbose)) {
2546 if ((type & 0xff) == SLJIT_MOV32)
2547 fprintf(compiler->verbose, " %s32",
2548 (type & SLJIT_MEM_STORE) ? "store" : "load");
2549 else
2550 fprintf(compiler->verbose, " %s%s%s",
2551 (type & SLJIT_MEM_STORE) ? "store" : "load",
2552 !(type & SLJIT_32) ? "" : "32", op1_types[(type & 0xff) - SLJIT_OP1_BASE]);
2553
2554 if (type & SLJIT_MEM_UNALIGNED)
2555 printf(".unal");
2556 else if (type & SLJIT_MEM_ALIGNED_16)
2557 printf(".al16");
2558 else if (type & SLJIT_MEM_ALIGNED_32)
2559 printf(".al32");
2560
2561 if (reg & REG_PAIR_MASK) {
2562 fprintf(compiler->verbose, " {");
2563 sljit_verbose_reg(compiler, REG_PAIR_FIRST(reg));
2564 fprintf(compiler->verbose, ", ");
2565 sljit_verbose_reg(compiler, REG_PAIR_SECOND(reg));
2566 fprintf(compiler->verbose, "}, ");
2567 } else {
2568 fprintf(compiler->verbose, " ");
2569 sljit_verbose_reg(compiler, reg);
2570 fprintf(compiler->verbose, ", ");
2571 }
2572 sljit_verbose_param(compiler, mem, memw);
2573 fprintf(compiler->verbose, "\n");
2574 }
2575 #endif
2576 CHECK_RETURN_OK;
2577 }
2578
check_sljit_emit_mem_update(struct sljit_compiler * compiler,sljit_s32 type,sljit_s32 reg,sljit_s32 mem,sljit_sw memw)2579 static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_mem_update(struct sljit_compiler *compiler, sljit_s32 type,
2580 sljit_s32 reg,
2581 sljit_s32 mem, sljit_sw memw)
2582 {
2583 if (SLJIT_UNLIKELY(compiler->skip_checks)) {
2584 compiler->skip_checks = 0;
2585 CHECK_RETURN_OK;
2586 }
2587
2588 #if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
2589 CHECK_ARGUMENT((type & 0xff) >= SLJIT_MOV && (type & 0xff) <= SLJIT_MOV_P);
2590 CHECK_ARGUMENT((type & ~(0xff | SLJIT_32 | SLJIT_MEM_STORE | SLJIT_MEM_SUPP | SLJIT_MEM_POST)) == 0);
2591 CHECK_ARGUMENT((mem & REG_MASK) != 0 && (mem & REG_MASK) != reg);
2592
2593 FUNCTION_CHECK_SRC_MEM(mem, memw);
2594 #endif
2595 #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
2596 if (SLJIT_UNLIKELY(!!compiler->verbose)) {
2597 if (type & SLJIT_MEM_SUPP)
2598 CHECK_RETURN_OK;
2599 if (sljit_emit_mem_update(compiler, type | SLJIT_MEM_SUPP, reg, mem, memw) == SLJIT_ERR_UNSUPPORTED) {
2600 fprintf(compiler->verbose, " # mem: unsupported form, no instructions are emitted\n");
2601 CHECK_RETURN_OK;
2602 }
2603
2604 if ((type & 0xff) == SLJIT_MOV32)
2605 fprintf(compiler->verbose, " %s32.%s ",
2606 (type & SLJIT_MEM_STORE) ? "store" : "load",
2607 (type & SLJIT_MEM_POST) ? "post" : "pre");
2608 else
2609 fprintf(compiler->verbose, " %s%s%s.%s ",
2610 (type & SLJIT_MEM_STORE) ? "store" : "load",
2611 !(type & SLJIT_32) ? "" : "32",
2612 op1_types[(type & 0xff) - SLJIT_OP1_BASE],
2613 (type & SLJIT_MEM_POST) ? "post" : "pre");
2614
2615 sljit_verbose_reg(compiler, reg);
2616 fprintf(compiler->verbose, ", ");
2617 sljit_verbose_param(compiler, mem, memw);
2618 fprintf(compiler->verbose, "\n");
2619 }
2620 #endif
2621 CHECK_RETURN_OK;
2622 }
2623
check_sljit_emit_fmem(struct sljit_compiler * compiler,sljit_s32 type,sljit_s32 freg,sljit_s32 mem,sljit_sw memw)2624 static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_fmem(struct sljit_compiler *compiler, sljit_s32 type,
2625 sljit_s32 freg,
2626 sljit_s32 mem, sljit_sw memw)
2627 {
2628 #if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
2629 CHECK_ARGUMENT(sljit_has_cpu_feature(SLJIT_HAS_FPU));
2630 CHECK_ARGUMENT((type & 0xff) == SLJIT_MOV_F64);
2631
2632 if (type & SLJIT_MEM_UNALIGNED) {
2633 CHECK_ARGUMENT(!(type & (SLJIT_MEM_ALIGNED_16 | SLJIT_MEM_ALIGNED_32)));
2634 } else if (type & SLJIT_MEM_ALIGNED_16) {
2635 CHECK_ARGUMENT(!(type & SLJIT_MEM_ALIGNED_32));
2636 } else {
2637 CHECK_ARGUMENT(type & SLJIT_MEM_ALIGNED_32);
2638 CHECK_ARGUMENT(!(type & SLJIT_32));
2639 }
2640
2641 CHECK_ARGUMENT(!(type & ~(0xff | SLJIT_32 | SLJIT_MEM_STORE | SLJIT_MEM_UNALIGNED | SLJIT_MEM_ALIGNED_16 | SLJIT_MEM_ALIGNED_32)));
2642 CHECK_ARGUMENT(FUNCTION_CHECK_IS_FREG(freg, type & SLJIT_32));
2643 FUNCTION_CHECK_SRC_MEM(mem, memw);
2644 #endif
2645 #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
2646 if (SLJIT_UNLIKELY(!!compiler->verbose)) {
2647 fprintf(compiler->verbose, " %s.%s",
2648 (type & SLJIT_MEM_STORE) ? "store" : "load",
2649 !(type & SLJIT_32) ? "f64" : "f32");
2650
2651 if (type & SLJIT_MEM_UNALIGNED)
2652 printf(".unal");
2653 else if (type & SLJIT_MEM_ALIGNED_16)
2654 printf(".al16");
2655 else if (type & SLJIT_MEM_ALIGNED_32)
2656 printf(".al32");
2657
2658 fprintf(compiler->verbose, " ");
2659 sljit_verbose_freg(compiler, freg);
2660 fprintf(compiler->verbose, ", ");
2661 sljit_verbose_param(compiler, mem, memw);
2662 fprintf(compiler->verbose, "\n");
2663 }
2664 #endif
2665 CHECK_RETURN_OK;
2666 }
2667
check_sljit_emit_fmem_update(struct sljit_compiler * compiler,sljit_s32 type,sljit_s32 freg,sljit_s32 mem,sljit_sw memw)2668 static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_fmem_update(struct sljit_compiler *compiler, sljit_s32 type,
2669 sljit_s32 freg,
2670 sljit_s32 mem, sljit_sw memw)
2671 {
2672 #if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
2673 CHECK_ARGUMENT(sljit_has_cpu_feature(SLJIT_HAS_FPU));
2674 CHECK_ARGUMENT((type & 0xff) == SLJIT_MOV_F64);
2675 CHECK_ARGUMENT((type & ~(0xff | SLJIT_32 | SLJIT_MEM_STORE | SLJIT_MEM_SUPP | SLJIT_MEM_POST)) == 0);
2676 FUNCTION_CHECK_SRC_MEM(mem, memw);
2677 CHECK_ARGUMENT(FUNCTION_CHECK_IS_FREG(freg, type & SLJIT_32));
2678 #endif
2679 #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
2680 if (SLJIT_UNLIKELY(!!compiler->verbose)) {
2681 if (type & SLJIT_MEM_SUPP)
2682 CHECK_RETURN_OK;
2683 if (sljit_emit_fmem_update(compiler, type | SLJIT_MEM_SUPP, freg, mem, memw) == SLJIT_ERR_UNSUPPORTED) {
2684 fprintf(compiler->verbose, " # fmem: unsupported form, no instructions are emitted\n");
2685 CHECK_RETURN_OK;
2686 }
2687
2688 fprintf(compiler->verbose, " %s.%s.%s ",
2689 (type & SLJIT_MEM_STORE) ? "store" : "load",
2690 !(type & SLJIT_32) ? "f64" : "f32",
2691 (type & SLJIT_MEM_POST) ? "post" : "pre");
2692
2693 sljit_verbose_freg(compiler, freg);
2694 fprintf(compiler->verbose, ", ");
2695 sljit_verbose_param(compiler, mem, memw);
2696 fprintf(compiler->verbose, "\n");
2697 }
2698 #endif
2699 CHECK_RETURN_OK;
2700 }
2701
check_sljit_emit_simd_mov(struct sljit_compiler * compiler,sljit_s32 type,sljit_s32 freg,sljit_s32 srcdst,sljit_sw srcdstw)2702 static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_simd_mov(struct sljit_compiler *compiler, sljit_s32 type,
2703 sljit_s32 freg,
2704 sljit_s32 srcdst, sljit_sw srcdstw)
2705 {
2706 #if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
2707 CHECK_ARGUMENT(sljit_has_cpu_feature(SLJIT_HAS_SIMD));
2708 CHECK_ARGUMENT((type & SLJIT_SIMD_TYPE_MASK2(SLJIT_SIMD_STORE)) == 0);
2709 CHECK_ARGUMENT(SLJIT_SIMD_CHECK_REG(type));
2710 CHECK_ARGUMENT(SLJIT_SIMD_GET_ELEM_SIZE(type) <= SLJIT_SIMD_GET_REG_SIZE(type));
2711 CHECK_ARGUMENT(SLJIT_SIMD_GET_ELEM2_SIZE(type) <= (srcdst & SLJIT_MEM) ? SLJIT_SIMD_GET_REG_SIZE(type) : 0);
2712 CHECK_ARGUMENT(FUNCTION_CHECK_IS_FREG(freg, 0));
2713 FUNCTION_FCHECK(srcdst, srcdstw, 0);
2714 #endif
2715 #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
2716 if (SLJIT_UNLIKELY(!!compiler->verbose)) {
2717 if (type & SLJIT_SIMD_TEST)
2718 CHECK_RETURN_OK;
2719 if (sljit_emit_simd_mov(compiler, type | SLJIT_SIMD_TEST, freg, srcdst, srcdstw) == SLJIT_ERR_UNSUPPORTED) {
2720 fprintf(compiler->verbose, " # simd_mem: unsupported form, no instructions are emitted\n");
2721 CHECK_RETURN_OK;
2722 }
2723
2724 fprintf(compiler->verbose, " simd_%s.%d.%s%d",
2725 (type & SLJIT_SIMD_STORE) ? "store" : "load",
2726 (8 << SLJIT_SIMD_GET_REG_SIZE(type)),
2727 (type & SLJIT_SIMD_FLOAT) ? "f" : "",
2728 (8 << SLJIT_SIMD_GET_ELEM_SIZE(type)));
2729
2730 if ((type & 0x3f000000) == SLJIT_SIMD_MEM_UNALIGNED)
2731 fprintf(compiler->verbose, ".unal ");
2732 else
2733 fprintf(compiler->verbose, ".al%d ", (8 << SLJIT_SIMD_GET_ELEM2_SIZE(type)));
2734
2735 sljit_verbose_freg(compiler, freg);
2736 fprintf(compiler->verbose, ", ");
2737 sljit_verbose_fparam(compiler, srcdst, srcdstw);
2738 fprintf(compiler->verbose, "\n");
2739 }
2740 #endif
2741 CHECK_RETURN_OK;
2742 }
2743
check_sljit_emit_simd_replicate(struct sljit_compiler * compiler,sljit_s32 type,sljit_s32 freg,sljit_s32 src,sljit_sw srcw)2744 static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_simd_replicate(struct sljit_compiler *compiler, sljit_s32 type,
2745 sljit_s32 freg,
2746 sljit_s32 src, sljit_sw srcw)
2747 {
2748 #if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
2749 CHECK_ARGUMENT(sljit_has_cpu_feature(SLJIT_HAS_SIMD));
2750 CHECK_ARGUMENT((type & SLJIT_SIMD_TYPE_MASK(0)) == 0);
2751 CHECK_ARGUMENT(SLJIT_SIMD_CHECK_REG(type));
2752 CHECK_ARGUMENT(SLJIT_SIMD_GET_ELEM_SIZE(type) < SLJIT_SIMD_GET_REG_SIZE(type));
2753 CHECK_ARGUMENT(FUNCTION_CHECK_IS_FREG(freg, 0));
2754
2755 if (type & SLJIT_SIMD_FLOAT) {
2756 if (src == SLJIT_IMM) {
2757 CHECK_ARGUMENT(srcw == 0);
2758 } else {
2759 FUNCTION_FCHECK(src, srcw, SLJIT_SIMD_GET_ELEM_SIZE(type) == 2);
2760 }
2761 } else if (src != SLJIT_IMM) {
2762 FUNCTION_CHECK_DST(src, srcw);
2763 }
2764 #endif
2765 #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
2766 if (SLJIT_UNLIKELY(!!compiler->verbose)) {
2767 if (type & SLJIT_SIMD_TEST)
2768 CHECK_RETURN_OK;
2769 if (sljit_emit_simd_replicate(compiler, type | SLJIT_SIMD_TEST, freg, src, srcw) == SLJIT_ERR_UNSUPPORTED) {
2770 fprintf(compiler->verbose, " # simd_dup: unsupported form, no instructions are emitted\n");
2771 CHECK_RETURN_OK;
2772 }
2773
2774 fprintf(compiler->verbose, " simd_replicate.%d.%s%d ",
2775 (8 << SLJIT_SIMD_GET_REG_SIZE(type)),
2776 (type & SLJIT_SIMD_FLOAT) ? "f" : "",
2777 (8 << SLJIT_SIMD_GET_ELEM_SIZE(type)));
2778
2779 sljit_verbose_freg(compiler, freg);
2780 fprintf(compiler->verbose, ", ");
2781 if (type & SLJIT_SIMD_FLOAT)
2782 sljit_verbose_fparam(compiler, src, srcw);
2783 else
2784 sljit_verbose_param(compiler, src, srcw);
2785 fprintf(compiler->verbose, "\n");
2786 }
2787 #endif
2788 CHECK_RETURN_OK;
2789 }
2790
check_sljit_emit_simd_lane_mov(struct sljit_compiler * compiler,sljit_s32 type,sljit_s32 freg,sljit_s32 lane_index,sljit_s32 srcdst,sljit_sw srcdstw)2791 static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_simd_lane_mov(struct sljit_compiler *compiler, sljit_s32 type,
2792 sljit_s32 freg, sljit_s32 lane_index,
2793 sljit_s32 srcdst, sljit_sw srcdstw)
2794 {
2795 #if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
2796 CHECK_ARGUMENT(sljit_has_cpu_feature(SLJIT_HAS_SIMD));
2797 CHECK_ARGUMENT((type & SLJIT_SIMD_TYPE_MASK(SLJIT_SIMD_STORE | SLJIT_SIMD_LANE_ZERO | SLJIT_SIMD_LANE_SIGNED | SLJIT_32)) == 0);
2798 CHECK_ARGUMENT((type & (SLJIT_SIMD_STORE | SLJIT_SIMD_LANE_ZERO)) != (SLJIT_SIMD_STORE | SLJIT_SIMD_LANE_ZERO));
2799 CHECK_ARGUMENT((type & (SLJIT_SIMD_STORE | SLJIT_SIMD_LANE_SIGNED)) != SLJIT_SIMD_LANE_SIGNED);
2800 CHECK_ARGUMENT(!(type & SLJIT_SIMD_FLOAT) || !(type & (SLJIT_SIMD_LANE_SIGNED | SLJIT_32)));
2801 CHECK_ARGUMENT(SLJIT_SIMD_CHECK_REG(type));
2802 CHECK_ARGUMENT(SLJIT_SIMD_GET_ELEM_SIZE(type) < SLJIT_SIMD_GET_REG_SIZE(type));
2803 CHECK_ARGUMENT(!(type & SLJIT_32) || SLJIT_SIMD_GET_ELEM_SIZE(type) <= 2);
2804 CHECK_ARGUMENT(FUNCTION_CHECK_IS_FREG(freg, 0));
2805 CHECK_ARGUMENT(lane_index >= 0 && lane_index < (1 << (SLJIT_SIMD_GET_REG_SIZE(type) - SLJIT_SIMD_GET_ELEM_SIZE(type))));
2806
2807 if (type & SLJIT_SIMD_FLOAT) {
2808 FUNCTION_FCHECK(srcdst, srcdstw, SLJIT_SIMD_GET_ELEM_SIZE(type) == 2);
2809 } else if ((type & SLJIT_SIMD_STORE) || srcdst != SLJIT_IMM) {
2810 FUNCTION_CHECK_DST(srcdst, srcdstw);
2811 }
2812 #endif
2813 #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
2814 if (SLJIT_UNLIKELY(!!compiler->verbose)) {
2815 if (type & SLJIT_SIMD_TEST)
2816 CHECK_RETURN_OK;
2817 if (sljit_emit_simd_lane_mov(compiler, type | SLJIT_SIMD_TEST, freg, lane_index, srcdst, srcdstw) == SLJIT_ERR_UNSUPPORTED) {
2818 fprintf(compiler->verbose, " # simd_move_lane: unsupported form, no instructions are emitted\n");
2819 CHECK_RETURN_OK;
2820 }
2821
2822 fprintf(compiler->verbose, " simd_%s_lane%s%s%s.%d.%s%d ",
2823 (type & SLJIT_SIMD_STORE) ? "store" : "load",
2824 (type & SLJIT_32) ? "32" : "",
2825 (type & SLJIT_SIMD_LANE_ZERO) ? "_z" : "",
2826 (type & SLJIT_SIMD_LANE_SIGNED) ? "_s" : "",
2827 (8 << SLJIT_SIMD_GET_REG_SIZE(type)),
2828 (type & SLJIT_SIMD_FLOAT) ? "f" : "",
2829 (8 << SLJIT_SIMD_GET_ELEM_SIZE(type)));
2830
2831 sljit_verbose_freg(compiler, freg);
2832 fprintf(compiler->verbose, "[%d], ", lane_index);
2833 if (type & SLJIT_SIMD_FLOAT)
2834 sljit_verbose_fparam(compiler, srcdst, srcdstw);
2835 else
2836 sljit_verbose_param(compiler, srcdst, srcdstw);
2837 fprintf(compiler->verbose, "\n");
2838 }
2839 #endif
2840 CHECK_RETURN_OK;
2841 }
2842
check_sljit_emit_simd_lane_replicate(struct sljit_compiler * compiler,sljit_s32 type,sljit_s32 freg,sljit_s32 src,sljit_s32 src_lane_index)2843 static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_simd_lane_replicate(struct sljit_compiler *compiler, sljit_s32 type,
2844 sljit_s32 freg,
2845 sljit_s32 src, sljit_s32 src_lane_index)
2846 {
2847 #if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
2848 CHECK_ARGUMENT(sljit_has_cpu_feature(SLJIT_HAS_SIMD));
2849 CHECK_ARGUMENT((type & SLJIT_SIMD_TYPE_MASK(0)) == 0);
2850 CHECK_ARGUMENT(SLJIT_SIMD_CHECK_REG(type));
2851 CHECK_ARGUMENT(SLJIT_SIMD_GET_ELEM_SIZE(type) < SLJIT_SIMD_GET_REG_SIZE(type));
2852 CHECK_ARGUMENT(FUNCTION_CHECK_IS_FREG(freg, 0));
2853 CHECK_ARGUMENT(FUNCTION_CHECK_IS_FREG(src, 0));
2854 CHECK_ARGUMENT(src_lane_index >= 0 && src_lane_index < (1 << (SLJIT_SIMD_GET_REG_SIZE(type) - SLJIT_SIMD_GET_ELEM_SIZE(type))));
2855 #endif
2856 #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
2857 if (SLJIT_UNLIKELY(!!compiler->verbose)) {
2858 if (type & SLJIT_SIMD_TEST)
2859 CHECK_RETURN_OK;
2860 if (sljit_emit_simd_lane_replicate(compiler, type | SLJIT_SIMD_TEST, freg, src, src_lane_index) == SLJIT_ERR_UNSUPPORTED) {
2861 fprintf(compiler->verbose, " # simd_lane_replicate: unsupported form, no instructions are emitted\n");
2862 CHECK_RETURN_OK;
2863 }
2864
2865 fprintf(compiler->verbose, " simd_lane_replicate.%d.%s%d ",
2866 (8 << SLJIT_SIMD_GET_REG_SIZE(type)),
2867 (type & SLJIT_SIMD_FLOAT) ? "f" : "",
2868 (8 << SLJIT_SIMD_GET_ELEM_SIZE(type)));
2869
2870 sljit_verbose_freg(compiler, freg);
2871 fprintf(compiler->verbose, ", ");
2872 sljit_verbose_freg(compiler, src);
2873 fprintf(compiler->verbose, "[%d]\n", src_lane_index);
2874 }
2875 #endif
2876 CHECK_RETURN_OK;
2877 }
2878
check_sljit_emit_simd_extend(struct sljit_compiler * compiler,sljit_s32 type,sljit_s32 freg,sljit_s32 src,sljit_sw srcw)2879 static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_simd_extend(struct sljit_compiler *compiler, sljit_s32 type,
2880 sljit_s32 freg,
2881 sljit_s32 src, sljit_sw srcw)
2882 {
2883 #if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
2884 CHECK_ARGUMENT(sljit_has_cpu_feature(SLJIT_HAS_SIMD));
2885 CHECK_ARGUMENT((type & SLJIT_SIMD_TYPE_MASK2(SLJIT_SIMD_EXTEND_SIGNED)) == 0);
2886 CHECK_ARGUMENT((type & (SLJIT_SIMD_EXTEND_SIGNED | SLJIT_SIMD_FLOAT)) != (SLJIT_SIMD_EXTEND_SIGNED | SLJIT_SIMD_FLOAT));
2887 CHECK_ARGUMENT(SLJIT_SIMD_CHECK_REG(type));
2888 CHECK_ARGUMENT(SLJIT_SIMD_GET_ELEM2_SIZE(type) < SLJIT_SIMD_GET_REG_SIZE(type));
2889 CHECK_ARGUMENT(SLJIT_SIMD_GET_ELEM_SIZE(type) < SLJIT_SIMD_GET_ELEM2_SIZE(type));
2890 CHECK_ARGUMENT(FUNCTION_CHECK_IS_FREG(freg, 0));
2891 FUNCTION_FCHECK(src, srcw, SLJIT_SIMD_GET_ELEM_SIZE(type) == 2);
2892 #endif
2893 #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
2894 if (SLJIT_UNLIKELY(!!compiler->verbose)) {
2895 if (type & SLJIT_SIMD_TEST)
2896 CHECK_RETURN_OK;
2897 if (sljit_emit_simd_extend(compiler, type | SLJIT_SIMD_TEST, freg, src, srcw) == SLJIT_ERR_UNSUPPORTED) {
2898 fprintf(compiler->verbose, " # simd_extend: unsupported form, no instructions are emitted\n");
2899 CHECK_RETURN_OK;
2900 }
2901
2902 fprintf(compiler->verbose, " simd_load_extend%s.%d.%s%d.%s%d ",
2903 (type & SLJIT_SIMD_EXTEND_SIGNED) ? "_s" : "",
2904 (8 << SLJIT_SIMD_GET_REG_SIZE(type)),
2905 (type & SLJIT_SIMD_FLOAT) ? "f" : "",
2906 (8 << SLJIT_SIMD_GET_ELEM2_SIZE(type)),
2907 (type & SLJIT_SIMD_FLOAT) ? "f" : "",
2908 (8 << SLJIT_SIMD_GET_ELEM_SIZE(type)));
2909
2910 sljit_verbose_freg(compiler, freg);
2911 fprintf(compiler->verbose, ", ");
2912 sljit_verbose_fparam(compiler, src, srcw);
2913 fprintf(compiler->verbose, "\n");
2914 }
2915 #endif
2916 CHECK_RETURN_OK;
2917 }
2918
check_sljit_emit_simd_sign(struct sljit_compiler * compiler,sljit_s32 type,sljit_s32 freg,sljit_s32 dst,sljit_sw dstw)2919 static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_simd_sign(struct sljit_compiler *compiler, sljit_s32 type,
2920 sljit_s32 freg,
2921 sljit_s32 dst, sljit_sw dstw)
2922 {
2923 #if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
2924 CHECK_ARGUMENT(sljit_has_cpu_feature(SLJIT_HAS_SIMD));
2925 CHECK_ARGUMENT((type & SLJIT_SIMD_TYPE_MASK(SLJIT_32)) == SLJIT_SIMD_STORE);
2926 CHECK_ARGUMENT(SLJIT_SIMD_CHECK_REG(type));
2927 CHECK_ARGUMENT(SLJIT_SIMD_GET_ELEM_SIZE(type) < SLJIT_SIMD_GET_REG_SIZE(type));
2928 CHECK_ARGUMENT(FUNCTION_CHECK_IS_FREG(freg, 0));
2929 FUNCTION_CHECK_DST(dst, dstw);
2930 #endif
2931 #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
2932 if (SLJIT_UNLIKELY(!!compiler->verbose)) {
2933 if (type & SLJIT_SIMD_TEST)
2934 CHECK_RETURN_OK;
2935 if (sljit_emit_simd_sign(compiler, type | SLJIT_SIMD_TEST, freg, dst, dstw) == SLJIT_ERR_UNSUPPORTED) {
2936 fprintf(compiler->verbose, " # simd_sign: unsupported form, no instructions are emitted\n");
2937 CHECK_RETURN_OK;
2938 }
2939
2940 fprintf(compiler->verbose, " simd_store_sign%s.%d.%s%d ",
2941 (type & SLJIT_32) ? "32" : "",
2942 (8 << SLJIT_SIMD_GET_REG_SIZE(type)),
2943 (type & SLJIT_SIMD_FLOAT) ? "f" : "",
2944 (8 << SLJIT_SIMD_GET_ELEM_SIZE(type)));
2945
2946 sljit_verbose_freg(compiler, freg);
2947 fprintf(compiler->verbose, ", ");
2948 sljit_verbose_param(compiler, dst, dstw);
2949 fprintf(compiler->verbose, "\n");
2950 }
2951 #endif
2952 CHECK_RETURN_OK;
2953 }
2954
check_sljit_emit_simd_op2(struct sljit_compiler * compiler,sljit_s32 type,sljit_s32 dst_freg,sljit_s32 src1_freg,sljit_s32 src2_freg)2955 static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_simd_op2(struct sljit_compiler *compiler, sljit_s32 type,
2956 sljit_s32 dst_freg, sljit_s32 src1_freg, sljit_s32 src2_freg)
2957 {
2958 #if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
2959 CHECK_ARGUMENT(sljit_has_cpu_feature(SLJIT_HAS_SIMD));
2960 CHECK_ARGUMENT((type & SLJIT_SIMD_TYPE_MASK(0)) >= SLJIT_SIMD_OP2_AND && (type & SLJIT_SIMD_TYPE_MASK(0)) <= SLJIT_SIMD_OP2_XOR);
2961 CHECK_ARGUMENT(SLJIT_SIMD_CHECK_REG(type));
2962 CHECK_ARGUMENT(SLJIT_SIMD_GET_ELEM_SIZE(type) <= SLJIT_SIMD_GET_REG_SIZE(type));
2963 CHECK_ARGUMENT(FUNCTION_CHECK_IS_FREG(dst_freg, 0));
2964 CHECK_ARGUMENT(FUNCTION_CHECK_IS_FREG(src1_freg, 0));
2965 CHECK_ARGUMENT(FUNCTION_CHECK_IS_FREG(src2_freg, 0));
2966 #endif
2967 #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
2968 if (SLJIT_UNLIKELY(!!compiler->verbose)) {
2969 if (type & SLJIT_SIMD_TEST)
2970 CHECK_RETURN_OK;
2971 if (sljit_emit_simd_op2(compiler, type | SLJIT_SIMD_TEST, dst_freg, src1_freg, src2_freg) == SLJIT_ERR_UNSUPPORTED) {
2972 fprintf(compiler->verbose, " # simd_op2: unsupported form, no instructions are emitted\n");
2973 CHECK_RETURN_OK;
2974 }
2975
2976 fprintf(compiler->verbose, " simd_%s.%d.%s%d ",
2977 simd_op2_names[SLJIT_SIMD_GET_OPCODE(type) - 1],
2978 (8 << SLJIT_SIMD_GET_REG_SIZE(type)),
2979 (type & SLJIT_SIMD_FLOAT) ? "f" : "",
2980 (8 << SLJIT_SIMD_GET_ELEM_SIZE(type)));
2981
2982 sljit_verbose_freg(compiler, dst_freg);
2983 fprintf(compiler->verbose, ", ");
2984 sljit_verbose_freg(compiler, src1_freg);
2985 fprintf(compiler->verbose, ", ");
2986 sljit_verbose_freg(compiler, src2_freg);
2987 fprintf(compiler->verbose, "\n");
2988 }
2989 #endif
2990 CHECK_RETURN_OK;
2991 }
2992
check_sljit_get_local_base(struct sljit_compiler * compiler,sljit_s32 dst,sljit_sw dstw,sljit_sw offset)2993 static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_get_local_base(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw dstw, sljit_sw offset)
2994 {
2995 /* Any offset is allowed. */
2996 SLJIT_UNUSED_ARG(offset);
2997
2998 #if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
2999 FUNCTION_CHECK_DST(dst, dstw);
3000 #endif
3001 #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
3002 if (SLJIT_UNLIKELY(!!compiler->verbose)) {
3003 fprintf(compiler->verbose, " local_base ");
3004 sljit_verbose_param(compiler, dst, dstw);
3005 fprintf(compiler->verbose, ", #%" SLJIT_PRINT_D "d\n", offset);
3006 }
3007 #endif
3008 CHECK_RETURN_OK;
3009 }
3010
check_sljit_emit_const(struct sljit_compiler * compiler,sljit_s32 dst,sljit_sw dstw,sljit_sw init_value)3011 static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_const(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw dstw, sljit_sw init_value)
3012 {
3013 SLJIT_UNUSED_ARG(init_value);
3014
3015 #if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
3016 FUNCTION_CHECK_DST(dst, dstw);
3017 #endif
3018 #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
3019 if (SLJIT_UNLIKELY(!!compiler->verbose)) {
3020 fprintf(compiler->verbose, " const ");
3021 sljit_verbose_param(compiler, dst, dstw);
3022 fprintf(compiler->verbose, ", #%" SLJIT_PRINT_D "d\n", init_value);
3023 }
3024 #endif
3025 CHECK_RETURN_OK;
3026 }
3027
check_sljit_emit_mov_addr(struct sljit_compiler * compiler,sljit_s32 dst,sljit_sw dstw)3028 static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_mov_addr(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw dstw)
3029 {
3030 #if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
3031 FUNCTION_CHECK_DST(dst, dstw);
3032 #endif
3033 #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
3034 if (SLJIT_UNLIKELY(!!compiler->verbose)) {
3035 fprintf(compiler->verbose, " mov_addr ");
3036 sljit_verbose_param(compiler, dst, dstw);
3037 fprintf(compiler->verbose, "\n");
3038 }
3039 #endif
3040 CHECK_RETURN_OK;
3041 }
3042
3043 #else /* !SLJIT_ARGUMENT_CHECKS && !SLJIT_VERBOSE */
3044
3045 #define SLJIT_SKIP_CHECKS(compiler)
3046
3047 #endif /* SLJIT_ARGUMENT_CHECKS || SLJIT_VERBOSE */
3048
3049 #define SELECT_FOP1_OPERATION_WITH_CHECKS(compiler, op, dst, dstw, src, srcw) \
3050 SLJIT_COMPILE_ASSERT(!(SLJIT_CONV_SW_FROM_F64 & 0x1) && !(SLJIT_CONV_F64_FROM_SW & 0x1) && !(SLJIT_CONV_F64_FROM_UW & 0x1), \
3051 invalid_float_opcodes); \
3052 if (GET_OPCODE(op) >= SLJIT_CONV_SW_FROM_F64 && GET_OPCODE(op) <= SLJIT_CMP_F64) { \
3053 if (GET_OPCODE(op) == SLJIT_CMP_F64) { \
3054 CHECK(check_sljit_emit_fop1_cmp(compiler, op, dst, dstw, src, srcw)); \
3055 ADJUST_LOCAL_OFFSET(dst, dstw); \
3056 ADJUST_LOCAL_OFFSET(src, srcw); \
3057 return sljit_emit_fop1_cmp(compiler, op, dst, dstw, src, srcw); \
3058 } \
3059 if ((GET_OPCODE(op) | 0x1) == SLJIT_CONV_S32_FROM_F64) { \
3060 CHECK(check_sljit_emit_fop1_conv_sw_from_f64(compiler, op, dst, dstw, src, srcw)); \
3061 ADJUST_LOCAL_OFFSET(dst, dstw); \
3062 ADJUST_LOCAL_OFFSET(src, srcw); \
3063 return sljit_emit_fop1_conv_sw_from_f64(compiler, op, dst, dstw, src, srcw); \
3064 } \
3065 if ((GET_OPCODE(op) | 0x1) == SLJIT_CONV_F64_FROM_S32) { \
3066 CHECK(check_sljit_emit_fop1_conv_f64_from_w(compiler, op, dst, dstw, src, srcw)); \
3067 ADJUST_LOCAL_OFFSET(dst, dstw); \
3068 ADJUST_LOCAL_OFFSET(src, srcw); \
3069 return sljit_emit_fop1_conv_f64_from_sw(compiler, op, dst, dstw, src, srcw); \
3070 } \
3071 CHECK(check_sljit_emit_fop1_conv_f64_from_w(compiler, op, dst, dstw, src, srcw)); \
3072 ADJUST_LOCAL_OFFSET(dst, dstw); \
3073 ADJUST_LOCAL_OFFSET(src, srcw); \
3074 return sljit_emit_fop1_conv_f64_from_uw(compiler, op, dst, dstw, src, srcw); \
3075 } \
3076 CHECK(check_sljit_emit_fop1(compiler, op, dst, dstw, src, srcw)); \
3077 ADJUST_LOCAL_OFFSET(dst, dstw); \
3078 ADJUST_LOCAL_OFFSET(src, srcw);
3079
3080 #if (!(defined SLJIT_CONFIG_MIPS && SLJIT_CONFIG_MIPS) || (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 6))
3081
sljit_emit_mem_unaligned(struct sljit_compiler * compiler,sljit_s32 type,sljit_s32 reg,sljit_s32 mem,sljit_sw memw)3082 static sljit_s32 sljit_emit_mem_unaligned(struct sljit_compiler *compiler, sljit_s32 type,
3083 sljit_s32 reg,
3084 sljit_s32 mem, sljit_sw memw)
3085 {
3086 SLJIT_SKIP_CHECKS(compiler);
3087
3088 if (type & SLJIT_MEM_STORE)
3089 return sljit_emit_op1(compiler, type & (0xff | SLJIT_32), mem, memw, reg, 0);
3090 return sljit_emit_op1(compiler, type & (0xff | SLJIT_32), reg, 0, mem, memw);
3091 }
3092
3093 #endif /* (!SLJIT_CONFIG_MIPS || SLJIT_MIPS_REV >= 6) */
3094
3095 #if (!(defined SLJIT_CONFIG_MIPS && SLJIT_CONFIG_MIPS) || (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 6)) \
3096 && !(defined SLJIT_CONFIG_ARM_32 && SLJIT_CONFIG_ARM_32)
3097
sljit_emit_fmem_unaligned(struct sljit_compiler * compiler,sljit_s32 type,sljit_s32 freg,sljit_s32 mem,sljit_sw memw)3098 static sljit_s32 sljit_emit_fmem_unaligned(struct sljit_compiler *compiler, sljit_s32 type,
3099 sljit_s32 freg,
3100 sljit_s32 mem, sljit_sw memw)
3101 {
3102 SLJIT_SKIP_CHECKS(compiler);
3103
3104 if (type & SLJIT_MEM_STORE)
3105 return sljit_emit_fop1(compiler, type & (0xff | SLJIT_32), mem, memw, freg, 0);
3106 return sljit_emit_fop1(compiler, type & (0xff | SLJIT_32), freg, 0, mem, memw);
3107 }
3108
3109 #endif /* (!SLJIT_CONFIG_MIPS || SLJIT_MIPS_REV >= 6) && !SLJIT_CONFIG_ARM */
3110
3111 /* CPU description section */
3112
3113 #if (defined SLJIT_32BIT_ARCHITECTURE && SLJIT_32BIT_ARCHITECTURE)
3114 #define SLJIT_CPUINFO_PART1 " 32bit ("
3115 #elif (defined SLJIT_64BIT_ARCHITECTURE && SLJIT_64BIT_ARCHITECTURE)
3116 #define SLJIT_CPUINFO_PART1 " 64bit ("
3117 #else
3118 #error "Internal error: CPU type info missing"
3119 #endif
3120
3121 #if (defined SLJIT_LITTLE_ENDIAN && SLJIT_LITTLE_ENDIAN)
3122 #define SLJIT_CPUINFO_PART2 "little endian + "
3123 #elif (defined SLJIT_BIG_ENDIAN && SLJIT_BIG_ENDIAN)
3124 #define SLJIT_CPUINFO_PART2 "big endian + "
3125 #else
3126 #error "Internal error: CPU type info missing"
3127 #endif
3128
3129 #if (defined SLJIT_UNALIGNED && SLJIT_UNALIGNED)
3130 #define SLJIT_CPUINFO_PART3 "unaligned)"
3131 #else
3132 #define SLJIT_CPUINFO_PART3 "aligned)"
3133 #endif
3134
3135 #define SLJIT_CPUINFO SLJIT_CPUINFO_PART1 SLJIT_CPUINFO_PART2 SLJIT_CPUINFO_PART3
3136
3137 #if (defined SLJIT_CONFIG_X86 && SLJIT_CONFIG_X86)
3138 # include "sljitNativeX86_common.c"
3139 #elif (defined SLJIT_CONFIG_ARM_V6 && SLJIT_CONFIG_ARM_V6)
3140 # include "sljitNativeARM_32.c"
3141 #elif (defined SLJIT_CONFIG_ARM_V7 && SLJIT_CONFIG_ARM_V7)
3142 # include "sljitNativeARM_32.c"
3143 #elif (defined SLJIT_CONFIG_ARM_THUMB2 && SLJIT_CONFIG_ARM_THUMB2)
3144 # include "sljitNativeARM_T2_32.c"
3145 #elif (defined SLJIT_CONFIG_ARM_64 && SLJIT_CONFIG_ARM_64)
3146 # include "sljitNativeARM_64.c"
3147 #elif (defined SLJIT_CONFIG_PPC && SLJIT_CONFIG_PPC)
3148 # include "sljitNativePPC_common.c"
3149 #elif (defined SLJIT_CONFIG_MIPS && SLJIT_CONFIG_MIPS)
3150 # include "sljitNativeMIPS_common.c"
3151 #elif (defined SLJIT_CONFIG_RISCV && SLJIT_CONFIG_RISCV)
3152 # include "sljitNativeRISCV_common.c"
3153 #elif (defined SLJIT_CONFIG_S390X && SLJIT_CONFIG_S390X)
3154 # include "sljitNativeS390X.c"
3155 #elif (defined SLJIT_CONFIG_LOONGARCH && SLJIT_CONFIG_LOONGARCH)
3156 # include "sljitNativeLOONGARCH_64.c"
3157 #endif
3158
3159 #include "sljitSerialize.c"
3160
emit_mov_before_return(struct sljit_compiler * compiler,sljit_s32 op,sljit_s32 src,sljit_sw srcw)3161 static SLJIT_INLINE sljit_s32 emit_mov_before_return(struct sljit_compiler *compiler, sljit_s32 op, sljit_s32 src, sljit_sw srcw)
3162 {
3163 #if (defined SLJIT_64BIT_ARCHITECTURE && SLJIT_64BIT_ARCHITECTURE)
3164 /* At the moment the pointer size is always equal to sljit_sw. May be changed in the future. */
3165 if (src == SLJIT_RETURN_REG && (op == SLJIT_MOV || op == SLJIT_MOV_P))
3166 return SLJIT_SUCCESS;
3167 #else
3168 if (src == SLJIT_RETURN_REG && (op == SLJIT_MOV || op == SLJIT_MOV_U32 || op == SLJIT_MOV_S32 || op == SLJIT_MOV_P))
3169 return SLJIT_SUCCESS;
3170 #endif
3171
3172 SLJIT_SKIP_CHECKS(compiler);
3173 return sljit_emit_op1(compiler, op, SLJIT_RETURN_REG, 0, src, srcw);
3174 }
3175
3176 #if !(defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) \
3177 && !((defined SLJIT_CONFIG_ARM_32 && SLJIT_CONFIG_ARM_32) && defined __SOFTFP__)
3178
emit_fmov_before_return(struct sljit_compiler * compiler,sljit_s32 op,sljit_s32 src,sljit_sw srcw)3179 static SLJIT_INLINE sljit_s32 emit_fmov_before_return(struct sljit_compiler *compiler, sljit_s32 op, sljit_s32 src, sljit_sw srcw)
3180 {
3181 if (src == SLJIT_FR0)
3182 return SLJIT_SUCCESS;
3183
3184 SLJIT_SKIP_CHECKS(compiler);
3185 return sljit_emit_fop1(compiler, op, SLJIT_RETURN_FREG, 0, src, srcw);
3186 }
3187
3188 #endif /* !SLJIT_CONFIG_X86_32 && !(SLJIT_CONFIG_ARM_32 && __SOFTFP__) */
3189
sljit_emit_return(struct sljit_compiler * compiler,sljit_s32 op,sljit_s32 src,sljit_sw srcw)3190 SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_return(struct sljit_compiler *compiler, sljit_s32 op, sljit_s32 src, sljit_sw srcw)
3191 {
3192 CHECK_ERROR();
3193 CHECK(check_sljit_emit_return(compiler, op, src, srcw));
3194
3195 if (GET_OPCODE(op) < SLJIT_MOV_F64) {
3196 FAIL_IF(emit_mov_before_return(compiler, op, src, srcw));
3197 } else {
3198 FAIL_IF(emit_fmov_before_return(compiler, op, src, srcw));
3199 }
3200
3201 SLJIT_SKIP_CHECKS(compiler);
3202 return sljit_emit_return_void(compiler);
3203 }
3204
3205 #if !(defined SLJIT_CONFIG_X86 && SLJIT_CONFIG_X86) \
3206 && !(defined SLJIT_CONFIG_S390X && SLJIT_CONFIG_S390X) \
3207 && !(defined(SLJIT_CONFIG_LOONGARCH_64) && SLJIT_CONFIG_LOONGARCH_64)
3208
sljit_emit_fop2r(struct sljit_compiler * compiler,sljit_s32 op,sljit_s32 dst_freg,sljit_s32 src1,sljit_sw src1w,sljit_s32 src2,sljit_sw src2w)3209 SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fop2r(struct sljit_compiler *compiler, sljit_s32 op,
3210 sljit_s32 dst_freg,
3211 sljit_s32 src1, sljit_sw src1w,
3212 sljit_s32 src2, sljit_sw src2w)
3213 {
3214 CHECK_ERROR();
3215 CHECK(check_sljit_emit_fop2r(compiler, op, dst_freg, src1, src1w, src2, src2w));
3216 ADJUST_LOCAL_OFFSET(src1, src1w);
3217 ADJUST_LOCAL_OFFSET(src2, src2w);
3218
3219 SLJIT_SKIP_CHECKS(compiler);
3220 return sljit_emit_fop2(compiler, op, dst_freg, 0, src1, src1w, src2, src2w);
3221 }
3222
3223 #endif /* !SLJIT_CONFIG_X86 && !SLJIT_CONFIG_S390X && !SLJIT_CONFIG_LOONGARCH_64 */
3224
3225 #if !(defined SLJIT_CONFIG_MIPS && SLJIT_CONFIG_MIPS) \
3226 && !(defined SLJIT_CONFIG_RISCV && SLJIT_CONFIG_RISCV) \
3227 && !(defined SLJIT_CONFIG_LOONGARCH && SLJIT_CONFIG_LOONGARCH)
3228
sljit_emit_cmp(struct sljit_compiler * compiler,sljit_s32 type,sljit_s32 src1,sljit_sw src1w,sljit_s32 src2,sljit_sw src2w)3229 SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_cmp(struct sljit_compiler *compiler, sljit_s32 type,
3230 sljit_s32 src1, sljit_sw src1w,
3231 sljit_s32 src2, sljit_sw src2w)
3232 {
3233 /* Default compare for most architectures. */
3234 sljit_s32 flags, tmp_src, condition;
3235 sljit_sw tmp_srcw;
3236
3237 CHECK_ERROR_PTR();
3238 CHECK_PTR(check_sljit_emit_cmp(compiler, type, src1, src1w, src2, src2w));
3239
3240 condition = type & 0xff;
3241 #if (defined SLJIT_CONFIG_ARM_64 && SLJIT_CONFIG_ARM_64)
3242 if ((condition == SLJIT_EQUAL || condition == SLJIT_NOT_EQUAL)) {
3243 if (src1 == SLJIT_IMM && !src1w) {
3244 src1 = src2;
3245 src1w = src2w;
3246 src2 = SLJIT_IMM;
3247 src2w = 0;
3248 }
3249 if (src2 == SLJIT_IMM && !src2w)
3250 return emit_cmp_to0(compiler, type, src1, src1w);
3251 }
3252 #endif
3253
3254 if (SLJIT_UNLIKELY(src1 == SLJIT_IMM && src2 != SLJIT_IMM)) {
3255 /* Immediate is preferred as second argument by most architectures. */
3256 switch (condition) {
3257 case SLJIT_LESS:
3258 condition = SLJIT_GREATER;
3259 break;
3260 case SLJIT_GREATER_EQUAL:
3261 condition = SLJIT_LESS_EQUAL;
3262 break;
3263 case SLJIT_GREATER:
3264 condition = SLJIT_LESS;
3265 break;
3266 case SLJIT_LESS_EQUAL:
3267 condition = SLJIT_GREATER_EQUAL;
3268 break;
3269 case SLJIT_SIG_LESS:
3270 condition = SLJIT_SIG_GREATER;
3271 break;
3272 case SLJIT_SIG_GREATER_EQUAL:
3273 condition = SLJIT_SIG_LESS_EQUAL;
3274 break;
3275 case SLJIT_SIG_GREATER:
3276 condition = SLJIT_SIG_LESS;
3277 break;
3278 case SLJIT_SIG_LESS_EQUAL:
3279 condition = SLJIT_SIG_GREATER_EQUAL;
3280 break;
3281 }
3282
3283 type = condition | (type & (SLJIT_32 | SLJIT_REWRITABLE_JUMP));
3284 tmp_src = src1;
3285 src1 = src2;
3286 src2 = tmp_src;
3287 tmp_srcw = src1w;
3288 src1w = src2w;
3289 src2w = tmp_srcw;
3290 }
3291
3292 if (condition <= SLJIT_NOT_ZERO)
3293 flags = SLJIT_SET_Z;
3294 else
3295 flags = (condition & 0xfe) << VARIABLE_FLAG_SHIFT;
3296
3297 SLJIT_SKIP_CHECKS(compiler);
3298 PTR_FAIL_IF(sljit_emit_op2u(compiler,
3299 SLJIT_SUB | flags | (type & SLJIT_32), src1, src1w, src2, src2w));
3300
3301 SLJIT_SKIP_CHECKS(compiler);
3302 return sljit_emit_jump(compiler, condition | (type & (SLJIT_REWRITABLE_JUMP | SLJIT_32)));
3303 }
3304
3305 #endif /* !SLJIT_CONFIG_MIPS */
3306
3307 #if (defined SLJIT_CONFIG_ARM_32 && SLJIT_CONFIG_ARM_32)
3308
sljit_cmp_info(sljit_s32 type)3309 SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_cmp_info(sljit_s32 type)
3310 {
3311 switch (type) {
3312 case SLJIT_UNORDERED_OR_EQUAL:
3313 case SLJIT_ORDERED_NOT_EQUAL:
3314 return 1;
3315 }
3316
3317 return 0;
3318 }
3319
3320 #endif /* SLJIT_CONFIG_ARM */
3321
sljit_emit_fcmp(struct sljit_compiler * compiler,sljit_s32 type,sljit_s32 src1,sljit_sw src1w,sljit_s32 src2,sljit_sw src2w)3322 SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_fcmp(struct sljit_compiler *compiler, sljit_s32 type,
3323 sljit_s32 src1, sljit_sw src1w,
3324 sljit_s32 src2, sljit_sw src2w)
3325 {
3326 CHECK_ERROR_PTR();
3327 CHECK_PTR(check_sljit_emit_fcmp(compiler, type, src1, src1w, src2, src2w));
3328
3329 SLJIT_SKIP_CHECKS(compiler);
3330 sljit_emit_fop1(compiler, SLJIT_CMP_F64 | ((type & 0xfe) << VARIABLE_FLAG_SHIFT) | (type & SLJIT_32), src1, src1w, src2, src2w);
3331
3332 SLJIT_SKIP_CHECKS(compiler);
3333 return sljit_emit_jump(compiler, type);
3334 }
3335
3336 #if !(defined SLJIT_CONFIG_ARM && SLJIT_CONFIG_ARM) \
3337 && !(defined SLJIT_CONFIG_PPC && SLJIT_CONFIG_PPC)
3338
sljit_emit_mem_update(struct sljit_compiler * compiler,sljit_s32 type,sljit_s32 reg,sljit_s32 mem,sljit_sw memw)3339 SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_mem_update(struct sljit_compiler *compiler, sljit_s32 type,
3340 sljit_s32 reg,
3341 sljit_s32 mem, sljit_sw memw)
3342 {
3343 CHECK_ERROR();
3344 CHECK(check_sljit_emit_mem_update(compiler, type, reg, mem, memw));
3345 SLJIT_UNUSED_ARG(type);
3346 SLJIT_UNUSED_ARG(reg);
3347 SLJIT_UNUSED_ARG(mem);
3348 SLJIT_UNUSED_ARG(memw);
3349
3350 return SLJIT_ERR_UNSUPPORTED;
3351 }
3352
3353 #endif /* !SLJIT_CONFIG_ARM && !SLJIT_CONFIG_PPC */
3354
3355 #if !(defined SLJIT_CONFIG_ARM_32 && SLJIT_CONFIG_ARM_32) \
3356 && !(defined SLJIT_CONFIG_MIPS && SLJIT_CONFIG_MIPS)
3357
sljit_emit_fmem(struct sljit_compiler * compiler,sljit_s32 type,sljit_s32 freg,sljit_s32 mem,sljit_sw memw)3358 SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fmem(struct sljit_compiler *compiler, sljit_s32 type,
3359 sljit_s32 freg,
3360 sljit_s32 mem, sljit_sw memw)
3361 {
3362 CHECK_ERROR();
3363 CHECK(check_sljit_emit_fmem(compiler, type, freg, mem, memw));
3364
3365 return sljit_emit_fmem_unaligned(compiler, type, freg, mem, memw);
3366 }
3367
3368 #endif /* !SLJIT_CONFIG_ARM_32 && !SLJIT_CONFIG_MIPS */
3369
3370 #if !(defined SLJIT_CONFIG_ARM_64 && SLJIT_CONFIG_ARM_64) \
3371 && !(defined SLJIT_CONFIG_PPC && SLJIT_CONFIG_PPC)
3372
sljit_emit_fmem_update(struct sljit_compiler * compiler,sljit_s32 type,sljit_s32 freg,sljit_s32 mem,sljit_sw memw)3373 SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fmem_update(struct sljit_compiler *compiler, sljit_s32 type,
3374 sljit_s32 freg,
3375 sljit_s32 mem, sljit_sw memw)
3376 {
3377 CHECK_ERROR();
3378 CHECK(check_sljit_emit_fmem_update(compiler, type, freg, mem, memw));
3379 SLJIT_UNUSED_ARG(type);
3380 SLJIT_UNUSED_ARG(freg);
3381 SLJIT_UNUSED_ARG(mem);
3382 SLJIT_UNUSED_ARG(memw);
3383
3384 return SLJIT_ERR_UNSUPPORTED;
3385 }
3386
3387 #endif /* !SLJIT_CONFIG_ARM_64 && !SLJIT_CONFIG_PPC */
3388
3389 #if !(defined SLJIT_CONFIG_X86 && SLJIT_CONFIG_X86) \
3390 && !(defined SLJIT_CONFIG_ARM && SLJIT_CONFIG_ARM) \
3391 && !(defined SLJIT_CONFIG_S390X && SLJIT_CONFIG_S390X) \
3392 && !(defined SLJIT_CONFIG_LOONGARCH && SLJIT_CONFIG_LOONGARCH)
3393
sljit_emit_simd_mov(struct sljit_compiler * compiler,sljit_s32 type,sljit_s32 freg,sljit_s32 srcdst,sljit_sw srcdstw)3394 SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_mov(struct sljit_compiler *compiler, sljit_s32 type,
3395 sljit_s32 freg,
3396 sljit_s32 srcdst, sljit_sw srcdstw)
3397 {
3398 CHECK_ERROR();
3399 CHECK(check_sljit_emit_simd_mov(compiler, type, freg, srcdst, srcdstw));
3400 SLJIT_UNUSED_ARG(compiler);
3401 SLJIT_UNUSED_ARG(type);
3402 SLJIT_UNUSED_ARG(freg);
3403 SLJIT_UNUSED_ARG(srcdst);
3404 SLJIT_UNUSED_ARG(srcdstw);
3405
3406 return SLJIT_ERR_UNSUPPORTED;
3407 }
3408
sljit_emit_simd_replicate(struct sljit_compiler * compiler,sljit_s32 type,sljit_s32 freg,sljit_s32 src,sljit_sw srcw)3409 SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_replicate(struct sljit_compiler *compiler, sljit_s32 type,
3410 sljit_s32 freg,
3411 sljit_s32 src, sljit_sw srcw)
3412 {
3413 CHECK_ERROR();
3414 CHECK(check_sljit_emit_simd_replicate(compiler, type, freg, src, srcw));
3415 SLJIT_UNUSED_ARG(compiler);
3416 SLJIT_UNUSED_ARG(type);
3417 SLJIT_UNUSED_ARG(freg);
3418 SLJIT_UNUSED_ARG(src);
3419 SLJIT_UNUSED_ARG(srcw);
3420
3421 return SLJIT_ERR_UNSUPPORTED;
3422 }
3423
sljit_emit_simd_lane_mov(struct sljit_compiler * compiler,sljit_s32 type,sljit_s32 freg,sljit_s32 lane_index,sljit_s32 srcdst,sljit_sw srcdstw)3424 SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_lane_mov(struct sljit_compiler *compiler, sljit_s32 type,
3425 sljit_s32 freg, sljit_s32 lane_index,
3426 sljit_s32 srcdst, sljit_sw srcdstw)
3427 {
3428 CHECK_ERROR();
3429 CHECK(check_sljit_emit_simd_lane_mov(compiler, type, freg, lane_index, srcdst, srcdstw));
3430 SLJIT_UNUSED_ARG(compiler);
3431 SLJIT_UNUSED_ARG(type);
3432 SLJIT_UNUSED_ARG(freg);
3433 SLJIT_UNUSED_ARG(lane_index);
3434 SLJIT_UNUSED_ARG(srcdst);
3435 SLJIT_UNUSED_ARG(srcdstw);
3436
3437 return SLJIT_ERR_UNSUPPORTED;
3438 }
3439
sljit_emit_simd_lane_replicate(struct sljit_compiler * compiler,sljit_s32 type,sljit_s32 freg,sljit_s32 src,sljit_s32 src_lane_index)3440 SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_lane_replicate(struct sljit_compiler *compiler, sljit_s32 type,
3441 sljit_s32 freg,
3442 sljit_s32 src, sljit_s32 src_lane_index)
3443 {
3444 CHECK_ERROR();
3445 CHECK(check_sljit_emit_simd_lane_replicate(compiler, type, freg, src, src_lane_index));
3446 SLJIT_UNUSED_ARG(compiler);
3447 SLJIT_UNUSED_ARG(type);
3448 SLJIT_UNUSED_ARG(freg);
3449 SLJIT_UNUSED_ARG(src);
3450 SLJIT_UNUSED_ARG(src_lane_index);
3451
3452 return SLJIT_ERR_UNSUPPORTED;
3453 }
3454
sljit_emit_simd_extend(struct sljit_compiler * compiler,sljit_s32 type,sljit_s32 freg,sljit_s32 src,sljit_sw srcw)3455 SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_extend(struct sljit_compiler *compiler, sljit_s32 type,
3456 sljit_s32 freg,
3457 sljit_s32 src, sljit_sw srcw)
3458 {
3459 CHECK_ERROR();
3460 CHECK(check_sljit_emit_simd_extend(compiler, type, freg, src, srcw));
3461 SLJIT_UNUSED_ARG(compiler);
3462 SLJIT_UNUSED_ARG(type);
3463 SLJIT_UNUSED_ARG(freg);
3464 SLJIT_UNUSED_ARG(src);
3465 SLJIT_UNUSED_ARG(srcw);
3466
3467 return SLJIT_ERR_UNSUPPORTED;
3468 }
3469
sljit_emit_simd_sign(struct sljit_compiler * compiler,sljit_s32 type,sljit_s32 freg,sljit_s32 dst,sljit_sw dstw)3470 SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_sign(struct sljit_compiler *compiler, sljit_s32 type,
3471 sljit_s32 freg,
3472 sljit_s32 dst, sljit_sw dstw)
3473 {
3474 CHECK_ERROR();
3475 CHECK(check_sljit_emit_simd_sign(compiler, type, freg, dst, dstw));
3476 SLJIT_UNUSED_ARG(compiler);
3477 SLJIT_UNUSED_ARG(type);
3478 SLJIT_UNUSED_ARG(freg);
3479 SLJIT_UNUSED_ARG(dst);
3480 SLJIT_UNUSED_ARG(dstw);
3481
3482 return SLJIT_ERR_UNSUPPORTED;
3483 }
3484
sljit_emit_simd_op2(struct sljit_compiler * compiler,sljit_s32 type,sljit_s32 dst_freg,sljit_s32 src1_freg,sljit_s32 src2_freg)3485 SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_op2(struct sljit_compiler *compiler, sljit_s32 type,
3486 sljit_s32 dst_freg, sljit_s32 src1_freg, sljit_s32 src2_freg)
3487 {
3488 CHECK_ERROR();
3489 CHECK(check_sljit_emit_simd_op2(compiler, type, dst_freg, src1_freg, src2_freg));
3490 SLJIT_UNUSED_ARG(compiler);
3491 SLJIT_UNUSED_ARG(type);
3492 SLJIT_UNUSED_ARG(dst_freg);
3493 SLJIT_UNUSED_ARG(src1_freg);
3494 SLJIT_UNUSED_ARG(src2_freg);
3495
3496 return SLJIT_ERR_UNSUPPORTED;
3497 }
3498
3499 #endif /* !SLJIT_CONFIG_X86 && !SLJIT_CONFIG_ARM */
3500
3501 #if !(defined(SLJIT_CONFIG_X86) && SLJIT_CONFIG_X86) \
3502 && !(defined(SLJIT_CONFIG_ARM) && SLJIT_CONFIG_ARM) \
3503 && !(defined(SLJIT_CONFIG_S390X) && SLJIT_CONFIG_S390X) \
3504 && !(defined(SLJIT_CONFIG_LOONGARCH) && SLJIT_CONFIG_LOONGARCH)
3505
sljit_emit_atomic_load(struct sljit_compiler * compiler,sljit_s32 op,sljit_s32 dst_reg,sljit_s32 mem_reg)3506 SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_atomic_load(struct sljit_compiler *compiler,
3507 sljit_s32 op,
3508 sljit_s32 dst_reg,
3509 sljit_s32 mem_reg)
3510 {
3511 SLJIT_UNUSED_ARG(compiler);
3512 SLJIT_UNUSED_ARG(op);
3513 SLJIT_UNUSED_ARG(dst_reg);
3514 SLJIT_UNUSED_ARG(mem_reg);
3515
3516 CHECK_ERROR();
3517 CHECK(check_sljit_emit_atomic_load(compiler, op, dst_reg, mem_reg));
3518
3519 return SLJIT_ERR_UNSUPPORTED;
3520 }
3521
sljit_emit_atomic_store(struct sljit_compiler * compiler,sljit_s32 op,sljit_s32 src_reg,sljit_s32 mem_reg,sljit_s32 temp_reg)3522 SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_atomic_store(struct sljit_compiler *compiler,
3523 sljit_s32 op,
3524 sljit_s32 src_reg,
3525 sljit_s32 mem_reg,
3526 sljit_s32 temp_reg)
3527 {
3528 SLJIT_UNUSED_ARG(compiler);
3529 SLJIT_UNUSED_ARG(op);
3530 SLJIT_UNUSED_ARG(src_reg);
3531 SLJIT_UNUSED_ARG(mem_reg);
3532 SLJIT_UNUSED_ARG(temp_reg);
3533
3534 CHECK_ERROR();
3535 CHECK(check_sljit_emit_atomic_store(compiler, op, src_reg, mem_reg, temp_reg));
3536
3537 return SLJIT_ERR_UNSUPPORTED;
3538 }
3539
3540 #endif /* !SLJIT_CONFIG_X86 && !SLJIT_CONFIG_ARM && !SLJIT_CONFIG_S390X && !SLJIT_CONFIG_LOONGARCH */
3541
3542 #if !(defined SLJIT_CONFIG_X86 && SLJIT_CONFIG_X86) \
3543 && !(defined SLJIT_CONFIG_ARM_64 && SLJIT_CONFIG_ARM_64)
3544
sljit_get_local_base(struct sljit_compiler * compiler,sljit_s32 dst,sljit_sw dstw,sljit_sw offset)3545 SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_get_local_base(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw dstw, sljit_sw offset)
3546 {
3547 CHECK_ERROR();
3548 CHECK(check_sljit_get_local_base(compiler, dst, dstw, offset));
3549
3550 ADJUST_LOCAL_OFFSET(SLJIT_MEM1(SLJIT_SP), offset);
3551
3552 SLJIT_SKIP_CHECKS(compiler);
3553
3554 if (offset != 0)
3555 return sljit_emit_op2(compiler, SLJIT_ADD, dst, dstw, SLJIT_SP, 0, SLJIT_IMM, offset);
3556 return sljit_emit_op1(compiler, SLJIT_MOV, dst, dstw, SLJIT_SP, 0);
3557 }
3558
3559 #endif /* !SLJIT_CONFIG_X86 && !SLJIT_CONFIG_ARM_64 */
3560
3561 #endif /* !SLJIT_CONFIG_UNSUPPORTED */
3562