• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 #define VARIABLE_FLAG_MASK (0x3f << VARIABLE_FLAG_SHIFT)
97 #define GET_FLAG_TYPE(op) ((op) >> VARIABLE_FLAG_SHIFT)
98 
99 #define GET_OPCODE(op) \
100 	((op) & ~(SLJIT_32 | SLJIT_SET_Z | VARIABLE_FLAG_MASK))
101 
102 #define HAS_FLAGS(op) \
103 	((op) & (SLJIT_SET_Z | VARIABLE_FLAG_MASK))
104 
105 #define GET_ALL_FLAGS(op) \
106 	((op) & (SLJIT_32 | SLJIT_SET_Z | VARIABLE_FLAG_MASK))
107 
108 #if (defined SLJIT_64BIT_ARCHITECTURE && SLJIT_64BIT_ARCHITECTURE)
109 #define TYPE_CAST_NEEDED(op) \
110 	((op) >= SLJIT_MOV_U8 && (op) <= SLJIT_MOV_S32)
111 #else /* !SLJIT_64BIT_ARCHITECTURE */
112 #define TYPE_CAST_NEEDED(op) \
113 	((op) >= SLJIT_MOV_U8 && (op) <= SLJIT_MOV_S16)
114 #endif /* SLJIT_64BIT_ARCHITECTURE */
115 
116 #define BUF_SIZE	4096
117 
118 #if (defined SLJIT_32BIT_ARCHITECTURE && SLJIT_32BIT_ARCHITECTURE)
119 #define ABUF_SIZE	2048
120 #else
121 #define ABUF_SIZE	4096
122 #endif
123 
124 /* Parameter parsing. */
125 #define REG_MASK		0x3f
126 #define OFFS_REG(reg)		(((reg) >> 8) & REG_MASK)
127 #define OFFS_REG_MASK		(REG_MASK << 8)
128 #define TO_OFFS_REG(reg)	((reg) << 8)
129 /* When reg cannot be unused. */
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 /* Jump flags. */
137 #define JUMP_LABEL	0x1
138 #define JUMP_ADDR	0x2
139 /* SLJIT_REWRITABLE_JUMP is 0x1000. */
140 
141 #if (defined SLJIT_CONFIG_X86 && SLJIT_CONFIG_X86)
142 #	define PATCH_MB		0x4
143 #	define PATCH_MW		0x8
144 #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
145 #	define PATCH_MD		0x10
146 #endif
147 #	define TYPE_SHIFT	13
148 #endif
149 
150 #if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5) || (defined SLJIT_CONFIG_ARM_V7 && SLJIT_CONFIG_ARM_V7)
151 #	define IS_BL		0x4
152 #	define PATCH_B		0x8
153 #endif
154 
155 #if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5)
156 #	define CPOOL_SIZE	512
157 #endif
158 
159 #if (defined SLJIT_CONFIG_ARM_THUMB2 && SLJIT_CONFIG_ARM_THUMB2)
160 #	define IS_COND		0x04
161 #	define IS_BL		0x08
162 	/* conditional + imm8 */
163 #	define PATCH_TYPE1	0x10
164 	/* conditional + imm20 */
165 #	define PATCH_TYPE2	0x20
166 	/* IT + imm24 */
167 #	define PATCH_TYPE3	0x30
168 	/* imm11 */
169 #	define PATCH_TYPE4	0x40
170 	/* imm24 */
171 #	define PATCH_TYPE5	0x50
172 	/* BL + imm24 */
173 #	define PATCH_BL		0x60
174 	/* 0xf00 cc code for branches */
175 #endif
176 
177 #if (defined SLJIT_CONFIG_ARM_64 && SLJIT_CONFIG_ARM_64)
178 #	define IS_COND		0x004
179 #	define IS_CBZ		0x008
180 #	define IS_BL		0x010
181 #	define PATCH_B		0x020
182 #	define PATCH_COND	0x040
183 #	define PATCH_ABS48	0x080
184 #	define PATCH_ABS64	0x100
185 #endif
186 
187 #if (defined SLJIT_CONFIG_PPC && SLJIT_CONFIG_PPC)
188 #	define IS_COND		0x004
189 #	define IS_CALL		0x008
190 #	define PATCH_B		0x010
191 #	define PATCH_ABS_B	0x020
192 #if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
193 #	define PATCH_ABS32	0x040
194 #	define PATCH_ABS48	0x080
195 #endif
196 #	define REMOVE_COND	0x100
197 #endif
198 
199 #if (defined SLJIT_CONFIG_MIPS && SLJIT_CONFIG_MIPS)
200 #	define IS_MOVABLE	0x004
201 #	define IS_JAL		0x008
202 #	define IS_CALL		0x010
203 #	define IS_BIT26_COND	0x020
204 #	define IS_BIT16_COND	0x040
205 #	define IS_BIT23_COND	0x080
206 
207 #	define IS_COND		(IS_BIT26_COND | IS_BIT16_COND | IS_BIT23_COND)
208 
209 #	define PATCH_B		0x100
210 #	define PATCH_J		0x200
211 
212 #if (defined SLJIT_CONFIG_MIPS_64 && SLJIT_CONFIG_MIPS_64)
213 #	define PATCH_ABS32	0x400
214 #	define PATCH_ABS48	0x800
215 #endif
216 
217 	/* instruction types */
218 #	define MOVABLE_INS	0
219 	/* 1 - 31 last destination register */
220 	/* no destination (i.e: store) */
221 #	define UNMOVABLE_INS	32
222 	/* FPU status register */
223 #	define FCSR_FCC		33
224 #endif
225 
226 #if (defined SLJIT_CONFIG_SPARC_32 && SLJIT_CONFIG_SPARC_32)
227 #	define IS_MOVABLE	0x04
228 #	define IS_COND		0x08
229 #	define IS_CALL		0x10
230 
231 #	define PATCH_B		0x20
232 #	define PATCH_CALL	0x40
233 
234 	/* instruction types */
235 #	define MOVABLE_INS	0
236 	/* 1 - 31 last destination register */
237 	/* no destination (i.e: store) */
238 #	define UNMOVABLE_INS	32
239 
240 #	define DST_INS_MASK	0xff
241 
242 	/* ICC_SET is the same as SET_FLAGS. */
243 #	define ICC_IS_SET	(1 << 23)
244 #	define FCC_IS_SET	(1 << 24)
245 #endif
246 
247 /* Stack management. */
248 
249 #define GET_SAVED_REGISTERS_SIZE(scratches, saveds, extra) \
250 	(((scratches < SLJIT_NUMBER_OF_SCRATCH_REGISTERS ? 0 : (scratches - SLJIT_NUMBER_OF_SCRATCH_REGISTERS)) + \
251 		(saveds) + (sljit_s32)(extra)) * (sljit_s32)sizeof(sljit_sw))
252 
253 #define GET_SAVED_FLOAT_REGISTERS_SIZE(fscratches, fsaveds, size) \
254 	(((fscratches < SLJIT_NUMBER_OF_SCRATCH_FLOAT_REGISTERS ? 0 : (fscratches - SLJIT_NUMBER_OF_SCRATCH_FLOAT_REGISTERS)) + \
255 		(fsaveds)) * (sljit_s32)(size))
256 
257 #define ADJUST_LOCAL_OFFSET(p, i) \
258 	if ((p) == (SLJIT_MEM1(SLJIT_SP))) \
259 		(i) += SLJIT_LOCALS_OFFSET;
260 
261 #endif /* !(defined SLJIT_CONFIG_UNSUPPORTED && SLJIT_CONFIG_UNSUPPORTED) */
262 
263 /* Utils can still be used even if SLJIT_CONFIG_UNSUPPORTED is set. */
264 #include "sljitUtils.c"
265 
266 #if !(defined SLJIT_CONFIG_UNSUPPORTED && SLJIT_CONFIG_UNSUPPORTED)
267 
268 #if (defined SLJIT_EXECUTABLE_ALLOCATOR && SLJIT_EXECUTABLE_ALLOCATOR)
269 
270 #if (defined SLJIT_PROT_EXECUTABLE_ALLOCATOR && SLJIT_PROT_EXECUTABLE_ALLOCATOR)
271 #include "sljitProtExecAllocator.c"
272 #elif (defined SLJIT_WX_EXECUTABLE_ALLOCATOR && SLJIT_WX_EXECUTABLE_ALLOCATOR)
273 #include "sljitWXExecAllocator.c"
274 #else
275 #include "sljitExecAllocator.c"
276 #endif
277 
278 #endif
279 
280 #if (defined SLJIT_PROT_EXECUTABLE_ALLOCATOR && SLJIT_PROT_EXECUTABLE_ALLOCATOR)
281 #define SLJIT_ADD_EXEC_OFFSET(ptr, exec_offset) ((sljit_u8 *)(ptr) + (exec_offset))
282 #else
283 #define SLJIT_ADD_EXEC_OFFSET(ptr, exec_offset) ((sljit_u8 *)(ptr))
284 #endif
285 
286 #ifndef SLJIT_UPDATE_WX_FLAGS
287 #define SLJIT_UPDATE_WX_FLAGS(from, to, enable_exec)
288 #endif
289 
290 /* Argument checking features. */
291 
292 #if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
293 
294 /* Returns with error when an invalid argument is passed. */
295 
296 #define CHECK_ARGUMENT(x) \
297 	do { \
298 		if (SLJIT_UNLIKELY(!(x))) \
299 			return 1; \
300 	} while (0)
301 
302 #define CHECK_RETURN_TYPE sljit_s32
303 #define CHECK_RETURN_OK return 0
304 
305 #define CHECK(x) \
306 	do { \
307 		if (SLJIT_UNLIKELY(x)) { \
308 			compiler->error = SLJIT_ERR_BAD_ARGUMENT; \
309 			return SLJIT_ERR_BAD_ARGUMENT; \
310 		} \
311 	} while (0)
312 
313 #define CHECK_PTR(x) \
314 	do { \
315 		if (SLJIT_UNLIKELY(x)) { \
316 			compiler->error = SLJIT_ERR_BAD_ARGUMENT; \
317 			return NULL; \
318 		} \
319 	} while (0)
320 
321 #define CHECK_REG_INDEX(x) \
322 	do { \
323 		if (SLJIT_UNLIKELY(x)) { \
324 			return -2; \
325 		} \
326 	} while (0)
327 
328 #elif (defined SLJIT_DEBUG && SLJIT_DEBUG)
329 
330 /* Assertion failure occures if an invalid argument is passed. */
331 #undef SLJIT_ARGUMENT_CHECKS
332 #define SLJIT_ARGUMENT_CHECKS 1
333 
334 #define CHECK_ARGUMENT(x) SLJIT_ASSERT(x)
335 #define CHECK_RETURN_TYPE void
336 #define CHECK_RETURN_OK return
337 #define CHECK(x) x
338 #define CHECK_PTR(x) x
339 #define CHECK_REG_INDEX(x) x
340 
341 #elif (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
342 
343 /* Arguments are not checked. */
344 #define CHECK_RETURN_TYPE void
345 #define CHECK_RETURN_OK return
346 #define CHECK(x) x
347 #define CHECK_PTR(x) x
348 #define CHECK_REG_INDEX(x) x
349 
350 #else
351 
352 /* Arguments are not checked. */
353 #define CHECK(x)
354 #define CHECK_PTR(x)
355 #define CHECK_REG_INDEX(x)
356 
357 #endif /* SLJIT_ARGUMENT_CHECKS */
358 
359 /* --------------------------------------------------------------------- */
360 /*  Public functions                                                     */
361 /* --------------------------------------------------------------------- */
362 
363 #if (defined SLJIT_CONFIG_X86 && SLJIT_CONFIG_X86)
364 #define SLJIT_NEEDS_COMPILER_INIT 1
365 static sljit_s32 compiler_initialized = 0;
366 /* A thread safe initialization. */
367 static void init_compiler(void);
368 #endif
369 
sljit_create_compiler(void * allocator_data,void * exec_allocator_data)370 SLJIT_API_FUNC_ATTRIBUTE struct sljit_compiler* sljit_create_compiler(void *allocator_data, void *exec_allocator_data)
371 {
372 	struct sljit_compiler *compiler = (struct sljit_compiler*)SLJIT_MALLOC(sizeof(struct sljit_compiler), allocator_data);
373 	if (!compiler)
374 		return NULL;
375 	SLJIT_ZEROMEM(compiler, sizeof(struct sljit_compiler));
376 
377 	SLJIT_COMPILE_ASSERT(
378 		sizeof(sljit_s8) == 1 && sizeof(sljit_u8) == 1
379 		&& sizeof(sljit_s16) == 2 && sizeof(sljit_u16) == 2
380 		&& sizeof(sljit_s32) == 4 && sizeof(sljit_u32) == 4
381 		&& (sizeof(sljit_p) == 4 || sizeof(sljit_p) == 8)
382 		&& sizeof(sljit_p) <= sizeof(sljit_sw)
383 		&& (sizeof(sljit_sw) == 4 || sizeof(sljit_sw) == 8)
384 		&& (sizeof(sljit_uw) == 4 || sizeof(sljit_uw) == 8),
385 		invalid_integer_types);
386 	SLJIT_COMPILE_ASSERT(SLJIT_REWRITABLE_JUMP != SLJIT_32,
387 		rewritable_jump_and_single_op_must_not_be_the_same);
388 	SLJIT_COMPILE_ASSERT(!(SLJIT_EQUAL & 0x1) && !(SLJIT_LESS & 0x1) && !(SLJIT_EQUAL_F64 & 0x1) && !(SLJIT_JUMP & 0x1),
389 		conditional_flags_must_be_even_numbers);
390 
391 	/* Only the non-zero members must be set. */
392 	compiler->error = SLJIT_SUCCESS;
393 
394 	compiler->allocator_data = allocator_data;
395 	compiler->exec_allocator_data = exec_allocator_data;
396 	compiler->buf = (struct sljit_memory_fragment*)SLJIT_MALLOC(BUF_SIZE, allocator_data);
397 	compiler->abuf = (struct sljit_memory_fragment*)SLJIT_MALLOC(ABUF_SIZE, allocator_data);
398 
399 	if (!compiler->buf || !compiler->abuf) {
400 		if (compiler->buf)
401 			SLJIT_FREE(compiler->buf, allocator_data);
402 		if (compiler->abuf)
403 			SLJIT_FREE(compiler->abuf, allocator_data);
404 		SLJIT_FREE(compiler, allocator_data);
405 		return NULL;
406 	}
407 
408 	compiler->buf->next = NULL;
409 	compiler->buf->used_size = 0;
410 	compiler->abuf->next = NULL;
411 	compiler->abuf->used_size = 0;
412 
413 	compiler->scratches = -1;
414 	compiler->saveds = -1;
415 	compiler->fscratches = -1;
416 	compiler->fsaveds = -1;
417 	compiler->local_size = -1;
418 
419 #if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
420 	compiler->args_size = -1;
421 #endif
422 
423 #if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5)
424 	compiler->cpool = (sljit_uw*)SLJIT_MALLOC(CPOOL_SIZE * sizeof(sljit_uw)
425 		+ CPOOL_SIZE * sizeof(sljit_u8), allocator_data);
426 	if (!compiler->cpool) {
427 		SLJIT_FREE(compiler->buf, allocator_data);
428 		SLJIT_FREE(compiler->abuf, allocator_data);
429 		SLJIT_FREE(compiler, allocator_data);
430 		return NULL;
431 	}
432 	compiler->cpool_unique = (sljit_u8*)(compiler->cpool + CPOOL_SIZE);
433 	compiler->cpool_diff = 0xffffffff;
434 #endif
435 
436 #if (defined SLJIT_CONFIG_MIPS && SLJIT_CONFIG_MIPS)
437 	compiler->delay_slot = UNMOVABLE_INS;
438 #endif
439 
440 #if (defined SLJIT_CONFIG_SPARC_32 && SLJIT_CONFIG_SPARC_32)
441 	compiler->delay_slot = UNMOVABLE_INS;
442 #endif
443 
444 #if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS) \
445 		|| (defined SLJIT_DEBUG && SLJIT_DEBUG)
446 	compiler->last_flags = 0;
447 	compiler->last_return = -1;
448 	compiler->logical_local_size = 0;
449 #endif
450 
451 #if (defined SLJIT_NEEDS_COMPILER_INIT && SLJIT_NEEDS_COMPILER_INIT)
452 	if (!compiler_initialized) {
453 		init_compiler();
454 		compiler_initialized = 1;
455 	}
456 #endif
457 
458 	return compiler;
459 }
460 
sljit_free_compiler(struct sljit_compiler * compiler)461 SLJIT_API_FUNC_ATTRIBUTE void sljit_free_compiler(struct sljit_compiler *compiler)
462 {
463 	struct sljit_memory_fragment *buf;
464 	struct sljit_memory_fragment *curr;
465 	void *allocator_data = compiler->allocator_data;
466 	SLJIT_UNUSED_ARG(allocator_data);
467 
468 	buf = compiler->buf;
469 	while (buf) {
470 		curr = buf;
471 		buf = buf->next;
472 		SLJIT_FREE(curr, allocator_data);
473 	}
474 
475 	buf = compiler->abuf;
476 	while (buf) {
477 		curr = buf;
478 		buf = buf->next;
479 		SLJIT_FREE(curr, allocator_data);
480 	}
481 
482 #if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5)
483 	SLJIT_FREE(compiler->cpool, allocator_data);
484 #endif
485 	SLJIT_FREE(compiler, allocator_data);
486 }
487 
sljit_set_compiler_memory_error(struct sljit_compiler * compiler)488 SLJIT_API_FUNC_ATTRIBUTE void sljit_set_compiler_memory_error(struct sljit_compiler *compiler)
489 {
490 	if (compiler->error == SLJIT_SUCCESS)
491 		compiler->error = SLJIT_ERR_ALLOC_FAILED;
492 }
493 
494 #if (defined SLJIT_CONFIG_ARM_THUMB2 && SLJIT_CONFIG_ARM_THUMB2)
sljit_free_code(void * code,void * exec_allocator_data)495 SLJIT_API_FUNC_ATTRIBUTE void sljit_free_code(void* code, void *exec_allocator_data)
496 {
497 	SLJIT_UNUSED_ARG(exec_allocator_data);
498 
499 	/* Remove thumb mode flag. */
500 	SLJIT_FREE_EXEC((void*)((sljit_uw)code & ~(sljit_uw)0x1), exec_allocator_data);
501 }
502 #elif (defined SLJIT_INDIRECT_CALL && SLJIT_INDIRECT_CALL)
sljit_free_code(void * code,void * exec_allocator_data)503 SLJIT_API_FUNC_ATTRIBUTE void sljit_free_code(void* code, void *exec_allocator_data)
504 {
505 	SLJIT_UNUSED_ARG(exec_allocator_data);
506 
507 	/* Resolve indirection. */
508 	code = (void*)(*(sljit_uw*)code);
509 	SLJIT_FREE_EXEC(code, exec_allocator_data);
510 }
511 #else
sljit_free_code(void * code,void * exec_allocator_data)512 SLJIT_API_FUNC_ATTRIBUTE void sljit_free_code(void* code, void *exec_allocator_data)
513 {
514 	SLJIT_UNUSED_ARG(exec_allocator_data);
515 
516 	SLJIT_FREE_EXEC(code, exec_allocator_data);
517 }
518 #endif
519 
sljit_set_label(struct sljit_jump * jump,struct sljit_label * label)520 SLJIT_API_FUNC_ATTRIBUTE void sljit_set_label(struct sljit_jump *jump, struct sljit_label* label)
521 {
522 	if (SLJIT_LIKELY(!!jump) && SLJIT_LIKELY(!!label)) {
523 		jump->flags &= (sljit_uw)~JUMP_ADDR;
524 		jump->flags |= JUMP_LABEL;
525 		jump->u.label = label;
526 	}
527 }
528 
sljit_set_target(struct sljit_jump * jump,sljit_uw target)529 SLJIT_API_FUNC_ATTRIBUTE void sljit_set_target(struct sljit_jump *jump, sljit_uw target)
530 {
531 	if (SLJIT_LIKELY(!!jump)) {
532 		jump->flags &= (sljit_uw)~JUMP_LABEL;
533 		jump->flags |= JUMP_ADDR;
534 		jump->u.target = target;
535 	}
536 }
537 
sljit_set_put_label(struct sljit_put_label * put_label,struct sljit_label * label)538 SLJIT_API_FUNC_ATTRIBUTE void sljit_set_put_label(struct sljit_put_label *put_label, struct sljit_label *label)
539 {
540 	if (SLJIT_LIKELY(!!put_label))
541 		put_label->label = label;
542 }
543 
544 #define SLJIT_CURRENT_FLAGS_ALL \
545 	(SLJIT_CURRENT_FLAGS_32 | SLJIT_CURRENT_FLAGS_ADD | SLJIT_CURRENT_FLAGS_SUB | SLJIT_CURRENT_FLAGS_COMPARE)
546 
sljit_set_current_flags(struct sljit_compiler * compiler,sljit_s32 current_flags)547 SLJIT_API_FUNC_ATTRIBUTE void sljit_set_current_flags(struct sljit_compiler *compiler, sljit_s32 current_flags)
548 {
549 	SLJIT_UNUSED_ARG(compiler);
550 	SLJIT_UNUSED_ARG(current_flags);
551 
552 #if (defined SLJIT_HAS_STATUS_FLAGS_STATE && SLJIT_HAS_STATUS_FLAGS_STATE)
553 	compiler->status_flags_state = current_flags;
554 #endif
555 
556 #if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
557 	compiler->last_flags = 0;
558 	if ((current_flags & ~(VARIABLE_FLAG_MASK | SLJIT_SET_Z | SLJIT_CURRENT_FLAGS_ALL)) == 0) {
559 		compiler->last_flags = GET_FLAG_TYPE(current_flags) | (current_flags & (SLJIT_32 | SLJIT_SET_Z));
560 	}
561 #endif
562 }
563 
564 /* --------------------------------------------------------------------- */
565 /*  Private functions                                                    */
566 /* --------------------------------------------------------------------- */
567 
ensure_buf(struct sljit_compiler * compiler,sljit_uw size)568 static void* ensure_buf(struct sljit_compiler *compiler, sljit_uw size)
569 {
570 	sljit_u8 *ret;
571 	struct sljit_memory_fragment *new_frag;
572 
573 	SLJIT_ASSERT(size <= 256);
574 	if (compiler->buf->used_size + size <= (BUF_SIZE - (sljit_uw)SLJIT_OFFSETOF(struct sljit_memory_fragment, memory))) {
575 		ret = compiler->buf->memory + compiler->buf->used_size;
576 		compiler->buf->used_size += size;
577 		return ret;
578 	}
579 	new_frag = (struct sljit_memory_fragment*)SLJIT_MALLOC(BUF_SIZE, compiler->allocator_data);
580 	PTR_FAIL_IF_NULL(new_frag);
581 	new_frag->next = compiler->buf;
582 	compiler->buf = new_frag;
583 	new_frag->used_size = size;
584 	return new_frag->memory;
585 }
586 
ensure_abuf(struct sljit_compiler * compiler,sljit_uw size)587 static void* ensure_abuf(struct sljit_compiler *compiler, sljit_uw size)
588 {
589 	sljit_u8 *ret;
590 	struct sljit_memory_fragment *new_frag;
591 
592 	SLJIT_ASSERT(size <= 256);
593 	if (compiler->abuf->used_size + size <= (ABUF_SIZE - (sljit_uw)SLJIT_OFFSETOF(struct sljit_memory_fragment, memory))) {
594 		ret = compiler->abuf->memory + compiler->abuf->used_size;
595 		compiler->abuf->used_size += size;
596 		return ret;
597 	}
598 	new_frag = (struct sljit_memory_fragment*)SLJIT_MALLOC(ABUF_SIZE, compiler->allocator_data);
599 	PTR_FAIL_IF_NULL(new_frag);
600 	new_frag->next = compiler->abuf;
601 	compiler->abuf = new_frag;
602 	new_frag->used_size = size;
603 	return new_frag->memory;
604 }
605 
sljit_alloc_memory(struct sljit_compiler * compiler,sljit_s32 size)606 SLJIT_API_FUNC_ATTRIBUTE void* sljit_alloc_memory(struct sljit_compiler *compiler, sljit_s32 size)
607 {
608 	CHECK_ERROR_PTR();
609 
610 #if (defined SLJIT_64BIT_ARCHITECTURE && SLJIT_64BIT_ARCHITECTURE)
611 	if (size <= 0 || size > 128)
612 		return NULL;
613 	size = (size + 7) & ~7;
614 #else
615 	if (size <= 0 || size > 64)
616 		return NULL;
617 	size = (size + 3) & ~3;
618 #endif
619 	return ensure_abuf(compiler, (sljit_uw)size);
620 }
621 
reverse_buf(struct sljit_compiler * compiler)622 static SLJIT_INLINE void reverse_buf(struct sljit_compiler *compiler)
623 {
624 	struct sljit_memory_fragment *buf = compiler->buf;
625 	struct sljit_memory_fragment *prev = NULL;
626 	struct sljit_memory_fragment *tmp;
627 
628 	do {
629 		tmp = buf->next;
630 		buf->next = prev;
631 		prev = buf;
632 		buf = tmp;
633 	} while (buf != NULL);
634 
635 	compiler->buf = prev;
636 }
637 
638 /* Only used in RISC architectures where the instruction size is constant */
639 #if !(defined SLJIT_CONFIG_X86 && SLJIT_CONFIG_X86) \
640 	&& !(defined SLJIT_CONFIG_S390X && SLJIT_CONFIG_S390X)
641 
compute_next_addr(struct sljit_label * label,struct sljit_jump * jump,struct sljit_const * const_,struct sljit_put_label * put_label)642 static SLJIT_INLINE sljit_uw compute_next_addr(struct sljit_label *label, struct sljit_jump *jump,
643 	struct sljit_const *const_, struct sljit_put_label *put_label)
644 {
645 	sljit_uw result = ~(sljit_uw)0;
646 
647 	if (label)
648 		result = label->size;
649 
650 	if (jump && jump->addr < result)
651 		result = jump->addr;
652 
653 	if (const_ && const_->addr < result)
654 		result = const_->addr;
655 
656 	if (put_label && put_label->addr < result)
657 		result = put_label->addr;
658 
659 	return result;
660 }
661 
662 #endif /* !SLJIT_CONFIG_X86 && !SLJIT_CONFIG_S390X */
663 
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)664 static SLJIT_INLINE void set_emit_enter(struct sljit_compiler *compiler,
665 	sljit_s32 options, sljit_s32 args, sljit_s32 scratches, sljit_s32 saveds,
666 	sljit_s32 fscratches, sljit_s32 fsaveds, sljit_s32 local_size)
667 {
668 	SLJIT_UNUSED_ARG(args);
669 	SLJIT_UNUSED_ARG(local_size);
670 
671 	compiler->options = options;
672 	compiler->scratches = scratches;
673 	compiler->saveds = saveds;
674 	compiler->fscratches = fscratches;
675 	compiler->fsaveds = fsaveds;
676 #if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
677 	compiler->last_return = args & SLJIT_ARG_MASK;
678 	compiler->logical_local_size = local_size;
679 #endif
680 }
681 
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)682 static SLJIT_INLINE void set_set_context(struct sljit_compiler *compiler,
683 	sljit_s32 options, sljit_s32 args, sljit_s32 scratches, sljit_s32 saveds,
684 	sljit_s32 fscratches, sljit_s32 fsaveds, sljit_s32 local_size)
685 {
686 	SLJIT_UNUSED_ARG(args);
687 	SLJIT_UNUSED_ARG(local_size);
688 
689 	compiler->options = options;
690 	compiler->scratches = scratches;
691 	compiler->saveds = saveds;
692 	compiler->fscratches = fscratches;
693 	compiler->fsaveds = fsaveds;
694 #if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
695 	compiler->last_return = args & SLJIT_ARG_MASK;
696 	compiler->logical_local_size = local_size;
697 #endif
698 }
699 
set_label(struct sljit_label * label,struct sljit_compiler * compiler)700 static SLJIT_INLINE void set_label(struct sljit_label *label, struct sljit_compiler *compiler)
701 {
702 	label->next = NULL;
703 	label->size = compiler->size;
704 	if (compiler->last_label)
705 		compiler->last_label->next = label;
706 	else
707 		compiler->labels = label;
708 	compiler->last_label = label;
709 }
710 
set_jump(struct sljit_jump * jump,struct sljit_compiler * compiler,sljit_u32 flags)711 static SLJIT_INLINE void set_jump(struct sljit_jump *jump, struct sljit_compiler *compiler, sljit_u32 flags)
712 {
713 	jump->next = NULL;
714 	jump->flags = flags;
715 	if (compiler->last_jump)
716 		compiler->last_jump->next = jump;
717 	else
718 		compiler->jumps = jump;
719 	compiler->last_jump = jump;
720 }
721 
set_const(struct sljit_const * const_,struct sljit_compiler * compiler)722 static SLJIT_INLINE void set_const(struct sljit_const *const_, struct sljit_compiler *compiler)
723 {
724 	const_->next = NULL;
725 	const_->addr = compiler->size;
726 	if (compiler->last_const)
727 		compiler->last_const->next = const_;
728 	else
729 		compiler->consts = const_;
730 	compiler->last_const = const_;
731 }
732 
set_put_label(struct sljit_put_label * put_label,struct sljit_compiler * compiler,sljit_uw offset)733 static SLJIT_INLINE void set_put_label(struct sljit_put_label *put_label, struct sljit_compiler *compiler, sljit_uw offset)
734 {
735 	put_label->next = NULL;
736 	put_label->label = NULL;
737 	put_label->addr = compiler->size - offset;
738 	put_label->flags = 0;
739 	if (compiler->last_put_label)
740 		compiler->last_put_label->next = put_label;
741 	else
742 		compiler->put_labels = put_label;
743 	compiler->last_put_label = put_label;
744 }
745 
746 #define ADDRESSING_DEPENDS_ON(exp, reg) \
747 	(((exp) & SLJIT_MEM) && (((exp) & REG_MASK) == reg || OFFS_REG(exp) == reg))
748 
749 #if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
750 
function_check_arguments(sljit_s32 arg_types,sljit_s32 scratches,sljit_s32 saveds,sljit_s32 fscratches)751 static sljit_s32 function_check_arguments(sljit_s32 arg_types, sljit_s32 scratches, sljit_s32 saveds, sljit_s32 fscratches)
752 {
753 	sljit_s32 word_arg_count, scratch_arg_end, saved_arg_count, float_arg_count, curr_type;
754 
755 	curr_type = (arg_types & SLJIT_ARG_FULL_MASK);
756 
757 	if (curr_type >= SLJIT_ARG_TYPE_F64) {
758 		if (curr_type > SLJIT_ARG_TYPE_F32 || fscratches == 0)
759 			return 0;
760 	} else if (curr_type >= SLJIT_ARG_TYPE_W) {
761 		if (scratches == 0)
762 			return 0;
763 	}
764 
765 	arg_types >>= SLJIT_ARG_SHIFT;
766 
767 	word_arg_count = 0;
768 	scratch_arg_end = 0;
769 	saved_arg_count = 0;
770 	float_arg_count = 0;
771 	while (arg_types != 0) {
772 		if (word_arg_count + float_arg_count >= 4)
773 			return 0;
774 
775 		curr_type = (arg_types & SLJIT_ARG_MASK);
776 
777 		if (arg_types & SLJIT_ARG_TYPE_SCRATCH_REG) {
778 			if (saveds == -1 || curr_type < SLJIT_ARG_TYPE_W || curr_type > SLJIT_ARG_TYPE_P)
779 				return 0;
780 
781 			word_arg_count++;
782 			scratch_arg_end = word_arg_count;
783 		} else {
784 			if (curr_type < SLJIT_ARG_TYPE_W || curr_type > SLJIT_ARG_TYPE_F32)
785 				return 0;
786 
787 			if (curr_type < SLJIT_ARG_TYPE_F64) {
788 				word_arg_count++;
789 				saved_arg_count++;
790 			} else
791 				float_arg_count++;
792 		}
793 
794 		arg_types >>= SLJIT_ARG_SHIFT;
795 	}
796 
797 	if (saveds == -1)
798 		return (word_arg_count <= scratches && float_arg_count <= fscratches);
799 
800 	return (saved_arg_count <= saveds && scratch_arg_end <= scratches && float_arg_count <= fscratches);
801 }
802 
803 #define FUNCTION_CHECK_IS_REG(r) \
804 	(((r) >= SLJIT_R0 && (r) < (SLJIT_R0 + compiler->scratches)) \
805 	|| ((r) > (SLJIT_S0 - compiler->saveds) && (r) <= SLJIT_S0))
806 
807 #define FUNCTION_CHECK_IS_FREG(fr) \
808 	(((fr) >= SLJIT_FR0 && (fr) < (SLJIT_FR0 + compiler->fscratches)) \
809 	|| ((fr) > (SLJIT_FS0 - compiler->fsaveds) && (fr) <= SLJIT_FS0))
810 
811 #if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
812 #define CHECK_IF_VIRTUAL_REGISTER(p) ((p) <= SLJIT_S3 && (p) >= SLJIT_S8)
813 #else
814 #define CHECK_IF_VIRTUAL_REGISTER(p) 0
815 #endif
816 
function_check_src_mem(struct sljit_compiler * compiler,sljit_s32 p,sljit_sw i)817 static sljit_s32 function_check_src_mem(struct sljit_compiler *compiler, sljit_s32 p, sljit_sw i)
818 {
819 	if (compiler->scratches == -1 || compiler->saveds == -1)
820 		return 0;
821 
822 	if (!(p & SLJIT_MEM))
823 		return 0;
824 
825 	if (!(!(p & REG_MASK) || FUNCTION_CHECK_IS_REG(p & REG_MASK)))
826 		return 0;
827 
828 	if (CHECK_IF_VIRTUAL_REGISTER(p & REG_MASK))
829 		return 0;
830 
831 	if (p & OFFS_REG_MASK) {
832 		if (!(p & REG_MASK))
833 			return 0;
834 
835 		if (!(FUNCTION_CHECK_IS_REG(OFFS_REG(p))))
836 			return 0;
837 
838 		if (CHECK_IF_VIRTUAL_REGISTER(OFFS_REG(p)))
839 			return 0;
840 
841 		if ((i & ~0x3) != 0)
842 			return 0;
843 	}
844 
845 	return (p & ~(SLJIT_MEM | REG_MASK | OFFS_REG_MASK)) == 0;
846 }
847 
848 #define FUNCTION_CHECK_SRC_MEM(p, i) \
849 	CHECK_ARGUMENT(function_check_src_mem(compiler, p, i));
850 
function_check_src(struct sljit_compiler * compiler,sljit_s32 p,sljit_sw i)851 static sljit_s32 function_check_src(struct sljit_compiler *compiler, sljit_s32 p, sljit_sw i)
852 {
853 	if (compiler->scratches == -1 || compiler->saveds == -1)
854 		return 0;
855 
856 	if (FUNCTION_CHECK_IS_REG(p))
857 		return (i == 0);
858 
859 	if (p == SLJIT_IMM)
860 		return 1;
861 
862 	if (p == SLJIT_MEM1(SLJIT_SP))
863 		return (i >= 0 && i < compiler->logical_local_size);
864 
865 	return function_check_src_mem(compiler, p, i);
866 }
867 
868 #define FUNCTION_CHECK_SRC(p, i) \
869 	CHECK_ARGUMENT(function_check_src(compiler, p, i));
870 
function_check_dst(struct sljit_compiler * compiler,sljit_s32 p,sljit_sw i)871 static sljit_s32 function_check_dst(struct sljit_compiler *compiler, sljit_s32 p, sljit_sw i)
872 {
873 	if (compiler->scratches == -1 || compiler->saveds == -1)
874 		return 0;
875 
876 	if (FUNCTION_CHECK_IS_REG(p))
877 		return (i == 0);
878 
879 	if (p == SLJIT_MEM1(SLJIT_SP))
880 		return (i >= 0 && i < compiler->logical_local_size);
881 
882 	return function_check_src_mem(compiler, p, i);
883 }
884 
885 #define FUNCTION_CHECK_DST(p, i) \
886 	CHECK_ARGUMENT(function_check_dst(compiler, p, i));
887 
function_fcheck(struct sljit_compiler * compiler,sljit_s32 p,sljit_sw i)888 static sljit_s32 function_fcheck(struct sljit_compiler *compiler, sljit_s32 p, sljit_sw i)
889 {
890 	if (compiler->scratches == -1 || compiler->saveds == -1)
891 		return 0;
892 
893 	if (FUNCTION_CHECK_IS_FREG(p))
894 		return (i == 0);
895 
896 	if (p == SLJIT_MEM1(SLJIT_SP))
897 		return (i >= 0 && i < compiler->logical_local_size);
898 
899 	return function_check_src_mem(compiler, p, i);
900 }
901 
902 #define FUNCTION_FCHECK(p, i) \
903 	CHECK_ARGUMENT(function_fcheck(compiler, p, i));
904 
905 #endif /* SLJIT_ARGUMENT_CHECKS */
906 
907 #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
908 
sljit_compiler_verbose(struct sljit_compiler * compiler,FILE * verbose)909 SLJIT_API_FUNC_ATTRIBUTE void sljit_compiler_verbose(struct sljit_compiler *compiler, FILE* verbose)
910 {
911 	compiler->verbose = verbose;
912 }
913 
914 #if (defined SLJIT_64BIT_ARCHITECTURE && SLJIT_64BIT_ARCHITECTURE)
915 #ifdef _WIN64
916 #	define SLJIT_PRINT_D	"I64"
917 #else
918 #	define SLJIT_PRINT_D	"l"
919 #endif
920 #else
921 #	define SLJIT_PRINT_D	""
922 #endif
923 
sljit_verbose_reg(struct sljit_compiler * compiler,sljit_s32 r)924 static void sljit_verbose_reg(struct sljit_compiler *compiler, sljit_s32 r)
925 {
926 	if (r < (SLJIT_R0 + compiler->scratches))
927 		fprintf(compiler->verbose, "r%d", r - SLJIT_R0);
928 	else if (r != SLJIT_SP)
929 		fprintf(compiler->verbose, "s%d", SLJIT_NUMBER_OF_REGISTERS - r);
930 	else
931 		fprintf(compiler->verbose, "sp");
932 }
933 
sljit_verbose_freg(struct sljit_compiler * compiler,sljit_s32 r)934 static void sljit_verbose_freg(struct sljit_compiler *compiler, sljit_s32 r)
935 {
936 	if (r < (SLJIT_FR0 + compiler->fscratches))
937 		fprintf(compiler->verbose, "fr%d", r - SLJIT_FR0);
938 	else
939 		fprintf(compiler->verbose, "fs%d", SLJIT_NUMBER_OF_FLOAT_REGISTERS - r);
940 }
941 
sljit_verbose_param(struct sljit_compiler * compiler,sljit_s32 p,sljit_sw i)942 static void sljit_verbose_param(struct sljit_compiler *compiler, sljit_s32 p, sljit_sw i)
943 {
944 	if ((p) & SLJIT_IMM)
945 		fprintf(compiler->verbose, "#%" SLJIT_PRINT_D "d", (i));
946 	else if ((p) & SLJIT_MEM) {
947 		if ((p) & REG_MASK) {
948 			fputc('[', compiler->verbose);
949 			sljit_verbose_reg(compiler, (p) & REG_MASK);
950 			if ((p) & OFFS_REG_MASK) {
951 				fprintf(compiler->verbose, " + ");
952 				sljit_verbose_reg(compiler, OFFS_REG(p));
953 				if (i)
954 					fprintf(compiler->verbose, " * %d", 1 << (i));
955 			}
956 			else if (i)
957 				fprintf(compiler->verbose, " + %" SLJIT_PRINT_D "d", (i));
958 			fputc(']', compiler->verbose);
959 		}
960 		else
961 			fprintf(compiler->verbose, "[#%" SLJIT_PRINT_D "d]", (i));
962 	} else
963 		sljit_verbose_reg(compiler, p);
964 }
965 
sljit_verbose_fparam(struct sljit_compiler * compiler,sljit_s32 p,sljit_sw i)966 static void sljit_verbose_fparam(struct sljit_compiler *compiler, sljit_s32 p, sljit_sw i)
967 {
968 	if ((p) & SLJIT_MEM) {
969 		if ((p) & REG_MASK) {
970 			fputc('[', compiler->verbose);
971 			sljit_verbose_reg(compiler, (p) & REG_MASK);
972 			if ((p) & OFFS_REG_MASK) {
973 				fprintf(compiler->verbose, " + ");
974 				sljit_verbose_reg(compiler, OFFS_REG(p));
975 				if (i)
976 					fprintf(compiler->verbose, "%d", 1 << (i));
977 			}
978 			else if (i)
979 				fprintf(compiler->verbose, " + %" SLJIT_PRINT_D "d", (i));
980 			fputc(']', compiler->verbose);
981 		}
982 		else
983 			fprintf(compiler->verbose, "[#%" SLJIT_PRINT_D "d]", (i));
984 	}
985 	else
986 		sljit_verbose_freg(compiler, p);
987 }
988 
989 static const char* op0_names[] = {
990 	"breakpoint", "nop", "lmul.uw", "lmul.sw",
991 	"divmod.u", "divmod.s", "div.u", "div.s",
992 	"endbr", "skip_frames_before_return"
993 };
994 
995 static const char* op1_names[] = {
996 	"", ".u8", ".s8", ".u16",
997 	".s16", ".u32", ".s32", "32",
998 	".p", "not", "clz",
999 };
1000 
1001 static const char* op2_names[] = {
1002 	"add", "addc", "sub", "subc",
1003 	"mul", "and", "or", "xor",
1004 	"shl", "lshr", "ashr",
1005 };
1006 
1007 static const char* op_src_names[] = {
1008 	"fast_return", "skip_frames_before_fast_return",
1009 	"prefetch_l1", "prefetch_l2",
1010 	"prefetch_l3", "prefetch_once",
1011 };
1012 
1013 static const char* fop1_names[] = {
1014 	"mov", "conv", "conv", "conv",
1015 	"conv", "conv", "cmp", "neg",
1016 	"abs",
1017 };
1018 
1019 static const char* fop2_names[] = {
1020 	"add", "sub", "mul", "div"
1021 };
1022 
1023 #define JUMP_POSTFIX(type) \
1024 	((type & 0xff) <= SLJIT_NOT_OVERFLOW ? ((type & SLJIT_32) ? "32" : "") \
1025 	: ((type & 0xff) <= SLJIT_ORDERED_F64 ? ((type & SLJIT_32) ? ".f32" : ".f64") : ""))
1026 
1027 static const char* jump_names[] = {
1028 	"equal", "not_equal",
1029 	"less", "greater_equal",
1030 	"greater", "less_equal",
1031 	"sig_less", "sig_greater_equal",
1032 	"sig_greater", "sig_less_equal",
1033 	"overflow", "not_overflow",
1034 	"carry", "",
1035 	"equal", "not_equal",
1036 	"less", "greater_equal",
1037 	"greater", "less_equal",
1038 	"unordered", "ordered",
1039 	"jump", "fast_call",
1040 	"call", "call.cdecl"
1041 };
1042 
1043 static const char* call_arg_names[] = {
1044 	"void", "w", "32", "p", "f64", "f32"
1045 };
1046 
1047 #endif /* SLJIT_VERBOSE */
1048 
1049 /* --------------------------------------------------------------------- */
1050 /*  Arch dependent                                                       */
1051 /* --------------------------------------------------------------------- */
1052 
1053 #if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS) \
1054 	|| (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
1055 
check_sljit_generate_code(struct sljit_compiler * compiler)1056 static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_generate_code(struct sljit_compiler *compiler)
1057 {
1058 #if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
1059 	struct sljit_jump *jump;
1060 #endif
1061 
1062 	SLJIT_UNUSED_ARG(compiler);
1063 
1064 #if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
1065 	CHECK_ARGUMENT(compiler->size > 0);
1066 	jump = compiler->jumps;
1067 	while (jump) {
1068 		/* All jumps have target. */
1069 		CHECK_ARGUMENT(jump->flags & (JUMP_LABEL | JUMP_ADDR));
1070 		jump = jump->next;
1071 	}
1072 #endif
1073 	CHECK_RETURN_OK;
1074 }
1075 
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)1076 static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_enter(struct sljit_compiler *compiler,
1077 	sljit_s32 options, sljit_s32 arg_types, sljit_s32 scratches, sljit_s32 saveds,
1078 	sljit_s32 fscratches, sljit_s32 fsaveds, sljit_s32 local_size)
1079 {
1080 	SLJIT_UNUSED_ARG(compiler);
1081 
1082 #if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
1083 	CHECK_ARGUMENT(!(options & ~SLJIT_ENTER_CDECL));
1084 	CHECK_ARGUMENT(scratches >= 0 && scratches <= SLJIT_NUMBER_OF_REGISTERS);
1085 	CHECK_ARGUMENT(saveds >= 0 && saveds <= SLJIT_NUMBER_OF_SAVED_REGISTERS);
1086 	CHECK_ARGUMENT(scratches + saveds <= SLJIT_NUMBER_OF_REGISTERS);
1087 	CHECK_ARGUMENT(fscratches >= 0 && fscratches <= SLJIT_NUMBER_OF_FLOAT_REGISTERS);
1088 	CHECK_ARGUMENT(fsaveds >= 0 && fsaveds <= SLJIT_NUMBER_OF_SAVED_FLOAT_REGISTERS);
1089 	CHECK_ARGUMENT(fscratches + fsaveds <= SLJIT_NUMBER_OF_FLOAT_REGISTERS);
1090 	CHECK_ARGUMENT(local_size >= 0 && local_size <= SLJIT_MAX_LOCAL_SIZE);
1091 	CHECK_ARGUMENT((arg_types & SLJIT_ARG_FULL_MASK) < SLJIT_ARG_TYPE_F64);
1092 	CHECK_ARGUMENT(function_check_arguments(arg_types, scratches, saveds, fscratches));
1093 
1094 	compiler->last_flags = 0;
1095 #endif
1096 #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
1097 	if (SLJIT_UNLIKELY(!!compiler->verbose)) {
1098 		fprintf(compiler->verbose, "  enter ret[%s", call_arg_names[arg_types & SLJIT_ARG_MASK]);
1099 
1100 		arg_types >>= SLJIT_ARG_SHIFT;
1101 		if (arg_types) {
1102 			fprintf(compiler->verbose, "], args[");
1103 			do {
1104 				fprintf(compiler->verbose, "%s%s", call_arg_names[arg_types & SLJIT_ARG_MASK],
1105 					(arg_types & SLJIT_ARG_TYPE_SCRATCH_REG) ? "_r" : "");
1106 				arg_types >>= SLJIT_ARG_SHIFT;
1107 				if (arg_types)
1108 					fprintf(compiler->verbose, ",");
1109 			} while (arg_types);
1110 		}
1111 
1112 		fprintf(compiler->verbose, "],%s scratches:%d, saveds:%d, fscratches:%d, fsaveds:%d, local_size:%d\n",
1113 			(options & SLJIT_ENTER_CDECL) ? " enter:cdecl," : "",
1114 			scratches, saveds, fscratches, fsaveds, local_size);
1115 	}
1116 #endif
1117 	CHECK_RETURN_OK;
1118 }
1119 
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)1120 static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_set_context(struct sljit_compiler *compiler,
1121 	sljit_s32 options, sljit_s32 arg_types, sljit_s32 scratches, sljit_s32 saveds,
1122 	sljit_s32 fscratches, sljit_s32 fsaveds, sljit_s32 local_size)
1123 {
1124 	SLJIT_UNUSED_ARG(compiler);
1125 
1126 #if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
1127 	CHECK_ARGUMENT(!(options & ~SLJIT_ENTER_CDECL));
1128 	CHECK_ARGUMENT(scratches >= 0 && scratches <= SLJIT_NUMBER_OF_REGISTERS);
1129 	CHECK_ARGUMENT(saveds >= 0 && saveds <= SLJIT_NUMBER_OF_SAVED_REGISTERS);
1130 	CHECK_ARGUMENT(scratches + saveds <= SLJIT_NUMBER_OF_REGISTERS);
1131 	CHECK_ARGUMENT(fscratches >= 0 && fscratches <= SLJIT_NUMBER_OF_FLOAT_REGISTERS);
1132 	CHECK_ARGUMENT(fsaveds >= 0 && fsaveds <= SLJIT_NUMBER_OF_SAVED_FLOAT_REGISTERS);
1133 	CHECK_ARGUMENT(fscratches + fsaveds <= SLJIT_NUMBER_OF_FLOAT_REGISTERS);
1134 	CHECK_ARGUMENT(local_size >= 0 && local_size <= SLJIT_MAX_LOCAL_SIZE);
1135 	CHECK_ARGUMENT((arg_types & SLJIT_ARG_FULL_MASK) < SLJIT_ARG_TYPE_F64);
1136 	CHECK_ARGUMENT(function_check_arguments(arg_types, scratches, saveds, fscratches));
1137 
1138 	compiler->last_flags = 0;
1139 #endif
1140 #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
1141 	if (SLJIT_UNLIKELY(!!compiler->verbose)) {
1142 		fprintf(compiler->verbose, "  set_context ret[%s", call_arg_names[arg_types & SLJIT_ARG_MASK]);
1143 
1144 		arg_types >>= SLJIT_ARG_SHIFT;
1145 		if (arg_types) {
1146 			fprintf(compiler->verbose, "], args[");
1147 			do {
1148 				fprintf(compiler->verbose, "%s%s", call_arg_names[arg_types & SLJIT_ARG_MASK],
1149 					(arg_types & SLJIT_ARG_TYPE_SCRATCH_REG) ? "_r" : "");
1150 				arg_types >>= SLJIT_ARG_SHIFT;
1151 				if (arg_types)
1152 					fprintf(compiler->verbose, ",");
1153 			} while (arg_types);
1154 		}
1155 
1156 		fprintf(compiler->verbose, "],%s scratches:%d, saveds:%d, fscratches:%d, fsaveds:%d, local_size:%d\n",
1157 			(options & SLJIT_ENTER_CDECL) ? " enter:cdecl," : "",
1158 			scratches, saveds, fscratches, fsaveds, local_size);
1159 	}
1160 #endif
1161 	CHECK_RETURN_OK;
1162 }
1163 
check_sljit_emit_return_void(struct sljit_compiler * compiler)1164 static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_return_void(struct sljit_compiler *compiler)
1165 {
1166 	if (SLJIT_UNLIKELY(compiler->skip_checks)) {
1167 		compiler->skip_checks = 0;
1168 		CHECK_RETURN_OK;
1169 	}
1170 
1171 #if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
1172 	CHECK_ARGUMENT(compiler->last_return == SLJIT_ARG_TYPE_VOID);
1173 #endif
1174 
1175 #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
1176 	if (SLJIT_UNLIKELY(!!compiler->verbose)) {
1177 		fprintf(compiler->verbose, "  return_void\n");
1178 	}
1179 #endif
1180 	CHECK_RETURN_OK;
1181 }
1182 
check_sljit_emit_return(struct sljit_compiler * compiler,sljit_s32 op,sljit_s32 src,sljit_sw srcw)1183 static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_return(struct sljit_compiler *compiler, sljit_s32 op, sljit_s32 src, sljit_sw srcw)
1184 {
1185 #if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
1186 	CHECK_ARGUMENT(compiler->scratches >= 0);
1187 
1188 	switch (compiler->last_return) {
1189 	case SLJIT_ARG_TYPE_W:
1190 		CHECK_ARGUMENT(op >= SLJIT_MOV && op <= SLJIT_MOV_S32);
1191 		break;
1192 	case SLJIT_ARG_TYPE_32:
1193 		CHECK_ARGUMENT(op == SLJIT_MOV32 || (op >= SLJIT_MOV32_U8 && op <= SLJIT_MOV32_S16));
1194 		break;
1195 	case SLJIT_ARG_TYPE_P:
1196 		CHECK_ARGUMENT(op == SLJIT_MOV_P);
1197 		break;
1198 	default:
1199 		/* Context not initialized, void, etc. */
1200 		CHECK_ARGUMENT(0);
1201 		break;
1202 	}
1203 	FUNCTION_CHECK_SRC(src, srcw);
1204 	compiler->last_flags = 0;
1205 #endif
1206 #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
1207 	if (SLJIT_UNLIKELY(!!compiler->verbose)) {
1208 		fprintf(compiler->verbose, "  return%s%s ", !(op & SLJIT_32) ? "" : "32",
1209 			op1_names[GET_OPCODE(op) - SLJIT_OP1_BASE]);
1210 		sljit_verbose_param(compiler, src, srcw);
1211 		fprintf(compiler->verbose, "\n");
1212 	}
1213 #endif
1214 	CHECK_RETURN_OK;
1215 }
1216 
check_sljit_emit_fast_enter(struct sljit_compiler * compiler,sljit_s32 dst,sljit_sw dstw)1217 static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_fast_enter(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw dstw)
1218 {
1219 #if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
1220 	FUNCTION_CHECK_DST(dst, dstw);
1221 	compiler->last_flags = 0;
1222 #endif
1223 #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
1224 	if (SLJIT_UNLIKELY(!!compiler->verbose)) {
1225 		fprintf(compiler->verbose, "  fast_enter ");
1226 		sljit_verbose_param(compiler, dst, dstw);
1227 		fprintf(compiler->verbose, "\n");
1228 	}
1229 #endif
1230 	CHECK_RETURN_OK;
1231 }
1232 
check_sljit_emit_op0(struct sljit_compiler * compiler,sljit_s32 op)1233 static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_op0(struct sljit_compiler *compiler, sljit_s32 op)
1234 {
1235 #if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
1236 	CHECK_ARGUMENT((op >= SLJIT_BREAKPOINT && op <= SLJIT_LMUL_SW)
1237 		|| ((op & ~SLJIT_32) >= SLJIT_DIVMOD_UW && (op & ~SLJIT_32) <= SLJIT_DIV_SW)
1238 		|| (op >= SLJIT_ENDBR && op <= SLJIT_SKIP_FRAMES_BEFORE_RETURN));
1239 	CHECK_ARGUMENT(GET_OPCODE(op) < SLJIT_LMUL_UW || GET_OPCODE(op) >= SLJIT_ENDBR || compiler->scratches >= 2);
1240 	if ((GET_OPCODE(op) >= SLJIT_LMUL_UW && GET_OPCODE(op) <= SLJIT_DIV_SW) || op == SLJIT_SKIP_FRAMES_BEFORE_RETURN)
1241 		compiler->last_flags = 0;
1242 #endif
1243 #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
1244 	if (SLJIT_UNLIKELY(!!compiler->verbose))
1245 	{
1246 		fprintf(compiler->verbose, "  %s", op0_names[GET_OPCODE(op) - SLJIT_OP0_BASE]);
1247 		if (GET_OPCODE(op) >= SLJIT_DIVMOD_UW && GET_OPCODE(op) <= SLJIT_DIV_SW) {
1248 			fprintf(compiler->verbose, (op & SLJIT_32) ? "32" : "w");
1249 		}
1250 		fprintf(compiler->verbose, "\n");
1251 	}
1252 #endif
1253 	CHECK_RETURN_OK;
1254 }
1255 
check_sljit_emit_op1(struct sljit_compiler * compiler,sljit_s32 op,sljit_s32 dst,sljit_sw dstw,sljit_s32 src,sljit_sw srcw)1256 static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_op1(struct sljit_compiler *compiler, sljit_s32 op,
1257 	sljit_s32 dst, sljit_sw dstw,
1258 	sljit_s32 src, sljit_sw srcw)
1259 {
1260 	if (SLJIT_UNLIKELY(compiler->skip_checks)) {
1261 		compiler->skip_checks = 0;
1262 		CHECK_RETURN_OK;
1263 	}
1264 
1265 #if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
1266 	CHECK_ARGUMENT(GET_OPCODE(op) >= SLJIT_MOV && GET_OPCODE(op) <= SLJIT_CLZ);
1267 
1268 	switch (GET_OPCODE(op)) {
1269 	case SLJIT_NOT:
1270 		/* Only SLJIT_32 and SLJIT_SET_Z are allowed. */
1271 		CHECK_ARGUMENT(!(op & VARIABLE_FLAG_MASK));
1272 		break;
1273 	case SLJIT_MOV:
1274 	case SLJIT_MOV_U32:
1275 	case SLJIT_MOV_P:
1276 		/* Nothing allowed */
1277 		CHECK_ARGUMENT(!(op & (SLJIT_32 | SLJIT_SET_Z | VARIABLE_FLAG_MASK)));
1278 		break;
1279 	default:
1280 		/* Only SLJIT_32 is allowed. */
1281 		CHECK_ARGUMENT(!(op & (SLJIT_SET_Z | VARIABLE_FLAG_MASK)));
1282 		break;
1283 	}
1284 
1285 	FUNCTION_CHECK_DST(dst, dstw);
1286 	FUNCTION_CHECK_SRC(src, srcw);
1287 
1288 	if (GET_OPCODE(op) >= SLJIT_NOT) {
1289 		CHECK_ARGUMENT(src != SLJIT_IMM);
1290 		compiler->last_flags = GET_FLAG_TYPE(op) | (op & (SLJIT_32 | SLJIT_SET_Z));
1291 	}
1292 #endif
1293 #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
1294 	if (SLJIT_UNLIKELY(!!compiler->verbose)) {
1295 		if (GET_OPCODE(op) <= SLJIT_MOV_P)
1296 		{
1297 			fprintf(compiler->verbose, "  mov%s%s ", !(op & SLJIT_32) ? "" : "32",
1298 				op1_names[GET_OPCODE(op) - SLJIT_OP1_BASE]);
1299 		}
1300 		else
1301 		{
1302 			fprintf(compiler->verbose, "  %s%s%s%s%s ", op1_names[GET_OPCODE(op) - SLJIT_OP1_BASE], !(op & SLJIT_32) ? "" : "32",
1303 				!(op & SLJIT_SET_Z) ? "" : ".z", !(op & VARIABLE_FLAG_MASK) ? "" : ".",
1304 				!(op & VARIABLE_FLAG_MASK) ? "" : jump_names[GET_FLAG_TYPE(op)]);
1305 		}
1306 
1307 		sljit_verbose_param(compiler, dst, dstw);
1308 		fprintf(compiler->verbose, ", ");
1309 		sljit_verbose_param(compiler, src, srcw);
1310 		fprintf(compiler->verbose, "\n");
1311 	}
1312 #endif
1313 	CHECK_RETURN_OK;
1314 }
1315 
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)1316 static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_op2(struct sljit_compiler *compiler, sljit_s32 op, sljit_s32 unset,
1317 	sljit_s32 dst, sljit_sw dstw,
1318 	sljit_s32 src1, sljit_sw src1w,
1319 	sljit_s32 src2, sljit_sw src2w)
1320 {
1321 	if (SLJIT_UNLIKELY(compiler->skip_checks)) {
1322 		compiler->skip_checks = 0;
1323 		CHECK_RETURN_OK;
1324 	}
1325 
1326 #if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
1327 	CHECK_ARGUMENT(GET_OPCODE(op) >= SLJIT_ADD && GET_OPCODE(op) <= SLJIT_ASHR);
1328 
1329 	switch (GET_OPCODE(op)) {
1330 	case SLJIT_AND:
1331 	case SLJIT_OR:
1332 	case SLJIT_XOR:
1333 	case SLJIT_SHL:
1334 	case SLJIT_LSHR:
1335 	case SLJIT_ASHR:
1336 		CHECK_ARGUMENT(!(op & VARIABLE_FLAG_MASK));
1337 		break;
1338 	case SLJIT_MUL:
1339 		CHECK_ARGUMENT(!(op & SLJIT_SET_Z));
1340 		CHECK_ARGUMENT(!(op & VARIABLE_FLAG_MASK)
1341 			|| GET_FLAG_TYPE(op) == SLJIT_OVERFLOW);
1342 		break;
1343 	case SLJIT_ADD:
1344 		CHECK_ARGUMENT(!(op & VARIABLE_FLAG_MASK)
1345 			|| GET_FLAG_TYPE(op) == GET_FLAG_TYPE(SLJIT_SET_CARRY)
1346 			|| GET_FLAG_TYPE(op) == SLJIT_OVERFLOW);
1347 		break;
1348 	case SLJIT_SUB:
1349 		CHECK_ARGUMENT(!(op & VARIABLE_FLAG_MASK)
1350 			|| (GET_FLAG_TYPE(op) >= SLJIT_LESS && GET_FLAG_TYPE(op) <= SLJIT_OVERFLOW)
1351 			|| GET_FLAG_TYPE(op) == GET_FLAG_TYPE(SLJIT_SET_CARRY));
1352 		break;
1353 	case SLJIT_ADDC:
1354 	case SLJIT_SUBC:
1355 		CHECK_ARGUMENT(!(op & VARIABLE_FLAG_MASK)
1356 			|| GET_FLAG_TYPE(op) == GET_FLAG_TYPE(SLJIT_SET_CARRY));
1357 		CHECK_ARGUMENT((compiler->last_flags & 0xff) == GET_FLAG_TYPE(SLJIT_SET_CARRY));
1358 		CHECK_ARGUMENT((op & SLJIT_32) == (compiler->last_flags & SLJIT_32));
1359 		break;
1360 	default:
1361 		SLJIT_UNREACHABLE();
1362 		break;
1363 	}
1364 
1365 	if (unset) {
1366 		CHECK_ARGUMENT(HAS_FLAGS(op));
1367 	} else {
1368 		FUNCTION_CHECK_DST(dst, dstw);
1369 	}
1370 	FUNCTION_CHECK_SRC(src1, src1w);
1371 	FUNCTION_CHECK_SRC(src2, src2w);
1372 	compiler->last_flags = GET_FLAG_TYPE(op) | (op & (SLJIT_32 | SLJIT_SET_Z));
1373 #endif
1374 #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
1375 	if (SLJIT_UNLIKELY(!!compiler->verbose)) {
1376 		fprintf(compiler->verbose, "  %s%s%s%s%s ", op2_names[GET_OPCODE(op) - SLJIT_OP2_BASE], !(op & SLJIT_32) ? "" : "32",
1377 			!(op & SLJIT_SET_Z) ? "" : ".z", !(op & VARIABLE_FLAG_MASK) ? "" : ".",
1378 			!(op & VARIABLE_FLAG_MASK) ? "" : jump_names[GET_FLAG_TYPE(op)]);
1379 		if (unset)
1380 			fprintf(compiler->verbose, "unset");
1381 		else
1382 			sljit_verbose_param(compiler, dst, dstw);
1383 		fprintf(compiler->verbose, ", ");
1384 		sljit_verbose_param(compiler, src1, src1w);
1385 		fprintf(compiler->verbose, ", ");
1386 		sljit_verbose_param(compiler, src2, src2w);
1387 		fprintf(compiler->verbose, "\n");
1388 	}
1389 #endif
1390 	CHECK_RETURN_OK;
1391 }
1392 
check_sljit_emit_op_src(struct sljit_compiler * compiler,sljit_s32 op,sljit_s32 src,sljit_sw srcw)1393 static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_op_src(struct sljit_compiler *compiler, sljit_s32 op,
1394 	sljit_s32 src, sljit_sw srcw)
1395 {
1396 #if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
1397 	CHECK_ARGUMENT(op >= SLJIT_FAST_RETURN && op <= SLJIT_PREFETCH_ONCE);
1398 	FUNCTION_CHECK_SRC(src, srcw);
1399 
1400 	if (op == SLJIT_FAST_RETURN || op == SLJIT_SKIP_FRAMES_BEFORE_FAST_RETURN)
1401 	{
1402 		CHECK_ARGUMENT(src != SLJIT_IMM);
1403 		compiler->last_flags = 0;
1404 	}
1405 	else if (op >= SLJIT_PREFETCH_L1 && op <= SLJIT_PREFETCH_ONCE)
1406 	{
1407 		CHECK_ARGUMENT(src & SLJIT_MEM);
1408 	}
1409 #endif
1410 #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
1411 	if (SLJIT_UNLIKELY(!!compiler->verbose)) {
1412 		fprintf(compiler->verbose, "  %s ", op_src_names[op - SLJIT_OP_SRC_BASE]);
1413 		sljit_verbose_param(compiler, src, srcw);
1414 		fprintf(compiler->verbose, "\n");
1415 	}
1416 #endif
1417 	CHECK_RETURN_OK;
1418 }
1419 
check_sljit_get_register_index(sljit_s32 reg)1420 static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_get_register_index(sljit_s32 reg)
1421 {
1422 	SLJIT_UNUSED_ARG(reg);
1423 #if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
1424 	CHECK_ARGUMENT(reg > 0 && reg <= SLJIT_NUMBER_OF_REGISTERS);
1425 #endif
1426 	CHECK_RETURN_OK;
1427 }
1428 
check_sljit_get_float_register_index(sljit_s32 reg)1429 static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_get_float_register_index(sljit_s32 reg)
1430 {
1431 	SLJIT_UNUSED_ARG(reg);
1432 #if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
1433 	CHECK_ARGUMENT(reg > 0 && reg <= SLJIT_NUMBER_OF_FLOAT_REGISTERS);
1434 #endif
1435 	CHECK_RETURN_OK;
1436 }
1437 
check_sljit_emit_op_custom(struct sljit_compiler * compiler,void * instruction,sljit_u32 size)1438 static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_op_custom(struct sljit_compiler *compiler,
1439 	void *instruction, sljit_u32 size)
1440 {
1441 #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
1442 	sljit_u32 i;
1443 #endif
1444 
1445 	SLJIT_UNUSED_ARG(compiler);
1446 
1447 #if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
1448 	CHECK_ARGUMENT(instruction);
1449 
1450 #if (defined SLJIT_CONFIG_X86 && SLJIT_CONFIG_X86)
1451 	CHECK_ARGUMENT(size > 0 && size < 16);
1452 #elif (defined SLJIT_CONFIG_ARM_THUMB2 && SLJIT_CONFIG_ARM_THUMB2)
1453 	CHECK_ARGUMENT((size == 2 && (((sljit_sw)instruction) & 0x1) == 0)
1454 		|| (size == 4 && (((sljit_sw)instruction) & 0x3) == 0));
1455 #elif (defined SLJIT_CONFIG_S390X && SLJIT_CONFIG_S390X)
1456 	CHECK_ARGUMENT(size == 2 || size == 4 || size == 6);
1457 #else
1458 	CHECK_ARGUMENT(size == 4 && (((sljit_sw)instruction) & 0x3) == 0);
1459 #endif
1460 
1461 	compiler->last_flags = 0;
1462 #endif
1463 #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
1464 	if (SLJIT_UNLIKELY(!!compiler->verbose)) {
1465 		fprintf(compiler->verbose, "  op_custom");
1466 		for (i = 0; i < size; i++)
1467 			fprintf(compiler->verbose, " 0x%x", ((sljit_u8*)instruction)[i]);
1468 		fprintf(compiler->verbose, "\n");
1469 	}
1470 #endif
1471 	CHECK_RETURN_OK;
1472 }
1473 
check_sljit_emit_fop1(struct sljit_compiler * compiler,sljit_s32 op,sljit_s32 dst,sljit_sw dstw,sljit_s32 src,sljit_sw srcw)1474 static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_fop1(struct sljit_compiler *compiler, sljit_s32 op,
1475 	sljit_s32 dst, sljit_sw dstw,
1476 	sljit_s32 src, sljit_sw srcw)
1477 {
1478 	if (SLJIT_UNLIKELY(compiler->skip_checks)) {
1479 		compiler->skip_checks = 0;
1480 		CHECK_RETURN_OK;
1481 	}
1482 
1483 #if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
1484 	CHECK_ARGUMENT(sljit_has_cpu_feature(SLJIT_HAS_FPU));
1485 	CHECK_ARGUMENT(GET_OPCODE(op) >= SLJIT_MOV_F64 && GET_OPCODE(op) <= SLJIT_ABS_F64);
1486 	CHECK_ARGUMENT(!(op & (SLJIT_SET_Z | VARIABLE_FLAG_MASK)));
1487 	FUNCTION_FCHECK(src, srcw);
1488 	FUNCTION_FCHECK(dst, dstw);
1489 #endif
1490 #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
1491 	if (SLJIT_UNLIKELY(!!compiler->verbose)) {
1492 		if (GET_OPCODE(op) == SLJIT_CONV_F64_FROM_F32)
1493 			fprintf(compiler->verbose, "  %s%s ", fop1_names[SLJIT_CONV_F64_FROM_F32 - SLJIT_FOP1_BASE],
1494 				(op & SLJIT_32) ? ".f32.from.f64" : ".f64.from.f32");
1495 		else
1496 			fprintf(compiler->verbose, "  %s%s ", fop1_names[GET_OPCODE(op) - SLJIT_FOP1_BASE],
1497 				(op & SLJIT_32) ? ".f32" : ".f64");
1498 
1499 		sljit_verbose_fparam(compiler, dst, dstw);
1500 		fprintf(compiler->verbose, ", ");
1501 		sljit_verbose_fparam(compiler, src, srcw);
1502 		fprintf(compiler->verbose, "\n");
1503 	}
1504 #endif
1505 	CHECK_RETURN_OK;
1506 }
1507 
check_sljit_emit_fop1_cmp(struct sljit_compiler * compiler,sljit_s32 op,sljit_s32 src1,sljit_sw src1w,sljit_s32 src2,sljit_sw src2w)1508 static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_fop1_cmp(struct sljit_compiler *compiler, sljit_s32 op,
1509 	sljit_s32 src1, sljit_sw src1w,
1510 	sljit_s32 src2, sljit_sw src2w)
1511 {
1512 #if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
1513 	compiler->last_flags = GET_FLAG_TYPE(op) | (op & (SLJIT_32 | SLJIT_SET_Z));
1514 #endif
1515 
1516 	if (SLJIT_UNLIKELY(compiler->skip_checks)) {
1517 		compiler->skip_checks = 0;
1518 		CHECK_RETURN_OK;
1519 	}
1520 
1521 #if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
1522 	CHECK_ARGUMENT(sljit_has_cpu_feature(SLJIT_HAS_FPU));
1523 	CHECK_ARGUMENT(GET_OPCODE(op) == SLJIT_CMP_F64);
1524 	CHECK_ARGUMENT(!(op & SLJIT_SET_Z));
1525 	CHECK_ARGUMENT((op & VARIABLE_FLAG_MASK)
1526 		|| (GET_FLAG_TYPE(op) >= SLJIT_EQUAL_F64 && GET_FLAG_TYPE(op) <= SLJIT_ORDERED_F64));
1527 	FUNCTION_FCHECK(src1, src1w);
1528 	FUNCTION_FCHECK(src2, src2w);
1529 #endif
1530 #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
1531 	if (SLJIT_UNLIKELY(!!compiler->verbose)) {
1532 		fprintf(compiler->verbose, "  %s%s", fop1_names[SLJIT_CMP_F64 - SLJIT_FOP1_BASE], (op & SLJIT_32) ? ".f32" : ".f64");
1533 		if (op & VARIABLE_FLAG_MASK) {
1534 			fprintf(compiler->verbose, ".%s_f", jump_names[GET_FLAG_TYPE(op)]);
1535 		}
1536 		fprintf(compiler->verbose, " ");
1537 		sljit_verbose_fparam(compiler, src1, src1w);
1538 		fprintf(compiler->verbose, ", ");
1539 		sljit_verbose_fparam(compiler, src2, src2w);
1540 		fprintf(compiler->verbose, "\n");
1541 	}
1542 #endif
1543 	CHECK_RETURN_OK;
1544 }
1545 
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)1546 static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_fop1_conv_sw_from_f64(struct sljit_compiler *compiler, sljit_s32 op,
1547 	sljit_s32 dst, sljit_sw dstw,
1548 	sljit_s32 src, sljit_sw srcw)
1549 {
1550 	if (SLJIT_UNLIKELY(compiler->skip_checks)) {
1551 		compiler->skip_checks = 0;
1552 		CHECK_RETURN_OK;
1553 	}
1554 
1555 #if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
1556 	CHECK_ARGUMENT(sljit_has_cpu_feature(SLJIT_HAS_FPU));
1557 	CHECK_ARGUMENT(GET_OPCODE(op) >= SLJIT_CONV_SW_FROM_F64 && GET_OPCODE(op) <= SLJIT_CONV_S32_FROM_F64);
1558 	CHECK_ARGUMENT(!(op & (SLJIT_SET_Z | VARIABLE_FLAG_MASK)));
1559 	FUNCTION_FCHECK(src, srcw);
1560 	FUNCTION_CHECK_DST(dst, dstw);
1561 #endif
1562 #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
1563 	if (SLJIT_UNLIKELY(!!compiler->verbose)) {
1564 		fprintf(compiler->verbose, "  %s%s.from%s ", fop1_names[GET_OPCODE(op) - SLJIT_FOP1_BASE],
1565 			(GET_OPCODE(op) == SLJIT_CONV_S32_FROM_F64) ? ".s32" : ".sw",
1566 			(op & SLJIT_32) ? ".f32" : ".f64");
1567 		sljit_verbose_param(compiler, dst, dstw);
1568 		fprintf(compiler->verbose, ", ");
1569 		sljit_verbose_fparam(compiler, src, srcw);
1570 		fprintf(compiler->verbose, "\n");
1571 	}
1572 #endif
1573 	CHECK_RETURN_OK;
1574 }
1575 
check_sljit_emit_fop1_conv_f64_from_sw(struct sljit_compiler * compiler,sljit_s32 op,sljit_s32 dst,sljit_sw dstw,sljit_s32 src,sljit_sw srcw)1576 static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_fop1_conv_f64_from_sw(struct sljit_compiler *compiler, sljit_s32 op,
1577 	sljit_s32 dst, sljit_sw dstw,
1578 	sljit_s32 src, sljit_sw srcw)
1579 {
1580 	if (SLJIT_UNLIKELY(compiler->skip_checks)) {
1581 		compiler->skip_checks = 0;
1582 		CHECK_RETURN_OK;
1583 	}
1584 
1585 #if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
1586 	CHECK_ARGUMENT(sljit_has_cpu_feature(SLJIT_HAS_FPU));
1587 	CHECK_ARGUMENT(GET_OPCODE(op) >= SLJIT_CONV_F64_FROM_SW && GET_OPCODE(op) <= SLJIT_CONV_F64_FROM_S32);
1588 	CHECK_ARGUMENT(!(op & (SLJIT_SET_Z | VARIABLE_FLAG_MASK)));
1589 	FUNCTION_CHECK_SRC(src, srcw);
1590 	FUNCTION_FCHECK(dst, dstw);
1591 #endif
1592 #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
1593 	if (SLJIT_UNLIKELY(!!compiler->verbose)) {
1594 		fprintf(compiler->verbose, "  %s%s.from%s ", fop1_names[GET_OPCODE(op) - SLJIT_FOP1_BASE],
1595 			(op & SLJIT_32) ? ".f32" : ".f64",
1596 			(GET_OPCODE(op) == SLJIT_CONV_F64_FROM_S32) ? ".s32" : ".sw");
1597 		sljit_verbose_fparam(compiler, dst, dstw);
1598 		fprintf(compiler->verbose, ", ");
1599 		sljit_verbose_param(compiler, src, srcw);
1600 		fprintf(compiler->verbose, "\n");
1601 	}
1602 #endif
1603 	CHECK_RETURN_OK;
1604 }
1605 
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)1606 static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_fop2(struct sljit_compiler *compiler, sljit_s32 op,
1607 	sljit_s32 dst, sljit_sw dstw,
1608 	sljit_s32 src1, sljit_sw src1w,
1609 	sljit_s32 src2, sljit_sw src2w)
1610 {
1611 #if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
1612 	CHECK_ARGUMENT(sljit_has_cpu_feature(SLJIT_HAS_FPU));
1613 	CHECK_ARGUMENT(GET_OPCODE(op) >= SLJIT_ADD_F64 && GET_OPCODE(op) <= SLJIT_DIV_F64);
1614 	CHECK_ARGUMENT(!(op & (SLJIT_SET_Z | VARIABLE_FLAG_MASK)));
1615 	FUNCTION_FCHECK(src1, src1w);
1616 	FUNCTION_FCHECK(src2, src2w);
1617 	FUNCTION_FCHECK(dst, dstw);
1618 #endif
1619 #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
1620 	if (SLJIT_UNLIKELY(!!compiler->verbose)) {
1621 		fprintf(compiler->verbose, "  %s%s ", fop2_names[GET_OPCODE(op) - SLJIT_FOP2_BASE], (op & SLJIT_32) ? ".f32" : ".f64");
1622 		sljit_verbose_fparam(compiler, dst, dstw);
1623 		fprintf(compiler->verbose, ", ");
1624 		sljit_verbose_fparam(compiler, src1, src1w);
1625 		fprintf(compiler->verbose, ", ");
1626 		sljit_verbose_fparam(compiler, src2, src2w);
1627 		fprintf(compiler->verbose, "\n");
1628 	}
1629 #endif
1630 	CHECK_RETURN_OK;
1631 }
1632 
check_sljit_emit_label(struct sljit_compiler * compiler)1633 static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_label(struct sljit_compiler *compiler)
1634 {
1635 	SLJIT_UNUSED_ARG(compiler);
1636 
1637 	if (SLJIT_UNLIKELY(compiler->skip_checks)) {
1638 		compiler->skip_checks = 0;
1639 		CHECK_RETURN_OK;
1640 	}
1641 
1642 #if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
1643 	compiler->last_flags = 0;
1644 #endif
1645 
1646 #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
1647 	if (SLJIT_UNLIKELY(!!compiler->verbose))
1648 		fprintf(compiler->verbose, "label:\n");
1649 #endif
1650 	CHECK_RETURN_OK;
1651 }
1652 
check_sljit_emit_jump(struct sljit_compiler * compiler,sljit_s32 type)1653 static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_jump(struct sljit_compiler *compiler, sljit_s32 type)
1654 {
1655 	if (SLJIT_UNLIKELY(compiler->skip_checks)) {
1656 		compiler->skip_checks = 0;
1657 		CHECK_RETURN_OK;
1658 	}
1659 
1660 #if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
1661 	CHECK_ARGUMENT(!(type & ~(0xff | SLJIT_REWRITABLE_JUMP | SLJIT_32)));
1662 	CHECK_ARGUMENT((type & 0xff) >= SLJIT_EQUAL && (type & 0xff) <= SLJIT_FAST_CALL);
1663 	CHECK_ARGUMENT((type & 0xff) < SLJIT_JUMP || !(type & SLJIT_32));
1664 
1665 	if ((type & 0xff) < SLJIT_JUMP) {
1666 		if ((type & 0xff) <= SLJIT_NOT_ZERO)
1667 			CHECK_ARGUMENT(compiler->last_flags & SLJIT_SET_Z);
1668 		else if ((compiler->last_flags & 0xff) == SLJIT_CARRY) {
1669 			CHECK_ARGUMENT((type & 0xff) == SLJIT_CARRY || (type & 0xff) == SLJIT_NOT_CARRY);
1670 			compiler->last_flags = 0;
1671 		} else
1672 			CHECK_ARGUMENT((type & 0xff) == (compiler->last_flags & 0xff)
1673 				|| ((type & 0xff) == SLJIT_NOT_OVERFLOW && (compiler->last_flags & 0xff) == SLJIT_OVERFLOW));
1674 	}
1675 #endif
1676 #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
1677 	if (SLJIT_UNLIKELY(!!compiler->verbose))
1678 		fprintf(compiler->verbose, "  jump%s %s%s\n", !(type & SLJIT_REWRITABLE_JUMP) ? "" : ".r",
1679 			jump_names[type & 0xff], JUMP_POSTFIX(type));
1680 #endif
1681 	CHECK_RETURN_OK;
1682 }
1683 
check_sljit_emit_call(struct sljit_compiler * compiler,sljit_s32 type,sljit_s32 arg_types)1684 static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_call(struct sljit_compiler *compiler, sljit_s32 type,
1685 	sljit_s32 arg_types)
1686 {
1687 #if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
1688 	CHECK_ARGUMENT(!(type & ~(0xff | SLJIT_REWRITABLE_JUMP | SLJIT_CALL_RETURN)));
1689 	CHECK_ARGUMENT((type & 0xff) == SLJIT_CALL || (type & 0xff) == SLJIT_CALL_CDECL);
1690 	CHECK_ARGUMENT(function_check_arguments(arg_types, compiler->scratches, -1, compiler->fscratches));
1691 
1692 	if (type & SLJIT_CALL_RETURN) {
1693 		CHECK_ARGUMENT((arg_types & SLJIT_ARG_MASK) == compiler->last_return);
1694 	}
1695 #endif
1696 #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
1697 	if (SLJIT_UNLIKELY(!!compiler->verbose)) {
1698 		fprintf(compiler->verbose, "  %s%s%s ret[%s", jump_names[type & 0xff],
1699 			!(type & SLJIT_REWRITABLE_JUMP) ? "" : ".r",
1700 			!(type & SLJIT_CALL_RETURN) ? "" : ".ret",
1701 			call_arg_names[arg_types & SLJIT_ARG_MASK]);
1702 
1703 		arg_types >>= SLJIT_ARG_SHIFT;
1704 		if (arg_types) {
1705 			fprintf(compiler->verbose, "], args[");
1706 			do {
1707 				fprintf(compiler->verbose, "%s", call_arg_names[arg_types & SLJIT_ARG_MASK]);
1708 				arg_types >>= SLJIT_ARG_SHIFT;
1709 				if (arg_types)
1710 					fprintf(compiler->verbose, ",");
1711 			} while (arg_types);
1712 		}
1713 		fprintf(compiler->verbose, "]\n");
1714 	}
1715 #endif
1716 	CHECK_RETURN_OK;
1717 }
1718 
check_sljit_emit_cmp(struct sljit_compiler * compiler,sljit_s32 type,sljit_s32 src1,sljit_sw src1w,sljit_s32 src2,sljit_sw src2w)1719 static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_cmp(struct sljit_compiler *compiler, sljit_s32 type,
1720 	sljit_s32 src1, sljit_sw src1w,
1721 	sljit_s32 src2, sljit_sw src2w)
1722 {
1723 #if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
1724 	CHECK_ARGUMENT(!(type & ~(0xff | SLJIT_REWRITABLE_JUMP | SLJIT_32)));
1725 	CHECK_ARGUMENT((type & 0xff) >= SLJIT_EQUAL && (type & 0xff) <= SLJIT_SIG_LESS_EQUAL);
1726 	FUNCTION_CHECK_SRC(src1, src1w);
1727 	FUNCTION_CHECK_SRC(src2, src2w);
1728 	compiler->last_flags = 0;
1729 #endif
1730 #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
1731 	if (SLJIT_UNLIKELY(!!compiler->verbose)) {
1732 		fprintf(compiler->verbose, "  cmp%s %s%s, ", !(type & SLJIT_REWRITABLE_JUMP) ? "" : ".r",
1733 			jump_names[type & 0xff], (type & SLJIT_32) ? "32" : "");
1734 		sljit_verbose_param(compiler, src1, src1w);
1735 		fprintf(compiler->verbose, ", ");
1736 		sljit_verbose_param(compiler, src2, src2w);
1737 		fprintf(compiler->verbose, "\n");
1738 	}
1739 #endif
1740 	CHECK_RETURN_OK;
1741 }
1742 
check_sljit_emit_fcmp(struct sljit_compiler * compiler,sljit_s32 type,sljit_s32 src1,sljit_sw src1w,sljit_s32 src2,sljit_sw src2w)1743 static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_fcmp(struct sljit_compiler *compiler, sljit_s32 type,
1744 	sljit_s32 src1, sljit_sw src1w,
1745 	sljit_s32 src2, sljit_sw src2w)
1746 {
1747 #if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
1748 	CHECK_ARGUMENT(sljit_has_cpu_feature(SLJIT_HAS_FPU));
1749 	CHECK_ARGUMENT(!(type & ~(0xff | SLJIT_REWRITABLE_JUMP | SLJIT_32)));
1750 	CHECK_ARGUMENT((type & 0xff) >= SLJIT_EQUAL_F64 && (type & 0xff) <= SLJIT_ORDERED_F64);
1751 	FUNCTION_FCHECK(src1, src1w);
1752 	FUNCTION_FCHECK(src2, src2w);
1753 	compiler->last_flags = 0;
1754 #endif
1755 #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
1756 	if (SLJIT_UNLIKELY(!!compiler->verbose)) {
1757 		fprintf(compiler->verbose, "  fcmp%s %s%s, ", !(type & SLJIT_REWRITABLE_JUMP) ? "" : ".r",
1758 			jump_names[type & 0xff], (type & SLJIT_32) ? ".f32" : ".f64");
1759 		sljit_verbose_fparam(compiler, src1, src1w);
1760 		fprintf(compiler->verbose, ", ");
1761 		sljit_verbose_fparam(compiler, src2, src2w);
1762 		fprintf(compiler->verbose, "\n");
1763 	}
1764 #endif
1765 	CHECK_RETURN_OK;
1766 }
1767 
check_sljit_emit_ijump(struct sljit_compiler * compiler,sljit_s32 type,sljit_s32 src,sljit_sw srcw)1768 static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_ijump(struct sljit_compiler *compiler, sljit_s32 type,
1769 	sljit_s32 src, sljit_sw srcw)
1770 {
1771 	if (SLJIT_UNLIKELY(compiler->skip_checks)) {
1772 		compiler->skip_checks = 0;
1773 		CHECK_RETURN_OK;
1774 	}
1775 
1776 #if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
1777 	CHECK_ARGUMENT(type >= SLJIT_JUMP && type <= SLJIT_FAST_CALL);
1778 	FUNCTION_CHECK_SRC(src, srcw);
1779 #endif
1780 #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
1781 	if (SLJIT_UNLIKELY(!!compiler->verbose)) {
1782 		fprintf(compiler->verbose, "  ijump.%s ", jump_names[type]);
1783 		sljit_verbose_param(compiler, src, srcw);
1784 		fprintf(compiler->verbose, "\n");
1785 	}
1786 #endif
1787 	CHECK_RETURN_OK;
1788 }
1789 
check_sljit_emit_icall(struct sljit_compiler * compiler,sljit_s32 type,sljit_s32 arg_types,sljit_s32 src,sljit_sw srcw)1790 static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_icall(struct sljit_compiler *compiler, sljit_s32 type,
1791 	sljit_s32 arg_types,
1792 	sljit_s32 src, sljit_sw srcw)
1793 {
1794 #if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
1795 	CHECK_ARGUMENT(!(type & ~(0xff | SLJIT_CALL_RETURN)));
1796 	CHECK_ARGUMENT((type & 0xff) == SLJIT_CALL || (type & 0xff) == SLJIT_CALL_CDECL);
1797 	CHECK_ARGUMENT(function_check_arguments(arg_types, compiler->scratches, -1, compiler->fscratches));
1798 	FUNCTION_CHECK_SRC(src, srcw);
1799 
1800 	if (type & SLJIT_CALL_RETURN) {
1801 		CHECK_ARGUMENT((arg_types & SLJIT_ARG_MASK) == compiler->last_return);
1802 	}
1803 #endif
1804 #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
1805 	if (SLJIT_UNLIKELY(!!compiler->verbose)) {
1806 		fprintf(compiler->verbose, "  i%s%s ret[%s", jump_names[type & 0xff],
1807 			!(type & SLJIT_CALL_RETURN) ? "" : ".ret",
1808 			call_arg_names[arg_types & SLJIT_ARG_MASK]);
1809 
1810 		arg_types >>= SLJIT_ARG_SHIFT;
1811 		if (arg_types) {
1812 			fprintf(compiler->verbose, "], args[");
1813 			do {
1814 				fprintf(compiler->verbose, "%s", call_arg_names[arg_types & SLJIT_ARG_MASK]);
1815 				arg_types >>= SLJIT_ARG_SHIFT;
1816 				if (arg_types)
1817 					fprintf(compiler->verbose, ",");
1818 			} while (arg_types);
1819 		}
1820 		fprintf(compiler->verbose, "], ");
1821 		sljit_verbose_param(compiler, src, srcw);
1822 		fprintf(compiler->verbose, "\n");
1823 	}
1824 #endif
1825 	CHECK_RETURN_OK;
1826 }
1827 
check_sljit_emit_op_flags(struct sljit_compiler * compiler,sljit_s32 op,sljit_s32 dst,sljit_sw dstw,sljit_s32 type)1828 static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_op_flags(struct sljit_compiler *compiler, sljit_s32 op,
1829 	sljit_s32 dst, sljit_sw dstw,
1830 	sljit_s32 type)
1831 {
1832 #if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
1833 	CHECK_ARGUMENT(!(type & ~(0xff | SLJIT_32)));
1834 	CHECK_ARGUMENT((type & 0xff) >= SLJIT_EQUAL && (type & 0xff) <= SLJIT_ORDERED_F64);
1835 	CHECK_ARGUMENT(op == SLJIT_MOV || op == SLJIT_MOV32
1836 		|| (GET_OPCODE(op) >= SLJIT_AND && GET_OPCODE(op) <= SLJIT_XOR));
1837 	CHECK_ARGUMENT(!(op & VARIABLE_FLAG_MASK));
1838 
1839 	if ((type & 0xff) <= SLJIT_NOT_ZERO)
1840 		CHECK_ARGUMENT(compiler->last_flags & SLJIT_SET_Z);
1841 	else
1842 		CHECK_ARGUMENT((type & 0xff) == (compiler->last_flags & 0xff)
1843 			|| ((type & 0xff) == SLJIT_NOT_CARRY && (compiler->last_flags & 0xff) == SLJIT_CARRY)
1844 			|| ((type & 0xff) == SLJIT_NOT_OVERFLOW && (compiler->last_flags & 0xff) == SLJIT_OVERFLOW));
1845 
1846 	FUNCTION_CHECK_DST(dst, dstw);
1847 
1848 	if (GET_OPCODE(op) >= SLJIT_ADD)
1849 		compiler->last_flags = GET_FLAG_TYPE(op) | (op & (SLJIT_32 | SLJIT_SET_Z));
1850 #endif
1851 #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
1852 	if (SLJIT_UNLIKELY(!!compiler->verbose)) {
1853 		fprintf(compiler->verbose, "  flags%s %s%s, ",
1854 			!(op & SLJIT_SET_Z) ? "" : ".z",
1855 			GET_OPCODE(op) < SLJIT_OP2_BASE ? "mov" : op2_names[GET_OPCODE(op) - SLJIT_OP2_BASE],
1856 			GET_OPCODE(op) < SLJIT_OP2_BASE ? op1_names[GET_OPCODE(op) - SLJIT_OP1_BASE] : ((op & SLJIT_32) ? "32" : ""));
1857 		sljit_verbose_param(compiler, dst, dstw);
1858 		fprintf(compiler->verbose, ", %s%s\n", jump_names[type & 0xff], JUMP_POSTFIX(type));
1859 	}
1860 #endif
1861 	CHECK_RETURN_OK;
1862 }
1863 
check_sljit_emit_cmov(struct sljit_compiler * compiler,sljit_s32 type,sljit_s32 dst_reg,sljit_s32 src,sljit_sw srcw)1864 static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_cmov(struct sljit_compiler *compiler, sljit_s32 type,
1865 	sljit_s32 dst_reg,
1866 	sljit_s32 src, sljit_sw srcw)
1867 {
1868 #if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
1869 	CHECK_ARGUMENT(!(type & ~(0xff | SLJIT_32)));
1870 	CHECK_ARGUMENT((type & 0xff) >= SLJIT_EQUAL && (type & 0xff) <= SLJIT_ORDERED_F64);
1871 
1872 	CHECK_ARGUMENT(compiler->scratches != -1 && compiler->saveds != -1);
1873 	CHECK_ARGUMENT(FUNCTION_CHECK_IS_REG(dst_reg & ~SLJIT_32));
1874 	if (src != SLJIT_IMM) {
1875 		CHECK_ARGUMENT(FUNCTION_CHECK_IS_REG(src));
1876 		CHECK_ARGUMENT(srcw == 0);
1877 	}
1878 
1879 	if ((type & 0xff) <= SLJIT_NOT_ZERO)
1880 		CHECK_ARGUMENT(compiler->last_flags & SLJIT_SET_Z);
1881 	else
1882 		CHECK_ARGUMENT((type & 0xff) == (compiler->last_flags & 0xff)
1883 			|| ((type & 0xff) == SLJIT_NOT_OVERFLOW && (compiler->last_flags & 0xff) == SLJIT_OVERFLOW));
1884 #endif
1885 #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
1886 	if (SLJIT_UNLIKELY(!!compiler->verbose)) {
1887 		fprintf(compiler->verbose, "  cmov%s %s%s, ",
1888 			!(dst_reg & SLJIT_32) ? "" : "32",
1889 			jump_names[type & 0xff], JUMP_POSTFIX(type));
1890 		sljit_verbose_reg(compiler, dst_reg & ~SLJIT_32);
1891 		fprintf(compiler->verbose, ", ");
1892 		sljit_verbose_param(compiler, src, srcw);
1893 		fprintf(compiler->verbose, "\n");
1894 	}
1895 #endif
1896 	CHECK_RETURN_OK;
1897 }
1898 
check_sljit_emit_mem(struct sljit_compiler * compiler,sljit_s32 type,sljit_s32 reg,sljit_s32 mem,sljit_sw memw)1899 static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_mem(struct sljit_compiler *compiler, sljit_s32 type,
1900 	sljit_s32 reg,
1901 	sljit_s32 mem, sljit_sw memw)
1902 {
1903 #if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
1904 	CHECK_ARGUMENT((type & 0xff) >= SLJIT_MOV && (type & 0xff) <= SLJIT_MOV_P);
1905 	CHECK_ARGUMENT(!(type & SLJIT_32) || ((type & 0xff) != SLJIT_MOV && (type & 0xff) != SLJIT_MOV_U32 && (type & 0xff) != SLJIT_MOV_P));
1906 	CHECK_ARGUMENT((type & SLJIT_MEM_PRE) || (type & SLJIT_MEM_POST));
1907 	CHECK_ARGUMENT((type & (SLJIT_MEM_PRE | SLJIT_MEM_POST)) != (SLJIT_MEM_PRE | SLJIT_MEM_POST));
1908 	CHECK_ARGUMENT((type & ~(0xff | SLJIT_32 | SLJIT_MEM_STORE | SLJIT_MEM_SUPP | SLJIT_MEM_PRE | SLJIT_MEM_POST)) == 0);
1909 
1910 	FUNCTION_CHECK_SRC_MEM(mem, memw);
1911 	CHECK_ARGUMENT(FUNCTION_CHECK_IS_REG(reg));
1912 
1913 	CHECK_ARGUMENT((mem & REG_MASK) != 0 && (mem & REG_MASK) != reg);
1914 #endif
1915 #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
1916 	if (!(type & SLJIT_MEM_SUPP) && SLJIT_UNLIKELY(!!compiler->verbose)) {
1917 		if (sljit_emit_mem(compiler, type | SLJIT_MEM_SUPP, reg, mem, memw) == SLJIT_ERR_UNSUPPORTED)
1918 			fprintf(compiler->verbose, "  //");
1919 
1920 		fprintf(compiler->verbose, "  mem%s.%s%s%s ",
1921 			!(type & SLJIT_32) ? "" : "32",
1922 			(type & SLJIT_MEM_STORE) ? "st" : "ld",
1923 			op1_names[(type & 0xff) - SLJIT_OP1_BASE],
1924 			(type & SLJIT_MEM_PRE) ? ".pre" : ".post");
1925 		sljit_verbose_reg(compiler, reg);
1926 		fprintf(compiler->verbose, ", ");
1927 		sljit_verbose_param(compiler, mem, memw);
1928 		fprintf(compiler->verbose, "\n");
1929 	}
1930 #endif
1931 	CHECK_RETURN_OK;
1932 }
1933 
check_sljit_emit_fmem(struct sljit_compiler * compiler,sljit_s32 type,sljit_s32 freg,sljit_s32 mem,sljit_sw memw)1934 static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_fmem(struct sljit_compiler *compiler, sljit_s32 type,
1935 	sljit_s32 freg,
1936 	sljit_s32 mem, sljit_sw memw)
1937 {
1938 #if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
1939 	CHECK_ARGUMENT((type & 0xff) == SLJIT_MOV_F64);
1940 	CHECK_ARGUMENT((type & SLJIT_MEM_PRE) || (type & SLJIT_MEM_POST));
1941 	CHECK_ARGUMENT((type & (SLJIT_MEM_PRE | SLJIT_MEM_POST)) != (SLJIT_MEM_PRE | SLJIT_MEM_POST));
1942 	CHECK_ARGUMENT((type & ~(0xff | SLJIT_32 | SLJIT_MEM_STORE | SLJIT_MEM_SUPP | SLJIT_MEM_PRE | SLJIT_MEM_POST)) == 0);
1943 
1944 	FUNCTION_CHECK_SRC_MEM(mem, memw);
1945 	CHECK_ARGUMENT(FUNCTION_CHECK_IS_FREG(freg));
1946 #endif
1947 #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
1948 	if (!(type & SLJIT_MEM_SUPP) && SLJIT_UNLIKELY(!!compiler->verbose)) {
1949 		if (sljit_emit_fmem(compiler, type | SLJIT_MEM_SUPP, freg, mem, memw) == SLJIT_ERR_UNSUPPORTED)
1950 			fprintf(compiler->verbose, "  //");
1951 
1952 		fprintf(compiler->verbose, "  fmem.%s%s%s ",
1953 			(type & SLJIT_MEM_STORE) ? "st" : "ld",
1954 			!(type & SLJIT_32) ? ".f64" : ".f32",
1955 			(type & SLJIT_MEM_PRE) ? ".pre" : ".post");
1956 		sljit_verbose_freg(compiler, freg);
1957 		fprintf(compiler->verbose, ", ");
1958 		sljit_verbose_param(compiler, mem, memw);
1959 		fprintf(compiler->verbose, "\n");
1960 	}
1961 #endif
1962 	CHECK_RETURN_OK;
1963 }
1964 
check_sljit_get_local_base(struct sljit_compiler * compiler,sljit_s32 dst,sljit_sw dstw,sljit_sw offset)1965 static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_get_local_base(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw dstw, sljit_sw offset)
1966 {
1967 	/* Any offset is allowed. */
1968 	SLJIT_UNUSED_ARG(offset);
1969 
1970 #if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
1971 	FUNCTION_CHECK_DST(dst, dstw);
1972 #endif
1973 #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
1974 	if (SLJIT_UNLIKELY(!!compiler->verbose)) {
1975 		fprintf(compiler->verbose, "  local_base ");
1976 		sljit_verbose_param(compiler, dst, dstw);
1977 		fprintf(compiler->verbose, ", #%" SLJIT_PRINT_D "d\n", offset);
1978 	}
1979 #endif
1980 	CHECK_RETURN_OK;
1981 }
1982 
check_sljit_emit_const(struct sljit_compiler * compiler,sljit_s32 dst,sljit_sw dstw,sljit_sw init_value)1983 static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_const(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw dstw, sljit_sw init_value)
1984 {
1985 	SLJIT_UNUSED_ARG(init_value);
1986 
1987 #if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
1988 	FUNCTION_CHECK_DST(dst, dstw);
1989 #endif
1990 #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
1991 	if (SLJIT_UNLIKELY(!!compiler->verbose)) {
1992 		fprintf(compiler->verbose, "  const ");
1993 		sljit_verbose_param(compiler, dst, dstw);
1994 		fprintf(compiler->verbose, ", #%" SLJIT_PRINT_D "d\n", init_value);
1995 	}
1996 #endif
1997 	CHECK_RETURN_OK;
1998 }
1999 
check_sljit_emit_put_label(struct sljit_compiler * compiler,sljit_s32 dst,sljit_sw dstw)2000 static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_put_label(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw dstw)
2001 {
2002 #if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
2003 	FUNCTION_CHECK_DST(dst, dstw);
2004 #endif
2005 #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
2006 	if (SLJIT_UNLIKELY(!!compiler->verbose)) {
2007 		fprintf(compiler->verbose, "  put_label ");
2008 		sljit_verbose_param(compiler, dst, dstw);
2009 		fprintf(compiler->verbose, "\n");
2010 	}
2011 #endif
2012 	CHECK_RETURN_OK;
2013 }
2014 
2015 #endif /* SLJIT_ARGUMENT_CHECKS || SLJIT_VERBOSE */
2016 
2017 #define SELECT_FOP1_OPERATION_WITH_CHECKS(compiler, op, dst, dstw, src, srcw) \
2018 	SLJIT_COMPILE_ASSERT(!(SLJIT_CONV_SW_FROM_F64 & 0x1) && !(SLJIT_CONV_F64_FROM_SW & 0x1), \
2019 		invalid_float_opcodes); \
2020 	if (GET_OPCODE(op) >= SLJIT_CONV_SW_FROM_F64 && GET_OPCODE(op) <= SLJIT_CMP_F64) { \
2021 		if (GET_OPCODE(op) == SLJIT_CMP_F64) { \
2022 			CHECK(check_sljit_emit_fop1_cmp(compiler, op, dst, dstw, src, srcw)); \
2023 			ADJUST_LOCAL_OFFSET(dst, dstw); \
2024 			ADJUST_LOCAL_OFFSET(src, srcw); \
2025 			return sljit_emit_fop1_cmp(compiler, op, dst, dstw, src, srcw); \
2026 		} \
2027 		if ((GET_OPCODE(op) | 0x1) == SLJIT_CONV_S32_FROM_F64) { \
2028 			CHECK(check_sljit_emit_fop1_conv_sw_from_f64(compiler, op, dst, dstw, src, srcw)); \
2029 			ADJUST_LOCAL_OFFSET(dst, dstw); \
2030 			ADJUST_LOCAL_OFFSET(src, srcw); \
2031 			return sljit_emit_fop1_conv_sw_from_f64(compiler, op, dst, dstw, src, srcw); \
2032 		} \
2033 		CHECK(check_sljit_emit_fop1_conv_f64_from_sw(compiler, op, dst, dstw, src, srcw)); \
2034 		ADJUST_LOCAL_OFFSET(dst, dstw); \
2035 		ADJUST_LOCAL_OFFSET(src, srcw); \
2036 		return sljit_emit_fop1_conv_f64_from_sw(compiler, op, dst, dstw, src, srcw); \
2037 	} \
2038 	CHECK(check_sljit_emit_fop1(compiler, op, dst, dstw, src, srcw)); \
2039 	ADJUST_LOCAL_OFFSET(dst, dstw); \
2040 	ADJUST_LOCAL_OFFSET(src, srcw);
2041 
emit_mov_before_return(struct sljit_compiler * compiler,sljit_s32 op,sljit_s32 src,sljit_sw srcw)2042 static SLJIT_INLINE sljit_s32 emit_mov_before_return(struct sljit_compiler *compiler, sljit_s32 op, sljit_s32 src, sljit_sw srcw)
2043 {
2044 #if (defined SLJIT_64BIT_ARCHITECTURE && SLJIT_64BIT_ARCHITECTURE)
2045 	/* At the moment the pointer size is always equal to sljit_sw. May be changed in the future. */
2046 	if (src == SLJIT_RETURN_REG && (op == SLJIT_MOV || op == SLJIT_MOV_P))
2047 		return SLJIT_SUCCESS;
2048 #else
2049 	if (src == SLJIT_RETURN_REG && (op == SLJIT_MOV || op == SLJIT_MOV_U32 || op == SLJIT_MOV_S32 || op == SLJIT_MOV_P))
2050 		return SLJIT_SUCCESS;
2051 #endif
2052 
2053 #if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS) \
2054 		|| (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
2055 	compiler->skip_checks = 1;
2056 #endif
2057 	return sljit_emit_op1(compiler, op, SLJIT_RETURN_REG, 0, src, srcw);
2058 }
2059 
2060 #if !(defined SLJIT_CONFIG_SPARC && SLJIT_CONFIG_SPARC)
2061 
sljit_emit_return(struct sljit_compiler * compiler,sljit_s32 op,sljit_s32 src,sljit_sw srcw)2062 SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_return(struct sljit_compiler *compiler, sljit_s32 op, sljit_s32 src, sljit_sw srcw)
2063 {
2064 	CHECK_ERROR();
2065 	CHECK(check_sljit_emit_return(compiler, op, src, srcw));
2066 
2067 	FAIL_IF(emit_mov_before_return(compiler, op, src, srcw));
2068 
2069 #if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS) \
2070 		|| (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
2071 	compiler->skip_checks = 1;
2072 #endif
2073 	return sljit_emit_return_void(compiler);
2074 }
2075 
2076 #endif
2077 
2078 #if (defined SLJIT_CONFIG_X86 && SLJIT_CONFIG_X86) \
2079 		|| (defined SLJIT_CONFIG_PPC && SLJIT_CONFIG_PPC) \
2080 		|| (defined SLJIT_CONFIG_SPARC_32 && SLJIT_CONFIG_SPARC_32) \
2081 		|| ((defined SLJIT_CONFIG_MIPS && SLJIT_CONFIG_MIPS) && !(defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 1 && SLJIT_MIPS_REV < 6))
2082 
sljit_emit_cmov_generic(struct sljit_compiler * compiler,sljit_s32 type,sljit_s32 dst_reg,sljit_s32 src,sljit_sw srcw)2083 static SLJIT_INLINE sljit_s32 sljit_emit_cmov_generic(struct sljit_compiler *compiler, sljit_s32 type,
2084 	sljit_s32 dst_reg,
2085 	sljit_s32 src, sljit_sw srcw)
2086 {
2087 	struct sljit_label *label;
2088 	struct sljit_jump *jump;
2089 	sljit_s32 op = (dst_reg & SLJIT_32) ? SLJIT_MOV32 : SLJIT_MOV;
2090 
2091 #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) \
2092 		|| (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
2093 	compiler->skip_checks = 1;
2094 #endif
2095 	jump = sljit_emit_jump(compiler, type ^ 0x1);
2096 	FAIL_IF(!jump);
2097 
2098 #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) \
2099 		|| (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
2100 	compiler->skip_checks = 1;
2101 #endif
2102 	FAIL_IF(sljit_emit_op1(compiler, op, dst_reg & ~SLJIT_32, 0, src, srcw));
2103 
2104 #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) \
2105 		|| (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
2106 	compiler->skip_checks = 1;
2107 #endif
2108 	label = sljit_emit_label(compiler);
2109 	FAIL_IF(!label);
2110 	sljit_set_label(jump, label);
2111 	return SLJIT_SUCCESS;
2112 }
2113 
2114 #endif
2115 
2116 /* CPU description section */
2117 
2118 #if (defined SLJIT_32BIT_ARCHITECTURE && SLJIT_32BIT_ARCHITECTURE)
2119 #define SLJIT_CPUINFO_PART1 " 32bit ("
2120 #elif (defined SLJIT_64BIT_ARCHITECTURE && SLJIT_64BIT_ARCHITECTURE)
2121 #define SLJIT_CPUINFO_PART1 " 64bit ("
2122 #else
2123 #error "Internal error: CPU type info missing"
2124 #endif
2125 
2126 #if (defined SLJIT_LITTLE_ENDIAN && SLJIT_LITTLE_ENDIAN)
2127 #define SLJIT_CPUINFO_PART2 "little endian + "
2128 #elif (defined SLJIT_BIG_ENDIAN && SLJIT_BIG_ENDIAN)
2129 #define SLJIT_CPUINFO_PART2 "big endian + "
2130 #else
2131 #error "Internal error: CPU type info missing"
2132 #endif
2133 
2134 #if (defined SLJIT_UNALIGNED && SLJIT_UNALIGNED)
2135 #define SLJIT_CPUINFO_PART3 "unaligned)"
2136 #else
2137 #define SLJIT_CPUINFO_PART3 "aligned)"
2138 #endif
2139 
2140 #define SLJIT_CPUINFO SLJIT_CPUINFO_PART1 SLJIT_CPUINFO_PART2 SLJIT_CPUINFO_PART3
2141 
2142 #if (defined SLJIT_CONFIG_X86 && SLJIT_CONFIG_X86)
2143 #	include "sljitNativeX86_common.c"
2144 #elif (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5)
2145 #	include "sljitNativeARM_32.c"
2146 #elif (defined SLJIT_CONFIG_ARM_V7 && SLJIT_CONFIG_ARM_V7)
2147 #	include "sljitNativeARM_32.c"
2148 #elif (defined SLJIT_CONFIG_ARM_THUMB2 && SLJIT_CONFIG_ARM_THUMB2)
2149 #	include "sljitNativeARM_T2_32.c"
2150 #elif (defined SLJIT_CONFIG_ARM_64 && SLJIT_CONFIG_ARM_64)
2151 #	include "sljitNativeARM_64.c"
2152 #elif (defined SLJIT_CONFIG_PPC && SLJIT_CONFIG_PPC)
2153 #	include "sljitNativePPC_common.c"
2154 #elif (defined SLJIT_CONFIG_MIPS && SLJIT_CONFIG_MIPS)
2155 #	include "sljitNativeMIPS_common.c"
2156 #elif (defined SLJIT_CONFIG_SPARC && SLJIT_CONFIG_SPARC)
2157 #	include "sljitNativeSPARC_common.c"
2158 #elif (defined SLJIT_CONFIG_S390X && SLJIT_CONFIG_S390X)
2159 #	include "sljitNativeS390X.c"
2160 #endif
2161 
2162 #if !(defined SLJIT_CONFIG_MIPS && SLJIT_CONFIG_MIPS)
2163 
sljit_emit_cmp(struct sljit_compiler * compiler,sljit_s32 type,sljit_s32 src1,sljit_sw src1w,sljit_s32 src2,sljit_sw src2w)2164 SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_cmp(struct sljit_compiler *compiler, sljit_s32 type,
2165 	sljit_s32 src1, sljit_sw src1w,
2166 	sljit_s32 src2, sljit_sw src2w)
2167 {
2168 	/* Default compare for most architectures. */
2169 	sljit_s32 flags, tmp_src, condition;
2170 	sljit_sw tmp_srcw;
2171 
2172 	CHECK_ERROR_PTR();
2173 	CHECK_PTR(check_sljit_emit_cmp(compiler, type, src1, src1w, src2, src2w));
2174 
2175 	condition = type & 0xff;
2176 #if (defined SLJIT_CONFIG_ARM_64 && SLJIT_CONFIG_ARM_64)
2177 	if ((condition == SLJIT_EQUAL || condition == SLJIT_NOT_EQUAL)) {
2178 		if ((src1 & SLJIT_IMM) && !src1w) {
2179 			src1 = src2;
2180 			src1w = src2w;
2181 			src2 = SLJIT_IMM;
2182 			src2w = 0;
2183 		}
2184 		if ((src2 & SLJIT_IMM) && !src2w)
2185 			return emit_cmp_to0(compiler, type, src1, src1w);
2186 	}
2187 #endif
2188 
2189 	if (SLJIT_UNLIKELY((src1 & SLJIT_IMM) && !(src2 & SLJIT_IMM))) {
2190 		/* Immediate is preferred as second argument by most architectures. */
2191 		switch (condition) {
2192 		case SLJIT_LESS:
2193 			condition = SLJIT_GREATER;
2194 			break;
2195 		case SLJIT_GREATER_EQUAL:
2196 			condition = SLJIT_LESS_EQUAL;
2197 			break;
2198 		case SLJIT_GREATER:
2199 			condition = SLJIT_LESS;
2200 			break;
2201 		case SLJIT_LESS_EQUAL:
2202 			condition = SLJIT_GREATER_EQUAL;
2203 			break;
2204 		case SLJIT_SIG_LESS:
2205 			condition = SLJIT_SIG_GREATER;
2206 			break;
2207 		case SLJIT_SIG_GREATER_EQUAL:
2208 			condition = SLJIT_SIG_LESS_EQUAL;
2209 			break;
2210 		case SLJIT_SIG_GREATER:
2211 			condition = SLJIT_SIG_LESS;
2212 			break;
2213 		case SLJIT_SIG_LESS_EQUAL:
2214 			condition = SLJIT_SIG_GREATER_EQUAL;
2215 			break;
2216 		}
2217 
2218 		type = condition | (type & (SLJIT_32 | SLJIT_REWRITABLE_JUMP));
2219 		tmp_src = src1;
2220 		src1 = src2;
2221 		src2 = tmp_src;
2222 		tmp_srcw = src1w;
2223 		src1w = src2w;
2224 		src2w = tmp_srcw;
2225 	}
2226 
2227 	if (condition <= SLJIT_NOT_ZERO)
2228 		flags = SLJIT_SET_Z;
2229 	else
2230 		flags = condition << VARIABLE_FLAG_SHIFT;
2231 
2232 #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) \
2233 		|| (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
2234 	compiler->skip_checks = 1;
2235 #endif
2236 	PTR_FAIL_IF(sljit_emit_op2u(compiler,
2237 		SLJIT_SUB | flags | (type & SLJIT_32), src1, src1w, src2, src2w));
2238 #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) \
2239 		|| (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
2240 	compiler->skip_checks = 1;
2241 #endif
2242 	return sljit_emit_jump(compiler, condition | (type & (SLJIT_REWRITABLE_JUMP | SLJIT_32)));
2243 }
2244 
2245 #endif
2246 
sljit_emit_fcmp(struct sljit_compiler * compiler,sljit_s32 type,sljit_s32 src1,sljit_sw src1w,sljit_s32 src2,sljit_sw src2w)2247 SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_fcmp(struct sljit_compiler *compiler, sljit_s32 type,
2248 	sljit_s32 src1, sljit_sw src1w,
2249 	sljit_s32 src2, sljit_sw src2w)
2250 {
2251 	CHECK_ERROR_PTR();
2252 	CHECK_PTR(check_sljit_emit_fcmp(compiler, type, src1, src1w, src2, src2w));
2253 
2254 #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) \
2255 		|| (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
2256 	compiler->skip_checks = 1;
2257 #endif
2258 	sljit_emit_fop1(compiler, SLJIT_CMP_F64 | ((type & 0xff) << VARIABLE_FLAG_SHIFT) | (type & SLJIT_32), src1, src1w, src2, src2w);
2259 
2260 #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) \
2261 		|| (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
2262 	compiler->skip_checks = 1;
2263 #endif
2264 	return sljit_emit_jump(compiler, type);
2265 }
2266 
2267 #if !(defined SLJIT_CONFIG_ARM_32 && SLJIT_CONFIG_ARM_32) \
2268 	&& !(defined SLJIT_CONFIG_ARM_64 && SLJIT_CONFIG_ARM_64) \
2269 	&& !(defined SLJIT_CONFIG_PPC && SLJIT_CONFIG_PPC)
2270 
sljit_emit_mem(struct sljit_compiler * compiler,sljit_s32 type,sljit_s32 reg,sljit_s32 mem,sljit_sw memw)2271 SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_mem(struct sljit_compiler *compiler, sljit_s32 type,
2272 	sljit_s32 reg,
2273 	sljit_s32 mem, sljit_sw memw)
2274 {
2275 	SLJIT_UNUSED_ARG(compiler);
2276 	SLJIT_UNUSED_ARG(type);
2277 	SLJIT_UNUSED_ARG(reg);
2278 	SLJIT_UNUSED_ARG(mem);
2279 	SLJIT_UNUSED_ARG(memw);
2280 
2281 	CHECK_ERROR();
2282 	CHECK(check_sljit_emit_mem(compiler, type, reg, mem, memw));
2283 
2284 	return SLJIT_ERR_UNSUPPORTED;
2285 }
2286 
2287 #endif
2288 
2289 #if !(defined SLJIT_CONFIG_ARM_64 && SLJIT_CONFIG_ARM_64) \
2290 	&& !(defined SLJIT_CONFIG_PPC && SLJIT_CONFIG_PPC)
2291 
sljit_emit_fmem(struct sljit_compiler * compiler,sljit_s32 type,sljit_s32 freg,sljit_s32 mem,sljit_sw memw)2292 SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fmem(struct sljit_compiler *compiler, sljit_s32 type,
2293 	sljit_s32 freg,
2294 	sljit_s32 mem, sljit_sw memw)
2295 {
2296 	SLJIT_UNUSED_ARG(compiler);
2297 	SLJIT_UNUSED_ARG(type);
2298 	SLJIT_UNUSED_ARG(freg);
2299 	SLJIT_UNUSED_ARG(mem);
2300 	SLJIT_UNUSED_ARG(memw);
2301 
2302 	CHECK_ERROR();
2303 	CHECK(check_sljit_emit_fmem(compiler, type, freg, mem, memw));
2304 
2305 	return SLJIT_ERR_UNSUPPORTED;
2306 }
2307 
2308 #endif
2309 
2310 #if !(defined SLJIT_CONFIG_X86 && SLJIT_CONFIG_X86) \
2311 	&& !(defined SLJIT_CONFIG_ARM_64 && SLJIT_CONFIG_ARM_64)
2312 
sljit_get_local_base(struct sljit_compiler * compiler,sljit_s32 dst,sljit_sw dstw,sljit_sw offset)2313 SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_get_local_base(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw dstw, sljit_sw offset)
2314 {
2315 	CHECK_ERROR();
2316 	CHECK(check_sljit_get_local_base(compiler, dst, dstw, offset));
2317 
2318 	ADJUST_LOCAL_OFFSET(SLJIT_MEM1(SLJIT_SP), offset);
2319 #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) \
2320 		|| (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
2321 	compiler->skip_checks = 1;
2322 #endif
2323 	if (offset != 0)
2324 		return sljit_emit_op2(compiler, SLJIT_ADD, dst, dstw, SLJIT_SP, 0, SLJIT_IMM, offset);
2325 	return sljit_emit_op1(compiler, SLJIT_MOV, dst, dstw, SLJIT_SP, 0);
2326 }
2327 
2328 #endif
2329 
2330 #else /* SLJIT_CONFIG_UNSUPPORTED */
2331 
2332 /* Empty function bodies for those machines, which are not (yet) supported. */
2333 
sljit_get_platform_name(void)2334 SLJIT_API_FUNC_ATTRIBUTE const char* sljit_get_platform_name(void)
2335 {
2336 	return "unsupported";
2337 }
2338 
sljit_create_compiler(void * allocator_data,void * exec_allocator_data)2339 SLJIT_API_FUNC_ATTRIBUTE struct sljit_compiler* sljit_create_compiler(void *allocator_data, void *exec_allocator_data)
2340 {
2341 	SLJIT_UNUSED_ARG(allocator_data);
2342 	SLJIT_UNUSED_ARG(exec_allocator_data);
2343 	SLJIT_UNREACHABLE();
2344 	return NULL;
2345 }
2346 
sljit_free_compiler(struct sljit_compiler * compiler)2347 SLJIT_API_FUNC_ATTRIBUTE void sljit_free_compiler(struct sljit_compiler *compiler)
2348 {
2349 	SLJIT_UNUSED_ARG(compiler);
2350 	SLJIT_UNREACHABLE();
2351 }
2352 
sljit_set_compiler_memory_error(struct sljit_compiler * compiler)2353 SLJIT_API_FUNC_ATTRIBUTE void sljit_set_compiler_memory_error(struct sljit_compiler *compiler)
2354 {
2355 	SLJIT_UNUSED_ARG(compiler);
2356 	SLJIT_UNREACHABLE();
2357 }
2358 
sljit_alloc_memory(struct sljit_compiler * compiler,sljit_s32 size)2359 SLJIT_API_FUNC_ATTRIBUTE void* sljit_alloc_memory(struct sljit_compiler *compiler, sljit_s32 size)
2360 {
2361 	SLJIT_UNUSED_ARG(compiler);
2362 	SLJIT_UNUSED_ARG(size);
2363 	SLJIT_UNREACHABLE();
2364 	return NULL;
2365 }
2366 
2367 #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
sljit_compiler_verbose(struct sljit_compiler * compiler,FILE * verbose)2368 SLJIT_API_FUNC_ATTRIBUTE void sljit_compiler_verbose(struct sljit_compiler *compiler, FILE* verbose)
2369 {
2370 	SLJIT_UNUSED_ARG(compiler);
2371 	SLJIT_UNUSED_ARG(verbose);
2372 	SLJIT_UNREACHABLE();
2373 }
2374 #endif
2375 
sljit_generate_code(struct sljit_compiler * compiler)2376 SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compiler)
2377 {
2378 	SLJIT_UNUSED_ARG(compiler);
2379 	SLJIT_UNREACHABLE();
2380 	return NULL;
2381 }
2382 
sljit_has_cpu_feature(sljit_s32 feature_type)2383 SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_has_cpu_feature(sljit_s32 feature_type)
2384 {
2385 	SLJIT_UNUSED_ARG(feature_type);
2386 	SLJIT_UNREACHABLE();
2387 	return 0;
2388 }
2389 
sljit_free_code(void * code,void * exec_allocator_data)2390 SLJIT_API_FUNC_ATTRIBUTE void sljit_free_code(void* code, void *exec_allocator_data)
2391 {
2392 	SLJIT_UNUSED_ARG(code);
2393 	SLJIT_UNUSED_ARG(exec_allocator_data);
2394 	SLJIT_UNREACHABLE();
2395 }
2396 
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)2397 SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_enter(struct sljit_compiler *compiler,
2398 	sljit_s32 options, sljit_s32 arg_types, sljit_s32 scratches, sljit_s32 saveds,
2399 	sljit_s32 fscratches, sljit_s32 fsaveds, sljit_s32 local_size)
2400 {
2401 	SLJIT_UNUSED_ARG(compiler);
2402 	SLJIT_UNUSED_ARG(options);
2403 	SLJIT_UNUSED_ARG(arg_types);
2404 	SLJIT_UNUSED_ARG(scratches);
2405 	SLJIT_UNUSED_ARG(saveds);
2406 	SLJIT_UNUSED_ARG(fscratches);
2407 	SLJIT_UNUSED_ARG(fsaveds);
2408 	SLJIT_UNUSED_ARG(local_size);
2409 	SLJIT_UNREACHABLE();
2410 	return SLJIT_ERR_UNSUPPORTED;
2411 }
2412 
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)2413 SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_set_context(struct sljit_compiler *compiler,
2414 	sljit_s32 options, sljit_s32 arg_types, sljit_s32 scratches, sljit_s32 saveds,
2415 	sljit_s32 fscratches, sljit_s32 fsaveds, sljit_s32 local_size)
2416 {
2417 	SLJIT_UNUSED_ARG(compiler);
2418 	SLJIT_UNUSED_ARG(options);
2419 	SLJIT_UNUSED_ARG(arg_types);
2420 	SLJIT_UNUSED_ARG(scratches);
2421 	SLJIT_UNUSED_ARG(saveds);
2422 	SLJIT_UNUSED_ARG(fscratches);
2423 	SLJIT_UNUSED_ARG(fsaveds);
2424 	SLJIT_UNUSED_ARG(local_size);
2425 	SLJIT_UNREACHABLE();
2426 	return SLJIT_ERR_UNSUPPORTED;
2427 }
2428 
sljit_emit_return(struct sljit_compiler * compiler,sljit_s32 op,sljit_s32 src,sljit_sw srcw)2429 SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_return(struct sljit_compiler *compiler, sljit_s32 op, sljit_s32 src, sljit_sw srcw)
2430 {
2431 	SLJIT_UNUSED_ARG(compiler);
2432 	SLJIT_UNUSED_ARG(op);
2433 	SLJIT_UNUSED_ARG(src);
2434 	SLJIT_UNUSED_ARG(srcw);
2435 	SLJIT_UNREACHABLE();
2436 	return SLJIT_ERR_UNSUPPORTED;
2437 }
2438 
sljit_emit_return_void(struct sljit_compiler * compiler)2439 SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_return_void(struct sljit_compiler *compiler)
2440 {
2441 	SLJIT_UNUSED_ARG(compiler);
2442 	SLJIT_UNREACHABLE();
2443 	return SLJIT_ERR_UNSUPPORTED;
2444 }
2445 
sljit_emit_fast_enter(struct sljit_compiler * compiler,sljit_s32 dst,sljit_sw dstw)2446 SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fast_enter(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw dstw)
2447 {
2448 	SLJIT_UNUSED_ARG(compiler);
2449 	SLJIT_UNUSED_ARG(dst);
2450 	SLJIT_UNUSED_ARG(dstw);
2451 	SLJIT_UNREACHABLE();
2452 	return SLJIT_ERR_UNSUPPORTED;
2453 }
2454 
sljit_emit_op0(struct sljit_compiler * compiler,sljit_s32 op)2455 SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op0(struct sljit_compiler *compiler, sljit_s32 op)
2456 {
2457 	SLJIT_UNUSED_ARG(compiler);
2458 	SLJIT_UNUSED_ARG(op);
2459 	SLJIT_UNREACHABLE();
2460 	return SLJIT_ERR_UNSUPPORTED;
2461 }
2462 
sljit_emit_op1(struct sljit_compiler * compiler,sljit_s32 op,sljit_s32 dst,sljit_sw dstw,sljit_s32 src,sljit_sw srcw)2463 SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op1(struct sljit_compiler *compiler, sljit_s32 op,
2464 	sljit_s32 dst, sljit_sw dstw,
2465 	sljit_s32 src, sljit_sw srcw)
2466 {
2467 	SLJIT_UNUSED_ARG(compiler);
2468 	SLJIT_UNUSED_ARG(op);
2469 	SLJIT_UNUSED_ARG(dst);
2470 	SLJIT_UNUSED_ARG(dstw);
2471 	SLJIT_UNUSED_ARG(src);
2472 	SLJIT_UNUSED_ARG(srcw);
2473 	SLJIT_UNREACHABLE();
2474 	return SLJIT_ERR_UNSUPPORTED;
2475 }
2476 
sljit_emit_op2(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)2477 SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op2(struct sljit_compiler *compiler, sljit_s32 op,
2478 	sljit_s32 dst, sljit_sw dstw,
2479 	sljit_s32 src1, sljit_sw src1w,
2480 	sljit_s32 src2, sljit_sw src2w)
2481 {
2482 	SLJIT_UNUSED_ARG(compiler);
2483 	SLJIT_UNUSED_ARG(op);
2484 	SLJIT_UNUSED_ARG(dst);
2485 	SLJIT_UNUSED_ARG(dstw);
2486 	SLJIT_UNUSED_ARG(src1);
2487 	SLJIT_UNUSED_ARG(src1w);
2488 	SLJIT_UNUSED_ARG(src2);
2489 	SLJIT_UNUSED_ARG(src2w);
2490 	SLJIT_UNREACHABLE();
2491 	return SLJIT_ERR_UNSUPPORTED;
2492 }
2493 
sljit_emit_op2u(struct sljit_compiler * compiler,sljit_s32 op,sljit_s32 src1,sljit_sw src1w,sljit_s32 src2,sljit_sw src2w)2494 SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op2u(struct sljit_compiler *compiler, sljit_s32 op,
2495 	sljit_s32 src1, sljit_sw src1w,
2496 	sljit_s32 src2, sljit_sw src2w)
2497 {
2498 	SLJIT_UNUSED_ARG(compiler);
2499 	SLJIT_UNUSED_ARG(op);
2500 	SLJIT_UNUSED_ARG(src1);
2501 	SLJIT_UNUSED_ARG(src1w);
2502 	SLJIT_UNUSED_ARG(src2);
2503 	SLJIT_UNUSED_ARG(src2w);
2504 	SLJIT_UNREACHABLE();
2505 	return SLJIT_ERR_UNSUPPORTED;
2506 }
2507 
sljit_emit_op_src(struct sljit_compiler * compiler,sljit_s32 op,sljit_s32 src,sljit_sw srcw)2508 SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_src(struct sljit_compiler *compiler, sljit_s32 op,
2509 	sljit_s32 src, sljit_sw srcw)
2510 {
2511 	SLJIT_UNUSED_ARG(compiler);
2512 	SLJIT_UNUSED_ARG(op);
2513 	SLJIT_UNUSED_ARG(src);
2514 	SLJIT_UNUSED_ARG(srcw);
2515 	SLJIT_UNREACHABLE();
2516 	return SLJIT_ERR_UNSUPPORTED;
2517 }
2518 
sljit_get_register_index(sljit_s32 reg)2519 SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_get_register_index(sljit_s32 reg)
2520 {
2521 	SLJIT_UNREACHABLE();
2522 	return reg;
2523 }
2524 
sljit_emit_op_custom(struct sljit_compiler * compiler,void * instruction,sljit_u32 size)2525 SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_custom(struct sljit_compiler *compiler,
2526 	void *instruction, sljit_u32 size)
2527 {
2528 	SLJIT_UNUSED_ARG(compiler);
2529 	SLJIT_UNUSED_ARG(instruction);
2530 	SLJIT_UNUSED_ARG(size);
2531 	SLJIT_UNREACHABLE();
2532 	return SLJIT_ERR_UNSUPPORTED;
2533 }
2534 
sljit_set_current_flags(struct sljit_compiler * compiler,sljit_s32 current_flags)2535 SLJIT_API_FUNC_ATTRIBUTE void sljit_set_current_flags(struct sljit_compiler *compiler, sljit_s32 current_flags)
2536 {
2537 	SLJIT_UNUSED_ARG(compiler);
2538 	SLJIT_UNUSED_ARG(current_flags);
2539 }
2540 
sljit_emit_fop1(struct sljit_compiler * compiler,sljit_s32 op,sljit_s32 dst,sljit_sw dstw,sljit_s32 src,sljit_sw srcw)2541 SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fop1(struct sljit_compiler *compiler, sljit_s32 op,
2542 	sljit_s32 dst, sljit_sw dstw,
2543 	sljit_s32 src, sljit_sw srcw)
2544 {
2545 	SLJIT_UNUSED_ARG(compiler);
2546 	SLJIT_UNUSED_ARG(op);
2547 	SLJIT_UNUSED_ARG(dst);
2548 	SLJIT_UNUSED_ARG(dstw);
2549 	SLJIT_UNUSED_ARG(src);
2550 	SLJIT_UNUSED_ARG(srcw);
2551 	SLJIT_UNREACHABLE();
2552 	return SLJIT_ERR_UNSUPPORTED;
2553 }
2554 
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)2555 SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fop2(struct sljit_compiler *compiler, sljit_s32 op,
2556 	sljit_s32 dst, sljit_sw dstw,
2557 	sljit_s32 src1, sljit_sw src1w,
2558 	sljit_s32 src2, sljit_sw src2w)
2559 {
2560 	SLJIT_UNUSED_ARG(compiler);
2561 	SLJIT_UNUSED_ARG(op);
2562 	SLJIT_UNUSED_ARG(dst);
2563 	SLJIT_UNUSED_ARG(dstw);
2564 	SLJIT_UNUSED_ARG(src1);
2565 	SLJIT_UNUSED_ARG(src1w);
2566 	SLJIT_UNUSED_ARG(src2);
2567 	SLJIT_UNUSED_ARG(src2w);
2568 	SLJIT_UNREACHABLE();
2569 	return SLJIT_ERR_UNSUPPORTED;
2570 }
2571 
sljit_emit_label(struct sljit_compiler * compiler)2572 SLJIT_API_FUNC_ATTRIBUTE struct sljit_label* sljit_emit_label(struct sljit_compiler *compiler)
2573 {
2574 	SLJIT_UNUSED_ARG(compiler);
2575 	SLJIT_UNREACHABLE();
2576 	return NULL;
2577 }
2578 
sljit_emit_jump(struct sljit_compiler * compiler,sljit_s32 type)2579 SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_jump(struct sljit_compiler *compiler, sljit_s32 type)
2580 {
2581 	SLJIT_UNUSED_ARG(compiler);
2582 	SLJIT_UNUSED_ARG(type);
2583 	SLJIT_UNREACHABLE();
2584 	return NULL;
2585 }
2586 
sljit_emit_call(struct sljit_compiler * compiler,sljit_s32 type,sljit_s32 arg_types)2587 SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_call(struct sljit_compiler *compiler, sljit_s32 type,
2588 	sljit_s32 arg_types)
2589 {
2590 	SLJIT_UNUSED_ARG(compiler);
2591 	SLJIT_UNUSED_ARG(type);
2592 	SLJIT_UNUSED_ARG(arg_types);
2593 	SLJIT_UNREACHABLE();
2594 	return NULL;
2595 }
2596 
sljit_emit_cmp(struct sljit_compiler * compiler,sljit_s32 type,sljit_s32 src1,sljit_sw src1w,sljit_s32 src2,sljit_sw src2w)2597 SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_cmp(struct sljit_compiler *compiler, sljit_s32 type,
2598 	sljit_s32 src1, sljit_sw src1w,
2599 	sljit_s32 src2, sljit_sw src2w)
2600 {
2601 	SLJIT_UNUSED_ARG(compiler);
2602 	SLJIT_UNUSED_ARG(type);
2603 	SLJIT_UNUSED_ARG(src1);
2604 	SLJIT_UNUSED_ARG(src1w);
2605 	SLJIT_UNUSED_ARG(src2);
2606 	SLJIT_UNUSED_ARG(src2w);
2607 	SLJIT_UNREACHABLE();
2608 	return NULL;
2609 }
2610 
sljit_emit_fcmp(struct sljit_compiler * compiler,sljit_s32 type,sljit_s32 src1,sljit_sw src1w,sljit_s32 src2,sljit_sw src2w)2611 SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_fcmp(struct sljit_compiler *compiler, sljit_s32 type,
2612 	sljit_s32 src1, sljit_sw src1w,
2613 	sljit_s32 src2, sljit_sw src2w)
2614 {
2615 	SLJIT_UNUSED_ARG(compiler);
2616 	SLJIT_UNUSED_ARG(type);
2617 	SLJIT_UNUSED_ARG(src1);
2618 	SLJIT_UNUSED_ARG(src1w);
2619 	SLJIT_UNUSED_ARG(src2);
2620 	SLJIT_UNUSED_ARG(src2w);
2621 	SLJIT_UNREACHABLE();
2622 	return NULL;
2623 }
2624 
sljit_set_label(struct sljit_jump * jump,struct sljit_label * label)2625 SLJIT_API_FUNC_ATTRIBUTE void sljit_set_label(struct sljit_jump *jump, struct sljit_label* label)
2626 {
2627 	SLJIT_UNUSED_ARG(jump);
2628 	SLJIT_UNUSED_ARG(label);
2629 	SLJIT_UNREACHABLE();
2630 }
2631 
sljit_set_target(struct sljit_jump * jump,sljit_uw target)2632 SLJIT_API_FUNC_ATTRIBUTE void sljit_set_target(struct sljit_jump *jump, sljit_uw target)
2633 {
2634 	SLJIT_UNUSED_ARG(jump);
2635 	SLJIT_UNUSED_ARG(target);
2636 	SLJIT_UNREACHABLE();
2637 }
2638 
sljit_set_put_label(struct sljit_put_label * put_label,struct sljit_label * label)2639 SLJIT_API_FUNC_ATTRIBUTE void sljit_set_put_label(struct sljit_put_label *put_label, struct sljit_label *label)
2640 {
2641 	SLJIT_UNUSED_ARG(put_label);
2642 	SLJIT_UNUSED_ARG(label);
2643 	SLJIT_UNREACHABLE();
2644 }
2645 
sljit_emit_ijump(struct sljit_compiler * compiler,sljit_s32 type,sljit_s32 src,sljit_sw srcw)2646 SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_ijump(struct sljit_compiler *compiler, sljit_s32 type, sljit_s32 src, sljit_sw srcw)
2647 {
2648 	SLJIT_UNUSED_ARG(compiler);
2649 	SLJIT_UNUSED_ARG(type);
2650 	SLJIT_UNUSED_ARG(src);
2651 	SLJIT_UNUSED_ARG(srcw);
2652 	SLJIT_UNREACHABLE();
2653 	return SLJIT_ERR_UNSUPPORTED;
2654 }
2655 
sljit_emit_icall(struct sljit_compiler * compiler,sljit_s32 type,sljit_s32 arg_types,sljit_s32 src,sljit_sw srcw)2656 SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_icall(struct sljit_compiler *compiler, sljit_s32 type,
2657 	sljit_s32 arg_types,
2658 	sljit_s32 src, sljit_sw srcw)
2659 {
2660 	SLJIT_UNUSED_ARG(compiler);
2661 	SLJIT_UNUSED_ARG(type);
2662 	SLJIT_UNUSED_ARG(arg_types);
2663 	SLJIT_UNUSED_ARG(src);
2664 	SLJIT_UNUSED_ARG(srcw);
2665 	SLJIT_UNREACHABLE();
2666 	return SLJIT_ERR_UNSUPPORTED;
2667 }
2668 
sljit_emit_op_flags(struct sljit_compiler * compiler,sljit_s32 op,sljit_s32 dst,sljit_sw dstw,sljit_s32 type)2669 SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_flags(struct sljit_compiler *compiler, sljit_s32 op,
2670 	sljit_s32 dst, sljit_sw dstw,
2671 	sljit_s32 type)
2672 {
2673 	SLJIT_UNUSED_ARG(compiler);
2674 	SLJIT_UNUSED_ARG(op);
2675 	SLJIT_UNUSED_ARG(dst);
2676 	SLJIT_UNUSED_ARG(dstw);
2677 	SLJIT_UNUSED_ARG(type);
2678 	SLJIT_UNREACHABLE();
2679 	return SLJIT_ERR_UNSUPPORTED;
2680 }
2681 
sljit_emit_cmov(struct sljit_compiler * compiler,sljit_s32 type,sljit_s32 dst_reg,sljit_s32 src,sljit_sw srcw)2682 SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_cmov(struct sljit_compiler *compiler, sljit_s32 type,
2683 	sljit_s32 dst_reg,
2684 	sljit_s32 src, sljit_sw srcw)
2685 {
2686 	SLJIT_UNUSED_ARG(compiler);
2687 	SLJIT_UNUSED_ARG(type);
2688 	SLJIT_UNUSED_ARG(dst_reg);
2689 	SLJIT_UNUSED_ARG(src);
2690 	SLJIT_UNUSED_ARG(srcw);
2691 	SLJIT_UNREACHABLE();
2692 	return SLJIT_ERR_UNSUPPORTED;
2693 }
2694 
sljit_emit_mem(struct sljit_compiler * compiler,sljit_s32 type,sljit_s32 reg,sljit_s32 mem,sljit_sw memw)2695 SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_mem(struct sljit_compiler *compiler, sljit_s32 type, sljit_s32 reg, sljit_s32 mem, sljit_sw memw)
2696 {
2697 	SLJIT_UNUSED_ARG(compiler);
2698 	SLJIT_UNUSED_ARG(type);
2699 	SLJIT_UNUSED_ARG(reg);
2700 	SLJIT_UNUSED_ARG(mem);
2701 	SLJIT_UNUSED_ARG(memw);
2702 	SLJIT_UNREACHABLE();
2703 	return SLJIT_ERR_UNSUPPORTED;
2704 }
2705 
sljit_emit_fmem(struct sljit_compiler * compiler,sljit_s32 type,sljit_s32 freg,sljit_s32 mem,sljit_sw memw)2706 SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fmem(struct sljit_compiler *compiler, sljit_s32 type, sljit_s32 freg, sljit_s32 mem, sljit_sw memw)
2707 {
2708 	SLJIT_UNUSED_ARG(compiler);
2709 	SLJIT_UNUSED_ARG(type);
2710 	SLJIT_UNUSED_ARG(freg);
2711 	SLJIT_UNUSED_ARG(mem);
2712 	SLJIT_UNUSED_ARG(memw);
2713 	SLJIT_UNREACHABLE();
2714 	return SLJIT_ERR_UNSUPPORTED;
2715 }
2716 
sljit_get_local_base(struct sljit_compiler * compiler,sljit_s32 dst,sljit_sw dstw,sljit_sw offset)2717 SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_get_local_base(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw dstw, sljit_sw offset)
2718 {
2719 	SLJIT_UNUSED_ARG(compiler);
2720 	SLJIT_UNUSED_ARG(dst);
2721 	SLJIT_UNUSED_ARG(dstw);
2722 	SLJIT_UNUSED_ARG(offset);
2723 	SLJIT_UNREACHABLE();
2724 	return SLJIT_ERR_UNSUPPORTED;
2725 }
2726 
sljit_emit_const(struct sljit_compiler * compiler,sljit_s32 dst,sljit_sw dstw,sljit_sw initval)2727 SLJIT_API_FUNC_ATTRIBUTE struct sljit_const* sljit_emit_const(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw dstw, sljit_sw initval)
2728 {
2729 	SLJIT_UNUSED_ARG(compiler);
2730 	SLJIT_UNUSED_ARG(dst);
2731 	SLJIT_UNUSED_ARG(dstw);
2732 	SLJIT_UNUSED_ARG(initval);
2733 	SLJIT_UNREACHABLE();
2734 	return NULL;
2735 }
2736 
sljit_emit_put_label(struct sljit_compiler * compiler,sljit_s32 dst,sljit_sw dstw)2737 SLJIT_API_FUNC_ATTRIBUTE struct sljit_put_label* sljit_emit_put_label(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw dstw)
2738 {
2739 	SLJIT_UNUSED_ARG(compiler);
2740 	SLJIT_UNUSED_ARG(dst);
2741 	SLJIT_UNUSED_ARG(dstw);
2742 	return NULL;
2743 }
2744 
sljit_set_jump_addr(sljit_uw addr,sljit_uw new_target,sljit_sw executable_offset)2745 SLJIT_API_FUNC_ATTRIBUTE void sljit_set_jump_addr(sljit_uw addr, sljit_uw new_target, sljit_sw executable_offset)
2746 {
2747 	SLJIT_UNUSED_ARG(addr);
2748 	SLJIT_UNUSED_ARG(new_target);
2749 	SLJIT_UNUSED_ARG(executable_offset);
2750 	SLJIT_UNREACHABLE();
2751 }
2752 
sljit_set_const(sljit_uw addr,sljit_sw new_constant,sljit_sw executable_offset)2753 SLJIT_API_FUNC_ATTRIBUTE void sljit_set_const(sljit_uw addr, sljit_sw new_constant, sljit_sw executable_offset)
2754 {
2755 	SLJIT_UNUSED_ARG(addr);
2756 	SLJIT_UNUSED_ARG(new_constant);
2757 	SLJIT_UNUSED_ARG(executable_offset);
2758 	SLJIT_UNREACHABLE();
2759 }
2760 
2761 #endif /* !SLJIT_CONFIG_UNSUPPORTED */
2762