xref: /php-src/ext/pcre/pcre2lib/sljit/sljitLir.c (revision ae5beff6)
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