Coverage Report

Created: 2025-12-08 06:11

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