41 sljit_unaligned_store_sw(inst, imm);
82 if (immb != 0 && !(b & OFFS_REG_MASK)) {
84 if (immb <= 127 && immb >= -128)
88 }
else if (reg_map[b & REG_MASK] == 5) {
90 if ((b & OFFS_REG_MASK) && (immb & 0x3) == 0 && reg_map[OFFS_REG(b)] != 5)
91 b =
SLJIT_MEM | OFFS_REG(b) | TO_OFFS_REG(b & REG_MASK);
96 if (reg_map[b & REG_MASK] == 4 && !(b & OFFS_REG_MASK))
99 if (b & OFFS_REG_MASK)
107 if (imma <= 127 && imma >= -128) {
121 inst_size +=
sizeof(short);
127 inst = (
sljit_u8*)ensure_buf(compiler, 1 + inst_size);
139 buf_ptr = inst +
size;
149 *buf_ptr =
U8(reg_map[
a] << 3);
151 *buf_ptr =
U8(freg_map[
a] << 3);
166 }
else if (b & REG_MASK) {
167 reg_map_b = reg_map[b & REG_MASK];
169 if (!(b & OFFS_REG_MASK) || (b & OFFS_REG_MASK) == TO_OFFS_REG(
SLJIT_SP)) {
170 if (immb != 0 || reg_map_b == 5) {
171 if (immb <= 127 && immb >= -128)
177 if (!(b & OFFS_REG_MASK))
178 *buf_ptr++ |= reg_map_b;
181 buf_ptr[1] =
U8(reg_map_b | (reg_map[OFFS_REG(b)] << 3));
185 if (immb != 0 || reg_map_b == 5) {
186 if (immb <= 127 && immb >= -128)
187 *buf_ptr++ =
U8(immb);
189 sljit_unaligned_store_sw(buf_ptr, immb);
198 buf_ptr[1] =
U8(reg_map_b | (reg_map[OFFS_REG(b)] << 3) | (immb << 6));
206 sljit_unaligned_store_sw(buf_ptr, immb);
214 sljit_unaligned_store_s16(buf_ptr, (
sljit_s16)imma);
216 sljit_unaligned_store_sw(buf_ptr, imma);
260 vex =
U8(vex | ((((op &
VEX_SSE2_OPV) ? freg_map[
v] : reg_map[
v]) ^ 0xf) << 3));
263 size |= (vex_m == 0) ? 3 : 4;
265 inst = emit_x86_instruction(compiler,
size,
a, 0, b, immb);
270 inst[1] =
U8(vex | 0x80);
276 inst[1] =
U8(vex_m | 0xe0);
296 *code_ptr++ = get_jump_code(
type);
301 if (jump->flags & JUMP_ADDR)
302 sljit_unaligned_store_sw(code_ptr, (
sljit_sw)(jump->u.target - (jump->addr + 4) - (
sljit_uw)executable_offset));
304 jump->flags |= PATCH_MW;
310#define ENTER_TMP_TO_R4 0x00001
311#define ENTER_TMP_TO_S 0x00002
317 sljit_s32 word_arg_count, saved_arg_count, float_arg_count;
326 CHECK(check_sljit_emit_enter(compiler,
options, arg_types, scratches, saveds, fscratches, fsaveds, local_size));
327 set_emit_enter(compiler,
options, arg_types, scratches, saveds, fscratches, fsaveds, local_size);
330 FAIL_IF(emit_endbranch(compiler));
339 args_size = 3 * SSIZE_OF(sw);
344 if (word_arg_count >= 4)
351 compiler->args_size = 0;
356 args_size = SSIZE_OF(sw);
358 switch (
types & SLJIT_ARG_MASK) {
362 args_size += SSIZE_OF(f64);
367 args_size += SSIZE_OF(f32);
375 if (word_arg_count == 4) {
379 }
else if (saved_arg_count == 4) {
385 args_size += SSIZE_OF(sw);
391 args_size -= SSIZE_OF(sw);
392 compiler->args_size = args_size;
395 size = (scratches > 9 ? (scratches - 9) : 0) + (saveds <= 3 ? saveds : 3) - kept_saveds_count;
408 if ((saveds > 2 && kept_saveds_count <= 2) || scratches > 9)
410 if ((saveds > 1 && kept_saveds_count <= 1) || scratches > 10)
412 if ((saveds > 0 && kept_saveds_count == 0) || scratches > 11)
415 size *= SSIZE_OF(sw);
421 size += SSIZE_OF(sw);
423 local_size = ((SLJIT_LOCALS_OFFSET_BASE + local_size +
size + 0xf) & ~0xf) -
size;
430 switch (arg_types & SLJIT_ARG_MASK) {
432 args_size += SSIZE_OF(f64);
435 args_size += SSIZE_OF(f32);
443 if (word_arg_count == 3 && local_size > 4 * 4096)
444 r2_offset = local_size + args_size;
454 args_size += SSIZE_OF(sw);
465 if (local_size > 4096) {
466 if (local_size <= 4 * 4096) {
469 if (local_size > 2 * 4096)
471 if (local_size > 3 * 4096)
483 local_size -= SSIZE_OF(sw);
484 r2_offset = local_size;
492 inst = (
sljit_u8*)ensure_buf(compiler, 1 + 2);
502 if (local_size > 0) {
518 size = SLJIT_LOCALS_OFFSET_BASE - SSIZE_OF(sw);
519 kept_saveds_count =
SLJIT_R3 - kept_saveds_count;
521 while (saved_arg_count > 3) {
524 size -= SSIZE_OF(sw);
530 size = 2 * SSIZE_OF(sw);
545 CHECK(check_sljit_set_context(compiler,
options, arg_types, scratches, saveds, fscratches, fsaveds, local_size));
546 set_set_context(compiler,
options, arg_types, scratches, saveds, fscratches, fsaveds, local_size);
553 switch (arg_types & SLJIT_ARG_MASK) {
555 args_size += SSIZE_OF(f64);
558 args_size += SSIZE_OF(f32);
561 args_size += SSIZE_OF(sw);
568 compiler->args_size = args_size;
572 saveds = (1 + (scratches > 9 ? (scratches - 9) : 0) + (saveds <= 3 ? saveds : 3) - SLJIT_KEPT_SAVEDS_COUNT(
options)) * SSIZE_OF(sw);
576 saveds += SSIZE_OF(sw);
578 compiler->
local_size = ((SLJIT_LOCALS_OFFSET_BASE + local_size + saveds + 0xf) & ~0xf) - saveds;
590 (compiler->
saveds <= 3 ? compiler->
saveds : 3) - kept_saveds_count);
596 else if (is_return_to &&
size == 0) {
597 local_size += SSIZE_OF(sw);
612 saveds = compiler->
saveds;
614 if ((saveds > 0 && kept_saveds_count == 0) || compiler->
scratches > 11)
616 if ((saveds > 1 && kept_saveds_count <= 1) || compiler->
scratches > 10)
618 if ((saveds > 2 && kept_saveds_count <= 2) || compiler->
scratches > 9)
633 CHECK(check_sljit_emit_return_void(compiler));
638 FAIL_IF(emit_stack_frame_release(compiler, 0));
640 return emit_byte(compiler,
RET_near);
649 CHECK(check_sljit_emit_return_to(compiler, src, srcw));
652 ADJUST_LOCAL_OFFSET(src, srcw);
657 EMIT_MOV(compiler, src_r, 0, src, srcw);
662 FAIL_IF(emit_stack_frame_release(compiler, 1));
664 SLJIT_SKIP_CHECKS(compiler);
680 switch (arg_types & SLJIT_ARG_MASK) {
682 stack_size += SSIZE_OF(f64);
685 stack_size += SSIZE_OF(f32);
689 stack_size += SSIZE_OF(sw);
696 if (word_arg_count_ptr)
697 *word_arg_count_ptr = word_arg_count;
699 if (stack_size <= 4 * SSIZE_OF(sw))
702 return ((stack_size - (4 * SSIZE_OF(sw)) + 0xf) & ~0xf);
708 sljit_s32 float_arg_count = 0, arg4_reg = 0, arg_offset;
711 if (word_arg_count >= 4) {
728 switch (arg_types & SLJIT_ARG_MASK) {
732 arg_offset += SSIZE_OF(f64);
737 arg_offset += SSIZE_OF(f32);
743 if (word_arg_count == 1 && arg4_reg ==
SLJIT_R0)
746 arg_offset += SSIZE_OF(sw);
770 inst = (
sljit_u8*)ensure_buf(compiler, 1 + 3);
774 inst[1] = (0x03 << 3) | 0x04;
775 inst[2] = (0x04 << 3) | reg_map[
SLJIT_SP];
784 sljit_sw args_size, saved_regs_size;
792 ADJUST_LOCAL_OFFSET(src, srcw);
796 + (compiler->
saveds <= 3 ? compiler->
saveds : 3) - kept_saveds_count) * SSIZE_OF(sw);
804 while (arg_types != 0) {
807 switch (arg_types & SLJIT_ARG_MASK) {
809 args_size += SSIZE_OF(f64);
813 args_size += SSIZE_OF(f32);
818 args_size += SSIZE_OF(sw);
824 if (args_size <= compiler->args_size) {
826 stack_size = args_size + SSIZE_OF(sw) + saved_regs_size;
831 if (word_arg_count >= 1) {
839 switch (
types & SLJIT_ARG_MASK) {
851 switch (word_arg_count) {
854 if (r2_offset != 0) {
879 return emit_stack_frame_release(compiler, 0);
882 stack_size = args_size + SSIZE_OF(sw);
885 r2_offset = SSIZE_OF(sw);
886 stack_size += SSIZE_OF(sw);
889 if (word_arg_count >= 3)
890 stack_size += SSIZE_OF(sw);
892 prev_stack_size = SSIZE_OF(sw) + saved_regs_size;
893 min_size = prev_stack_size + compiler->
local_size;
895 word_arg4_offset = 2 * SSIZE_OF(sw);
897 if (stack_size > min_size) {
900 srcw += stack_size - min_size;
901 word_arg4_offset += stack_size - min_size;
904 stack_size = min_size;
906 if (word_arg_count >= 3) {
909 if (word_arg_count >= 4)
914 if (word_arg_count >= 1) {
922 offset = stack_size - 2 * SSIZE_OF(sw);
929 if ((compiler->
saveds > 1 && kept_saveds_count <= 1) || compiler->
scratches > 10) {
933 if ((compiler->
saveds > 0 && kept_saveds_count == 0) || compiler->
scratches > 11) {
939 offset = stack_size - SSIZE_OF(sw);
940 *extra_space = args_size;
942 if (word_arg_count >= 4) {
948 switch (
types & SLJIT_ARG_MASK) {
960 switch (word_arg_count) {
963 if (r2_offset != 0) {
1000 return emit_byte(compiler,
RET_near);
1017 if (word_arg_count < 4)
1022 kept_saveds_count = SLJIT_KEPT_SAVEDS_COUNT(compiler->
options);
1025 if ((compiler->
saveds > 0 && kept_saveds_count == 0) || compiler->
scratches > 11)
1027 if ((compiler->
saveds > 1 && kept_saveds_count <= 1) || compiler->
scratches > 10)
1029 if ((compiler->
saveds > 2 && kept_saveds_count <= 2) || compiler->
scratches > 9)
1043 CHECK_PTR(check_sljit_emit_call(compiler,
type, arg_types));
1047 PTR_FAIL_IF(tail_call_reg_arg_with_args(compiler, arg_types));
1048 PTR_FAIL_IF(emit_stack_frame_release(compiler, 0));
1050 SLJIT_SKIP_CHECKS(compiler);
1057 SLJIT_SKIP_CHECKS(compiler);
1059 if (stack_size == 0)
1065 PTR_FAIL_IF(emit_tail_call_end(compiler, stack_size));
1070 SLJIT_SKIP_CHECKS(compiler);
1074 stack_size = call_get_stack_size(arg_types, &word_arg_count);
1075 PTR_FAIL_IF(call_with_args(compiler, arg_types, stack_size, word_arg_count, 0));
1077 SLJIT_SKIP_CHECKS(compiler);
1081 PTR_FAIL_IF(post_call_with_args(compiler, arg_types, stack_size));
1093 CHECK(check_sljit_emit_icall(compiler,
type, arg_types, src, srcw));
1097 FAIL_IF(tail_call_reg_arg_with_args(compiler, arg_types));
1100 ADJUST_LOCAL_OFFSET(src, srcw);
1108 FAIL_IF(emit_stack_frame_release(compiler, 0));
1110 SLJIT_SKIP_CHECKS(compiler);
1115 FAIL_IF(tail_call_with_args(compiler, &stack_size, arg_types, src, srcw));
1122 SLJIT_SKIP_CHECKS(compiler);
1124 if (stack_size == 0)
1128 return emit_tail_call_end(compiler, stack_size);
1132 SLJIT_SKIP_CHECKS(compiler);
1136 ADJUST_LOCAL_OFFSET(src, srcw);
1145 stack_size = call_get_stack_size(arg_types, &word_arg_count);
1146 FAIL_IF(call_with_args(compiler, arg_types, stack_size, word_arg_count, src ==
TMP_REG1));
1151 SLJIT_SKIP_CHECKS(compiler);
1154 return post_call_with_args(compiler, arg_types, stack_size);
1165 SLJIT_SKIP_CHECKS(compiler);
1169 if (FAST_IS_REG(src)) {
1175 ADJUST_LOCAL_OFFSET(src, srcw);
1178 inst = emit_x86_instruction(compiler, 1 |
EX86_SSE2_OP1, 0, 0, src, srcw);
1191 if (FAST_IS_REG(dst))
1192 return emit_byte(compiler,
U8(
POP_r + reg_map[dst]));
1195 inst = emit_x86_instruction(compiler, 1, 0, 0, dst, dstw);
1207 if (FAST_IS_REG(src)) {
1208 inst = (
sljit_u8*)ensure_buf(compiler, 1 + 1 + 1);
1215 inst = emit_x86_instruction(compiler, 1, 0, 0, src, srcw);
1220 inst = (
sljit_u8*)ensure_buf(compiler, 1 + 1);
1236 saveds = ((scratches > 9 ? (scratches - 9) : 0) + (saveds <= 3 ? saveds : 3) - SLJIT_KEPT_SAVEDS_COUNT(
options)) * SSIZE_OF(sw);
1240 saveds += SSIZE_OF(sw);
1259 CHECK(check_sljit_emit_select(compiler,
type, dst_reg, src1, src1w, src2_reg));
1261 ADJUST_LOCAL_OFFSET(src1, src1w);
1280 if (dst_reg != src2_reg) {
1281 if (dst_reg == src1) {
1285 }
else if (ADDRESSING_DEPENDS_ON(src1, dst_reg)) {
1286 EMIT_MOV(compiler, dst_reg, 0, src1, src1w);
1291 EMIT_MOV(compiler, dst_reg, 0, src2_reg, src2w);
1304 FAIL_IF(emit_cmov_generic(compiler,
type, dst_reg, src1, src1w));
1307 return emit_mov(compiler, dst, dstw,
TMP_REG1, 0);
1320 CHECK(check_sljit_emit_mem(compiler,
type, reg, mem, memw));
1322 if (!(reg & REG_PAIR_MASK))
1323 return sljit_emit_mem_unaligned(compiler,
type, reg, mem, memw);
1325 ADJUST_LOCAL_OFFSET(mem, memw);
1327 regs[0] =
U8(REG_PAIR_FIRST(reg));
1328 regs[1] =
U8(REG_PAIR_SECOND(reg));
1330 next = SSIZE_OF(sw);
1332 if (!(
type &
SLJIT_MEM_STORE) && (regs[0] == (mem & REG_MASK) || regs[0] == OFFS_REG(mem))) {
1333 if (regs[1] == (mem & REG_MASK) || regs[1] == OFFS_REG(mem)) {
1337 if (regs[1] == OFFS_REG(mem))
1338 next = -SSIZE_OF(sw);
1340 mem = (mem & ~OFFS_REG_MASK) | TO_OFFS_REG(
TMP_REG1);
1342 next = -SSIZE_OF(sw);
1344 if (!(mem & OFFS_REG_MASK))
1345 memw += SSIZE_OF(sw);
1349 for (i = 0; i < 2; i++) {
1350 reg_idx =
next > 0 ? i : (i ^ 0x1);
1351 reg = regs[reg_idx];
1363 if ((mem & OFFS_REG_MASK) && (reg_idx == 1)) {
1370 inst[1] = 0x44 |
U8(reg_map[reg] << 3);
1371 inst[2] =
U8(memw << 6) |
U8(reg_map[OFFS_REG(mem)] << 3) | reg_map[mem & REG_MASK];
1374 EMIT_MOV(compiler, mem, memw, reg, 0);
1376 EMIT_MOV(compiler, reg, 0, mem, memw);
1379 if (!(mem & OFFS_REG_MASK))
1394 sljit_u8 *inst, *jump_inst1, *jump_inst2;
1415 inst = (
sljit_u8*)ensure_buf(compiler, 1 + 2);
1420 size1 = compiler->
size;
1423 inst[1] =
U8(compiler->
size - size1);
1426 return emit_sse2_store(compiler, 0, dst, dstw,
TMP_FREG);
1430 if (!FAST_IS_REG(src)) {
1437 inst = (
sljit_u8*)ensure_buf(compiler, 1 + 2);
1443 size1 = compiler->
size;
1447 inst = (
sljit_u8*)ensure_buf(compiler, 1 + 2);
1453 size2 = compiler->
size;
1455 jump_inst1[1] =
U8(size2 - size1);
1464 inst = (
sljit_u8*)ensure_buf(compiler, 1 + 2);
1470 size1 = compiler->
size;
1473 jump_inst1[1] =
U8(compiler->
size - size1);
1478 jump_inst2[1] =
U8(compiler->
size - size2);
1495 CHECK(check_sljit_emit_fset32(compiler, freg,
value));
1502 inst = (
sljit_u8*)ensure_buf(compiler, 1 + 4);
1511 inst[3] =
U8(freg_map[freg] | (freg_map[freg] << 3) |
MOD_REG);
1530 CHECK(check_sljit_emit_fset64(compiler, freg,
value));
1534 if (
u.imm[0] == 0) {
1557 if (
u.imm[0] == 0) {
1558 inst = (
sljit_u8*)ensure_buf(compiler, 1 + 4);
1564 inst[2] =
U8(
MOD_REG | (freg_map[freg] << 3) | freg_map[freg]);
1569 if (
u.imm[0] !=
u.imm[1]) {
1574 return emit_byte(compiler, 1);
1577 inst = (
sljit_u8*)ensure_buf(compiler, 1 + 3);
1583 inst[2] =
U8(
MOD_REG | (freg_map[freg] << 3) | freg_map[freg]);
1595 CHECK(check_sljit_emit_fcopy(compiler, op, freg, reg));
1604 if (reg & REG_PAIR_MASK) {
1605 reg2 = REG_PAIR_FIRST(reg);
1606 reg = REG_PAIR_SECOND(reg);
1619 return emit_byte(compiler, 1);
1622 if (reg & REG_PAIR_MASK) {
1623 reg2 = REG_PAIR_SECOND(reg);
1624 reg = REG_PAIR_FIRST(reg);
1639 inst = (
sljit_u8*)ensure_buf(compiler, 1 + 5);
1648 }
else if (reg != 0)
1656 inst = (
sljit_u8*)ensure_buf(compiler, 1 + 3);
1662 inst[2] =
U8(
MOD_REG | (freg_map[freg] << 3) | freg_map[reg == 0 ? freg :
TMP_FREG]);
1674 if (!cpu_has_shadow_stack())
1682 + (compiler->
saveds <= 3 ? compiler->
saveds : 3)) * SSIZE_OF(sw);
PHP_JSON_API size_t int options
signed short int sljit_s16
#define SLJIT_UNLIKELY(x)
#define SLJIT_LOCALS_OFFSET
#define SLJIT_API_FUNC_ATTRIBUTE
#define SLJIT_COMPILE_ASSERT(x, description)
#define PTR_FAIL_IF(expr)
#define CHECK_ERROR_PTR()
SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump * sljit_emit_jump(struct sljit_compiler *compiler, sljit_s32 type)
#define SLJIT_CALL_REG_ARG
#define SLJIT_ARG_TYPE_SCRATCH_REG
SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_has_cpu_feature(sljit_s32 feature_type)
#define SLJIT_ARG_TYPE_F32
#define SLJIT_RETURN_FREG
#define SLJIT_ARG_TYPE_F64
SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_ijump(struct sljit_compiler *compiler, sljit_s32 type, sljit_s32 src, sljit_sw srcw)
#define SLJIT_CALL_RETURN
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)
#define SLJIT_REWRITABLE_JUMP
#define SLJIT_ENTER_REG_ARG
#define SLJIT_COPY_TO_F64
#define SLJIT_COPY_FROM_F64
#define EMIT_MOV(type, type_flags, type_cast)
SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump * sljit_emit_call(struct sljit_compiler *compiler, sljit_s32 type, sljit_s32 arg_types)
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 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_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_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)
SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fset64(struct sljit_compiler *compiler, sljit_s32 freg, sljit_f64 value)
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)
#define CHECK_EXTRA_REGS(p, w, do)
#define EX86_SELECT_F2_F3(op)
#define CPU_FEATURE_SSE41
#define BINARY_IMM32(op_imm, immw, arg, argw)