40 inst[0] =
REX_W | ((reg_map[reg] <= 7) ? 0 :
REX_B);
42 sljit_unaligned_store_sw(inst + 2, imm);
51 inst = (
sljit_u8*)ensure_buf(compiler, 1 + length);
57 sljit_unaligned_store_s32(inst, (
sljit_s32)imm);
114 if (immb != 0 && !(b & OFFS_REG_MASK)) {
116 if (immb <= 127 && immb >= -128)
120 }
else if (reg_lmap[b & REG_MASK] == 5) {
122 if ((b & OFFS_REG_MASK) && (immb & 0x3) == 0 && reg_lmap[OFFS_REG(b)] != 5)
123 b =
SLJIT_MEM | OFFS_REG(b) | TO_OFFS_REG(b & REG_MASK);
128 if (reg_map[b & REG_MASK] >= 8)
131 if (reg_lmap[b & REG_MASK] == 4 && !(b & OFFS_REG_MASK))
134 if (b & OFFS_REG_MASK) {
136 if (reg_map[OFFS_REG(b)] >= 8)
143 }
else if (freg_map[b] >= 8)
154 if (imma <= 127 && imma >= -128) {
168 inst_size +=
sizeof(short);
178 else if (freg_map[
a] >= 8)
185 inst = (
sljit_u8*)ensure_buf(compiler, 1 + inst_size);
201 buf_ptr = inst +
size;
211 *buf_ptr =
U8(reg_lmap[
a] << 3);
213 *buf_ptr =
U8(freg_lmap[
a] << 3);
228 }
else if (b & REG_MASK) {
229 reg_lmap_b = reg_lmap[b & REG_MASK];
231 if (!(b & OFFS_REG_MASK) || (b & OFFS_REG_MASK) == TO_OFFS_REG(
SLJIT_SP)) {
232 if (immb != 0 || reg_lmap_b == 5) {
233 if (immb <= 127 && immb >= -128)
239 if (!(b & OFFS_REG_MASK))
240 *buf_ptr++ |= reg_lmap_b;
243 buf_ptr[1] =
U8(reg_lmap_b | (reg_lmap[OFFS_REG(b)] << 3));
247 if (immb != 0 || reg_lmap_b == 5) {
248 if (immb <= 127 && immb >= -128)
249 *buf_ptr++ =
U8(immb);
251 sljit_unaligned_store_s32(buf_ptr, (
sljit_s32)immb);
260 buf_ptr[1] =
U8(reg_lmap_b | (reg_lmap[OFFS_REG(b)] << 3) | (immb << 6));
270 sljit_unaligned_store_s32(buf_ptr, (
sljit_s32)immb);
278 sljit_unaligned_store_s16(buf_ptr, (
sljit_s16)imma);
280 sljit_unaligned_store_s32(buf_ptr, (
sljit_s32)imma);
326 vex =
U8(vex | ((((op &
VEX_SSE2_OPV) ? freg_map[
v] : reg_map[
v]) ^ 0xf) << 3));
331 inst = emit_x86_instruction(compiler,
size,
a, 0, b, immb);
337 if (vex_m == 0 && inst[-1] & 0x3)
341 vex |=
U8(((inst[-1] >> 2) ^ 0x1) << 7);
349 vex_m |=
U8((inst[-1] ^ 0x7) << 5);
365 int short_addr = !(jump->flags &
SLJIT_REWRITABLE_JUMP) && (jump->flags & JUMP_ADDR) && (jump->u.target <= 0xffffffff);
372 code_ptr[0] =
U8(get_jump_code(
type ^ 0x1) - 0x10);
373 code_ptr[1] = short_addr ? (6 + 3) : (10 + 3);
382 if (!(jump->flags & JUMP_ADDR))
383 jump->flags |= PATCH_MD;
385 sljit_unaligned_store_s32(code_ptr, (
sljit_s32)jump->u.target);
387 sljit_unaligned_store_sw(code_ptr, (
sljit_sw)jump->u.target);
404 SLJIT_ASSERT(((jump->flags >> JUMP_SIZE_SHIFT) & 0x1f) <= 10);
405 if (jump->flags & JUMP_ADDR)
406 addr = jump->u.target;
408 addr = (
sljit_uw)SLJIT_ADD_EXEC_OFFSET(code, executable_offset) + jump->u.label->size;
410 if (
addr > 0xffffffffl) {
414 SLJIT_ASSERT(((jump->flags >> JUMP_SIZE_SHIFT) & 0x1f) >= 7);
415 code_ptr -= SSIZE_OF(s32) - 1;
420 code_ptr[-3 - SSIZE_OF(s32)] =
U8(
REX_W | ((code_ptr[-3 - SSIZE_OF(s32)] & 0x1) << 2));
421 code_ptr[-1 - SSIZE_OF(s32)] =
U8(((code_ptr[-2 - SSIZE_OF(s32)] & 0x7) << 3) | 0x5);
422 code_ptr[-2 - SSIZE_OF(s32)] =
LEA_r_m;
424 jump->flags |= PATCH_MW;
428 jump->flags |= PATCH_MD;
437 if ((code_ptr[0] & 0x07) != 0) {
438 SLJIT_ASSERT(((jump->flags >> JUMP_SIZE_SHIFT) & 0x1f) >= 6);
439 code_ptr[0] =
U8(code_ptr[0] & ~0x08);
442 SLJIT_ASSERT(((jump->flags >> JUMP_SIZE_SHIFT) & 0x1f) >= 5);
443 code_ptr[0] = code_ptr[1];
472 CHECK(check_sljit_emit_enter(compiler,
options, arg_types, scratches, saveds, fscratches, fsaveds, local_size));
473 set_emit_enter(compiler,
options, arg_types, scratches, saveds, fscratches, fsaveds, local_size);
479 FAIL_IF(emit_endbranch(compiler));
481 compiler->mode32 = 0;
484 saved_regs_size = GET_SAVED_REGISTERS_SIZE(scratches, saveds - saved_arg_count, 1);
487 for (i =
SLJIT_S0 - saved_arg_count; i > tmp; i--) {
488 size = reg_map[i] >= 8 ? 2 : 1;
498 size = reg_map[i] >= 8 ? 2 : 1;
509 saved_float_regs_size = GET_SAVED_FLOAT_REGISTERS_SIZE(fscratches, fsaveds, sse2_reg);
511 if (saved_float_regs_size > 0) {
512 saved_float_regs_offset = ((local_size + 0xf) & ~0xf);
513 local_size = saved_float_regs_offset + saved_float_regs_size;
521 while (arg_types > 0) {
525 switch (word_arg_count) {
540 switch (word_arg_count + float_arg_count) {
556 if (tmp !=
SLJIT_R0 + word_arg_count)
567 if (float_arg_count != float_arg_count + word_arg_count)
569 float_arg_count, float_arg_count + word_arg_count, 0));
575 local_size = ((local_size + saved_regs_size + 0xf) & ~0xf) - saved_regs_size;
579 if (local_size > 0) {
580 if (local_size <= 4 * 4096) {
581 if (local_size > 4096)
583 if (local_size > 2 * 4096)
585 if (local_size > 3 * 4096)
595 inst = (
sljit_u8*)ensure_buf(compiler, 1 + 2);
613 if (saved_float_regs_size > 0) {
614 compiler->mode32 = 1;
619 saved_float_regs_offset += 16;
624 saved_float_regs_offset += 16;
642 CHECK(check_sljit_set_context(compiler,
options, arg_types, scratches, saveds, fscratches, fsaveds, local_size));
643 set_set_context(compiler,
options, arg_types, scratches, saveds, fscratches, fsaveds, local_size);
647 saved_float_regs_size = GET_SAVED_FLOAT_REGISTERS_SIZE(fscratches, fsaveds, sse2_reg);
649 if (saved_float_regs_size > 0)
650 local_size = ((local_size + 0xf) & ~0xf) + saved_float_regs_size;
656 saved_regs_size = GET_SAVED_REGISTERS_SIZE(scratches, saveds - SLJIT_KEPT_SAVEDS_COUNT(
options), 1);
657 compiler->
local_size = ((local_size + saved_regs_size + 0xf) & ~0xf) - saved_regs_size;
673 saved_float_regs_offset = GET_SAVED_FLOAT_REGISTERS_SIZE(fscratches, fsaveds, sse2_reg);
675 if (saved_float_regs_offset > 0) {
676 compiler->mode32 = 1;
677 saved_float_regs_offset = (compiler->
local_size - saved_float_regs_offset) & ~0xf;
682 saved_float_regs_offset += 16;
687 saved_float_regs_offset += 16;
690 compiler->mode32 = 0;
697 local_size += SSIZE_OF(sw);
706 size = reg_map[i] >= 8 ? 2 : 1;
717 size = reg_map[i] >= 8 ? 2 : 1;
735 CHECK(check_sljit_emit_return_void(compiler));
737 compiler->mode32 = 0;
739 FAIL_IF(emit_stack_frame_release(compiler, 0));
740 return emit_byte(compiler,
RET_near);
747 CHECK(check_sljit_emit_return_to(compiler, src, srcw));
749 compiler->mode32 = 0;
752 ADJUST_LOCAL_OFFSET(src, srcw);
759 FAIL_IF(emit_stack_frame_release(compiler, 1));
761 SLJIT_SKIP_CHECKS(compiler);
773 sljit_s32 src = src_ptr ? (*src_ptr) : 0;
788 if (word_arg_count == 0)
791 if (word_arg_count >= 3) {
804 sljit_s32 src = src_ptr ? (*src_ptr) : 0;
820 switch (arg_types & SLJIT_ARG_MASK) {
826 if (arg_count != float_arg_count)
833 if (arg_count != word_arg_count || arg_count != word_arg_regs[arg_count]) {
836 if (src == word_arg_regs[arg_count]) {
851 switch (
types & SLJIT_ARG_MASK) {
853 if (arg_count != float_arg_count)
854 FAIL_IF(emit_sse2_load(compiler, 0, arg_count, float_arg_count, 0));
859 if (arg_count != float_arg_count)
860 FAIL_IF(emit_sse2_load(compiler, 1, arg_count, float_arg_count, 0));
865 if (arg_count != word_arg_count || arg_count != word_arg_regs[arg_count])
866 EMIT_MOV(compiler, word_arg_regs[arg_count], 0, word_arg_count, 0);
884 CHECK_PTR(check_sljit_emit_call(compiler,
type, arg_types));
886 compiler->mode32 = 0;
892 PTR_FAIL_IF(emit_stack_frame_release(compiler, 0));
896 SLJIT_SKIP_CHECKS(compiler);
905 CHECK(check_sljit_emit_icall(compiler,
type, arg_types, src, srcw));
907 compiler->mode32 = 0;
910 ADJUST_LOCAL_OFFSET(src, srcw);
921 FAIL_IF(emit_stack_frame_release(compiler, 0));
925 FAIL_IF(call_with_args(compiler, arg_types, &src));
930 SLJIT_SKIP_CHECKS(compiler);
938 if (FAST_IS_REG(dst)) {
939 if (reg_map[dst] < 8)
940 return emit_byte(compiler,
U8(
POP_r + reg_lmap[dst]));
942 inst = (
sljit_u8*)ensure_buf(compiler, 1 + 2);
951 compiler->mode32 = 1;
952 inst = emit_x86_instruction(compiler, 1, 0, 0, dst, dstw);
962 if (FAST_IS_REG(src)) {
963 if (reg_map[src] < 8) {
964 inst = (
sljit_u8*)ensure_buf(compiler, 1 + 1 + 1);
971 inst = (
sljit_u8*)ensure_buf(compiler, 1 + 2 + 1);
981 compiler->mode32 = 1;
982 inst = emit_x86_instruction(compiler, 1, 0, 0, src, srcw);
987 inst = (
sljit_u8*)ensure_buf(compiler, 1 + 1);
1001 compiler->mode32 = 0;
1002 saved_regs_size = GET_SAVED_REGISTERS_SIZE(compiler->
scratches, compiler->
saveds - SLJIT_KEPT_SAVEDS_COUNT(compiler->
options), 0);
1016 CHECK(check_sljit_emit_select(compiler,
type, dst_reg, src1, src1w, src2_reg));
1018 ADJUST_LOCAL_OFFSET(src1, src1w);
1023 if (dst_reg != src2_reg) {
1024 if (dst_reg == src1) {
1028 }
else if (ADDRESSING_DEPENDS_ON(src1, dst_reg)) {
1029 EMIT_MOV(compiler, dst_reg, 0, src1, src1w);
1034 EMIT_MOV(compiler, dst_reg, 0, src2_reg, 0);
1044 return emit_groupf(compiler,
U8(get_jump_code((
sljit_uw)
type) - 0x40), dst_reg, src1, src1w);
1047 return emit_cmov_generic(compiler,
type, dst_reg, src1, src1w);
1059 CHECK(check_sljit_emit_mem(compiler,
type, reg, mem, memw));
1061 if (!(reg & REG_PAIR_MASK))
1062 return sljit_emit_mem_unaligned(compiler,
type, reg, mem, memw);
1064 ADJUST_LOCAL_OFFSET(mem, memw);
1066 compiler->mode32 = 0;
1068 if ((mem & REG_MASK) == 0) {
1080 regs[0] =
U8(REG_PAIR_FIRST(reg));
1081 regs[1] =
U8(REG_PAIR_SECOND(reg));
1083 next = SSIZE_OF(sw);
1085 if (!(
type &
SLJIT_MEM_STORE) && (regs[0] == (mem & REG_MASK) || regs[0] == OFFS_REG(mem))) {
1086 if (regs[1] == (mem & REG_MASK) || regs[1] == OFFS_REG(mem)) {
1090 if (regs[1] == OFFS_REG(mem))
1091 next = -SSIZE_OF(sw);
1093 mem = (mem & ~OFFS_REG_MASK) | TO_OFFS_REG(
TMP_REG1);
1095 next = -SSIZE_OF(sw);
1097 if (!(mem & OFFS_REG_MASK))
1098 memw += SSIZE_OF(sw);
1102 for (i = 0; i < 2; i++) {
1103 reg_idx =
next > 0 ? i : (i ^ 0x1);
1104 reg = regs[reg_idx];
1106 if ((mem & OFFS_REG_MASK) && (reg_idx == 1)) {
1112 inst[0] =
U8(
REX_W | ((reg_map[reg] >= 8) ?
REX_R : 0) | ((reg_map[mem & REG_MASK] >= 8) ?
REX_B : 0) | ((reg_map[OFFS_REG(mem)] >= 8) ?
REX_X : 0));
1114 inst[2] = 0x44 |
U8(reg_lmap[reg] << 3);
1115 inst[3] =
U8(memw << 6) |
U8(reg_lmap[OFFS_REG(mem)] << 3) | reg_lmap[mem & REG_MASK];
1118 EMIT_MOV(compiler, mem, memw, reg, 0);
1120 EMIT_MOV(compiler, reg, 0, mem, memw);
1123 if (!(mem & OFFS_REG_MASK))
1137 compiler->mode32 = 0;
1140 if (FAST_IS_REG(dst)) {
1142 return emit_do_imm32(compiler, reg_map[dst] <= 7 ? 0 :
REX_B,
U8(
MOV_r_i32 | reg_lmap[dst]), srcw);
1149 compiler->mode32 = 1;
1153 compiler->mode32 = 0;
1157 dst_r = FAST_IS_REG(dst) ? dst :
TMP_REG1;
1159 if ((dst &
SLJIT_MEM) && FAST_IS_REG(src))
1163 inst = emit_x86_instruction(compiler, 1, dst_r, 0, src, srcw);
1167 compiler->mode32 = 1;
1168 EMIT_MOV(compiler, dst_r, 0, src, srcw);
1169 compiler->mode32 = 0;
1174 compiler->mode32 = 1;
1175 inst = emit_x86_instruction(compiler, 1, dst_r, 0, dst, dstw);
1178 compiler->mode32 = 0;
1189 sljit_u8 *inst, *jump_inst1, *jump_inst2;
1192 compiler->mode32 = 0;
1196 compiler->mode32 = 1;
1198 compiler->mode32 = 0;
1204 compiler->mode32 = 1;
1211 if (!FAST_IS_REG(src)) {
1218 inst = (
sljit_u8*)ensure_buf(compiler, 1 + 2);
1224 size1 = compiler->
size;
1226 compiler->mode32 = 0;
1229 inst = (
sljit_u8*)ensure_buf(compiler, 1 + 2);
1235 size2 = compiler->
size;
1237 jump_inst1[1] =
U8(size2 - size1);
1248 compiler->mode32 = 1;
1251 compiler->mode32 = 0;
1257 compiler->mode32 = 1;
1260 jump_inst2[1] =
U8(compiler->
size - size2);
1274 rex = freg_map[freg] >= 8 ? (
REX_R |
REX_B) : 0;
1276 if (freg_map[freg] >= 8)
1282 size = (rex != 0) ? 5 : 4;
1295 inst[2] =
U8(freg_lmap[freg] | (freg_lmap[freg] << 3) |
MOD_REG);
1313 CHECK(check_sljit_emit_fset32(compiler, freg,
value));
1318 compiler->mode32 = 1;
1322 return sljit_emit_fset(compiler, freg, 0,
u.imm == 0);
1334 CHECK(check_sljit_emit_fset64(compiler, freg,
value));
1339 compiler->mode32 = 0;
1343 return sljit_emit_fset(compiler, freg,
REX_W,
u.imm == 0);
1354 CHECK(check_sljit_emit_fcopy(compiler, op, freg, reg));
1359 if (freg_map[freg] >= 8)
1362 if (reg_map[reg] >= 8)
1365 size = (rex != 0) ? 5 : 4;
1376 inst[2] =
U8(reg_lmap[reg] | (freg_lmap[freg] << 3) |
MOD_REG);
1386 if (!cpu_has_shadow_stack())
sizeof(Countable|array $value, int $mode=COUNT_NORMAL)
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 SLJIT_UNUSED_ARG(arg)
#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
#define SLJIT_FIRST_SAVED_REG
SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_has_cpu_feature(sljit_s32 feature_type)
#define SLJIT_CONV_F64_FROM_U32
#define SLJIT_MEM2(r1, r2)
#define SLJIT_ARG_TYPE_F32
#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
#define SLJIT_REWRITABLE_JUMP
#define SLJIT_ENTER_REG_ARG
#define SLJIT_FIRST_SAVED_FLOAT_REG
#define SLJIT_COPY_TO_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 EX86_SELECT_F2_F3(op)
#define BINARY_IMM32(op_imm, immw, arg, argw)