30 return "ARM-Thumb2" SLJIT_CPUINFO
" ABI:softfp";
32 return "ARM-Thumb2" SLJIT_CPUINFO
" ABI:hardfp";
40#define TMP_REG1 (SLJIT_NUMBER_OF_REGISTERS + 2)
41#define TMP_REG2 (SLJIT_NUMBER_OF_REGISTERS + 3)
42#define TMP_PC (SLJIT_NUMBER_OF_REGISTERS + 4)
44#define TMP_FREG1 (SLJIT_NUMBER_OF_FLOAT_REGISTERS + 1)
45#define TMP_FREG2 (SLJIT_NUMBER_OF_FLOAT_REGISTERS + 2)
48static const sljit_u8 reg_map[SLJIT_NUMBER_OF_REGISTERS + 5] = {
49 0, 0, 1, 2, 3, 11, 10, 9, 8, 7, 6, 5, 4, 13, 12, 14, 15
52static const sljit_u8 freg_map[((SLJIT_NUMBER_OF_FLOAT_REGISTERS + 2) << 1) + 1] = {
54 0, 1, 2, 3, 4, 5, 15, 14, 13, 12, 11, 10, 9, 8,
56 0, 1, 2, 3, 4, 5, 15, 14, 13, 12, 11, 10, 9, 8,
60static const sljit_u8 freg_ebit_map[((SLJIT_NUMBER_OF_FLOAT_REGISTERS + 2) << 1) + 1] = {
62 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
64 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
68#define COPY_BITS(src, from, to, bits) \
69 ((from >= to ? ((sljit_ins)(src) >> (from - to)) : ((sljit_ins)(src) << (to - from))) & (((1 << bits) - 1) << to))
71#define NEGATE(uimm) ((sljit_uw)-(sljit_sw)(uimm))
74#define RD3(rd) ((sljit_ins)reg_map[rd])
75#define RN3(rn) ((sljit_ins)reg_map[rn] << 3)
76#define RM3(rm) ((sljit_ins)reg_map[rm] << 6)
77#define RDN3(rdn) ((sljit_ins)reg_map[rdn] << 8)
78#define IMM3(imm) ((sljit_ins)imm << 6)
79#define IMM8(imm) ((sljit_ins)imm)
82#define SET_REGS44(rd, rn) \
83 (((sljit_ins)reg_map[rn] << 3) | ((sljit_ins)reg_map[rd] & 0x7) | (((sljit_ins)reg_map[rd] & 0x8) << 4))
84#define IS_2_LO_REGS(reg1, reg2) \
85 (reg_map[reg1] <= 7 && reg_map[reg2] <= 7)
86#define IS_3_LO_REGS(reg1, reg2, reg3) \
87 (reg_map[reg1] <= 7 && reg_map[reg2] <= 7 && reg_map[reg3] <= 7)
90#define RM4(rm) ((sljit_ins)reg_map[rm])
91#define RD4(rd) ((sljit_ins)reg_map[rd] << 8)
92#define RT4(rt) ((sljit_ins)reg_map[rt] << 12)
93#define RN4(rn) ((sljit_ins)reg_map[rn] << 16)
95#define VM4(vm) (((sljit_ins)freg_map[vm]) | ((sljit_ins)freg_ebit_map[vm] << 5))
96#define VD4(vd) (((sljit_ins)freg_map[vd] << 12) | ((sljit_ins)freg_ebit_map[vd] << 22))
97#define VN4(vn) (((sljit_ins)freg_map[vn] << 16) | ((sljit_ins)freg_ebit_map[vn] << 7))
100 (COPY_BITS(imm, 2, 12, 3) | (((sljit_ins)imm & 0x3) << 6))
102 (COPY_BITS(imm, 11, 26, 1) | COPY_BITS(imm, 8, 12, 3) | ((sljit_ins)imm & 0xff))
110#define ADCI 0xf1400000
112#define ADC_W 0xeb400000
117#define ADDWI 0xf2000000
119#define ADD_SP_I 0xb000
120#define ADD_W 0xeb000000
121#define ADD_WI 0xf1000000
122#define ANDI 0xf0000000
124#define AND_W 0xea000000
127#define ASR_W 0xfa40f000
128#define ASR_WI 0xea4f0020
130#define BICI 0xf0200000
134#define CLZ 0xfab0f080
135#define CMNI_W 0xf1100f00
138#define CMPI_W 0xf1b00f00
140#define CMP_W 0xebb00f00
141#define EORI 0xf0800000
143#define EOR_W 0xea800000
145#define LDR 0xf8d00000
147#define LDRD 0xe9500000
148#define LDREX 0xe8500f00
149#define LDREXB 0xe8d00f4f
150#define LDREXH 0xe8d00f5f
151#define LDRI 0xf8500800
154#define LSL_W 0xfa00f000
155#define LSL_WI 0xea4f0000
158#define LSR_W 0xfa20f000
159#define LSR_WI 0xea4f0010
160#define MLA 0xfb000000
164#define MOVT 0xf2c00000
165#define MOVW 0xf2400000
166#define MOV_W 0xea4f0000
167#define MOV_WI 0xf04f0000
168#define MUL 0xfb00f000
170#define MVN_W 0xea6f0000
171#define MVN_WI 0xf06f0000
173#define ORNI 0xf0600000
174#define ORRI 0xf0400000
176#define ORR_W 0xea400000
178#define POP_W 0xe8bd0000
180#define PUSH_W 0xe92d0000
182#define REV_W 0xfa90f080
184#define REV16_W 0xfa90f090
185#define RBIT 0xfa90f0a0
187#define ROR_W 0xfa60f000
188#define ROR_WI 0xea4f0030
189#define RSB_WI 0xf1c00000
191#define SBCI 0xf1600000
193#define SBC_W 0xeb600000
194#define SDIV 0xfb90f0f0
195#define SMULL 0xfb800000
197#define STRD 0xe9400000
198#define STREX 0xe8400000
199#define STREXB 0xe8c00f40
200#define STREXH 0xe8c00f50
204#define SUB_W 0xeba00000
205#define SUBWI 0xf2a00000
206#define SUB_SP_I 0xb080
207#define SUB_WI 0xf1a00000
209#define SXTB_W 0xfa4ff080
211#define SXTH_W 0xfa0ff080
213#define TSTI 0xf0000f00
214#define TST_W 0xea000f00
215#define UDIV 0xfbb0f0f0
216#define UMULL 0xfba00000
218#define UXTB_W 0xfa5ff080
220#define UXTH_W 0xfa1ff080
221#define VABS_F32 0xeeb00ac0
222#define VADD_F32 0xee300a00
223#define VAND 0xef000110
224#define VCMP_F32 0xeeb40a40
225#define VCVT_F32_S32 0xeeb80ac0
226#define VCVT_F32_U32 0xeeb80a40
227#define VCVT_F64_F32 0xeeb70ac0
228#define VCVT_S32_F32 0xeebd0ac0
229#define VDIV_F32 0xee800a00
230#define VDUP 0xee800b10
231#define VDUP_s 0xffb00c00
232#define VEOR 0xff000110
233#define VLD1 0xf9200000
234#define VLD1_r 0xf9a00c00
235#define VLD1_s 0xf9a00000
236#define VLDR_F32 0xed100a00
237#define VMOV_F32 0xeeb00a40
238#define VMOV 0xee000a10
239#define VMOV2 0xec400a10
240#define VMOV_i 0xef800010
241#define VMOV_s 0xee000b10
242#define VMOVN 0xffb20200
243#define VMRS 0xeef1fa10
244#define VMUL_F32 0xee200a00
245#define VNEG_F32 0xeeb10a40
246#define VORR 0xef200110
247#define VPOP 0xecbd0b00
248#define VPUSH 0xed2d0b00
249#define VSHLL 0xef800a10
250#define VSHR 0xef800010
251#define VSRA 0xef800110
252#define VST1 0xf9000000
253#define VST1_s 0xf9800000
254#define VSTR_F32 0xed000a00
255#define VSUB_F32 0xee300a40
257#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
300 return push_inst32(compiler,
MOVT |
RD4(dst)
310 inst[3] = (
sljit_u16)(dst |
COPY_BITS(new_imm, 8 + 16, 12, 3) | ((new_imm & 0xff0000) >> 16));
316 SLJIT_ASSERT(((inst[0] & 0xfbf0) == (
MOVW >> 16)) && ((inst[2] & 0xfbf0) == (
MOVT >> 16)) && dst == (inst[3] & 0x0f00));
317 set_imm32_const(inst, dst, new_imm);
327 if (jump->flags & JUMP_ADDR) {
329 if (!(jump->u.target & 0x1))
331 diff = (
sljit_sw)jump->u.target - (
sljit_sw)(code_ptr + 2) - executable_offset;
337 if (jump->flags & IS_COND) {
340 diff += SSIZE_OF(
u16);
341 if (diff <= 0xff && diff >= -0x100) {
342 jump->flags |= PATCH_TYPE1;
343 jump->addr = (
sljit_uw)(code_ptr - 1);
346 if (diff <= 0xfffff && diff >= -0x100000) {
347 jump->flags |= PATCH_TYPE2;
348 jump->addr = (
sljit_uw)(code_ptr - 1);
351 diff -= SSIZE_OF(
u16);
352 }
else if (jump->flags & IS_BL) {
354 if (diff <= 0xffffff && diff >= -0x1000000) {
355 jump->flags |= PATCH_TYPE5;
359 }
else if (diff <= 0x7ff && diff >= -0x800) {
360 jump->flags |= PATCH_TYPE3;
364 if (diff <= 0xffffff && diff >= -0x1000000) {
365 jump->flags |= PATCH_TYPE4;
370 code_ptr[4] = code_ptr[0];
372 if (jump->flags & IS_COND) {
373 code_ptr[3] = code_ptr[-1];
374 jump->addr = (
sljit_uw)(code_ptr - 1);
386 if (jump->flags & JUMP_ADDR)
387 addr = jump->u.target;
389 addr = (
sljit_uw)SLJIT_ADD_EXEC_OFFSET(code + jump->u.label->size, executable_offset);
396 if (diff <= 0xffd + 2 * SSIZE_OF(
u16) && diff >= -0xfff + 2 * SSIZE_OF(
u16)) {
397 jump->flags |= PATCH_TYPE6;
411 diff = (
sljit_sw)((jump->flags & JUMP_ADDR) ? jump->u.target : jump->u.label->u.addr);
414 ins = (jump->flags & JUMP_MOV_ADDR) ? *jump_inst :
RDN3(
TMP_REG1);
421 diff -= (
sljit_sw)SLJIT_ADD_EXEC_OFFSET(jump_inst + 2, executable_offset) & ~(
sljit_sw)0x3;
436 SLJIT_ASSERT((diff & 0x1) != 0 && !(jump->flags & JUMP_MOV_ADDR));
437 diff = (diff - (
sljit_sw)(jump->addr +
sizeof(
sljit_u32)) - executable_offset) >> 1;
442 SLJIT_ASSERT(diff <= 0x7f && diff >= -0x80 && (jump->flags & IS_COND));
443 jump_inst[0] = (
sljit_u16)(0xd000 | (jump->flags & 0xf00) | ((
sljit_ins)diff & 0xff));
447 SLJIT_ASSERT(diff <= 0x7ffff && diff >= -0x80000 && (jump->flags & IS_COND));
453 SLJIT_ASSERT(diff <= 0x3ff && diff >= -0x400 && !(jump->flags & IS_COND));
454 jump_inst[0] = (
sljit_u16)(0xe000 | (diff & 0x7ff));
461 diff ^= ((diff >> 2) & 0x600000) ^ 0x600000;
470 jump_inst[1] |= 0x9000;
472 jump_inst[1] |= 0xd000;
480 SLJIT_NEXT_DEFINE_TYPES;
486 jump = compiler->
jumps;
487 const_ = compiler->
consts;
488 SLJIT_NEXT_INIT_TYPES();
491 SLJIT_GET_NEXT_MIN();
493 if (next_min_addr == SLJIT_MAX_ADDRESS)
496 if (next_min_addr == next_label_size) {
497 label->
size -= size_reduce;
500 next_label_size = SLJIT_GET_NEXT_SIZE(label);
503 if (next_min_addr == next_const_addr) {
504 const_->
addr -= size_reduce;
505 const_ = const_->
next;
506 next_const_addr = SLJIT_GET_NEXT_ADDRESS(const_);
510 if (next_min_addr != next_jump_addr)
513 jump->addr -= size_reduce;
514 if (!(jump->flags & JUMP_MOV_ADDR)) {
515 total_size = JUMP_MAX_SIZE;
521 if (jump->flags & IS_COND) {
524 if (diff <= (0xff / SSIZE_OF(
u16)) && diff >= (-0x100 / SSIZE_OF(
u16)))
526 else if (diff <= (0xfffff / SSIZE_OF(
u16)) && diff >= (-0x100000 / SSIZE_OF(
u16)))
529 }
else if (!(jump->flags & IS_BL) && diff <= (0x7ff / SSIZE_OF(
u16)) && diff >= (-0x800 / SSIZE_OF(
u16)))
532 if (total_size == JUMP_MAX_SIZE && diff <= (0xffffff / SSIZE_OF(
u16)) && diff >= (-0x1000000 / SSIZE_OF(
u16)))
536 size_reduce += JUMP_MAX_SIZE - total_size;
541 if (!(jump->flags & JUMP_ADDR)) {
544 if (diff <= (0xffd / SSIZE_OF(
u16)) && diff >= (-0xfff / SSIZE_OF(
u16)))
548 size_reduce += 3 - total_size;
551 jump->flags |= total_size << JUMP_SIZE_SHIFT;
553 next_jump_addr = SLJIT_GET_NEXT_ADDRESS(jump);
556 compiler->
size -= size_reduce;
567 SLJIT_NEXT_DEFINE_TYPES;
576 CHECK_PTR(check_sljit_generate_code(compiler));
578 reduce_code_size(compiler);
583 reverse_buf(compiler);
589 jump = compiler->
jumps;
590 const_ = compiler->
consts;
591 SLJIT_NEXT_INIT_TYPES();
592 SLJIT_GET_NEXT_MIN();
596 buf_end = buf_ptr + (
buf->used_size >> 1);
598 *code_ptr = *buf_ptr++;
599 if (next_min_addr == half_count) {
605 if (next_min_addr == next_label_size) {
606 label->
u.
addr = ((
sljit_uw)SLJIT_ADD_EXEC_OFFSET(code_ptr, executable_offset)) | 0x1;
609 next_label_size = SLJIT_GET_NEXT_SIZE(label);
612 if (next_min_addr == next_jump_addr) {
613 if (!(jump->flags & JUMP_MOV_ADDR)) {
614 half_count = half_count - 1 + (jump->flags >> JUMP_SIZE_SHIFT);
616 code_ptr = detect_jump_type(jump, code_ptr, code, executable_offset);
618 ((jump->flags >> JUMP_SIZE_SHIFT) + ((jump->flags & 0xf0) <= PATCH_TYPE2)) *
sizeof(
sljit_u16));
620 half_count += jump->flags >> JUMP_SIZE_SHIFT;
622 code_ptr += mov_addr_get_length(jump, code_ptr, code, executable_offset);
627 next_jump_addr = SLJIT_GET_NEXT_ADDRESS(jump);
628 }
else if (next_min_addr == next_const_addr) {
630 const_ = const_->
next;
631 next_const_addr = SLJIT_GET_NEXT_ADDRESS(const_);
634 SLJIT_GET_NEXT_MIN();
638 }
while (buf_ptr < buf_end);
643 if (label && label->
size == half_count) {
644 label->
u.
addr = ((
sljit_uw)SLJIT_ADD_EXEC_OFFSET(code_ptr, executable_offset)) | 0x1;
654 jump = compiler->
jumps;
656 generate_jump_or_mov_addr(jump, executable_offset);
664 code = (
sljit_u16 *)SLJIT_ADD_EXEC_OFFSET(code, executable_offset);
665 code_ptr = (
sljit_u16 *)SLJIT_ADD_EXEC_OFFSET(code_ptr, executable_offset);
671 return (
void*)((
sljit_uw)code | 0x1);
676 switch (feature_type) {
680#ifdef SLJIT_IS_FPU_AVAILABLE
708#define INVALID_IMM 0x80000000
717 if ((imm & 0xffff) == (imm >> 16)) {
720 return (1 << 12) | (imm & 0xff);
722 return (2 << 12) | ((imm >> 8) & 0xff);
723 if ((imm & 0xff00) == ((imm & 0xff) << 8))
724 return (3 << 12) | (imm & 0xff);
729 if (!(imm & 0xffff0000)) {
733 if (!(imm & 0xff000000)) {
737 if (!(imm & 0xf0000000)) {
741 if (!(imm & 0xc0000000)) {
745 if (!(imm & 0x80000000)) {
752 if (imm & 0x00ffffff)
764 if (imm >= 0x10000) {
767 return push_inst32(compiler,
MOV_WI |
RD4(dst) | tmp);
770 return push_inst32(compiler,
MVN_WI |
RD4(dst) | tmp);
779 return push_inst32(compiler,
MOVT |
RD4(dst)
784#define ARG1_IMM 0x0010000
785#define ARG2_IMM 0x0020000
787#define SET_FLAGS 0x0100000
788#define UNUSED_RETURN 0x0200000
789#define REGISTER_OP 0x0400000
810 switch (
flags & 0xffff) {
824 return load_immediate(compiler, dst, imm);
849 imm = get_imm(
NEGATE(imm));
868 return push_inst16(compiler,
RSBSI |
RD3(dst) |
RN3(reg));
875 if (imm <= 0xff && reg_map[reg] <= 7)
876 return push_inst16(compiler,
CMPI |
IMM8(imm) |
RDN3(reg));
879 return push_inst32(compiler,
CMPI_W |
RN4(reg) | imm2);
880 imm = get_imm(
NEGATE(imm));
882 return push_inst32(compiler,
CMNI_W |
RN4(reg) | imm);
907 imm = get_imm(
NEGATE(imm));
941 return push_inst16(compiler,
MVNS |
RD3(dst) |
RN3(reg));
964 return push_inst16(compiler,
MOVS |
RD3(dst) |
RN3(reg));
968 switch (
flags & 0xffff) {
972 return push_inst16(compiler,
LSLSI |
RD3(dst) |
RN3(reg) | (imm << 6));
977 return push_inst16(compiler,
LSRSI |
RD3(dst) |
RN3(reg) | (imm << 6));
982 return push_inst16(compiler,
ASRSI |
RD3(dst) |
RN3(reg) | (imm << 6));
985 imm = (imm ^ 0x1f) + 1;
1009 switch (
flags & 0xffff) {
1045 return push_inst32(compiler,
CLZ |
RN4(dst) |
RD4(dst) |
RM4(dst));
1066 if (reg_map[dst] <= 7)
1097 compiler->status_flags_state = 0;
1103 return push_inst32(compiler,
CMP_W |
RN4(reg) | 0x70e0 |
RM4(dst));
1155 compiler->status_flags_state = 0;
1166#define WORD_SIZE 0x00
1167#define BYTE_SIZE 0x04
1168#define HALF_SIZE 0x08
1171#define IS_WORD_SIZE(flags) (!((flags) & (BYTE_SIZE | HALF_SIZE)))
1172#define ALIGN_CHECK(argw, imm, shift) (!((argw) & ~((imm) << (shift))))
1189static const sljit_ins sljit_mem16[12] = {
1206static const sljit_ins sljit_mem16_imm5[12] = {
1223#define MEM_IMM8 0xc00
1224#define MEM_IMM12 0x800000
1225static const sljit_ins sljit_mem32[13] = {
1254 return push_inst32(compiler,
ADD_WI |
RD4(dst) |
RN4(reg) | imm);
1262 return push_inst32(compiler,
SUB_WI |
RD4(dst) |
RN4(reg) | imm);
1280 return push_inst32(compiler, sljit_mem32[
flags] |
MEM_IMM12 |
RT4(reg) |
RN4(tmp_reg) | (argw & 0xfff));
1285 return push_inst16(compiler, sljit_mem16_imm5[
flags] |
RD3(reg) |
RN3(tmp_reg));
1291 other_r = OFFS_REG(
arg);
1295 return push_inst16(compiler, sljit_mem16[
flags] |
RD3(reg) |
RN3(
arg) |
RM3(other_r));
1302 imm = get_imm((
sljit_uw)(argw & ~0xfff));
1306 argw = argw & 0xfff;
1309 else if (argw < -0xff) {
1310 tmp = (
sljit_uw)((-argw + 0xfff) & ~0xfff);
1349 if (argw >= 0 && argw <= 0xfff)
1351 else if (argw < 0 && argw >= -0xff)
1358 return push_inst16(compiler, sljit_mem16[
flags] |
RD3(reg) |
RN3(
arg) |
RM3(tmp_reg));
1359 return push_inst32(compiler, sljit_mem32[
flags] |
RT4(reg) |
RN4(
arg) |
RM4(tmp_reg));
1386 CHECK(check_sljit_emit_enter(compiler,
options, arg_types, scratches, saveds, fscratches, fsaveds, local_size));
1387 set_emit_enter(compiler,
options, arg_types, scratches, saveds, fscratches, fsaveds, local_size);
1390 for (i =
SLJIT_S0 - saved_arg_count; i > tmp; i--)
1398 ? push_inst32(compiler,
PUSH_W | (1 << 14) | imm)
1399 : push_inst16(compiler,
PUSH | (1 << 8) | imm));
1402 size = GET_SAVED_REGISTERS_SIZE(scratches, saveds - saved_arg_count, 1);
1405 if ((
size & SSIZE_OF(sw)) != 0) {
1407 size += SSIZE_OF(sw);
1410 if (fsaveds + fscratches >= SLJIT_NUMBER_OF_FLOAT_REGISTERS) {
1420 local_size = ((
size + local_size + 0x7) & ~0x7) -
size;
1428 saved_arg_count = 0;
1433 float_arg_count = 0;
1436 switch (arg_types & SLJIT_ARG_MASK) {
1451 FAIL_IF(push_inst32(compiler,
VMOV | (float_arg_count << 16) | (
offset << 10)));
1464 tmp = word_arg_count;
1470 else if (reg_map[tmp] <= 7)
1483 compiler->args_size =
offset;
1490 switch (arg_types & SLJIT_ARG_MASK) {
1492 if (
offset != old_offset)
1498 if (f32_offset != 0) {
1502 if (
offset != old_offset)
1504 f32_offset = old_offset;
1523 while (remap_ptr > remap)
1524 FAIL_IF(push_inst32(compiler, *(--remap_ptr)));
1528 if (local_size >= 4096) {
1529 imm = get_imm(4096);
1534 if (local_size < 4 * 4096) {
1535 if (local_size > 2 * 4096) {
1536 if (local_size > 3 * 4096) {
1549 FAIL_IF(push_inst16(compiler,
BCC | (0x1 << 8) | (-8 & 0xff)));
1553 local_size &= 0xfff;
1556 if (local_size >= 256) {
1559 if (local_size <= (127 << 2))
1565 }
else if (local_size > 0)
1568 if (local_size > 0) {
1569 if (local_size <= (127 << 2))
1586 CHECK(check_sljit_set_context(compiler,
options, arg_types, scratches, saveds, fscratches, fsaveds, local_size));
1587 set_set_context(compiler,
options, arg_types, scratches, saveds, fscratches, fsaveds, local_size);
1589 size = GET_SAVED_REGISTERS_SIZE(scratches, saveds - SLJIT_KEPT_SAVEDS_COUNT(
options), 1);
1593 size += SSIZE_OF(sw);
1604 if (imm <= (127u << 2))
1605 return push_inst16(compiler,
ADD_SP_I | (imm >> 2));
1610 imm2 = get_imm(imm);
1621 sljit_s32 local_size, fscratches, fsaveds, i, tmp;
1636 if (fsaveds + fscratches >= SLJIT_NUMBER_OF_FLOAT_REGISTERS) {
1645 local_size = GET_SAVED_REGISTERS_SIZE(compiler->
scratches, compiler->
saveds, 1) & 0x7;
1648 if (frame_size < 0) {
1651 }
else if (frame_size > 0) {
1652 SLJIT_ASSERT(frame_size == 1 || (frame_size & 0x7) == 0);
1662 reg_list |= (
sljit_uw)1 << reg_map[i];
1663 }
while (--i > tmp);
1670 reg_list |= (
sljit_uw)1 << reg_map[i];
1674 if (lr_dst ==
TMP_REG2 && reg_list == 0) {
1680 if (lr_dst == 0 && (reg_list & (reg_list - 1)) == 0) {
1683 if (reg_list != 0) {
1685 if (local_size <= 0xfff) {
1686 if (local_size == 0) {
1688 if (frame_size == 0)
1690 if (frame_size > 2 * SSIZE_OF(sw))
1694 if (reg_map[restored_reg] <= 7 && local_size <= 0x3fc)
1699 }
else if (frame_size == 0) {
1700 frame_size = (restored_reg ==
TMP_REG2) ? SSIZE_OF(sw) : 2 * SSIZE_OF(sw);
1706 local_size += SSIZE_OF(sw);
1710 local_size += SSIZE_OF(sw);
1712 if (frame_size > local_size)
1714 else if (frame_size < local_size)
1721 frame_size -= SSIZE_OF(sw);
1723 frame_size -= SSIZE_OF(sw);
1725 if (reg_map[restored_reg] <= 7)
1726 return push_inst16(compiler,
STR_SP | 0x800 |
RDN3(restored_reg) | (
sljit_ins)(frame_size >> 2));
1731 tmp = (restored_reg ==
TMP_REG2) ? 0x304 : 0x308;
1738 if (!(reg_list & 0xff00) && lr_dst !=
TMP_REG2) {
1740 reg_list |= 1u << 8;
1745 FAIL_IF(push_inst16(compiler,
POP | reg_list));
1748 reg_list |= (
sljit_uw)1 << reg_map[lr_dst];
1762 return push_inst16(compiler,
ADD_SP_I | 1);
1768 CHECK(check_sljit_emit_return_void(compiler));
1770 return emit_stack_frame_release(compiler, 0);
1777 CHECK(check_sljit_emit_return_to(compiler, src, srcw));
1789 FAIL_IF(emit_stack_frame_release(compiler, 1));
1791 SLJIT_SKIP_CHECKS(compiler);
1799#if !(defined __ARM_FEATURE_IDIV) && !(defined __ARM_ARCH_EXT_IDIV__)
1806extern unsigned long long __rt_udiv(
unsigned int denominator,
unsigned int numerator);
1807extern long long __rt_sdiv(
int denominator,
int numerator);
1808#elif defined(__GNUC__)
1809extern unsigned int __aeabi_uidivmod(
unsigned int numerator,
int unsigned denominator);
1810extern int __aeabi_idivmod(
int numerator,
int denominator);
1812#error "Software divmod functions are needed"
1823#if !(defined __ARM_FEATURE_IDIV) && !(defined __ARM_ARCH_EXT_IDIV__)
1829 CHECK(check_sljit_emit_op0(compiler, op));
1834 return push_inst16(compiler,
BKPT);
1836 return push_inst16(compiler,
NOP);
1841#if (defined __ARM_FEATURE_IDIV) || (defined __ARM_ARCH_EXT_IDIV__)
1857 SLJIT_ASSERT(reg_map[2] == 1 && reg_map[3] == 2 && reg_map[4] == 3);
1859 saved_reg_count = 0;
1861 saved_reg_list[saved_reg_count++] = 3;
1863 saved_reg_list[saved_reg_count++] = 2;
1865 saved_reg_list[saved_reg_count++] = 1;
1867 if (saved_reg_count > 0) {
1868 FAIL_IF(push_inst32(compiler, 0xf84d0d00 | (saved_reg_count >= 3 ? 16 : 8)
1869 | (saved_reg_list[0] << 12) ));
1870 if (saved_reg_count >= 2) {
1872 FAIL_IF(push_inst16(compiler, 0x9001 | (saved_reg_list[1] << 8) ));
1874 if (saved_reg_count >= 3) {
1876 FAIL_IF(push_inst16(compiler, 0x9002 | (saved_reg_list[2] << 8) ));
1886#elif defined(__GNUC__)
1890#error "Software divmod functions are needed"
1893 if (saved_reg_count > 0) {
1894 if (saved_reg_count >= 3) {
1896 FAIL_IF(push_inst16(compiler, 0x9802 | (saved_reg_list[2] << 8) ));
1898 if (saved_reg_count >= 2) {
1900 FAIL_IF(push_inst16(compiler, 0x9801 | (saved_reg_list[1] << 8) ));
1902 return push_inst32(compiler, 0xf85d0b00 | (saved_reg_count >= 3 ? 16 : 8)
1903 | (saved_reg_list[0] << 12) );
1922 CHECK(check_sljit_emit_op1(compiler, op, dst, dstw, src, srcw));
1923 ADJUST_LOCAL_OFFSET(dst, dstw);
1924 ADJUST_LOCAL_OFFSET(src, srcw);
1926 dst_r = FAST_IS_REG(dst) ? dst :
TMP_REG2;
1968 else if (FAST_IS_REG(dst))
2008 CHECK(check_sljit_emit_op2(compiler, op, 0, dst, dstw, src1, src1w, src2, src2w));
2009 ADJUST_LOCAL_OFFSET(dst, dstw);
2010 ADJUST_LOCAL_OFFSET(src1, src1w);
2011 ADJUST_LOCAL_OFFSET(src2, src2w);
2013 dst_reg = FAST_IS_REG(dst) ? dst :
TMP_REG2;
2024 src2w = src2_tmp_reg;
2048 CHECK(check_sljit_emit_op2(compiler, op, 1, 0, 0, src1, src1w, src2, src2w));
2050 SLJIT_SKIP_CHECKS(compiler);
2060 CHECK(check_sljit_emit_op2r(compiler, op, dst_reg, src1, src1w, src2, src2w));
2064 SLJIT_SKIP_CHECKS(compiler);
2065 return sljit_emit_op2(compiler, op, dst_reg, 0, src1, src1w, src2, src2w);
2080 CHECK(check_sljit_emit_shift_into(compiler, op, dst_reg, src1_reg, src2_reg, src3, src3w));
2085 if (src1_reg == src2_reg) {
2086 SLJIT_SKIP_CHECKS(compiler);
2090 ADJUST_LOCAL_OFFSET(src3, src3w);
2103 src3w = (src3w ^ 0x1f) + 1;
2104 return push_inst32(compiler,
ORR_W |
RD4(dst_reg) |
RN4(dst_reg) |
RM4(src2_reg) | (is_left ? 0x10 : 0x0) |
IMM5(src3w));
2117 if (dst_reg == src1_reg &&
IS_2_LO_REGS(dst_reg, src3))
2132 CHECK(check_sljit_emit_op_src(compiler, op, src, srcw));
2133 ADJUST_LOCAL_OFFSET(src, srcw);
2139 if (FAST_IS_REG(src))
2163 CHECK(check_sljit_emit_op_dst(compiler, op, dst, dstw));
2164 ADJUST_LOCAL_OFFSET(dst, dstw);
2170 if (FAST_IS_REG(dst))
2178 if ((
size & SSIZE_OF(sw)) == 0)
2179 size += SSIZE_OF(sw);
2186 dst_r = FAST_IS_REG(dst) ? dst :
TMP_REG2;
2199 CHECK_REG_INDEX(check_sljit_get_register_index(
type, reg));
2202 return reg_map[reg];
2205 return freg_map[reg];
2208 return freg_map[reg] & ~0x1;
2217 CHECK(check_sljit_emit_op_custom(compiler, instruction,
size));
2220 return push_inst16(compiler, *(
sljit_u16*)instruction);
2221 return push_inst32(compiler, *(
sljit_ins*)instruction);
2228#define FPU_LOAD (1 << 20)
2244 if ((
arg & REG_MASK) && (argw & 0x3) == 0) {
2245 if (!(argw & ~0x3fc))
2246 return push_inst32(compiler, inst | 0x800000 |
RN4(
arg & REG_MASK) |
VD4(reg) | ((
sljit_uw)argw >> 2));
2247 if (!(-argw & ~0x3fc))
2248 return push_inst32(compiler, inst |
RN4(
arg & REG_MASK) |
VD4(reg) | ((
sljit_uw)-argw >> 2));
2251 if (
arg & REG_MASK) {
2254 return push_inst32(compiler, inst | 0x800000 |
RN4(
TMP_REG1) |
VD4(reg));
2260 return push_inst32(compiler, inst | 0x800000 |
RN4(
TMP_REG1) |
VD4(reg) | (((
sljit_uw)argw & 0x3fc) >> 2));
2274 return push_inst32(compiler, inst | 0x800000 |
RN4(
TMP_REG1) |
VD4(reg));
2290 if (FAST_IS_REG(dst))
2294 return emit_fop_mem(compiler, 0,
TMP_FREG1, dst, dstw);
2303 if (FAST_IS_REG(src))
2325 return sljit_emit_fop1_conv_f64_from_w(compiler,
VCVT_F32_S32 | (~op &
SLJIT_32), dst, dstw, src, srcw);
2332 return sljit_emit_fop1_conv_f64_from_w(compiler,
VCVT_F32_U32 | (~op &
SLJIT_32), dst, dstw, src, srcw);
2357 FAIL_IF(push_inst16(compiler,
IT | (0x6 << 4) | 0x8));
2358 return push_inst16(compiler,
CMP );
2370 SELECT_FOP1_OPERATION_WITH_CHECKS(compiler, op, dst, dstw, src, srcw);
2372 dst_r = FAST_IS_REG(dst) ? dst :
TMP_FREG1;
2404 return emit_fop_mem(compiler, (op &
SLJIT_32), dst_r, dst, dstw);
2416 CHECK(check_sljit_emit_fop2(compiler, op, dst, dstw, src1, src1w, src2, src2w));
2417 ADJUST_LOCAL_OFFSET(dst, dstw);
2418 ADJUST_LOCAL_OFFSET(src1, src1w);
2419 ADJUST_LOCAL_OFFSET(src2, src2w);
2423 dst_r = FAST_IS_REG(dst) ? dst :
TMP_FREG1;
2450 FAIL_IF(push_inst16(compiler,
IT | (0xb << 4) | 0x8));
2462#if defined(__ARM_NEON) && __ARM_NEON
2472 CHECK(check_sljit_emit_fset32(compiler, freg,
value));
2476#if defined(__ARM_NEON) && __ARM_NEON
2477 if ((
u.imm << (32 - 19)) == 0) {
2478 exp = (
u.imm >> (23 + 2)) & 0x3f;
2480 if (
exp == 0x20 ||
exp == 0x1f) {
2481 ins = ((
u.imm >> 24) & 0x80) | ((
u.imm >> 19) & 0x7f);
2482 return push_inst32(compiler, (
VMOV_F32 ^ (1 << 6)) | ((ins & 0xf0) << 12) |
VD4(freg) | (ins & 0xf));
2494#if defined(__ARM_NEON) && __ARM_NEON
2504 CHECK(check_sljit_emit_fset64(compiler, freg,
value));
2508#if defined(__ARM_NEON) && __ARM_NEON
2509 if (
u.imm[0] == 0 && (
u.imm[1] << (64 - 48)) == 0) {
2510 exp = (
u.imm[1] >> ((52 - 32) + 2)) & 0x1ff;
2512 if (
exp == 0x100 ||
exp == 0xff) {
2513 ins = ((
u.imm[1] >> (56 - 32)) & 0x80) | ((
u.imm[1] >> (48 - 32)) & 0x7f);
2514 return push_inst32(compiler, (
VMOV_F32 ^ (1 << 6)) | (1 << 8) | ((ins & 0xf0) << 12) |
VD4(freg) | (ins & 0xf));
2520 if (
u.imm[0] ==
u.imm[1])
2534 CHECK(check_sljit_emit_fcopy(compiler, op, freg, reg));
2536 if (reg & REG_PAIR_MASK) {
2537 reg2 = REG_PAIR_SECOND(reg);
2538 reg = REG_PAIR_FIRST(reg);
2551 return push_inst32(compiler, inst);
2652 CHECK_PTR(check_sljit_emit_label(compiler));
2659 set_label(label, compiler);
2669 CHECK_PTR(check_sljit_emit_jump(compiler,
type));
2677 jump->flags |= IS_COND;
2678 cc = get_cc(compiler,
type);
2679 jump->flags |= cc << 8;
2683 jump->addr = compiler->
size;
2687 jump->flags |= IS_BL;
2692 compiler->
size += JUMP_MAX_SIZE - 1;
2709 if (src && FAST_IS_REG(*src))
2717 switch (arg_types & SLJIT_ARG_MASK) {
2733 word_arg_offset +=
sizeof(
sljit_sw);
2755 FAIL_IF(emit_stack_frame_release(compiler, -1));
2763 switch (
types & SLJIT_ARG_MASK) {
2766 offset = *(--offset_ptr);
2772 FAIL_IF(push_inst16(compiler,
MOV | (src_offset << 1) | 4 | (1 << 7)));
2778 | (float_arg_count << 12) | ((
offset - 4 *
sizeof(
sljit_sw)) >> 2)));
2782 offset = *(--offset_ptr);
2785 if (src_offset ==
offset) {
2786 FAIL_IF(push_inst16(compiler,
MOV | (src_offset << 1) | 4 | (1 << 7)));
2789 FAIL_IF(push_inst32(compiler,
VMOV | 0x100000 | (float_arg_count << 16) | (
offset << 10)));
2792 | (float_arg_count << 12) | ((
offset - 4 *
sizeof(
sljit_sw)) >> 2)));
2795 word_arg_offset -=
sizeof(
sljit_sw);
2796 offset = *(--offset_ptr);
2800 if (
offset != word_arg_offset) {
2802 if (src_offset ==
offset) {
2803 FAIL_IF(push_inst16(compiler,
MOV | (src_offset << 1) | 4 | (1 << 7)));
2806 else if (src_offset == word_arg_offset) {
2810 FAIL_IF(push_inst16(compiler,
MOV | (
offset >> 2) | (word_arg_offset << 1)));
2826 FAIL_IF(push_inst32(compiler,
VMOV2 | (1 << 16) | (0 << 12) | 0));
2828 FAIL_IF(push_inst32(compiler,
VMOV | (0 << 16) | (0 << 12)));
2845 switch (arg_types & SLJIT_ARG_MASK) {
2847 if (
offset != new_offset)
2854 if (f32_offset != 0) {
2858 if (
offset != new_offset)
2860 f32_offset = new_offset;
2883 CHECK_PTR(check_sljit_emit_call(compiler,
type, arg_types));
2887 PTR_FAIL_IF(softfloat_call_with_args(compiler, arg_types,
NULL, &extra_space));
2893 SLJIT_SKIP_CHECKS(compiler);
2897 if (extra_space > 0) {
2911 PTR_FAIL_IF(softfloat_post_call_with_args(compiler, arg_types));
2918 PTR_FAIL_IF(emit_stack_frame_release(compiler, -1));
2924 PTR_FAIL_IF(hardfloat_call_with_args(compiler, arg_types));
2927 SLJIT_SKIP_CHECKS(compiler);
2936 CHECK(check_sljit_emit_ijump(compiler,
type, src, srcw));
2937 ADJUST_LOCAL_OFFSET(src, srcw);
2942 if (FAST_IS_REG(src)) {
2958 jump->addr = compiler->
size;
2960 compiler->
size += JUMP_MAX_SIZE - 1;
2973 CHECK(check_sljit_emit_icall(compiler,
type, arg_types, src, srcw));
2987 FAIL_IF(softfloat_call_with_args(compiler, arg_types, &src, &extra_space));
2993 SLJIT_SKIP_CHECKS(compiler);
2996 if (extra_space > 0) {
3008 return softfloat_post_call_with_args(compiler, arg_types);
3014 FAIL_IF(emit_stack_frame_release(compiler, -1));
3020 FAIL_IF(hardfloat_call_with_args(compiler, arg_types));
3023 SLJIT_SKIP_CHECKS(compiler);
3035 SLJIT_SKIP_CHECKS(compiler);
3039 if (FAST_IS_REG(src)) {
3045 SLJIT_SKIP_CHECKS(compiler);
3062 CHECK(check_sljit_emit_op_flags(compiler, op, dst, dstw,
type));
3063 ADJUST_LOCAL_OFFSET(dst, dstw);
3066 cc = get_cc(compiler,
type);
3067 dst_r = FAST_IS_REG(dst) ? dst :
TMP_REG1;
3070 FAIL_IF(push_inst16(compiler,
IT | (cc << 4) | (((cc & 0x1) ^ 0x1) << 3) | 0x4));
3071 if (reg_map[dst_r] > 7) {
3088 FAIL_IF(push_inst16(compiler,
IT | (cc << 4) | (((cc & 0x1) ^ 0x1) << 3) | 0x4));
3093 FAIL_IF(push_inst16(compiler,
IT | (cc << 4) | 0x8));
3115 CHECK(check_sljit_emit_select(compiler,
type, dst_reg, src1, src1w, src2_reg));
3117 ADJUST_LOCAL_OFFSET(src1, src1w);
3119 if (src2_reg != dst_reg && src1 == dst_reg) {
3129 if (src2_reg != dst_reg) {
3137 }
else if (dst_reg != src2_reg)
3143 FAIL_IF(push_inst16(compiler,
IT | (cc << 4) | 0x8));
3144 return push_inst16(compiler,
MOV |
SET_REGS44(dst_reg, src1));
3149 if (tmp < 0x10000) {
3151 FAIL_IF(push_inst16(compiler,
IT | (cc << 4) | 0x8));
3152 return push_inst32(compiler,
MOVW |
RD4(dst_reg)
3158 FAIL_IF(push_inst16(compiler,
IT | (cc << 4) | 0x8));
3159 return push_inst32(compiler,
MOV_WI |
RD4(dst_reg) | tmp);
3164 FAIL_IF(push_inst16(compiler,
IT | (cc << 4) | 0x8));
3165 return push_inst32(compiler,
MVN_WI |
RD4(dst_reg) | tmp);
3168 FAIL_IF(push_inst16(compiler,
IT | (cc << 4) | ((cc & 0x1) << 3) | 0x4));
3173 return push_inst32(compiler,
MOVT |
RD4(dst_reg)
3183 CHECK(check_sljit_emit_fselect(compiler,
type, dst_freg, src1, src1w, src2_freg));
3185 ADJUST_LOCAL_OFFSET(src1, src1w);
3189 if (dst_freg != src2_freg) {
3190 if (dst_freg == src1) {
3215 CHECK(check_sljit_emit_mem(compiler,
type, reg, mem, memw));
3217 if (!(reg & REG_PAIR_MASK))
3218 return sljit_emit_mem_unaligned(compiler,
type, reg, mem, memw);
3221 if ((mem & REG_MASK) == 0) {
3222 if ((memw & 0xfff) >= (0x1000 - SSIZE_OF(sw))) {
3223 imm = get_imm((
sljit_uw)((memw + 0x1000) & ~0xfff));
3226 memw = (memw & 0xfff) - 0x1000;
3228 imm = get_imm((
sljit_uw)(memw & ~0xfff));
3241 }
else if (mem & OFFS_REG_MASK) {
3245 }
else if (memw < -0xff) {
3247 if ((-memw & 0xfff) <= SSIZE_OF(sw))
3248 tmp = (
sljit_uw)((-memw + 0x7ff) & ~0x7ff);
3250 tmp = (
sljit_uw)((-memw + 0xfff) & ~0xfff);
3258 SLJIT_ASSERT(memw >= 0 && memw <= 0xfff - SSIZE_OF(sw));
3266 }
else if (memw >= (0x1000 - SSIZE_OF(sw))) {
3267 if ((memw & 0xfff) >= (0x1000 - SSIZE_OF(sw))) {
3268 imm = get_imm((
sljit_uw)((memw + 0x1000) & ~0xfff));
3271 memw = (memw & 0xfff) - 0x1000;
3273 imm = get_imm((
sljit_uw)(memw & ~0xfff));
3293 SLJIT_ASSERT(memw <= 0xfff - SSIZE_OF(sw) && memw >= -0xff);
3297 }
else if (REG_PAIR_FIRST(reg) == (mem & REG_MASK)) {
3299 return emit_op_mem(compiler,
WORD_SIZE, REG_PAIR_FIRST(reg), mem, memw,
TMP_REG2);
3303 return emit_op_mem(compiler,
flags, REG_PAIR_SECOND(reg), mem, memw + SSIZE_OF(sw),
TMP_REG2);
3308 if ((mem & REG_MASK) == 0) {
3310 imm = get_imm((
sljit_uw)((memw + (tmp <= 0x400 ? 0 : 0x400)) & ~0x3fc));
3317 memw = (memw & 0x3fc) >> 2;
3320 memw = 0x100 - memw;
3328 }
else if (mem & OFFS_REG_MASK) {
3332 }
else if (memw < 0) {
3333 if ((-memw & ~0x3fc) == 0) {
3338 imm = get_imm((
sljit_uw)((-memw + (tmp <= 0x400 ? 0 : 0x400)) & ~0x3fc));
3342 memw = (-memw & 0x3fc) >> 2;
3347 memw = 0x100 - memw;
3356 }
else if ((memw & ~0x3fc) != 0) {
3358 imm = get_imm((
sljit_uw)((memw + (tmp <= 0x400 ? 0 : 0x400)) & ~0x3fc));
3362 memw = (memw & 0x3fc) >> 2;
3365 memw = 0x100 - memw;
3390 CHECK(check_sljit_emit_mem_update(compiler,
type, reg, mem, memw));
3392 if ((mem & OFFS_REG_MASK) || (memw > 255 || memw < -255))
3398 switch (
type & 0xff) {
3427 inst = sljit_mem32[
flags] | 0x900;
3437 return push_inst32(compiler, inst |
RT4(reg) |
RN4(mem & REG_MASK) | (
sljit_ins)memw);
3456 if (argw <= max_offset && argw >= -0xff) {
3462 imm = get_imm((
sljit_uw)(-argw & ~0xff));
3465 *memw = -(-argw & 0xff);
3468 }
else if ((argw & 0xfff) <= max_offset) {
3469 imm = get_imm((
sljit_uw)(argw & ~0xfff));
3472 *memw = argw & 0xfff;
3476 imm = get_imm((
sljit_uw)((argw | 0xfff) + 1));
3479 *memw = (argw & 0xfff) - 0x1000;
3487 if ((argw & 0xfff) > max_offset) {
3489 *memw = (argw & 0xfff) - 0x1000;
3491 *memw = argw & 0xfff;
3506 CHECK(check_sljit_emit_fmem(compiler,
type, freg, mem, memw));
3517 FAIL_IF(update_mem_addr(compiler, &mem, &memw, 0xfff - 4));
3530 FAIL_IF(update_mem_addr(compiler, &mem, &memw, 0xfff - 4));
3561 imm = get_imm((
sljit_uw)(memw < 0 ? -memw : memw));
3582#define SLJIT_QUAD_OTHER_HALF(freg) ((((freg) & 0x1) << 1) - 1)
3594 CHECK(check_sljit_emit_simd_mov(compiler,
type, freg, srcdst, srcdstw));
3596 ADJUST_LOCAL_OFFSET(srcdst, srcdstw);
3598 if (reg_size != 3 && reg_size != 4)
3608 freg = simd_get_quad_reg_index(freg);
3612 srcdst = simd_get_quad_reg_index(srcdst);
3615 ins =
VD4(srcdst) |
VN4(freg) |
VM4(freg);
3617 ins =
VD4(freg) |
VN4(srcdst) |
VM4(srcdst);
3622 return push_inst32(compiler,
VORR | ins);
3625 FAIL_IF(sljit_emit_simd_mem_offset(compiler, &srcdst, srcdstw));
3631 | (
sljit_ins)((reg_size == 3) ? (0x7 << 8) : (0xa << 8));
3637 else if (alignment >= 4)
3640 return push_inst32(compiler, ins |
RN4(srcdst) | ((
sljit_ins)elem_size) << 6 | 0xf);
3657 switch (elem_size) {
3667 if (
value <= 0xff) {
3672 if ((
value & 0xff) == 0) {
3690 if (
value <= 0xff) {
3746 CHECK(check_sljit_emit_simd_replicate(compiler,
type, freg, src, srcw));
3748 ADJUST_LOCAL_OFFSET(src, srcw);
3750 if (reg_size != 3 && reg_size != 4)
3760 freg = simd_get_quad_reg_index(freg);
3763 return push_inst32(compiler,
VMOV_i | ((reg_size == 4) ? (1 << 6) : 0) |
VD4(freg));
3771 }
else if (freg != src)
3777 return push_inst32(compiler,
VORR |
VD4(freg) |
VN4(src) |
VM4(src));
3782 FAIL_IF(sljit_emit_simd_mem_offset(compiler, &src, srcw));
3789 return push_inst32(compiler,
VLD1_r | ins |
VD4(freg) |
RN4(src) | 0xf);
3806 imm = simd_get_imm(elem_size, (
sljit_uw)srcw);
3812 return push_inst32(compiler,
VMOV_i | imm |
VD4(freg));
3819 switch (elem_size) {
3834 return push_inst32(compiler,
VDUP | ins |
VN4(freg) |
RT4(src));
3846 CHECK(check_sljit_emit_simd_lane_mov(compiler,
type, freg, lane_index, srcdst, srcdstw));
3848 ADJUST_LOCAL_OFFSET(srcdst, srcdstw);
3850 if (reg_size != 3 && reg_size != 4)
3860 freg = simd_get_quad_reg_index(freg);
3863 ins = (reg_size == 3) ? 0 : ((
sljit_ins)1 << 6);
3866 if (elem_size == 3 && !(srcdst &
SLJIT_MEM)) {
3867 if (lane_index == 1)
3874 return push_inst32(compiler,
VMOV_i |
VD4(freg));
3887 if (reg_size == 4 && lane_index >= (0x8 >> elem_size)) {
3888 lane_index -= (0x8 >> elem_size);
3896 FAIL_IF(sljit_emit_simd_mem_offset(compiler, &srcdst, srcdstw));
3898 lane_index = lane_index << elem_size;
3899 ins = (
sljit_ins)((elem_size << 10) | (lane_index << 5));
3904 if (elem_size == 3) {
3906 return push_inst32(compiler,
VORR |
VD4(srcdst) |
VN4(freg) |
VM4(freg));
3911 if (freg_ebit_map[freg] == 0) {
3912 if (lane_index == 1)
3915 return push_inst32(compiler,
VMOV_F32 |
VD4(srcdst) |
VM4(freg));
3936 else if (elem_size == 1)
3941 lane_index = lane_index << elem_size;
3942 ins |= (
sljit_ins)(((lane_index & 0x4) << 19) | ((lane_index & 0x3) << 5));
3951 return push_inst32(compiler,
VMOV_s | ins |
VN4(freg) |
RT4(srcdst));
3963 CHECK(check_sljit_emit_simd_lane_replicate(compiler,
type, freg, src, src_lane_index));
3965 if (reg_size != 3 && reg_size != 4)
3974 if (reg_size == 4) {
3975 freg = simd_get_quad_reg_index(freg);
3976 src = simd_get_quad_reg_index(src);
3978 if (src_lane_index >= (0x8 >> elem_size)) {
3979 src_lane_index -= (0x8 >> elem_size);
3984 if (elem_size == 3) {
3991 return push_inst32(compiler,
VORR |
VD4(freg) |
VN4(src) |
VM4(src));
3995 ins = ((((
sljit_ins)src_lane_index << 1) | 1) << (16 + elem_size));
4000 return push_inst32(compiler,
VDUP_s | ins |
VD4(freg) |
VM4(src));
4013 CHECK(check_sljit_emit_simd_extend(compiler,
type, freg, src, srcw));
4015 ADJUST_LOCAL_OFFSET(src, srcw);
4017 if (reg_size != 3 && reg_size != 4)
4027 freg = simd_get_quad_reg_index(freg);
4030 FAIL_IF(sljit_emit_simd_mem_offset(compiler, &src, srcw));
4031 if (reg_size == 4 && elem2_size - elem_size == 1)
4036 }
else if (reg_size == 4)
4037 src = simd_get_quad_reg_index(src);
4040 dst_reg = (reg_size == 4) ? freg :
TMP_FREG2;
4046 }
while (++elem_size < elem2_size);
4078 CHECK(check_sljit_emit_simd_sign(compiler,
type, freg, dst, dstw));
4080 ADJUST_LOCAL_OFFSET(dst, dstw);
4082 if (reg_size != 3 && reg_size != 4)
4091 switch (elem_size) {
4094 ins =
VSHR | (1 << 28) | (0x9 << 16);
4097 imms = (reg_size == 4) ? 0x243219 : 0x2231;
4098 ins =
VSHR | (1 << 28) | (0x11 << 16);
4101 imms = (reg_size == 4) ? 0x2231 : 0x21;
4102 ins =
VSHR | (1 << 28) | (0x21 << 16);
4106 ins =
VSHR | (1 << 28) | (0x1 << 16) | (1 << 7);
4110 if (reg_size == 4) {
4111 freg = simd_get_quad_reg_index(freg);
4118 if (reg_size == 4 && elem_size > 0)
4121 ins = (reg_size == 4 && elem_size == 0) ? (1 << 6) : 0;
4123 while (imms >= 0x100) {
4130 dst_r = FAST_IS_REG(dst) ? dst :
TMP_REG1;
4133 if (reg_size == 4 && elem_size == 0) {
4153 CHECK(check_sljit_emit_simd_op2(compiler,
type, dst_freg, src1_freg, src2_freg));
4155 if (reg_size != 3 && reg_size != 4)
4161 switch (SLJIT_SIMD_GET_OPCODE(
type)) {
4176 if (reg_size == 4) {
4177 dst_freg = simd_get_quad_reg_index(dst_freg);
4178 src1_freg = simd_get_quad_reg_index(src1_freg);
4179 src2_freg = simd_get_quad_reg_index(src2_freg);
4183 return push_inst32(compiler, ins |
VD4(dst_freg) |
VN4(src1_freg) |
VM4(src2_freg));
4195 CHECK(check_sljit_emit_atomic_load(compiler, op, dst_reg, mem_reg));
4209 return push_inst32(compiler, ins |
RN4(mem_reg) |
RT4(dst_reg));
4223 CHECK(check_sljit_emit_atomic_store(compiler, op, src_reg, mem_reg, temp_reg));
4237 FAIL_IF(push_inst32(compiler, ins |
RN4(mem_reg) |
RT4(src_reg)));
4250 CHECK_PTR(check_sljit_emit_const(compiler, dst, dstw, init_value));
4251 ADJUST_LOCAL_OFFSET(dst, dstw);
4255 set_const(const_, compiler);
4257 dst_r = FAST_IS_REG(dst) ? dst :
TMP_REG1;
4271 CHECK_PTR(check_sljit_emit_mov_addr(compiler, dst, dstw));
4272 ADJUST_LOCAL_OFFSET(dst, dstw);
4276 set_mov_addr(jump, compiler, 0);
4278 dst_r = FAST_IS_REG(dst) ? dst :
TMP_REG1;
4280 compiler->
size += 3;
4293 modify_imm32_const(inst, new_target);
4295 inst = (
sljit_u16 *)SLJIT_ADD_EXEC_OFFSET(inst, executable_offset);
zend_ffi_ctype_name_buf buf
PHP_JSON_API size_t int options
#define SLJIT_UNREACHABLE()
unsigned short int sljit_u16
signed short int sljit_s16
#define SLJIT_UNLIKELY(x)
#define SLJIT_API_FUNC_ATTRIBUTE
#define SLJIT_COMPILE_ASSERT(x, description)
#define SLJIT_F64_SECOND(reg)
#define SLJIT_UNUSED_ARG(arg)
#define SLJIT_NUMBER_OF_SCRATCH_FLOAT_REGISTERS
#define SLJIT_TMP_FREGISTER_BASE
#define SLJIT_CACHE_FLUSH(from, to)
#define SLJIT_UPDATE_WX_FLAGS(from, to, enable_exec)
#define PTR_FAIL_IF(expr)
#define PTR_FAIL_WITH_EXEC_IF(ptr)
#define CHECK_ERROR_PTR()
#define SLJIT_UNORDERED_OR_LESS_EQUAL
#define SLJIT_SKIP_FRAMES_BEFORE_FAST_RETURN
#define SLJIT_CALL_REG_ARG
#define SLJIT_ARG_TYPE_SCRATCH_REG
#define SLJIT_SIMD_OP2_AND
#define SLJIT_ORDERED_LESS_EQUAL
#define SLJIT_FAST_RETURN
#define SLJIT_MEM_UNALIGNED
#define SLJIT_SIMD_REG_64
#define SLJIT_ATOMIC_NOT_STORED
#define SLJIT_FIRST_SAVED_REG
#define SLJIT_UNORDERED_OR_GREATER
#define SLJIT_ARG_TYPE_F32
#define SLJIT_ORDERED_GREATER_EQUAL
#define SLJIT_FUNC_ADDR(func_name)
#define SLJIT_PREFETCH_L3
#define SLJIT_SIG_GREATER_EQUAL
#define SLJIT_RETURN_FREG
#define SLJIT_UNORDERED_OR_NOT_EQUAL
#define SLJIT_ARG_TYPE_F64
#define SLJIT_SIMD_EXTEND_SIGNED
#define SLJIT_PREFETCH_L1
#define SLJIT_SIMD_OP2_XOR
#define SLJIT_COPYSIGN_F64
#define SLJIT_ORDERED_EQUAL
#define SLJIT_ERR_UNSUPPORTED
#define SLJIT_UNORDERED_OR_LESS
#define SLJIT_MEM_ALIGNED_16
#define SLJIT_ORDERED_GREATER
#define SLJIT_SIMD_REGS_ARE_PAIRS
#define SLJIT_SIG_LESS_EQUAL
#define SLJIT_UNORDERED_OR_EQUAL
#define SLJIT_CALL_RETURN
#define SLJIT_REWRITABLE_JUMP
#define SLJIT_NOT_OVERFLOW
#define SLJIT_F_NOT_EQUAL
#define SLJIT_F_GREATER_EQUAL
#define SLJIT_CURRENT_FLAGS_ADD
#define SLJIT_HAS_PREFETCH
#define SLJIT_ENTER_REG_ARG
#define SLJIT_SIG_GREATER
#define SLJIT_SIMD_LANE_ZERO
#define SLJIT_FLOAT_REGISTER
#define SLJIT_ATOMIC_STORED
#define SLJIT_GET_RETURN_ADDRESS
#define SLJIT_MEM_ALIGNED_32
#define SLJIT_HAS_F64_AS_F32_PAIR
#define SLJIT_FIRST_SAVED_FLOAT_REG
#define SLJIT_SIMD_OP2_OR
#define SLJIT_SIMD_LANE_SIGNED
#define SLJIT_GREATER_EQUAL
#define SLJIT_GP_REGISTER
#define SLJIT_SKIP_FRAMES_BEFORE_RETURN
#define SLJIT_ERR_COMPILED
#define SLJIT_HAS_COPY_F64
#define SLJIT_SIMD_REG_128
#define SLJIT_F_LESS_EQUAL
#define SLJIT_ORDERED_LESS
#define SLJIT_HAS_COPY_F32
#define SLJIT_CONV_F64_FROM_F32
#define SLJIT_REG_PAIR(r1, r2)
#define SLJIT_PREFETCH_L2
#define SLJIT_SET_ATOMIC_STORED
#define SLJIT_CURRENT_FLAGS_SUB
#define SLJIT_PREFETCH_ONCE
#define SLJIT_ORDERED_NOT_EQUAL
#define SLJIT_COPY_FROM_F64
#define SLJIT_UNORDERED_OR_GREATER_EQUAL
SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_flags(struct sljit_compiler *compiler, sljit_s32 op, sljit_s32 dst, sljit_sw dstw, sljit_s32 type)
SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump * sljit_emit_jump(struct sljit_compiler *compiler, sljit_s32 type)
SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump * sljit_emit_call(struct sljit_compiler *compiler, sljit_s32 type, sljit_s32 arg_types)
#define COPY_BITS(src, from, to, bits)
SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op2r(struct sljit_compiler *compiler, sljit_s32 op, sljit_s32 dst_reg, sljit_s32 src1, sljit_sw src1w, sljit_s32 src2, sljit_sw src2w)
SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_select(struct sljit_compiler *compiler, sljit_s32 type, sljit_s32 dst_reg, sljit_s32 src1, sljit_sw src1w, sljit_s32 src2_reg)
SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_mem(struct sljit_compiler *compiler, sljit_s32 type, sljit_s32 reg, sljit_s32 mem, sljit_sw memw)
SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_return_to(struct sljit_compiler *compiler, sljit_s32 src, sljit_sw srcw)
SLJIT_API_FUNC_ATTRIBUTE const char * sljit_get_platform_name(void)
SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_has_cpu_feature(sljit_s32 feature_type)
SLJIT_API_FUNC_ATTRIBUTE void * sljit_generate_code(struct sljit_compiler *compiler, sljit_s32 options, void *exec_allocator_data)
SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op2u(struct sljit_compiler *compiler, sljit_s32 op, sljit_s32 src1, sljit_sw src1w, sljit_s32 src2, sljit_sw src2w)
SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_atomic_load(struct sljit_compiler *compiler, sljit_s32 op, sljit_s32 dst_reg, sljit_s32 mem_reg)
SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_get_register_index(sljit_s32 type, sljit_s32 reg)
#define ALIGN_CHECK(argw, imm, shift)
SLJIT_API_FUNC_ATTRIBUTE struct sljit_const * sljit_emit_const(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw dstw, sljit_sw init_value)
SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_replicate(struct sljit_compiler *compiler, sljit_s32 type, sljit_s32 freg, sljit_s32 src, sljit_sw srcw)
SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_op2(struct sljit_compiler *compiler, sljit_s32 type, sljit_s32 dst_freg, sljit_s32 src1_freg, sljit_s32 src2_freg)
#define IS_3_LO_REGS(reg1, reg2, reg3)
SLJIT_API_FUNC_ATTRIBUTE void sljit_set_const(sljit_uw addr, sljit_sw new_constant, sljit_sw executable_offset)
SLJIT_API_FUNC_ATTRIBUTE struct sljit_label * sljit_emit_label(struct sljit_compiler *compiler)
SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_ijump(struct sljit_compiler *compiler, sljit_s32 type, sljit_s32 src, sljit_sw srcw)
SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fset32(struct sljit_compiler *compiler, sljit_s32 freg, sljit_f32 value)
SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fcopy(struct sljit_compiler *compiler, sljit_s32 op, sljit_s32 freg, sljit_s32 reg)
SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_return_void(struct sljit_compiler *compiler)
SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_mem_update(struct sljit_compiler *compiler, sljit_s32 type, sljit_s32 reg, sljit_s32 mem, sljit_sw memw)
SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_set_context(struct sljit_compiler *compiler, sljit_s32 options, sljit_s32 arg_types, sljit_s32 scratches, sljit_s32 saveds, sljit_s32 fscratches, sljit_s32 fsaveds, sljit_s32 local_size)
SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_lane_mov(struct sljit_compiler *compiler, sljit_s32 type, sljit_s32 freg, sljit_s32 lane_index, sljit_s32 srcdst, sljit_sw srcdstw)
SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump * sljit_emit_mov_addr(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw dstw)
SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op0(struct sljit_compiler *compiler, sljit_s32 op)
SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fop2(struct sljit_compiler *compiler, sljit_s32 op, sljit_s32 dst, sljit_sw dstw, sljit_s32 src1, sljit_sw src1w, sljit_s32 src2, sljit_sw src2w)
SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fop1(struct sljit_compiler *compiler, sljit_s32 op, sljit_s32 dst, sljit_sw dstw, sljit_s32 src, sljit_sw srcw)
SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_shift_into(struct sljit_compiler *compiler, sljit_s32 op, sljit_s32 dst_reg, sljit_s32 src1_reg, sljit_s32 src2_reg, sljit_s32 src3, sljit_sw src3w)
SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_extend(struct sljit_compiler *compiler, sljit_s32 type, sljit_s32 freg, sljit_s32 src, sljit_sw srcw)
SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_enter(struct sljit_compiler *compiler, sljit_s32 options, sljit_s32 arg_types, sljit_s32 scratches, sljit_s32 saveds, sljit_s32 fscratches, sljit_s32 fsaveds, sljit_s32 local_size)
#define IS_WORD_SIZE(flags)
SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_mov(struct sljit_compiler *compiler, sljit_s32 type, sljit_s32 freg, sljit_s32 srcdst, sljit_sw srcdstw)
#define IS_2_LO_REGS(reg1, reg2)
#define SET_REGS44(rd, rn)
SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fset64(struct sljit_compiler *compiler, sljit_s32 freg, sljit_f64 value)
SLJIT_API_FUNC_ATTRIBUTE void sljit_set_jump_addr(sljit_uw addr, sljit_uw new_target, sljit_sw executable_offset)
SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_dst(struct sljit_compiler *compiler, sljit_s32 op, sljit_s32 dst, sljit_sw dstw)
SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_atomic_store(struct sljit_compiler *compiler, sljit_s32 op, sljit_s32 src_reg, sljit_s32 mem_reg, sljit_s32 temp_reg)
SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fselect(struct sljit_compiler *compiler, sljit_s32 type, sljit_s32 dst_freg, sljit_s32 src1, sljit_sw src1w, sljit_s32 src2_freg)
#define SLJIT_QUAD_OTHER_HALF(freg)
SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_src(struct sljit_compiler *compiler, sljit_s32 op, sljit_s32 src, sljit_sw srcw)
SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_sign(struct sljit_compiler *compiler, sljit_s32 type, sljit_s32 freg, sljit_s32 dst, sljit_sw dstw)
SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fmem(struct sljit_compiler *compiler, sljit_s32 type, sljit_s32 freg, sljit_s32 mem, sljit_sw memw)
SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op2(struct sljit_compiler *compiler, sljit_s32 op, sljit_s32 dst, sljit_sw dstw, sljit_s32 src1, sljit_sw src1w, sljit_s32 src2, sljit_sw src2w)
SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_custom(struct sljit_compiler *compiler, void *instruction, sljit_u32 size)
SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_icall(struct sljit_compiler *compiler, sljit_s32 type, sljit_s32 arg_types, sljit_s32 src, sljit_sw srcw)
SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op1(struct sljit_compiler *compiler, sljit_s32 op, sljit_s32 dst, sljit_sw dstw, sljit_s32 src, sljit_sw srcw)
SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_lane_replicate(struct sljit_compiler *compiler, sljit_s32 type, sljit_s32 freg, sljit_s32 src, sljit_s32 src_lane_index)
#define SLJIT_IS_FPU_AVAILABLE
struct sljit_const * consts
sljit_sw executable_offset
struct sljit_jump * jumps
struct sljit_label * last_label
struct sljit_memory_fragment * buf
struct sljit_label * labels
struct sljit_const * next
struct sljit_label * next
union sljit_label::@034003116150245300057154161307153110213245130244 u
exit(string|int $status=0)