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