1/*	$NetBSD: sljitLir.c,v 1.7 2019/01/21 00:07:10 alnsn Exp $	*/
2
3/*
4 *    Stack-less Just-In-Time compiler
5 *
6 *    Copyright Zoltan Herczeg (hzmester@freemail.hu). All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without modification, are
9 * permitted provided that the following conditions are met:
10 *
11 *   1. Redistributions of source code must retain the above copyright notice, this list of
12 *      conditions and the following disclaimer.
13 *
14 *   2. Redistributions in binary form must reproduce the above copyright notice, this list
15 *      of conditions and the following disclaimer in the documentation and/or other materials
16 *      provided with the distribution.
17 *
18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) AND CONTRIBUTORS ``AS IS'' AND ANY
19 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
20 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
21 * SHALL THE COPYRIGHT HOLDER(S) OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
22 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
23 * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
24 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
25 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
26 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
28
29#include "sljitLir.h"
30
31#if !(defined SLJIT_STD_MACROS_DEFINED && SLJIT_STD_MACROS_DEFINED)
32
33#ifndef _KERNEL
34/* These libraries are needed for the macros below. */
35#include <stdlib.h>
36#include <string.h>
37#endif
38
39#endif /* SLJIT_STD_MACROS_DEFINED */
40
41#define CHECK_ERROR() \
42	do { \
43		if (SLJIT_UNLIKELY(compiler->error)) \
44			return compiler->error; \
45	} while (0)
46
47#define CHECK_ERROR_PTR() \
48	do { \
49		if (SLJIT_UNLIKELY(compiler->error)) \
50			return NULL; \
51	} while (0)
52
53#define FAIL_IF(expr) \
54	do { \
55		if (SLJIT_UNLIKELY(expr)) \
56			return compiler->error; \
57	} while (0)
58
59#define PTR_FAIL_IF(expr) \
60	do { \
61		if (SLJIT_UNLIKELY(expr)) \
62			return NULL; \
63	} while (0)
64
65#define FAIL_IF_NULL(ptr) \
66	do { \
67		if (SLJIT_UNLIKELY(!(ptr))) { \
68			compiler->error = SLJIT_ERR_ALLOC_FAILED; \
69			return SLJIT_ERR_ALLOC_FAILED; \
70		} \
71	} while (0)
72
73#define PTR_FAIL_IF_NULL(ptr) \
74	do { \
75		if (SLJIT_UNLIKELY(!(ptr))) { \
76			compiler->error = SLJIT_ERR_ALLOC_FAILED; \
77			return NULL; \
78		} \
79	} while (0)
80
81#define PTR_FAIL_WITH_EXEC_IF(ptr) \
82	do { \
83		if (SLJIT_UNLIKELY(!(ptr))) { \
84			compiler->error = SLJIT_ERR_EX_ALLOC_FAILED; \
85			return NULL; \
86		} \
87	} while (0)
88
89#if !(defined SLJIT_CONFIG_UNSUPPORTED && SLJIT_CONFIG_UNSUPPORTED)
90
91#define VARIABLE_FLAG_SHIFT (10)
92#define VARIABLE_FLAG_MASK (0x3f << VARIABLE_FLAG_SHIFT)
93#define GET_FLAG_TYPE(op) ((op) >> VARIABLE_FLAG_SHIFT)
94
95#define GET_OPCODE(op) \
96	((op) & ~(SLJIT_I32_OP | SLJIT_SET_Z | VARIABLE_FLAG_MASK))
97
98#define HAS_FLAGS(op) \
99	((op) & (SLJIT_SET_Z | VARIABLE_FLAG_MASK))
100
101#define GET_ALL_FLAGS(op) \
102	((op) & (SLJIT_I32_OP | SLJIT_SET_Z | VARIABLE_FLAG_MASK))
103
104#define TYPE_CAST_NEEDED(op) \
105	(((op) >= SLJIT_MOV_U8 && (op) <= SLJIT_MOV_S16) || ((op) >= SLJIT_MOVU_U8 && (op) <= SLJIT_MOVU_S16))
106
107#define BUF_SIZE	4096
108
109#if (defined SLJIT_32BIT_ARCHITECTURE && SLJIT_32BIT_ARCHITECTURE)
110#define ABUF_SIZE	2048
111#else
112#define ABUF_SIZE	4096
113#endif
114
115/* Parameter parsing. */
116#define REG_MASK		0x3f
117#define OFFS_REG(reg)		(((reg) >> 8) & REG_MASK)
118#define OFFS_REG_MASK		(REG_MASK << 8)
119#define TO_OFFS_REG(reg)	((reg) << 8)
120/* When reg cannot be unused. */
121#define FAST_IS_REG(reg)	((reg) <= REG_MASK)
122/* When reg can be unused. */
123#define SLOW_IS_REG(reg)	((reg) > 0 && (reg) <= REG_MASK)
124
125/* Jump flags. */
126#define JUMP_LABEL	0x1
127#define JUMP_ADDR	0x2
128/* SLJIT_REWRITABLE_JUMP is 0x1000. */
129
130#if (defined SLJIT_CONFIG_X86 && SLJIT_CONFIG_X86)
131#	define PATCH_MB	0x4
132#	define PATCH_MW	0x8
133#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
134#	define PATCH_MD	0x10
135#endif
136#endif
137
138#if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5) || (defined SLJIT_CONFIG_ARM_V7 && SLJIT_CONFIG_ARM_V7)
139#	define IS_BL		0x4
140#	define PATCH_B		0x8
141#endif
142
143#if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5)
144#	define CPOOL_SIZE	512
145#endif
146
147#if (defined SLJIT_CONFIG_ARM_THUMB2 && SLJIT_CONFIG_ARM_THUMB2)
148#	define IS_COND		0x04
149#	define IS_BL		0x08
150	/* conditional + imm8 */
151#	define PATCH_TYPE1	0x10
152	/* conditional + imm20 */
153#	define PATCH_TYPE2	0x20
154	/* IT + imm24 */
155#	define PATCH_TYPE3	0x30
156	/* imm11 */
157#	define PATCH_TYPE4	0x40
158	/* imm24 */
159#	define PATCH_TYPE5	0x50
160	/* BL + imm24 */
161#	define PATCH_BL		0x60
162	/* 0xf00 cc code for branches */
163#endif
164
165#if (defined SLJIT_CONFIG_ARM_64 && SLJIT_CONFIG_ARM_64)
166#	define IS_COND		0x004
167#	define IS_CBZ		0x008
168#	define IS_BL		0x010
169#	define PATCH_B		0x020
170#	define PATCH_COND	0x040
171#	define PATCH_ABS48	0x080
172#	define PATCH_ABS64	0x100
173#endif
174
175#if (defined SLJIT_CONFIG_PPC && SLJIT_CONFIG_PPC)
176#	define IS_COND		0x004
177#	define IS_CALL		0x008
178#	define PATCH_B		0x010
179#	define PATCH_ABS_B	0x020
180#if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
181#	define PATCH_ABS32	0x040
182#	define PATCH_ABS48	0x080
183#endif
184#	define REMOVE_COND	0x100
185#endif
186
187#if (defined SLJIT_CONFIG_MIPS && SLJIT_CONFIG_MIPS)
188#	define IS_MOVABLE	0x004
189#	define IS_JAL		0x008
190#	define IS_CALL		0x010
191#	define IS_BIT26_COND	0x020
192#	define IS_BIT16_COND	0x040
193
194#	define IS_COND		(IS_BIT26_COND | IS_BIT16_COND)
195
196#	define PATCH_B		0x080
197#	define PATCH_J		0x100
198
199#if (defined SLJIT_CONFIG_MIPS_64 && SLJIT_CONFIG_MIPS_64)
200#	define PATCH_ABS32	0x200
201#	define PATCH_ABS48	0x400
202#endif
203
204	/* instruction types */
205#	define MOVABLE_INS	0
206	/* 1 - 31 last destination register */
207	/* no destination (i.e: store) */
208#	define UNMOVABLE_INS	32
209	/* FPU status register */
210#	define FCSR_FCC		33
211#endif
212
213#if (defined SLJIT_CONFIG_TILEGX && SLJIT_CONFIG_TILEGX)
214#	define IS_JAL		0x04
215#	define IS_COND		0x08
216
217#	define PATCH_B		0x10
218#	define PATCH_J		0x20
219#endif
220
221#if (defined SLJIT_CONFIG_SPARC_32 && SLJIT_CONFIG_SPARC_32)
222#	define IS_MOVABLE	0x04
223#	define IS_COND		0x08
224#	define IS_CALL		0x10
225
226#	define PATCH_B		0x20
227#	define PATCH_CALL	0x40
228
229	/* instruction types */
230#	define MOVABLE_INS	0
231	/* 1 - 31 last destination register */
232	/* no destination (i.e: store) */
233#	define UNMOVABLE_INS	32
234
235#	define DST_INS_MASK	0xff
236
237	/* ICC_SET is the same as SET_FLAGS. */
238#	define ICC_IS_SET	(1 << 23)
239#	define FCC_IS_SET	(1 << 24)
240#endif
241
242/* Stack management. */
243
244#define GET_SAVED_REGISTERS_SIZE(scratches, saveds, extra) \
245	(((scratches < SLJIT_NUMBER_OF_SCRATCH_REGISTERS ? 0 : (scratches - SLJIT_NUMBER_OF_SCRATCH_REGISTERS)) + \
246		(saveds < SLJIT_NUMBER_OF_SAVED_REGISTERS ? saveds : SLJIT_NUMBER_OF_SAVED_REGISTERS) + \
247		extra) * sizeof(sljit_sw))
248
249#define ADJUST_LOCAL_OFFSET(p, i) \
250	if ((p) == (SLJIT_MEM1(SLJIT_SP))) \
251		(i) += SLJIT_LOCALS_OFFSET;
252
253#endif /* !(defined SLJIT_CONFIG_UNSUPPORTED && SLJIT_CONFIG_UNSUPPORTED) */
254
255/* Utils can still be used even if SLJIT_CONFIG_UNSUPPORTED is set. */
256#include "sljitUtils.c"
257
258#if !(defined SLJIT_CONFIG_UNSUPPORTED && SLJIT_CONFIG_UNSUPPORTED)
259
260#if (defined SLJIT_EXECUTABLE_ALLOCATOR && SLJIT_EXECUTABLE_ALLOCATOR)
261
262#if (defined SLJIT_PROT_EXECUTABLE_ALLOCATOR && SLJIT_PROT_EXECUTABLE_ALLOCATOR)
263#include "sljitProtExecAllocator.c"
264#else
265#include "sljitExecAllocator.c"
266#endif
267
268#endif
269
270#if (defined SLJIT_PROT_EXECUTABLE_ALLOCATOR && SLJIT_PROT_EXECUTABLE_ALLOCATOR)
271#define SLJIT_ADD_EXEC_OFFSET(ptr, exec_offset) ((sljit_u8 *)(ptr) + (exec_offset))
272#else
273#define SLJIT_ADD_EXEC_OFFSET(ptr, exec_offset) ((sljit_u8 *)(ptr))
274#endif
275
276/* Argument checking features. */
277
278#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
279
280/* Returns with error when an invalid argument is passed. */
281
282#define CHECK_ARGUMENT(x) \
283	do { \
284		if (SLJIT_UNLIKELY(!(x))) \
285			return 1; \
286	} while (0)
287
288#define CHECK_RETURN_TYPE sljit_s32
289#define CHECK_RETURN_OK return 0
290
291#define CHECK(x) \
292	do { \
293		if (SLJIT_UNLIKELY(x)) { \
294			compiler->error = SLJIT_ERR_BAD_ARGUMENT; \
295			return SLJIT_ERR_BAD_ARGUMENT; \
296		} \
297	} while (0)
298
299#define CHECK_PTR(x) \
300	do { \
301		if (SLJIT_UNLIKELY(x)) { \
302			compiler->error = SLJIT_ERR_BAD_ARGUMENT; \
303			return NULL; \
304		} \
305	} while (0)
306
307#define CHECK_REG_INDEX(x) \
308	do { \
309		if (SLJIT_UNLIKELY(x)) { \
310			return -2; \
311		} \
312	} while (0)
313
314#elif (defined SLJIT_DEBUG && SLJIT_DEBUG)
315
316/* Assertion failure occures if an invalid argument is passed. */
317#undef SLJIT_ARGUMENT_CHECKS
318#define SLJIT_ARGUMENT_CHECKS 1
319
320#define CHECK_ARGUMENT(x) SLJIT_ASSERT(x)
321#define CHECK_RETURN_TYPE void
322#define CHECK_RETURN_OK return
323#define CHECK(x) x
324#define CHECK_PTR(x) x
325#define CHECK_REG_INDEX(x) x
326
327#elif (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
328
329/* Arguments are not checked. */
330#define CHECK_RETURN_TYPE void
331#define CHECK_RETURN_OK return
332#define CHECK(x) x
333#define CHECK_PTR(x) x
334#define CHECK_REG_INDEX(x) x
335
336#else
337
338/* Arguments are not checked. */
339#define CHECK(x)
340#define CHECK_PTR(x)
341#define CHECK_REG_INDEX(x)
342
343#endif /* SLJIT_ARGUMENT_CHECKS */
344
345/* --------------------------------------------------------------------- */
346/*  Public functions                                                     */
347/* --------------------------------------------------------------------- */
348
349#if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5) || (defined SLJIT_CONFIG_X86 && SLJIT_CONFIG_X86)
350#define SLJIT_NEEDS_COMPILER_INIT 1
351static sljit_s32 compiler_initialized = 0;
352/* A thread safe initialization. */
353static void init_compiler(void);
354#endif
355
356SLJIT_API_FUNC_ATTRIBUTE struct sljit_compiler* sljit_create_compiler(void *allocator_data)
357{
358	struct sljit_compiler *compiler = (struct sljit_compiler*)SLJIT_MALLOC(sizeof(struct sljit_compiler), allocator_data);
359	if (!compiler)
360		return NULL;
361	SLJIT_ZEROMEM(compiler, sizeof(struct sljit_compiler));
362
363	SLJIT_COMPILE_ASSERT(
364		sizeof(sljit_s8) == 1 && sizeof(sljit_u8) == 1
365		&& sizeof(sljit_s16) == 2 && sizeof(sljit_u16) == 2
366		&& sizeof(sljit_s32) == 4 && sizeof(sljit_u32) == 4
367		&& (sizeof(sljit_p) == 4 || sizeof(sljit_p) == 8)
368		&& sizeof(sljit_p) <= sizeof(sljit_sw)
369		&& (sizeof(sljit_sw) == 4 || sizeof(sljit_sw) == 8)
370		&& (sizeof(sljit_uw) == 4 || sizeof(sljit_uw) == 8),
371		invalid_integer_types);
372	SLJIT_COMPILE_ASSERT(SLJIT_I32_OP == SLJIT_F32_OP,
373		int_op_and_single_op_must_be_the_same);
374	SLJIT_COMPILE_ASSERT(SLJIT_REWRITABLE_JUMP != SLJIT_F32_OP,
375		rewritable_jump_and_single_op_must_not_be_the_same);
376	SLJIT_COMPILE_ASSERT(!(SLJIT_EQUAL & 0x1) && !(SLJIT_LESS & 0x1) && !(SLJIT_EQUAL_F64 & 0x1) && !(SLJIT_JUMP & 0x1),
377		conditional_flags_must_be_even_numbers);
378
379	/* Only the non-zero members must be set. */
380	compiler->error = SLJIT_SUCCESS;
381
382	compiler->allocator_data = allocator_data;
383	compiler->buf = (struct sljit_memory_fragment*)SLJIT_MALLOC(BUF_SIZE, allocator_data);
384	compiler->abuf = (struct sljit_memory_fragment*)SLJIT_MALLOC(ABUF_SIZE, allocator_data);
385
386	if (!compiler->buf || !compiler->abuf) {
387		if (compiler->buf)
388			SLJIT_FREE(compiler->buf, allocator_data);
389		if (compiler->abuf)
390			SLJIT_FREE(compiler->abuf, allocator_data);
391		SLJIT_FREE(compiler, allocator_data);
392		return NULL;
393	}
394
395	compiler->buf->next = NULL;
396	compiler->buf->used_size = 0;
397	compiler->abuf->next = NULL;
398	compiler->abuf->used_size = 0;
399
400	compiler->scratches = -1;
401	compiler->saveds = -1;
402	compiler->fscratches = -1;
403	compiler->fsaveds = -1;
404	compiler->local_size = -1;
405
406#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
407	compiler->args = -1;
408#endif
409
410#if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5)
411	compiler->cpool = (sljit_uw*)SLJIT_MALLOC(CPOOL_SIZE * sizeof(sljit_uw)
412		+ CPOOL_SIZE * sizeof(sljit_u8), allocator_data);
413	if (!compiler->cpool) {
414		SLJIT_FREE(compiler->buf, allocator_data);
415		SLJIT_FREE(compiler->abuf, allocator_data);
416		SLJIT_FREE(compiler, allocator_data);
417		return NULL;
418	}
419	compiler->cpool_unique = (sljit_u8*)(compiler->cpool + CPOOL_SIZE);
420	compiler->cpool_diff = 0xffffffff;
421#endif
422
423#if (defined SLJIT_CONFIG_MIPS && SLJIT_CONFIG_MIPS)
424	compiler->delay_slot = UNMOVABLE_INS;
425#endif
426
427#if (defined SLJIT_CONFIG_SPARC_32 && SLJIT_CONFIG_SPARC_32)
428	compiler->delay_slot = UNMOVABLE_INS;
429#endif
430
431#if (defined SLJIT_NEEDS_COMPILER_INIT && SLJIT_NEEDS_COMPILER_INIT)
432	if (!compiler_initialized) {
433		init_compiler();
434		compiler_initialized = 1;
435	}
436#endif
437
438	return compiler;
439}
440
441SLJIT_API_FUNC_ATTRIBUTE void sljit_free_compiler(struct sljit_compiler *compiler)
442{
443	struct sljit_memory_fragment *buf;
444	struct sljit_memory_fragment *curr;
445	void *allocator_data = compiler->allocator_data;
446	SLJIT_UNUSED_ARG(allocator_data);
447
448	buf = compiler->buf;
449	while (buf) {
450		curr = buf;
451		buf = buf->next;
452		SLJIT_FREE(curr, allocator_data);
453	}
454
455	buf = compiler->abuf;
456	while (buf) {
457		curr = buf;
458		buf = buf->next;
459		SLJIT_FREE(curr, allocator_data);
460	}
461
462#if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5)
463	SLJIT_FREE(compiler->cpool, allocator_data);
464#endif
465	SLJIT_FREE(compiler, allocator_data);
466}
467
468SLJIT_API_FUNC_ATTRIBUTE void sljit_set_compiler_memory_error(struct sljit_compiler *compiler)
469{
470	if (compiler->error == SLJIT_SUCCESS)
471		compiler->error = SLJIT_ERR_ALLOC_FAILED;
472}
473
474#if (defined SLJIT_CONFIG_ARM_THUMB2 && SLJIT_CONFIG_ARM_THUMB2)
475SLJIT_API_FUNC_ATTRIBUTE void sljit_free_code(void* code)
476{
477	/* Remove thumb mode flag. */
478	SLJIT_FREE_EXEC((void*)((sljit_uw)code & ~0x1));
479}
480#elif (defined SLJIT_INDIRECT_CALL && SLJIT_INDIRECT_CALL)
481SLJIT_API_FUNC_ATTRIBUTE void sljit_free_code(void* code)
482{
483	/* Resolve indirection. */
484	code = (void*)(*(sljit_uw*)code);
485	SLJIT_FREE_EXEC(code);
486}
487#else
488SLJIT_API_FUNC_ATTRIBUTE void sljit_free_code(void* code)
489{
490	SLJIT_FREE_EXEC(code);
491}
492#endif
493
494SLJIT_API_FUNC_ATTRIBUTE void sljit_set_label(struct sljit_jump *jump, struct sljit_label* label)
495{
496	if (SLJIT_LIKELY(!!jump) && SLJIT_LIKELY(!!label)) {
497		jump->flags &= ~JUMP_ADDR;
498		jump->flags |= JUMP_LABEL;
499		jump->u.label = label;
500	}
501}
502
503SLJIT_API_FUNC_ATTRIBUTE void sljit_set_target(struct sljit_jump *jump, sljit_uw target)
504{
505	if (SLJIT_LIKELY(!!jump)) {
506		jump->flags &= ~JUMP_LABEL;
507		jump->flags |= JUMP_ADDR;
508		jump->u.target = target;
509	}
510}
511
512SLJIT_API_FUNC_ATTRIBUTE void sljit_set_current_flags(struct sljit_compiler *compiler, sljit_s32 current_flags)
513{
514	SLJIT_UNUSED_ARG(compiler);
515	SLJIT_UNUSED_ARG(current_flags);
516
517#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
518	if ((current_flags & ~(VARIABLE_FLAG_MASK | SLJIT_I32_OP | SLJIT_SET_Z)) == 0) {
519		compiler->last_flags = GET_FLAG_TYPE(current_flags) | (current_flags & (SLJIT_I32_OP | SLJIT_SET_Z));
520	}
521#endif
522}
523
524/* --------------------------------------------------------------------- */
525/*  Private functions                                                    */
526/* --------------------------------------------------------------------- */
527
528static void* ensure_buf(struct sljit_compiler *compiler, sljit_uw size)
529{
530	sljit_u8 *ret;
531	struct sljit_memory_fragment *new_frag;
532
533	SLJIT_ASSERT(size <= 256);
534	if (compiler->buf->used_size + size <= (BUF_SIZE - (sljit_uw)SLJIT_OFFSETOF(struct sljit_memory_fragment, memory))) {
535		ret = compiler->buf->memory + compiler->buf->used_size;
536		compiler->buf->used_size += size;
537		return ret;
538	}
539	new_frag = (struct sljit_memory_fragment*)SLJIT_MALLOC(BUF_SIZE, compiler->allocator_data);
540	PTR_FAIL_IF_NULL(new_frag);
541	new_frag->next = compiler->buf;
542	compiler->buf = new_frag;
543	new_frag->used_size = size;
544	return new_frag->memory;
545}
546
547static void* ensure_abuf(struct sljit_compiler *compiler, sljit_uw size)
548{
549	sljit_u8 *ret;
550	struct sljit_memory_fragment *new_frag;
551
552	SLJIT_ASSERT(size <= 256);
553	if (compiler->abuf->used_size + size <= (ABUF_SIZE - (sljit_uw)SLJIT_OFFSETOF(struct sljit_memory_fragment, memory))) {
554		ret = compiler->abuf->memory + compiler->abuf->used_size;
555		compiler->abuf->used_size += size;
556		return ret;
557	}
558	new_frag = (struct sljit_memory_fragment*)SLJIT_MALLOC(ABUF_SIZE, compiler->allocator_data);
559	PTR_FAIL_IF_NULL(new_frag);
560	new_frag->next = compiler->abuf;
561	compiler->abuf = new_frag;
562	new_frag->used_size = size;
563	return new_frag->memory;
564}
565
566SLJIT_API_FUNC_ATTRIBUTE void* sljit_alloc_memory(struct sljit_compiler *compiler, sljit_s32 size)
567{
568	CHECK_ERROR_PTR();
569
570#if (defined SLJIT_64BIT_ARCHITECTURE && SLJIT_64BIT_ARCHITECTURE)
571	if (size <= 0 || size > 128)
572		return NULL;
573	size = (size + 7) & ~7;
574#else
575	if (size <= 0 || size > 64)
576		return NULL;
577	size = (size + 3) & ~3;
578#endif
579	return ensure_abuf(compiler, size);
580}
581
582static SLJIT_INLINE void reverse_buf(struct sljit_compiler *compiler)
583{
584	struct sljit_memory_fragment *buf = compiler->buf;
585	struct sljit_memory_fragment *prev = NULL;
586	struct sljit_memory_fragment *tmp;
587
588	do {
589		tmp = buf->next;
590		buf->next = prev;
591		prev = buf;
592		buf = tmp;
593	} while (buf != NULL);
594
595	compiler->buf = prev;
596}
597
598static SLJIT_INLINE void set_emit_enter(struct sljit_compiler *compiler,
599	sljit_s32 options, sljit_s32 args, sljit_s32 scratches, sljit_s32 saveds,
600	sljit_s32 fscratches, sljit_s32 fsaveds, sljit_s32 local_size)
601{
602	SLJIT_UNUSED_ARG(args);
603	SLJIT_UNUSED_ARG(local_size);
604
605	compiler->options = options;
606	compiler->scratches = scratches;
607	compiler->saveds = saveds;
608	compiler->fscratches = fscratches;
609	compiler->fsaveds = fsaveds;
610#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
611	compiler->logical_local_size = local_size;
612#endif
613}
614
615static SLJIT_INLINE void set_set_context(struct sljit_compiler *compiler,
616	sljit_s32 options, sljit_s32 args, sljit_s32 scratches, sljit_s32 saveds,
617	sljit_s32 fscratches, sljit_s32 fsaveds, sljit_s32 local_size)
618{
619	SLJIT_UNUSED_ARG(args);
620	SLJIT_UNUSED_ARG(local_size);
621
622	compiler->options = options;
623	compiler->scratches = scratches;
624	compiler->saveds = saveds;
625	compiler->fscratches = fscratches;
626	compiler->fsaveds = fsaveds;
627#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
628	compiler->logical_local_size = local_size;
629#endif
630}
631
632static SLJIT_INLINE void set_label(struct sljit_label *label, struct sljit_compiler *compiler)
633{
634	label->next = NULL;
635	label->size = compiler->size;
636	if (compiler->last_label)
637		compiler->last_label->next = label;
638	else
639		compiler->labels = label;
640	compiler->last_label = label;
641}
642
643static SLJIT_INLINE void set_jump(struct sljit_jump *jump, struct sljit_compiler *compiler, sljit_s32 flags)
644{
645	jump->next = NULL;
646	jump->flags = flags;
647	if (compiler->last_jump)
648		compiler->last_jump->next = jump;
649	else
650		compiler->jumps = jump;
651	compiler->last_jump = jump;
652}
653
654static SLJIT_INLINE void set_const(struct sljit_const *const_, struct sljit_compiler *compiler)
655{
656	const_->next = NULL;
657	const_->addr = compiler->size;
658	if (compiler->last_const)
659		compiler->last_const->next = const_;
660	else
661		compiler->consts = const_;
662	compiler->last_const = const_;
663}
664
665#define ADDRESSING_DEPENDS_ON(exp, reg) \
666	(((exp) & SLJIT_MEM) && (((exp) & REG_MASK) == reg || OFFS_REG(exp) == reg))
667
668#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
669
670#define FUNCTION_CHECK_IS_REG(r) \
671	(((r) >= SLJIT_R0 && (r) < (SLJIT_R0 + compiler->scratches)) || \
672	((r) > (SLJIT_S0 - compiler->saveds) && (r) <= SLJIT_S0))
673
674#define FUNCTION_CHECK_IS_REG_OR_UNUSED(r) \
675	((r) == SLJIT_UNUSED || \
676	((r) >= SLJIT_R0 && (r) < (SLJIT_R0 + compiler->scratches)) || \
677	((r) > (SLJIT_S0 - compiler->saveds) && (r) <= SLJIT_S0))
678
679#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
680#define CHECK_NOT_VIRTUAL_REGISTER(p) \
681	CHECK_ARGUMENT((p) < SLJIT_R3 || (p) > SLJIT_R6);
682#else
683#define CHECK_NOT_VIRTUAL_REGISTER(p)
684#endif
685
686#define FUNCTION_CHECK_SRC(p, i) \
687	CHECK_ARGUMENT(compiler->scratches != -1 && compiler->saveds != -1); \
688	if (FUNCTION_CHECK_IS_REG(p)) \
689		CHECK_ARGUMENT((i) == 0); \
690	else if ((p) == SLJIT_IMM) \
691		; \
692	else if ((p) == (SLJIT_MEM1(SLJIT_SP))) \
693		CHECK_ARGUMENT((i) >= 0 && (i) < compiler->logical_local_size); \
694	else { \
695		CHECK_ARGUMENT((p) & SLJIT_MEM); \
696		CHECK_ARGUMENT(FUNCTION_CHECK_IS_REG_OR_UNUSED((p) & REG_MASK)); \
697		CHECK_NOT_VIRTUAL_REGISTER((p) & REG_MASK); \
698		if ((p) & OFFS_REG_MASK) { \
699			CHECK_ARGUMENT(((p) & REG_MASK) != SLJIT_UNUSED); \
700			CHECK_ARGUMENT(FUNCTION_CHECK_IS_REG(OFFS_REG(p))); \
701			CHECK_NOT_VIRTUAL_REGISTER(OFFS_REG(p)); \
702			CHECK_ARGUMENT(!((i) & ~0x3)); \
703		} \
704		CHECK_ARGUMENT(!((p) & ~(SLJIT_MEM | SLJIT_IMM | REG_MASK | OFFS_REG_MASK))); \
705	}
706
707#define FUNCTION_CHECK_DST(p, i) \
708	CHECK_ARGUMENT(compiler->scratches != -1 && compiler->saveds != -1); \
709	if (FUNCTION_CHECK_IS_REG_OR_UNUSED(p)) \
710		CHECK_ARGUMENT((i) == 0); \
711	else if ((p) == (SLJIT_MEM1(SLJIT_SP))) \
712		CHECK_ARGUMENT((i) >= 0 && (i) < compiler->logical_local_size); \
713	else { \
714		CHECK_ARGUMENT((p) & SLJIT_MEM); \
715		CHECK_ARGUMENT(FUNCTION_CHECK_IS_REG_OR_UNUSED((p) & REG_MASK)); \
716		CHECK_NOT_VIRTUAL_REGISTER((p) & REG_MASK); \
717		if ((p) & OFFS_REG_MASK) { \
718			CHECK_ARGUMENT(((p) & REG_MASK) != SLJIT_UNUSED); \
719			CHECK_ARGUMENT(FUNCTION_CHECK_IS_REG(OFFS_REG(p))); \
720			CHECK_NOT_VIRTUAL_REGISTER(OFFS_REG(p)); \
721			CHECK_ARGUMENT(!((i) & ~0x3)); \
722		} \
723		CHECK_ARGUMENT(!((p) & ~(SLJIT_MEM | SLJIT_IMM | REG_MASK | OFFS_REG_MASK))); \
724	}
725
726#define FUNCTION_FCHECK(p, i) \
727	CHECK_ARGUMENT(compiler->fscratches != -1 && compiler->fsaveds != -1); \
728	if (((p) >= SLJIT_FR0 && (p) < (SLJIT_FR0 + compiler->fscratches)) || \
729			((p) > (SLJIT_FS0 - compiler->fsaveds) && (p) <= SLJIT_FS0)) \
730		CHECK_ARGUMENT(i == 0); \
731	else if ((p) == (SLJIT_MEM1(SLJIT_SP))) \
732		CHECK_ARGUMENT((i) >= 0 && (i) < compiler->logical_local_size); \
733	else { \
734		CHECK_ARGUMENT((p) & SLJIT_MEM); \
735		CHECK_ARGUMENT(FUNCTION_CHECK_IS_REG_OR_UNUSED((p) & REG_MASK)); \
736		CHECK_NOT_VIRTUAL_REGISTER((p) & REG_MASK); \
737		if ((p) & OFFS_REG_MASK) { \
738			CHECK_ARGUMENT(((p) & REG_MASK) != SLJIT_UNUSED); \
739			CHECK_ARGUMENT(FUNCTION_CHECK_IS_REG(OFFS_REG(p))); \
740			CHECK_NOT_VIRTUAL_REGISTER(OFFS_REG(p)); \
741			CHECK_ARGUMENT(((p) & OFFS_REG_MASK) != TO_OFFS_REG(SLJIT_SP) && !(i & ~0x3)); \
742		} \
743		CHECK_ARGUMENT(!((p) & ~(SLJIT_MEM | SLJIT_IMM | REG_MASK | OFFS_REG_MASK))); \
744	}
745
746#endif /* SLJIT_ARGUMENT_CHECKS */
747
748#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
749
750SLJIT_API_FUNC_ATTRIBUTE void sljit_compiler_verbose(struct sljit_compiler *compiler, FILE* verbose)
751{
752	compiler->verbose = verbose;
753}
754
755#if (defined SLJIT_64BIT_ARCHITECTURE && SLJIT_64BIT_ARCHITECTURE)
756#ifdef _WIN64
757#	define SLJIT_PRINT_D	"I64"
758#else
759#	define SLJIT_PRINT_D	"l"
760#endif
761#else
762#	define SLJIT_PRINT_D	""
763#endif
764
765#define sljit_verbose_reg(compiler, r) \
766	do { \
767		if ((r) < (SLJIT_R0 + compiler->scratches)) \
768			fprintf(compiler->verbose, "r%d", (r) - SLJIT_R0); \
769		else if ((r) != SLJIT_SP) \
770			fprintf(compiler->verbose, "s%d", SLJIT_NUMBER_OF_REGISTERS - (r)); \
771		else \
772			fprintf(compiler->verbose, "sp"); \
773	} while (0)
774
775#define sljit_verbose_param(compiler, p, i) \
776	if ((p) & SLJIT_IMM) \
777		fprintf(compiler->verbose, "#%" SLJIT_PRINT_D "d", (i)); \
778	else if ((p) & SLJIT_MEM) { \
779		if ((p) & REG_MASK) { \
780			fputc('[', compiler->verbose); \
781			sljit_verbose_reg(compiler, (p) & REG_MASK); \
782			if ((p) & OFFS_REG_MASK) { \
783				fprintf(compiler->verbose, " + "); \
784				sljit_verbose_reg(compiler, OFFS_REG(p)); \
785				if (i) \
786					fprintf(compiler->verbose, " * %d", 1 << (i)); \
787			} \
788			else if (i) \
789				fprintf(compiler->verbose, " + %" SLJIT_PRINT_D "d", (i)); \
790			fputc(']', compiler->verbose); \
791		} \
792		else \
793			fprintf(compiler->verbose, "[#%" SLJIT_PRINT_D "d]", (i)); \
794	} else if (p) \
795		sljit_verbose_reg(compiler, p); \
796	else \
797		fprintf(compiler->verbose, "unused");
798
799#define sljit_verbose_fparam(compiler, p, i) \
800	if ((p) & SLJIT_MEM) { \
801		if ((p) & REG_MASK) { \
802			fputc('[', compiler->verbose); \
803			sljit_verbose_reg(compiler, (p) & REG_MASK); \
804			if ((p) & OFFS_REG_MASK) { \
805				fprintf(compiler->verbose, " + "); \
806				sljit_verbose_reg(compiler, OFFS_REG(p)); \
807				if (i) \
808					fprintf(compiler->verbose, "%d", 1 << (i)); \
809			} \
810			else if (i) \
811				fprintf(compiler->verbose, "%" SLJIT_PRINT_D "d", (i)); \
812			fputc(']', compiler->verbose); \
813		} \
814		else \
815			fprintf(compiler->verbose, "[#%" SLJIT_PRINT_D "d]", (i)); \
816	} \
817	else { \
818		if ((p) < (SLJIT_FR0 + compiler->fscratches)) \
819			fprintf(compiler->verbose, "fr%d", (p) - SLJIT_FR0); \
820		else \
821			fprintf(compiler->verbose, "fs%d", SLJIT_NUMBER_OF_FLOAT_REGISTERS - (p)); \
822	}
823
824static const char* op0_names[] = {
825	(char*)"breakpoint", (char*)"nop", (char*)"lmul.uw", (char*)"lmul.sw",
826	(char*)"divmod.u", (char*)"divmod.s", (char*)"div.u", (char*)"div.s"
827};
828
829static const char* op1_names[] = {
830	(char*)"", (char*)".u8", (char*)".s8", (char*)".u16",
831	(char*)".s16", (char*)".u32", (char*)".s32", (char*)".p",
832	(char*)"", (char*)".u8", (char*)".s8", (char*)".u16",
833	(char*)".s16", (char*)".u32", (char*)".s32", (char*)".p",
834	(char*)"not", (char*)"neg", (char*)"clz",
835};
836
837static const char* op2_names[] = {
838	(char*)"add", (char*)"addc", (char*)"sub", (char*)"subc",
839	(char*)"mul", (char*)"and", (char*)"or", (char*)"xor",
840	(char*)"shl", (char*)"lshr", (char*)"ashr",
841};
842
843static const char* fop1_names[] = {
844	(char*)"mov", (char*)"conv", (char*)"conv", (char*)"conv",
845	(char*)"conv", (char*)"conv", (char*)"cmp", (char*)"neg",
846	(char*)"abs",
847};
848
849static const char* fop2_names[] = {
850	(char*)"add", (char*)"sub", (char*)"mul", (char*)"div"
851};
852
853#define JUMP_POSTFIX(type) \
854	((type & 0xff) <= SLJIT_MUL_NOT_OVERFLOW ? ((type & SLJIT_I32_OP) ? "32" : "") \
855	: ((type & 0xff) <= SLJIT_ORDERED_F64 ? ((type & SLJIT_F32_OP) ? ".f32" : ".f64") : ""))
856
857static char* jump_names[] = {
858	(char*)"equal", (char*)"not_equal",
859	(char*)"less", (char*)"greater_equal",
860	(char*)"greater", (char*)"less_equal",
861	(char*)"sig_less", (char*)"sig_greater_equal",
862	(char*)"sig_greater", (char*)"sig_less_equal",
863	(char*)"overflow", (char*)"not_overflow",
864	(char*)"mul_overflow", (char*)"mul_not_overflow",
865	(char*)"carry", (char*)"",
866	(char*)"equal", (char*)"not_equal",
867	(char*)"less", (char*)"greater_equal",
868	(char*)"greater", (char*)"less_equal",
869	(char*)"unordered", (char*)"ordered",
870	(char*)"jump", (char*)"fast_call",
871	(char*)"call0", (char*)"call1", (char*)"call2", (char*)"call3"
872};
873
874#endif /* SLJIT_VERBOSE */
875
876/* --------------------------------------------------------------------- */
877/*  Arch dependent                                                       */
878/* --------------------------------------------------------------------- */
879
880#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS) \
881	|| (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
882
883static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_generate_code(struct sljit_compiler *compiler)
884{
885#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
886	struct sljit_jump *jump;
887#endif
888
889	SLJIT_UNUSED_ARG(compiler);
890
891#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
892	CHECK_ARGUMENT(compiler->size > 0);
893	jump = compiler->jumps;
894	while (jump) {
895		/* All jumps have target. */
896		CHECK_ARGUMENT(jump->flags & (JUMP_LABEL | JUMP_ADDR));
897		jump = jump->next;
898	}
899#endif
900	CHECK_RETURN_OK;
901}
902
903static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_enter(struct sljit_compiler *compiler,
904	sljit_s32 options, sljit_s32 args, sljit_s32 scratches, sljit_s32 saveds,
905	sljit_s32 fscratches, sljit_s32 fsaveds, sljit_s32 local_size)
906{
907	SLJIT_UNUSED_ARG(compiler);
908
909#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
910	CHECK_ARGUMENT(!(options & ~SLJIT_F64_ALIGNMENT));
911	CHECK_ARGUMENT(args >= 0 && args <= 3);
912	CHECK_ARGUMENT(scratches >= 0 && scratches <= SLJIT_NUMBER_OF_REGISTERS);
913	CHECK_ARGUMENT(saveds >= 0 && saveds <= SLJIT_NUMBER_OF_REGISTERS);
914	CHECK_ARGUMENT(scratches + saveds <= SLJIT_NUMBER_OF_REGISTERS);
915	CHECK_ARGUMENT(args <= saveds);
916	CHECK_ARGUMENT(fscratches >= 0 && fscratches <= SLJIT_NUMBER_OF_FLOAT_REGISTERS);
917	CHECK_ARGUMENT(fsaveds >= 0 && fsaveds <= SLJIT_NUMBER_OF_FLOAT_REGISTERS);
918	CHECK_ARGUMENT(fscratches + fsaveds <= SLJIT_NUMBER_OF_FLOAT_REGISTERS);
919	CHECK_ARGUMENT(local_size >= 0 && local_size <= SLJIT_MAX_LOCAL_SIZE);
920	compiler->last_flags = 0;
921#endif
922#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
923	if (SLJIT_UNLIKELY(!!compiler->verbose))
924		fprintf(compiler->verbose, "  enter options:none args:%d scratches:%d saveds:%d fscratches:%d fsaveds:%d local_size:%d\n",
925			args, scratches, saveds, fscratches, fsaveds, local_size);
926#endif
927	CHECK_RETURN_OK;
928}
929
930static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_set_context(struct sljit_compiler *compiler,
931	sljit_s32 options, sljit_s32 args, sljit_s32 scratches, sljit_s32 saveds,
932	sljit_s32 fscratches, sljit_s32 fsaveds, sljit_s32 local_size)
933{
934#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
935	CHECK_ARGUMENT(!(options & ~SLJIT_F64_ALIGNMENT));
936	CHECK_ARGUMENT(args >= 0 && args <= 3);
937	CHECK_ARGUMENT(scratches >= 0 && scratches <= SLJIT_NUMBER_OF_REGISTERS);
938	CHECK_ARGUMENT(saveds >= 0 && saveds <= SLJIT_NUMBER_OF_REGISTERS);
939	CHECK_ARGUMENT(scratches + saveds <= SLJIT_NUMBER_OF_REGISTERS);
940	CHECK_ARGUMENT(args <= saveds);
941	CHECK_ARGUMENT(fscratches >= 0 && fscratches <= SLJIT_NUMBER_OF_FLOAT_REGISTERS);
942	CHECK_ARGUMENT(fsaveds >= 0 && fsaveds <= SLJIT_NUMBER_OF_FLOAT_REGISTERS);
943	CHECK_ARGUMENT(fscratches + fsaveds <= SLJIT_NUMBER_OF_FLOAT_REGISTERS);
944	CHECK_ARGUMENT(local_size >= 0 && local_size <= SLJIT_MAX_LOCAL_SIZE);
945	compiler->last_flags = 0;
946#endif
947#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
948	if (SLJIT_UNLIKELY(!!compiler->verbose))
949		fprintf(compiler->verbose, "  set_context options:none args:%d scratches:%d saveds:%d fscratches:%d fsaveds:%d local_size:%d\n",
950			args, scratches, saveds, fscratches, fsaveds, local_size);
951#endif
952	CHECK_RETURN_OK;
953}
954
955static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_return(struct sljit_compiler *compiler, sljit_s32 op, sljit_s32 src, sljit_sw srcw)
956{
957#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
958	CHECK_ARGUMENT(compiler->scratches >= 0);
959	if (op != SLJIT_UNUSED) {
960		CHECK_ARGUMENT(op >= SLJIT_MOV && op <= SLJIT_MOV_P);
961		FUNCTION_CHECK_SRC(src, srcw);
962	}
963	else
964		CHECK_ARGUMENT(src == 0 && srcw == 0);
965	compiler->last_flags = 0;
966#endif
967#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
968	if (SLJIT_UNLIKELY(!!compiler->verbose)) {
969		if (op == SLJIT_UNUSED)
970			fprintf(compiler->verbose, "  return\n");
971		else {
972			fprintf(compiler->verbose, "  return%s ", op1_names[op - SLJIT_OP1_BASE]);
973			sljit_verbose_param(compiler, src, srcw);
974			fprintf(compiler->verbose, "\n");
975		}
976	}
977#endif
978	CHECK_RETURN_OK;
979}
980
981static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_fast_enter(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw dstw)
982{
983#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
984	FUNCTION_CHECK_DST(dst, dstw);
985	compiler->last_flags = 0;
986#endif
987#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
988	if (SLJIT_UNLIKELY(!!compiler->verbose)) {
989		fprintf(compiler->verbose, "  fast_enter ");
990		sljit_verbose_param(compiler, dst, dstw);
991		fprintf(compiler->verbose, "\n");
992	}
993#endif
994	CHECK_RETURN_OK;
995}
996
997static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_fast_return(struct sljit_compiler *compiler, sljit_s32 src, sljit_sw srcw)
998{
999#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
1000	FUNCTION_CHECK_SRC(src, srcw);
1001	compiler->last_flags = 0;
1002#endif
1003#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
1004	if (SLJIT_UNLIKELY(!!compiler->verbose)) {
1005		fprintf(compiler->verbose, "  fast_return ");
1006		sljit_verbose_param(compiler, src, srcw);
1007		fprintf(compiler->verbose, "\n");
1008	}
1009#endif
1010	CHECK_RETURN_OK;
1011}
1012
1013static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_op0(struct sljit_compiler *compiler, sljit_s32 op)
1014{
1015#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
1016	CHECK_ARGUMENT((op >= SLJIT_BREAKPOINT && op <= SLJIT_LMUL_SW)
1017		|| ((op & ~SLJIT_I32_OP) >= SLJIT_DIVMOD_UW && (op & ~SLJIT_I32_OP) <= SLJIT_DIV_SW));
1018	CHECK_ARGUMENT(op < SLJIT_LMUL_UW || compiler->scratches >= 2);
1019	if (op >= SLJIT_LMUL_UW)
1020		compiler->last_flags = 0;
1021#endif
1022#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
1023	if (SLJIT_UNLIKELY(!!compiler->verbose))
1024	{
1025		fprintf(compiler->verbose, "  %s", op0_names[GET_OPCODE(op) - SLJIT_OP0_BASE]);
1026		if (GET_OPCODE(op) >= SLJIT_DIVMOD_UW) {
1027			fprintf(compiler->verbose, (op & SLJIT_I32_OP) ? "32" : "w");
1028		}
1029		fprintf(compiler->verbose, "\n");
1030	}
1031#endif
1032	CHECK_RETURN_OK;
1033}
1034
1035static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_op1(struct sljit_compiler *compiler, sljit_s32 op,
1036	sljit_s32 dst, sljit_sw dstw,
1037	sljit_s32 src, sljit_sw srcw)
1038{
1039	if (SLJIT_UNLIKELY(compiler->skip_checks)) {
1040		compiler->skip_checks = 0;
1041		CHECK_RETURN_OK;
1042	}
1043
1044#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
1045	CHECK_ARGUMENT(GET_OPCODE(op) >= SLJIT_MOV && GET_OPCODE(op) <= SLJIT_CLZ);
1046
1047	switch (GET_OPCODE(op)) {
1048	case SLJIT_NOT:
1049	case SLJIT_CLZ:
1050		CHECK_ARGUMENT(!(op & VARIABLE_FLAG_MASK));
1051		break;
1052	case SLJIT_NEG:
1053		CHECK_ARGUMENT(!(op & VARIABLE_FLAG_MASK)
1054			|| GET_FLAG_TYPE(op) == SLJIT_OVERFLOW
1055			|| GET_FLAG_TYPE(op) == SLJIT_NOT_OVERFLOW);
1056		break;
1057	case SLJIT_MOV:
1058	case SLJIT_MOV_U32:
1059	case SLJIT_MOV_P:
1060	case SLJIT_MOVU:
1061	case SLJIT_MOVU_U32:
1062	case SLJIT_MOVU_P:
1063		/* Nothing allowed */
1064		CHECK_ARGUMENT(!(op & (SLJIT_I32_OP | SLJIT_SET_Z | VARIABLE_FLAG_MASK)));
1065		break;
1066	default:
1067		/* Only SLJIT_I32_OP or SLJIT_F32_OP is allowed. */
1068		CHECK_ARGUMENT(!(op & (SLJIT_SET_Z | VARIABLE_FLAG_MASK)));
1069		break;
1070	}
1071
1072	FUNCTION_CHECK_SRC(src, srcw);
1073	FUNCTION_CHECK_DST(dst, dstw);
1074
1075	if (GET_OPCODE(op) >= SLJIT_NOT)
1076		compiler->last_flags = GET_FLAG_TYPE(op) | (op & (SLJIT_I32_OP | SLJIT_SET_Z));
1077	else if (GET_OPCODE(op) >= SLJIT_MOVU) {
1078		CHECK_ARGUMENT(!(src & SLJIT_MEM) || (src & REG_MASK) != SLJIT_SP);
1079		CHECK_ARGUMENT(!(dst & SLJIT_MEM) || (dst & REG_MASK) != SLJIT_SP);
1080		if ((src & REG_MASK) != SLJIT_UNUSED) {
1081			CHECK_ARGUMENT((src & REG_MASK) != (dst & REG_MASK) && (src & REG_MASK) != OFFS_REG(dst));
1082			CHECK_ARGUMENT((src & OFFS_REG_MASK) == SLJIT_UNUSED || srcw == 0);
1083		}
1084		if ((dst & REG_MASK) != SLJIT_UNUSED) {
1085			CHECK_ARGUMENT((dst & REG_MASK) != OFFS_REG(src));
1086			CHECK_ARGUMENT((dst & OFFS_REG_MASK) == SLJIT_UNUSED || dstw == 0);
1087		}
1088		compiler->last_flags = 0;
1089	}
1090#endif
1091#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
1092	if (SLJIT_UNLIKELY(!!compiler->verbose)) {
1093		if (GET_OPCODE(op) <= SLJIT_MOVU_P)
1094		{
1095			fprintf(compiler->verbose, "  mov%s%s%s ", (GET_OPCODE(op) >= SLJIT_MOVU) ? "u" : "",
1096				!(op & SLJIT_I32_OP) ? "" : "32", (op != SLJIT_MOV32 && op != SLJIT_MOVU32) ? op1_names[GET_OPCODE(op) - SLJIT_OP1_BASE] : "");
1097		}
1098		else
1099		{
1100			fprintf(compiler->verbose, "  %s%s%s%s%s ", op1_names[GET_OPCODE(op) - SLJIT_OP1_BASE], !(op & SLJIT_I32_OP) ? "" : "32",
1101				!(op & SLJIT_SET_Z) ? "" : ".z", !(op & VARIABLE_FLAG_MASK) ? "" : ".",
1102				!(op & VARIABLE_FLAG_MASK) ? "" : jump_names[GET_FLAG_TYPE(op)]);
1103		}
1104
1105		sljit_verbose_param(compiler, dst, dstw);
1106		fprintf(compiler->verbose, ", ");
1107		sljit_verbose_param(compiler, src, srcw);
1108		fprintf(compiler->verbose, "\n");
1109	}
1110#endif
1111	CHECK_RETURN_OK;
1112}
1113
1114static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_op2(struct sljit_compiler *compiler, sljit_s32 op,
1115	sljit_s32 dst, sljit_sw dstw,
1116	sljit_s32 src1, sljit_sw src1w,
1117	sljit_s32 src2, sljit_sw src2w)
1118{
1119	if (SLJIT_UNLIKELY(compiler->skip_checks)) {
1120		compiler->skip_checks = 0;
1121		CHECK_RETURN_OK;
1122	}
1123
1124#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
1125	CHECK_ARGUMENT(GET_OPCODE(op) >= SLJIT_ADD && GET_OPCODE(op) <= SLJIT_ASHR);
1126
1127	switch (GET_OPCODE(op)) {
1128	case SLJIT_AND:
1129	case SLJIT_OR:
1130	case SLJIT_XOR:
1131	case SLJIT_SHL:
1132	case SLJIT_LSHR:
1133	case SLJIT_ASHR:
1134		CHECK_ARGUMENT(!(op & VARIABLE_FLAG_MASK));
1135		break;
1136	case SLJIT_MUL:
1137		CHECK_ARGUMENT(!(op & SLJIT_SET_Z));
1138		CHECK_ARGUMENT(!(op & VARIABLE_FLAG_MASK)
1139			|| GET_FLAG_TYPE(op) == SLJIT_MUL_OVERFLOW
1140			|| GET_FLAG_TYPE(op) == SLJIT_MUL_NOT_OVERFLOW);
1141		break;
1142	case SLJIT_ADD:
1143		CHECK_ARGUMENT(!(op & VARIABLE_FLAG_MASK)
1144			|| GET_FLAG_TYPE(op) == GET_FLAG_TYPE(SLJIT_SET_CARRY)
1145			|| GET_FLAG_TYPE(op) == SLJIT_OVERFLOW
1146			|| GET_FLAG_TYPE(op) == SLJIT_NOT_OVERFLOW);
1147		break;
1148	case SLJIT_SUB:
1149		CHECK_ARGUMENT(!(op & VARIABLE_FLAG_MASK)
1150			|| (GET_FLAG_TYPE(op) >= SLJIT_LESS && GET_FLAG_TYPE(op) <= SLJIT_NOT_OVERFLOW)
1151			|| GET_FLAG_TYPE(op) == GET_FLAG_TYPE(SLJIT_SET_CARRY));
1152		break;
1153	case SLJIT_ADDC:
1154	case SLJIT_SUBC:
1155		CHECK_ARGUMENT(!(op & VARIABLE_FLAG_MASK)
1156			|| GET_FLAG_TYPE(op) == GET_FLAG_TYPE(SLJIT_SET_CARRY));
1157		CHECK_ARGUMENT((compiler->last_flags & 0xff) == GET_FLAG_TYPE(SLJIT_SET_CARRY));
1158		CHECK_ARGUMENT((op & SLJIT_I32_OP) == (compiler->last_flags & SLJIT_I32_OP));
1159		break;
1160	default:
1161		SLJIT_UNREACHABLE();
1162		break;
1163	}
1164
1165	FUNCTION_CHECK_SRC(src1, src1w);
1166	FUNCTION_CHECK_SRC(src2, src2w);
1167	FUNCTION_CHECK_DST(dst, dstw);
1168	compiler->last_flags = GET_FLAG_TYPE(op) | (op & (SLJIT_I32_OP | SLJIT_SET_Z));
1169#endif
1170#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
1171	if (SLJIT_UNLIKELY(!!compiler->verbose)) {
1172		fprintf(compiler->verbose, "  %s%s%s%s%s ", op2_names[GET_OPCODE(op) - SLJIT_OP2_BASE], !(op & SLJIT_I32_OP) ? "" : "32",
1173			!(op & SLJIT_SET_Z) ? "" : ".z", !(op & VARIABLE_FLAG_MASK) ? "" : ".",
1174			!(op & VARIABLE_FLAG_MASK) ? "" : jump_names[GET_FLAG_TYPE(op)]);
1175		sljit_verbose_param(compiler, dst, dstw);
1176		fprintf(compiler->verbose, ", ");
1177		sljit_verbose_param(compiler, src1, src1w);
1178		fprintf(compiler->verbose, ", ");
1179		sljit_verbose_param(compiler, src2, src2w);
1180		fprintf(compiler->verbose, "\n");
1181	}
1182#endif
1183	CHECK_RETURN_OK;
1184}
1185
1186static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_get_register_index(sljit_s32 reg)
1187{
1188	SLJIT_UNUSED_ARG(reg);
1189#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
1190	CHECK_ARGUMENT(reg > 0 && reg <= SLJIT_NUMBER_OF_REGISTERS);
1191#endif
1192	CHECK_RETURN_OK;
1193}
1194
1195static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_get_float_register_index(sljit_s32 reg)
1196{
1197	SLJIT_UNUSED_ARG(reg);
1198#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
1199	CHECK_ARGUMENT(reg > 0 && reg <= SLJIT_NUMBER_OF_FLOAT_REGISTERS);
1200#endif
1201	CHECK_RETURN_OK;
1202}
1203
1204static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_op_custom(struct sljit_compiler *compiler,
1205	void *instruction, sljit_s32 size)
1206{
1207#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
1208	int i;
1209#endif
1210
1211	SLJIT_UNUSED_ARG(compiler);
1212
1213#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
1214	CHECK_ARGUMENT(instruction);
1215
1216#if (defined SLJIT_CONFIG_X86 && SLJIT_CONFIG_X86)
1217	CHECK_ARGUMENT(size > 0 && size < 16);
1218#elif (defined SLJIT_CONFIG_ARM_THUMB2 && SLJIT_CONFIG_ARM_THUMB2)
1219	CHECK_ARGUMENT((size == 2 && (((sljit_sw)instruction) & 0x1) == 0)
1220		|| (size == 4 && (((sljit_sw)instruction) & 0x3) == 0));
1221#else
1222	CHECK_ARGUMENT(size == 4 && (((sljit_sw)instruction) & 0x3) == 0);
1223#endif
1224
1225	compiler->last_flags = 0;
1226#endif
1227#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
1228	if (SLJIT_UNLIKELY(!!compiler->verbose)) {
1229		fprintf(compiler->verbose, "  op_custom");
1230		for (i = 0; i < size; i++)
1231			fprintf(compiler->verbose, " 0x%x", ((sljit_u8*)instruction)[i]);
1232		fprintf(compiler->verbose, "\n");
1233	}
1234#endif
1235	CHECK_RETURN_OK;
1236}
1237
1238static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_fop1(struct sljit_compiler *compiler, sljit_s32 op,
1239	sljit_s32 dst, sljit_sw dstw,
1240	sljit_s32 src, sljit_sw srcw)
1241{
1242	if (SLJIT_UNLIKELY(compiler->skip_checks)) {
1243		compiler->skip_checks = 0;
1244		CHECK_RETURN_OK;
1245	}
1246
1247#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
1248	CHECK_ARGUMENT(sljit_is_fpu_available());
1249	CHECK_ARGUMENT(GET_OPCODE(op) >= SLJIT_MOV_F64 && GET_OPCODE(op) <= SLJIT_ABS_F64);
1250	CHECK_ARGUMENT(!(op & (SLJIT_SET_Z | VARIABLE_FLAG_MASK)));
1251	FUNCTION_FCHECK(src, srcw);
1252	FUNCTION_FCHECK(dst, dstw);
1253#endif
1254#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
1255	if (SLJIT_UNLIKELY(!!compiler->verbose)) {
1256		if (GET_OPCODE(op) == SLJIT_CONV_F64_FROM_F32)
1257			fprintf(compiler->verbose, "  %s%s ", fop1_names[SLJIT_CONV_F64_FROM_F32 - SLJIT_FOP1_BASE],
1258				(op & SLJIT_F32_OP) ? ".f32.from.f64" : ".f64.from.f32");
1259		else
1260			fprintf(compiler->verbose, "  %s%s ", fop1_names[GET_OPCODE(op) - SLJIT_FOP1_BASE],
1261				(op & SLJIT_F32_OP) ? ".f32" : ".f64");
1262
1263		sljit_verbose_fparam(compiler, dst, dstw);
1264		fprintf(compiler->verbose, ", ");
1265		sljit_verbose_fparam(compiler, src, srcw);
1266		fprintf(compiler->verbose, "\n");
1267	}
1268#endif
1269	CHECK_RETURN_OK;
1270}
1271
1272static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_fop1_cmp(struct sljit_compiler *compiler, sljit_s32 op,
1273	sljit_s32 src1, sljit_sw src1w,
1274	sljit_s32 src2, sljit_sw src2w)
1275{
1276#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
1277	compiler->last_flags = GET_FLAG_TYPE(op) | (op & (SLJIT_I32_OP | SLJIT_SET_Z));
1278#endif
1279
1280	if (SLJIT_UNLIKELY(compiler->skip_checks)) {
1281		compiler->skip_checks = 0;
1282		CHECK_RETURN_OK;
1283	}
1284
1285#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
1286	CHECK_ARGUMENT(sljit_is_fpu_available());
1287	CHECK_ARGUMENT(GET_OPCODE(op) == SLJIT_CMP_F64);
1288	CHECK_ARGUMENT(!(op & SLJIT_SET_Z));
1289	CHECK_ARGUMENT((op & VARIABLE_FLAG_MASK)
1290		|| (GET_FLAG_TYPE(op) >= SLJIT_EQUAL_F64 && GET_FLAG_TYPE(op) <= SLJIT_ORDERED_F64));
1291	FUNCTION_FCHECK(src1, src1w);
1292	FUNCTION_FCHECK(src2, src2w);
1293#endif
1294#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
1295	if (SLJIT_UNLIKELY(!!compiler->verbose)) {
1296		fprintf(compiler->verbose, "  %s%s", fop1_names[SLJIT_CMP_F64 - SLJIT_FOP1_BASE], (op & SLJIT_F32_OP) ? ".f32" : ".f64");
1297		if (op & VARIABLE_FLAG_MASK) {
1298			fprintf(compiler->verbose, ".%s_f", jump_names[GET_FLAG_TYPE(op)]);
1299		}
1300		fprintf(compiler->verbose, " ");
1301		sljit_verbose_fparam(compiler, src1, src1w);
1302		fprintf(compiler->verbose, ", ");
1303		sljit_verbose_fparam(compiler, src2, src2w);
1304		fprintf(compiler->verbose, "\n");
1305	}
1306#endif
1307	CHECK_RETURN_OK;
1308}
1309
1310static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_fop1_conv_sw_from_f64(struct sljit_compiler *compiler, sljit_s32 op,
1311	sljit_s32 dst, sljit_sw dstw,
1312	sljit_s32 src, sljit_sw srcw)
1313{
1314	if (SLJIT_UNLIKELY(compiler->skip_checks)) {
1315		compiler->skip_checks = 0;
1316		CHECK_RETURN_OK;
1317	}
1318
1319#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
1320	CHECK_ARGUMENT(sljit_is_fpu_available());
1321	CHECK_ARGUMENT(GET_OPCODE(op) >= SLJIT_CONV_SW_FROM_F64 && GET_OPCODE(op) <= SLJIT_CONV_S32_FROM_F64);
1322	CHECK_ARGUMENT(!(op & (SLJIT_SET_Z | VARIABLE_FLAG_MASK)));
1323	FUNCTION_FCHECK(src, srcw);
1324	FUNCTION_CHECK_DST(dst, dstw);
1325#endif
1326#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
1327	if (SLJIT_UNLIKELY(!!compiler->verbose)) {
1328		fprintf(compiler->verbose, "  %s%s.from%s ", fop1_names[GET_OPCODE(op) - SLJIT_FOP1_BASE],
1329			(GET_OPCODE(op) == SLJIT_CONV_S32_FROM_F64) ? ".s32" : ".sw",
1330			(op & SLJIT_F32_OP) ? ".f32" : ".f64");
1331		sljit_verbose_param(compiler, dst, dstw);
1332		fprintf(compiler->verbose, ", ");
1333		sljit_verbose_fparam(compiler, src, srcw);
1334		fprintf(compiler->verbose, "\n");
1335	}
1336#endif
1337	CHECK_RETURN_OK;
1338}
1339
1340static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_fop1_conv_f64_from_sw(struct sljit_compiler *compiler, sljit_s32 op,
1341	sljit_s32 dst, sljit_sw dstw,
1342	sljit_s32 src, sljit_sw srcw)
1343{
1344	if (SLJIT_UNLIKELY(compiler->skip_checks)) {
1345		compiler->skip_checks = 0;
1346		CHECK_RETURN_OK;
1347	}
1348
1349#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
1350	CHECK_ARGUMENT(sljit_is_fpu_available());
1351	CHECK_ARGUMENT(GET_OPCODE(op) >= SLJIT_CONV_F64_FROM_SW && GET_OPCODE(op) <= SLJIT_CONV_F64_FROM_S32);
1352	CHECK_ARGUMENT(!(op & (SLJIT_SET_Z | VARIABLE_FLAG_MASK)));
1353	FUNCTION_CHECK_SRC(src, srcw);
1354	FUNCTION_FCHECK(dst, dstw);
1355#endif
1356#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
1357	if (SLJIT_UNLIKELY(!!compiler->verbose)) {
1358		fprintf(compiler->verbose, "  %s%s.from%s ", fop1_names[GET_OPCODE(op) - SLJIT_FOP1_BASE],
1359			(op & SLJIT_F32_OP) ? ".f32" : ".f64",
1360			(GET_OPCODE(op) == SLJIT_CONV_F64_FROM_S32) ? ".s32" : ".sw");
1361		sljit_verbose_fparam(compiler, dst, dstw);
1362		fprintf(compiler->verbose, ", ");
1363		sljit_verbose_param(compiler, src, srcw);
1364		fprintf(compiler->verbose, "\n");
1365	}
1366#endif
1367	CHECK_RETURN_OK;
1368}
1369
1370static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_fop2(struct sljit_compiler *compiler, sljit_s32 op,
1371	sljit_s32 dst, sljit_sw dstw,
1372	sljit_s32 src1, sljit_sw src1w,
1373	sljit_s32 src2, sljit_sw src2w)
1374{
1375#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
1376	CHECK_ARGUMENT(sljit_is_fpu_available());
1377	CHECK_ARGUMENT(GET_OPCODE(op) >= SLJIT_ADD_F64 && GET_OPCODE(op) <= SLJIT_DIV_F64);
1378	CHECK_ARGUMENT(!(op & (SLJIT_SET_Z | VARIABLE_FLAG_MASK)));
1379	FUNCTION_FCHECK(src1, src1w);
1380	FUNCTION_FCHECK(src2, src2w);
1381	FUNCTION_FCHECK(dst, dstw);
1382#endif
1383#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
1384	if (SLJIT_UNLIKELY(!!compiler->verbose)) {
1385		fprintf(compiler->verbose, "  %s%s ", fop2_names[GET_OPCODE(op) - SLJIT_FOP2_BASE], (op & SLJIT_F32_OP) ? ".f32" : ".f64");
1386		sljit_verbose_fparam(compiler, dst, dstw);
1387		fprintf(compiler->verbose, ", ");
1388		sljit_verbose_fparam(compiler, src1, src1w);
1389		fprintf(compiler->verbose, ", ");
1390		sljit_verbose_fparam(compiler, src2, src2w);
1391		fprintf(compiler->verbose, "\n");
1392	}
1393#endif
1394	CHECK_RETURN_OK;
1395}
1396
1397static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_label(struct sljit_compiler *compiler)
1398{
1399	SLJIT_UNUSED_ARG(compiler);
1400
1401#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
1402	compiler->last_flags = 0;
1403#endif
1404
1405#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
1406	if (SLJIT_UNLIKELY(!!compiler->verbose))
1407		fprintf(compiler->verbose, "label:\n");
1408#endif
1409	CHECK_RETURN_OK;
1410}
1411
1412static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_jump(struct sljit_compiler *compiler, sljit_s32 type)
1413{
1414	if (SLJIT_UNLIKELY(compiler->skip_checks)) {
1415		compiler->skip_checks = 0;
1416		CHECK_RETURN_OK;
1417	}
1418
1419#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
1420	CHECK_ARGUMENT(!(type & ~(0xff | SLJIT_REWRITABLE_JUMP | SLJIT_I32_OP)));
1421	CHECK_ARGUMENT((type & 0xff) != GET_FLAG_TYPE(SLJIT_SET_CARRY) && (type & 0xff) != (GET_FLAG_TYPE(SLJIT_SET_CARRY) + 1));
1422	CHECK_ARGUMENT((type & 0xff) >= SLJIT_EQUAL && (type & 0xff) <= SLJIT_CALL3);
1423	CHECK_ARGUMENT((type & 0xff) < SLJIT_JUMP || !(type & SLJIT_I32_OP));
1424	CHECK_ARGUMENT((type & 0xff) <= SLJIT_CALL0 || ((type & 0xff) - SLJIT_CALL0) <= compiler->scratches);
1425
1426	if ((type & 0xff) < SLJIT_JUMP) {
1427		if ((type & 0xff) <= SLJIT_NOT_ZERO)
1428			CHECK_ARGUMENT(compiler->last_flags & SLJIT_SET_Z);
1429		else
1430			CHECK_ARGUMENT((type & 0xff) == (compiler->last_flags & 0xff));
1431		CHECK_ARGUMENT((type & SLJIT_I32_OP) == (compiler->last_flags & SLJIT_I32_OP));
1432	}
1433#endif
1434#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
1435	if (SLJIT_UNLIKELY(!!compiler->verbose))
1436		fprintf(compiler->verbose, "  jump%s %s%s\n", !(type & SLJIT_REWRITABLE_JUMP) ? "" : ".r",
1437			jump_names[type & 0xff], JUMP_POSTFIX(type));
1438#endif
1439	CHECK_RETURN_OK;
1440}
1441
1442static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_cmp(struct sljit_compiler *compiler, sljit_s32 type,
1443	sljit_s32 src1, sljit_sw src1w,
1444	sljit_s32 src2, sljit_sw src2w)
1445{
1446#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
1447	CHECK_ARGUMENT(!(type & ~(0xff | SLJIT_REWRITABLE_JUMP | SLJIT_I32_OP)));
1448	CHECK_ARGUMENT((type & 0xff) >= SLJIT_EQUAL && (type & 0xff) <= SLJIT_SIG_LESS_EQUAL);
1449	FUNCTION_CHECK_SRC(src1, src1w);
1450	FUNCTION_CHECK_SRC(src2, src2w);
1451	compiler->last_flags = 0;
1452#endif
1453#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
1454	if (SLJIT_UNLIKELY(!!compiler->verbose)) {
1455		fprintf(compiler->verbose, "  cmp%s %s%s, ", !(type & SLJIT_REWRITABLE_JUMP) ? "" : ".r",
1456			jump_names[type & 0xff], (type & SLJIT_I32_OP) ? "32" : "");
1457		sljit_verbose_param(compiler, src1, src1w);
1458		fprintf(compiler->verbose, ", ");
1459		sljit_verbose_param(compiler, src2, src2w);
1460		fprintf(compiler->verbose, "\n");
1461	}
1462#endif
1463	CHECK_RETURN_OK;
1464}
1465
1466static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_fcmp(struct sljit_compiler *compiler, sljit_s32 type,
1467	sljit_s32 src1, sljit_sw src1w,
1468	sljit_s32 src2, sljit_sw src2w)
1469{
1470#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
1471	CHECK_ARGUMENT(sljit_is_fpu_available());
1472	CHECK_ARGUMENT(!(type & ~(0xff | SLJIT_REWRITABLE_JUMP | SLJIT_F32_OP)));
1473	CHECK_ARGUMENT((type & 0xff) >= SLJIT_EQUAL_F64 && (type & 0xff) <= SLJIT_ORDERED_F64);
1474	FUNCTION_FCHECK(src1, src1w);
1475	FUNCTION_FCHECK(src2, src2w);
1476	compiler->last_flags = 0;
1477#endif
1478#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
1479	if (SLJIT_UNLIKELY(!!compiler->verbose)) {
1480		fprintf(compiler->verbose, "  fcmp%s %s%s, ", !(type & SLJIT_REWRITABLE_JUMP) ? "" : ".r",
1481			jump_names[type & 0xff], (type & SLJIT_F32_OP) ? ".f32" : ".f64");
1482		sljit_verbose_fparam(compiler, src1, src1w);
1483		fprintf(compiler->verbose, ", ");
1484		sljit_verbose_fparam(compiler, src2, src2w);
1485		fprintf(compiler->verbose, "\n");
1486	}
1487#endif
1488	CHECK_RETURN_OK;
1489}
1490
1491static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_ijump(struct sljit_compiler *compiler, sljit_s32 type, sljit_s32 src, sljit_sw srcw)
1492{
1493#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
1494	compiler->last_flags = 0;
1495#endif
1496
1497	if (SLJIT_UNLIKELY(compiler->skip_checks)) {
1498		compiler->skip_checks = 0;
1499		CHECK_RETURN_OK;
1500	}
1501
1502#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
1503	CHECK_ARGUMENT(type >= SLJIT_JUMP && type <= SLJIT_CALL3);
1504	CHECK_ARGUMENT(type <= SLJIT_CALL0 || (type - SLJIT_CALL0) <= compiler->scratches);
1505	FUNCTION_CHECK_SRC(src, srcw);
1506#endif
1507#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
1508	if (SLJIT_UNLIKELY(!!compiler->verbose)) {
1509		fprintf(compiler->verbose, "  ijump.%s ", jump_names[type]);
1510		sljit_verbose_param(compiler, src, srcw);
1511		fprintf(compiler->verbose, "\n");
1512	}
1513#endif
1514	CHECK_RETURN_OK;
1515}
1516
1517static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_op_flags(struct sljit_compiler *compiler, sljit_s32 op,
1518	sljit_s32 dst, sljit_sw dstw,
1519	sljit_s32 src, sljit_sw srcw,
1520	sljit_s32 type)
1521{
1522#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
1523	CHECK_ARGUMENT(!(type & ~(0xff | SLJIT_I32_OP)));
1524	CHECK_ARGUMENT((type & 0xff) >= SLJIT_EQUAL && (type & 0xff) <= SLJIT_ORDERED_F64);
1525	CHECK_ARGUMENT((type & 0xff) != GET_FLAG_TYPE(SLJIT_SET_CARRY) && (type & 0xff) != (GET_FLAG_TYPE(SLJIT_SET_CARRY) + 1));
1526	CHECK_ARGUMENT(op == SLJIT_MOV || GET_OPCODE(op) == SLJIT_MOV_U32 || GET_OPCODE(op) == SLJIT_MOV_S32
1527		|| (GET_OPCODE(op) >= SLJIT_AND && GET_OPCODE(op) <= SLJIT_XOR));
1528	CHECK_ARGUMENT(!(op & VARIABLE_FLAG_MASK));
1529
1530	if ((type & 0xff) <= SLJIT_NOT_ZERO)
1531		CHECK_ARGUMENT(compiler->last_flags & SLJIT_SET_Z);
1532	else
1533		CHECK_ARGUMENT((type & 0xff) == (compiler->last_flags & 0xff));
1534
1535	if (GET_OPCODE(op) < SLJIT_ADD) {
1536		CHECK_ARGUMENT(src == SLJIT_UNUSED && srcw == 0);
1537	} else {
1538		CHECK_ARGUMENT(src == dst && srcw == dstw);
1539		compiler->last_flags = GET_FLAG_TYPE(op) | (op & (SLJIT_I32_OP | SLJIT_SET_Z));
1540	}
1541	FUNCTION_CHECK_DST(dst, dstw);
1542#endif
1543#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
1544	if (SLJIT_UNLIKELY(!!compiler->verbose)) {
1545		fprintf(compiler->verbose, "  flags%s %s%s, ",
1546			!(op & SLJIT_SET_Z) ? "" : ".z",
1547			GET_OPCODE(op) < SLJIT_OP2_BASE ? "mov" : op2_names[GET_OPCODE(op) - SLJIT_OP2_BASE],
1548			GET_OPCODE(op) < SLJIT_OP2_BASE ? op1_names[GET_OPCODE(op) - SLJIT_OP1_BASE] : ((op & SLJIT_I32_OP) ? "32" : ""));
1549		sljit_verbose_param(compiler, dst, dstw);
1550		if (src != SLJIT_UNUSED) {
1551			fprintf(compiler->verbose, ", ");
1552			sljit_verbose_param(compiler, src, srcw);
1553		}
1554		fprintf(compiler->verbose, ", %s%s\n", jump_names[type & 0xff], JUMP_POSTFIX(type));
1555	}
1556#endif
1557	CHECK_RETURN_OK;
1558}
1559
1560static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_get_local_base(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw dstw, sljit_sw offset)
1561{
1562	SLJIT_UNUSED_ARG(offset);
1563
1564#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
1565	FUNCTION_CHECK_DST(dst, dstw);
1566#endif
1567#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
1568	if (SLJIT_UNLIKELY(!!compiler->verbose)) {
1569		fprintf(compiler->verbose, "  local_base ");
1570		sljit_verbose_param(compiler, dst, dstw);
1571		fprintf(compiler->verbose, ", #%" SLJIT_PRINT_D "d\n", offset);
1572	}
1573#endif
1574	CHECK_RETURN_OK;
1575}
1576
1577static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_const(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw dstw, sljit_sw init_value)
1578{
1579	SLJIT_UNUSED_ARG(init_value);
1580
1581#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
1582	FUNCTION_CHECK_DST(dst, dstw);
1583#endif
1584#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
1585	if (SLJIT_UNLIKELY(!!compiler->verbose)) {
1586		fprintf(compiler->verbose, "  const ");
1587		sljit_verbose_param(compiler, dst, dstw);
1588		fprintf(compiler->verbose, ", #%" SLJIT_PRINT_D "d\n", init_value);
1589	}
1590#endif
1591	CHECK_RETURN_OK;
1592}
1593
1594#endif /* SLJIT_ARGUMENT_CHECKS || SLJIT_VERBOSE */
1595
1596#define SELECT_FOP1_OPERATION_WITH_CHECKS(compiler, op, dst, dstw, src, srcw) \
1597	SLJIT_COMPILE_ASSERT(!(SLJIT_CONV_SW_FROM_F64 & 0x1) && !(SLJIT_CONV_F64_FROM_SW & 0x1), \
1598		invalid_float_opcodes); \
1599	if (GET_OPCODE(op) >= SLJIT_CONV_SW_FROM_F64 && GET_OPCODE(op) <= SLJIT_CMP_F64) { \
1600		if (GET_OPCODE(op) == SLJIT_CMP_F64) { \
1601			CHECK(check_sljit_emit_fop1_cmp(compiler, op, dst, dstw, src, srcw)); \
1602			ADJUST_LOCAL_OFFSET(dst, dstw); \
1603			ADJUST_LOCAL_OFFSET(src, srcw); \
1604			return sljit_emit_fop1_cmp(compiler, op, dst, dstw, src, srcw); \
1605		} \
1606		if ((GET_OPCODE(op) | 0x1) == SLJIT_CONV_S32_FROM_F64) { \
1607			CHECK(check_sljit_emit_fop1_conv_sw_from_f64(compiler, op, dst, dstw, src, srcw)); \
1608			ADJUST_LOCAL_OFFSET(dst, dstw); \
1609			ADJUST_LOCAL_OFFSET(src, srcw); \
1610			return sljit_emit_fop1_conv_sw_from_f64(compiler, op, dst, dstw, src, srcw); \
1611		} \
1612		CHECK(check_sljit_emit_fop1_conv_f64_from_sw(compiler, op, dst, dstw, src, srcw)); \
1613		ADJUST_LOCAL_OFFSET(dst, dstw); \
1614		ADJUST_LOCAL_OFFSET(src, srcw); \
1615		return sljit_emit_fop1_conv_f64_from_sw(compiler, op, dst, dstw, src, srcw); \
1616	} \
1617	CHECK(check_sljit_emit_fop1(compiler, op, dst, dstw, src, srcw)); \
1618	ADJUST_LOCAL_OFFSET(dst, dstw); \
1619	ADJUST_LOCAL_OFFSET(src, srcw);
1620
1621static SLJIT_INLINE sljit_s32 emit_mov_before_return(struct sljit_compiler *compiler, sljit_s32 op, sljit_s32 src, sljit_sw srcw)
1622{
1623	/* Return if don't need to do anything. */
1624	if (op == SLJIT_UNUSED)
1625		return SLJIT_SUCCESS;
1626
1627#if (defined SLJIT_64BIT_ARCHITECTURE && SLJIT_64BIT_ARCHITECTURE)
1628	/* At the moment the pointer size is always equal to sljit_sw. May be changed in the future. */
1629	if (src == SLJIT_RETURN_REG && (op == SLJIT_MOV || op == SLJIT_MOV_P))
1630		return SLJIT_SUCCESS;
1631#else
1632	if (src == SLJIT_RETURN_REG && (op == SLJIT_MOV || op == SLJIT_MOV_U32 || op == SLJIT_MOV_S32 || op == SLJIT_MOV_P))
1633		return SLJIT_SUCCESS;
1634#endif
1635
1636#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS) \
1637		|| (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
1638	compiler->skip_checks = 1;
1639#endif
1640	return sljit_emit_op1(compiler, op, SLJIT_RETURN_REG, 0, src, srcw);
1641}
1642
1643/* CPU description section */
1644
1645#if (defined SLJIT_32BIT_ARCHITECTURE && SLJIT_32BIT_ARCHITECTURE)
1646#define SLJIT_CPUINFO_PART1 " 32bit ("
1647#elif (defined SLJIT_64BIT_ARCHITECTURE && SLJIT_64BIT_ARCHITECTURE)
1648#define SLJIT_CPUINFO_PART1 " 64bit ("
1649#else
1650#error "Internal error: CPU type info missing"
1651#endif
1652
1653#if (defined SLJIT_LITTLE_ENDIAN && SLJIT_LITTLE_ENDIAN)
1654#define SLJIT_CPUINFO_PART2 "little endian + "
1655#elif (defined SLJIT_BIG_ENDIAN && SLJIT_BIG_ENDIAN)
1656#define SLJIT_CPUINFO_PART2 "big endian + "
1657#else
1658#error "Internal error: CPU type info missing"
1659#endif
1660
1661#if (defined SLJIT_UNALIGNED && SLJIT_UNALIGNED)
1662#define SLJIT_CPUINFO_PART3 "unaligned)"
1663#else
1664#define SLJIT_CPUINFO_PART3 "aligned)"
1665#endif
1666
1667#define SLJIT_CPUINFO SLJIT_CPUINFO_PART1 SLJIT_CPUINFO_PART2 SLJIT_CPUINFO_PART3
1668
1669#if (defined SLJIT_CONFIG_X86 && SLJIT_CONFIG_X86)
1670#	include "sljitNativeX86_common.c"
1671#elif (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5)
1672#	include "sljitNativeARM_32.c"
1673#elif (defined SLJIT_CONFIG_ARM_V7 && SLJIT_CONFIG_ARM_V7)
1674#	include "sljitNativeARM_32.c"
1675#elif (defined SLJIT_CONFIG_ARM_THUMB2 && SLJIT_CONFIG_ARM_THUMB2)
1676#	include "sljitNativeARM_T2_32.c"
1677#elif (defined SLJIT_CONFIG_ARM_64 && SLJIT_CONFIG_ARM_64)
1678#	include "sljitNativeARM_64.c"
1679#elif (defined SLJIT_CONFIG_PPC && SLJIT_CONFIG_PPC)
1680#	include "sljitNativePPC_common.c"
1681#elif (defined SLJIT_CONFIG_MIPS && SLJIT_CONFIG_MIPS)
1682#	include "sljitNativeMIPS_common.c"
1683#elif (defined SLJIT_CONFIG_SPARC && SLJIT_CONFIG_SPARC)
1684#	include "sljitNativeSPARC_common.c"
1685#elif (defined SLJIT_CONFIG_TILEGX && SLJIT_CONFIG_TILEGX)
1686#	include "sljitNativeTILEGX_64.c"
1687#endif
1688
1689#if !(defined SLJIT_CONFIG_MIPS && SLJIT_CONFIG_MIPS)
1690
1691SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_cmp(struct sljit_compiler *compiler, sljit_s32 type,
1692	sljit_s32 src1, sljit_sw src1w,
1693	sljit_s32 src2, sljit_sw src2w)
1694{
1695	/* Default compare for most architectures. */
1696	sljit_s32 flags, tmp_src, condition;
1697	sljit_sw tmp_srcw;
1698
1699	CHECK_ERROR_PTR();
1700	CHECK_PTR(check_sljit_emit_cmp(compiler, type, src1, src1w, src2, src2w));
1701
1702	condition = type & 0xff;
1703#if (defined SLJIT_CONFIG_ARM_64 && SLJIT_CONFIG_ARM_64)
1704	if ((condition == SLJIT_EQUAL || condition == SLJIT_NOT_EQUAL)) {
1705		if ((src1 & SLJIT_IMM) && !src1w) {
1706			src1 = src2;
1707			src1w = src2w;
1708			src2 = SLJIT_IMM;
1709			src2w = 0;
1710		}
1711		if ((src2 & SLJIT_IMM) && !src2w)
1712			return emit_cmp_to0(compiler, type, src1, src1w);
1713	}
1714#endif
1715
1716	if (SLJIT_UNLIKELY((src1 & SLJIT_IMM) && !(src2 & SLJIT_IMM))) {
1717		/* Immediate is prefered as second argument by most architectures. */
1718		switch (condition) {
1719		case SLJIT_LESS:
1720			condition = SLJIT_GREATER;
1721			break;
1722		case SLJIT_GREATER_EQUAL:
1723			condition = SLJIT_LESS_EQUAL;
1724			break;
1725		case SLJIT_GREATER:
1726			condition = SLJIT_LESS;
1727			break;
1728		case SLJIT_LESS_EQUAL:
1729			condition = SLJIT_GREATER_EQUAL;
1730			break;
1731		case SLJIT_SIG_LESS:
1732			condition = SLJIT_SIG_GREATER;
1733			break;
1734		case SLJIT_SIG_GREATER_EQUAL:
1735			condition = SLJIT_SIG_LESS_EQUAL;
1736			break;
1737		case SLJIT_SIG_GREATER:
1738			condition = SLJIT_SIG_LESS;
1739			break;
1740		case SLJIT_SIG_LESS_EQUAL:
1741			condition = SLJIT_SIG_GREATER_EQUAL;
1742			break;
1743		}
1744
1745		type = condition | (type & (SLJIT_I32_OP | SLJIT_REWRITABLE_JUMP));
1746		tmp_src = src1;
1747		src1 = src2;
1748		src2 = tmp_src;
1749		tmp_srcw = src1w;
1750		src1w = src2w;
1751		src2w = tmp_srcw;
1752	}
1753
1754	if (condition <= SLJIT_NOT_ZERO)
1755		flags = SLJIT_SET_Z;
1756	else
1757		flags = condition << VARIABLE_FLAG_SHIFT;
1758
1759#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) \
1760		|| (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
1761	compiler->skip_checks = 1;
1762#endif
1763	PTR_FAIL_IF(sljit_emit_op2(compiler, SLJIT_SUB | flags | (type & SLJIT_I32_OP),
1764		SLJIT_UNUSED, 0, src1, src1w, src2, src2w));
1765#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) \
1766		|| (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
1767	compiler->skip_checks = 1;
1768#endif
1769	return sljit_emit_jump(compiler, condition | (type & (SLJIT_REWRITABLE_JUMP | SLJIT_I32_OP)));
1770}
1771
1772#endif
1773
1774SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_fcmp(struct sljit_compiler *compiler, sljit_s32 type,
1775	sljit_s32 src1, sljit_sw src1w,
1776	sljit_s32 src2, sljit_sw src2w)
1777{
1778	CHECK_ERROR_PTR();
1779	CHECK_PTR(check_sljit_emit_fcmp(compiler, type, src1, src1w, src2, src2w));
1780
1781#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) \
1782		|| (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
1783	compiler->skip_checks = 1;
1784#endif
1785	sljit_emit_fop1(compiler, SLJIT_CMP_F64 | ((type & 0xff) << VARIABLE_FLAG_SHIFT) | (type & SLJIT_I32_OP), src1, src1w, src2, src2w);
1786
1787#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) \
1788		|| (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
1789	compiler->skip_checks = 1;
1790#endif
1791	return sljit_emit_jump(compiler, type);
1792}
1793
1794#if !(defined SLJIT_CONFIG_X86 && SLJIT_CONFIG_X86)
1795
1796SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_get_local_base(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw dstw, sljit_sw offset)
1797{
1798	CHECK_ERROR();
1799	CHECK(check_sljit_get_local_base(compiler, dst, dstw, offset));
1800
1801	ADJUST_LOCAL_OFFSET(SLJIT_MEM1(SLJIT_SP), offset);
1802#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) \
1803		|| (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
1804	compiler->skip_checks = 1;
1805#endif
1806	if (offset != 0)
1807		return sljit_emit_op2(compiler, SLJIT_ADD, dst, dstw, SLJIT_SP, 0, SLJIT_IMM, offset);
1808	return sljit_emit_op1(compiler, SLJIT_MOV, dst, dstw, SLJIT_SP, 0);
1809}
1810
1811#endif
1812
1813#else /* SLJIT_CONFIG_UNSUPPORTED */
1814
1815/* Empty function bodies for those machines, which are not (yet) supported. */
1816
1817SLJIT_API_FUNC_ATTRIBUTE const char* sljit_get_platform_name(void)
1818{
1819	return "unsupported";
1820}
1821
1822SLJIT_API_FUNC_ATTRIBUTE struct sljit_compiler* sljit_create_compiler(void *allocator_data)
1823{
1824	SLJIT_UNUSED_ARG(allocator_data);
1825	SLJIT_UNREACHABLE();
1826	return NULL;
1827}
1828
1829SLJIT_API_FUNC_ATTRIBUTE void sljit_free_compiler(struct sljit_compiler *compiler)
1830{
1831	SLJIT_UNUSED_ARG(compiler);
1832	SLJIT_UNREACHABLE();
1833}
1834
1835SLJIT_API_FUNC_ATTRIBUTE void sljit_set_compiler_memory_error(struct sljit_compiler *compiler)
1836{
1837	SLJIT_UNUSED_ARG(compiler);
1838	SLJIT_UNREACHABLE();
1839}
1840
1841SLJIT_API_FUNC_ATTRIBUTE void* sljit_alloc_memory(struct sljit_compiler *compiler, sljit_s32 size)
1842{
1843	SLJIT_UNUSED_ARG(compiler);
1844	SLJIT_UNUSED_ARG(size);
1845	SLJIT_UNREACHABLE();
1846	return NULL;
1847}
1848
1849#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
1850SLJIT_API_FUNC_ATTRIBUTE void sljit_compiler_verbose(struct sljit_compiler *compiler, FILE* verbose)
1851{
1852	SLJIT_UNUSED_ARG(compiler);
1853	SLJIT_UNUSED_ARG(verbose);
1854	SLJIT_UNREACHABLE();
1855}
1856#endif
1857
1858SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compiler)
1859{
1860	SLJIT_UNUSED_ARG(compiler);
1861	SLJIT_UNREACHABLE();
1862	return NULL;
1863}
1864
1865SLJIT_API_FUNC_ATTRIBUTE void sljit_free_code(void* code)
1866{
1867	SLJIT_UNUSED_ARG(code);
1868	SLJIT_UNREACHABLE();
1869}
1870
1871SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_enter(struct sljit_compiler *compiler,
1872	sljit_s32 options, sljit_s32 args, sljit_s32 scratches, sljit_s32 saveds,
1873	sljit_s32 fscratches, sljit_s32 fsaveds, sljit_s32 local_size)
1874{
1875	SLJIT_UNUSED_ARG(compiler);
1876	SLJIT_UNUSED_ARG(options);
1877	SLJIT_UNUSED_ARG(args);
1878	SLJIT_UNUSED_ARG(scratches);
1879	SLJIT_UNUSED_ARG(saveds);
1880	SLJIT_UNUSED_ARG(fscratches);
1881	SLJIT_UNUSED_ARG(fsaveds);
1882	SLJIT_UNUSED_ARG(local_size);
1883	SLJIT_UNREACHABLE();
1884	return SLJIT_ERR_UNSUPPORTED;
1885}
1886
1887SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_set_context(struct sljit_compiler *compiler,
1888	sljit_s32 options, sljit_s32 args, sljit_s32 scratches, sljit_s32 saveds,
1889	sljit_s32 fscratches, sljit_s32 fsaveds, sljit_s32 local_size)
1890{
1891	SLJIT_UNUSED_ARG(compiler);
1892	SLJIT_UNUSED_ARG(options);
1893	SLJIT_UNUSED_ARG(args);
1894	SLJIT_UNUSED_ARG(scratches);
1895	SLJIT_UNUSED_ARG(saveds);
1896	SLJIT_UNUSED_ARG(fscratches);
1897	SLJIT_UNUSED_ARG(fsaveds);
1898	SLJIT_UNUSED_ARG(local_size);
1899	SLJIT_UNREACHABLE();
1900	return SLJIT_ERR_UNSUPPORTED;
1901}
1902
1903SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_return(struct sljit_compiler *compiler, sljit_s32 op, sljit_s32 src, sljit_sw srcw)
1904{
1905	SLJIT_UNUSED_ARG(compiler);
1906	SLJIT_UNUSED_ARG(op);
1907	SLJIT_UNUSED_ARG(src);
1908	SLJIT_UNUSED_ARG(srcw);
1909	SLJIT_UNREACHABLE();
1910	return SLJIT_ERR_UNSUPPORTED;
1911}
1912
1913SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fast_enter(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw dstw)
1914{
1915	SLJIT_UNUSED_ARG(compiler);
1916	SLJIT_UNUSED_ARG(dst);
1917	SLJIT_UNUSED_ARG(dstw);
1918	SLJIT_UNREACHABLE();
1919	return SLJIT_ERR_UNSUPPORTED;
1920}
1921
1922SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fast_return(struct sljit_compiler *compiler, sljit_s32 src, sljit_sw srcw)
1923{
1924	SLJIT_UNUSED_ARG(compiler);
1925	SLJIT_UNUSED_ARG(src);
1926	SLJIT_UNUSED_ARG(srcw);
1927	SLJIT_UNREACHABLE();
1928	return SLJIT_ERR_UNSUPPORTED;
1929}
1930
1931SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op0(struct sljit_compiler *compiler, sljit_s32 op)
1932{
1933	SLJIT_UNUSED_ARG(compiler);
1934	SLJIT_UNUSED_ARG(op);
1935	SLJIT_UNREACHABLE();
1936	return SLJIT_ERR_UNSUPPORTED;
1937}
1938
1939SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op1(struct sljit_compiler *compiler, sljit_s32 op,
1940	sljit_s32 dst, sljit_sw dstw,
1941	sljit_s32 src, sljit_sw srcw)
1942{
1943	SLJIT_UNUSED_ARG(compiler);
1944	SLJIT_UNUSED_ARG(op);
1945	SLJIT_UNUSED_ARG(dst);
1946	SLJIT_UNUSED_ARG(dstw);
1947	SLJIT_UNUSED_ARG(src);
1948	SLJIT_UNUSED_ARG(srcw);
1949	SLJIT_UNREACHABLE();
1950	return SLJIT_ERR_UNSUPPORTED;
1951}
1952
1953SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op2(struct sljit_compiler *compiler, sljit_s32 op,
1954	sljit_s32 dst, sljit_sw dstw,
1955	sljit_s32 src1, sljit_sw src1w,
1956	sljit_s32 src2, sljit_sw src2w)
1957{
1958	SLJIT_UNUSED_ARG(compiler);
1959	SLJIT_UNUSED_ARG(op);
1960	SLJIT_UNUSED_ARG(dst);
1961	SLJIT_UNUSED_ARG(dstw);
1962	SLJIT_UNUSED_ARG(src1);
1963	SLJIT_UNUSED_ARG(src1w);
1964	SLJIT_UNUSED_ARG(src2);
1965	SLJIT_UNUSED_ARG(src2w);
1966	SLJIT_UNREACHABLE();
1967	return SLJIT_ERR_UNSUPPORTED;
1968}
1969
1970SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_get_register_index(sljit_s32 reg)
1971{
1972	SLJIT_UNREACHABLE();
1973	return reg;
1974}
1975
1976SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_custom(struct sljit_compiler *compiler,
1977	void *instruction, sljit_s32 size)
1978{
1979	SLJIT_UNUSED_ARG(compiler);
1980	SLJIT_UNUSED_ARG(instruction);
1981	SLJIT_UNUSED_ARG(size);
1982	SLJIT_UNREACHABLE();
1983	return SLJIT_ERR_UNSUPPORTED;
1984}
1985
1986SLJIT_API_FUNC_ATTRIBUTE void sljit_set_current_flags(struct sljit_compiler *compiler, sljit_s32 current_flags)
1987{
1988	SLJIT_UNUSED_ARG(compiler);
1989	SLJIT_UNUSED_ARG(current_flags);
1990}
1991
1992SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_is_fpu_available(void)
1993{
1994	SLJIT_UNREACHABLE();
1995	return 0;
1996}
1997
1998SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fop1(struct sljit_compiler *compiler, sljit_s32 op,
1999	sljit_s32 dst, sljit_sw dstw,
2000	sljit_s32 src, sljit_sw srcw)
2001{
2002	SLJIT_UNUSED_ARG(compiler);
2003	SLJIT_UNUSED_ARG(op);
2004	SLJIT_UNUSED_ARG(dst);
2005	SLJIT_UNUSED_ARG(dstw);
2006	SLJIT_UNUSED_ARG(src);
2007	SLJIT_UNUSED_ARG(srcw);
2008	SLJIT_UNREACHABLE();
2009	return SLJIT_ERR_UNSUPPORTED;
2010}
2011
2012SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fop2(struct sljit_compiler *compiler, sljit_s32 op,
2013	sljit_s32 dst, sljit_sw dstw,
2014	sljit_s32 src1, sljit_sw src1w,
2015	sljit_s32 src2, sljit_sw src2w)
2016{
2017	SLJIT_UNUSED_ARG(compiler);
2018	SLJIT_UNUSED_ARG(op);
2019	SLJIT_UNUSED_ARG(dst);
2020	SLJIT_UNUSED_ARG(dstw);
2021	SLJIT_UNUSED_ARG(src1);
2022	SLJIT_UNUSED_ARG(src1w);
2023	SLJIT_UNUSED_ARG(src2);
2024	SLJIT_UNUSED_ARG(src2w);
2025	SLJIT_UNREACHABLE();
2026	return SLJIT_ERR_UNSUPPORTED;
2027}
2028
2029SLJIT_API_FUNC_ATTRIBUTE struct sljit_label* sljit_emit_label(struct sljit_compiler *compiler)
2030{
2031	SLJIT_UNUSED_ARG(compiler);
2032	SLJIT_UNREACHABLE();
2033	return NULL;
2034}
2035
2036SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_jump(struct sljit_compiler *compiler, sljit_s32 type)
2037{
2038	SLJIT_UNUSED_ARG(compiler);
2039	SLJIT_UNUSED_ARG(type);
2040	SLJIT_UNREACHABLE();
2041	return NULL;
2042}
2043
2044SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_cmp(struct sljit_compiler *compiler, sljit_s32 type,
2045	sljit_s32 src1, sljit_sw src1w,
2046	sljit_s32 src2, sljit_sw src2w)
2047{
2048	SLJIT_UNUSED_ARG(compiler);
2049	SLJIT_UNUSED_ARG(type);
2050	SLJIT_UNUSED_ARG(src1);
2051	SLJIT_UNUSED_ARG(src1w);
2052	SLJIT_UNUSED_ARG(src2);
2053	SLJIT_UNUSED_ARG(src2w);
2054	SLJIT_UNREACHABLE();
2055	return NULL;
2056}
2057
2058SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_fcmp(struct sljit_compiler *compiler, sljit_s32 type,
2059	sljit_s32 src1, sljit_sw src1w,
2060	sljit_s32 src2, sljit_sw src2w)
2061{
2062	SLJIT_UNUSED_ARG(compiler);
2063	SLJIT_UNUSED_ARG(type);
2064	SLJIT_UNUSED_ARG(src1);
2065	SLJIT_UNUSED_ARG(src1w);
2066	SLJIT_UNUSED_ARG(src2);
2067	SLJIT_UNUSED_ARG(src2w);
2068	SLJIT_UNREACHABLE();
2069	return NULL;
2070}
2071
2072SLJIT_API_FUNC_ATTRIBUTE void sljit_set_label(struct sljit_jump *jump, struct sljit_label* label)
2073{
2074	SLJIT_UNUSED_ARG(jump);
2075	SLJIT_UNUSED_ARG(label);
2076	SLJIT_UNREACHABLE();
2077}
2078
2079SLJIT_API_FUNC_ATTRIBUTE void sljit_set_target(struct sljit_jump *jump, sljit_uw target)
2080{
2081	SLJIT_UNUSED_ARG(jump);
2082	SLJIT_UNUSED_ARG(target);
2083	SLJIT_UNREACHABLE();
2084}
2085
2086SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_ijump(struct sljit_compiler *compiler, sljit_s32 type, sljit_s32 src, sljit_sw srcw)
2087{
2088	SLJIT_UNUSED_ARG(compiler);
2089	SLJIT_UNUSED_ARG(type);
2090	SLJIT_UNUSED_ARG(src);
2091	SLJIT_UNUSED_ARG(srcw);
2092	SLJIT_UNREACHABLE();
2093	return SLJIT_ERR_UNSUPPORTED;
2094}
2095
2096SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_flags(struct sljit_compiler *compiler, sljit_s32 op,
2097	sljit_s32 dst, sljit_sw dstw,
2098	sljit_s32 src, sljit_sw srcw,
2099	sljit_s32 type)
2100{
2101	SLJIT_UNUSED_ARG(compiler);
2102	SLJIT_UNUSED_ARG(op);
2103	SLJIT_UNUSED_ARG(dst);
2104	SLJIT_UNUSED_ARG(dstw);
2105	SLJIT_UNUSED_ARG(src);
2106	SLJIT_UNUSED_ARG(srcw);
2107	SLJIT_UNUSED_ARG(type);
2108	SLJIT_UNREACHABLE();
2109	return SLJIT_ERR_UNSUPPORTED;
2110}
2111
2112SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_get_local_base(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw dstw, sljit_sw offset)
2113{
2114	SLJIT_UNUSED_ARG(compiler);
2115	SLJIT_UNUSED_ARG(dst);
2116	SLJIT_UNUSED_ARG(dstw);
2117	SLJIT_UNUSED_ARG(offset);
2118	SLJIT_UNREACHABLE();
2119	return SLJIT_ERR_UNSUPPORTED;
2120}
2121
2122SLJIT_API_FUNC_ATTRIBUTE struct sljit_const* sljit_emit_const(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw dstw, sljit_sw initval)
2123{
2124	SLJIT_UNUSED_ARG(compiler);
2125	SLJIT_UNUSED_ARG(dst);
2126	SLJIT_UNUSED_ARG(dstw);
2127	SLJIT_UNUSED_ARG(initval);
2128	SLJIT_UNREACHABLE();
2129	return NULL;
2130}
2131
2132SLJIT_API_FUNC_ATTRIBUTE void sljit_set_jump_addr(sljit_uw addr, sljit_uw new_target, sljit_sw executable_offset)
2133{
2134	SLJIT_UNUSED_ARG(addr);
2135	SLJIT_UNUSED_ARG(new_target);
2136	SLJIT_UNUSED_ARG(executable_offset);
2137	SLJIT_UNREACHABLE();
2138}
2139
2140SLJIT_API_FUNC_ATTRIBUTE void sljit_set_const(sljit_uw addr, sljit_sw new_constant, sljit_sw executable_offset)
2141{
2142	SLJIT_UNUSED_ARG(addr);
2143	SLJIT_UNUSED_ARG(new_constant);
2144	SLJIT_UNUSED_ARG(executable_offset);
2145	SLJIT_UNREACHABLE();
2146}
2147
2148#endif
2149