|| }
|.endmacro
-|.macro SSE_GET_ZVAL_LVAL, reg, addr
-|| if (Z_MODE(addr) == IS_CONST_ZVAL) {
-|| if (Z_LVAL_P(Z_ZV(addr)) == 0) {
+|.macro SSE_GET_LONG, reg, lval
+|| if (lval == 0) {
|| if (zend_jit_x86_flags & ZEND_JIT_CPU_AVX) {
| vxorps xmm(reg-ZREG_XMM0), xmm(reg-ZREG_XMM0), xmm(reg-ZREG_XMM0)
|| } else {
|| }
|| } else {
|.if X64
-|| if (!IS_SIGNED_32BIT(Z_LVAL_P(Z_ZV(addr)))) {
-| mov64 r0, Z_LVAL_P(Z_ZV(addr))
+|| if (!IS_SIGNED_32BIT(lval)) {
+| mov64 r0, lval
|| } else {
-| mov r0, Z_LVAL_P(Z_ZV(addr))
+| mov r0, lval
|| }
|.else
-| mov r0, Z_LVAL_P(Z_ZV(addr))
+| mov r0, lval
|.endif
|| if (zend_jit_x86_flags & ZEND_JIT_CPU_AVX) {
| vcvtsi2sd, xmm(reg-ZREG_XMM0), xmm(reg-ZREG_XMM0), r0
| cvtsi2sd, xmm(reg-ZREG_XMM0), r0
|| }
|| }
+|.endmacro
+
+|.macro SSE_GET_ZVAL_LVAL, reg, addr
+|| if (Z_MODE(addr) == IS_CONST_ZVAL) {
+| SSE_GET_LONG reg, Z_LVAL_P(Z_ZV(addr))
|| } else if (Z_MODE(addr) == IS_MEM_ZVAL) {
|| if (zend_jit_x86_flags & ZEND_JIT_CPU_AVX) {
| vcvtsi2sd xmm(reg-ZREG_XMM0), xmm(reg-ZREG_XMM0), aword [Ra(Z_REG(addr))+Z_OFFSET(addr)]
|| }
|.endmacro
-|.macro ZVAL_COPY_CONST, dst_addr, dst_info, zv, tmp_reg
+|.macro ZVAL_COPY_CONST, dst_addr, dst_info, dst_def_info, zv, tmp_reg
|| if (Z_TYPE_P(zv) > IS_TRUE) {
|| if (Z_TYPE_P(zv) == IS_DOUBLE) {
|| zend_reg dst_reg = (Z_MODE(dst_addr) == IS_REG) ? Z_REG(dst_addr) : ZREG_XMM0;
| SSE_AVX_INS movsd, vmovsd, xmm(dst_reg-ZREG_XMM0), qword [((uint32_t)(uintptr_t)zv)]
|| }
| SSE_SET_ZVAL_DVAL dst_addr, dst_reg
+|| } else if (Z_TYPE_P(zv) == IS_LONG && dst_def_info == MAY_BE_DOUBLE) {
+|| zend_reg dst_reg = (Z_MODE(dst_addr) == IS_REG) ? Z_REG(dst_addr) : ZREG_XMM0;
+| SSE_GET_LONG dst_reg, Z_LVAL_P(zv)
+| SSE_SET_ZVAL_DVAL dst_addr, dst_reg
|| } else if (Z_LVAL_P(zv) == 0 && Z_MODE(dst_addr) == IS_REG) {
| xor Ra(Z_REG(dst_addr)), Ra(Z_REG(dst_addr))
|| } else {
|| }
|| }
|| if (Z_MODE(dst_addr) == IS_MEM_ZVAL) {
-|| if (((dst_info & (MAY_BE_ANY|MAY_BE_UNDEF)) != (1<<Z_TYPE_P(zv))) || (dst_info & (MAY_BE_STRING|MAY_BE_ARRAY)) != 0) {
+|| if (dst_def_info == MAY_BE_DOUBLE) {
+|| if ((dst_info & (MAY_BE_ANY|MAY_BE_UNDEF)) != MAY_BE_DOUBLE) {
+| SET_ZVAL_TYPE_INFO dst_addr, IS_DOUBLE
+|| }
+|| } else if (((dst_info & (MAY_BE_ANY|MAY_BE_UNDEF)) != (1<<Z_TYPE_P(zv))) || (dst_info & (MAY_BE_STRING|MAY_BE_ARRAY)) != 0) {
| SET_ZVAL_TYPE_INFO dst_addr, Z_TYPE_INFO_P(zv)
|| }
|| }
|.endmacro
-|.macro ZVAL_COPY_CONST_2, dst_addr, res_addr, dst_info, zv, tmp_reg
+|.macro ZVAL_COPY_CONST_2, dst_addr, res_addr, dst_info, dst_def_info, zv, tmp_reg
|| if (Z_TYPE_P(zv) > IS_TRUE) {
|| if (Z_TYPE_P(zv) == IS_DOUBLE) {
|| zend_reg dst_reg = (Z_MODE(dst_addr) == IS_REG) ?
|| }
| SSE_SET_ZVAL_DVAL dst_addr, ZREG_XMM0
| SSE_SET_ZVAL_DVAL res_addr, ZREG_XMM0
+|| } else if (Z_TYPE_P(zv) == IS_LONG && dst_def_info == MAY_BE_DOUBLE) {
+|| if (Z_MODE(dst_addr) == IS_REG) {
+| SSE_GET_LONG Z_REG(dst_addr), Z_LVAL_P(zv)
+| SSE_SET_ZVAL_DVAL res_addr, Z_REG(dst_addr)
+|| } else if (Z_MODE(res_addr) == IS_REG) {
+| SSE_GET_LONG Z_REG(res_addr), Z_LVAL_P(zv)
+| SSE_SET_ZVAL_DVAL dst_addr, Z_REG(res_addr)
+|| } else {
+| SSE_GET_LONG ZREG_XMM0, Z_LVAL_P(zv)
+| SSE_SET_ZVAL_DVAL dst_addr, ZREG_XMM0
+| SSE_SET_ZVAL_DVAL res_addr, ZREG_XMM0
+|| }
|| } else if (Z_LVAL_P(zv) == 0 && (Z_MODE(dst_addr) == IS_REG || Z_MODE(res_addr) == IS_REG)) {
|| if (Z_MODE(dst_addr) == IS_REG) {
| xor Ra(Z_REG(dst_addr)), Ra(Z_REG(dst_addr))
|| }
|| }
|| if (Z_MODE(dst_addr) == IS_MEM_ZVAL) {
-|| if (((dst_info & (MAY_BE_ANY|MAY_BE_UNDEF)) != (1<<Z_TYPE_P(zv))) || (dst_info & (MAY_BE_STRING|MAY_BE_ARRAY)) != 0) {
+|| if (dst_def_info == MAY_BE_DOUBLE) {
+|| if ((dst_info & (MAY_BE_ANY|MAY_BE_UNDEF)) != MAY_BE_DOUBLE) {
+| SET_ZVAL_TYPE_INFO dst_addr, IS_DOUBLE
+|| }
+|| } else if (((dst_info & (MAY_BE_ANY|MAY_BE_UNDEF)) != (1<<Z_TYPE_P(zv))) || (dst_info & (MAY_BE_STRING|MAY_BE_ARRAY)) != 0) {
| SET_ZVAL_TYPE_INFO dst_addr, Z_TYPE_INFO_P(zv)
|| }
|| }
|| if (Z_MODE(res_addr) == IS_MEM_ZVAL) {
-| SET_ZVAL_TYPE_INFO res_addr, Z_TYPE_INFO_P(zv)
+|| if (dst_def_info == MAY_BE_DOUBLE) {
+| SET_ZVAL_TYPE_INFO res_addr, IS_DOUBLE
+|| } else {
+| SET_ZVAL_TYPE_INFO res_addr, Z_TYPE_INFO_P(zv)
+|| }
|| }
|.endmacro
zend_ssa *ssa,
zend_jit_addr var_addr,
uint32_t var_info,
+ uint32_t var_def_info,
zend_uchar val_type,
znode_op val,
zend_jit_addr val_addr,
zval *zv = Z_ZV(val_addr);
if (!res_addr) {
- | ZVAL_COPY_CONST var_addr, var_info, zv, r0
+ | ZVAL_COPY_CONST var_addr, var_info, var_def_info, zv, r0
} else {
- | ZVAL_COPY_CONST_2 var_addr, res_addr, var_info, zv, r0
+ | ZVAL_COPY_CONST_2 var_addr, res_addr, var_info, var_def_info, zv, r0
}
if (Z_REFCOUNTED_P(zv)) {
if (!res_addr) {
zend_ssa *ssa,
zend_jit_addr var_addr,
uint32_t var_info,
+ uint32_t var_def_info,
zend_uchar val_type,
znode_op val,
zend_jit_addr val_addr,
| jnz >4
}
| mov aword T1, r0 // save
- if (!zend_jit_simple_assign(Dst, opline, op_array, ssa, var_addr, var_info, val_type, val, val_addr, val_info, res_addr, in_cold)) {
+ if (!zend_jit_simple_assign(Dst, opline, op_array, ssa, var_addr, var_def_info, var_info, val_type, val, val_addr, val_info, res_addr, in_cold)) {
return 0;
}
| mov FCARG1a, aword T1 // restore
|5:
}
- if (!zend_jit_simple_assign(Dst, opline, op_array, ssa, var_addr, var_info, val_type, val, val_addr, val_info, res_addr, 0)) {
+ if (!zend_jit_simple_assign(Dst, opline, op_array, ssa, var_addr, var_info, var_def_info, val_type, val, val_addr, val_info, res_addr, 0)) {
return 0;
}
|8:
if (op1_info & (MAY_BE_ARRAY_OF_REF|MAY_BE_OBJECT)) {
var_info |= MAY_BE_REF;
}
- if (!zend_jit_simple_assign(Dst, opline, op_array, ssa, var_addr, var_info, (opline+1)->op1_type, (opline+1)->op1, op3_addr, val_info, res_addr, 0)) {
+ if (!zend_jit_simple_assign(Dst, opline, op_array, ssa, var_addr, var_info, -1, (opline+1)->op1_type, (opline+1)->op1, op3_addr, val_info, res_addr, 0)) {
return 0;
}
} else {
var_info |= MAY_BE_REF;
}
| // value = zend_assign_to_variable(variable_ptr, value, OP_DATA_TYPE);
- if (!zend_jit_assign_to_variable(Dst, opline, op_array, ssa, var_addr, var_info, (opline+1)->op1_type, (opline+1)->op1, op3_addr, val_info, res_addr)) {
+ if (!zend_jit_assign_to_variable(Dst, opline, op_array, ssa, var_addr, var_info, -1, (opline+1)->op1_type, (opline+1)->op1, op3_addr, val_info, res_addr)) {
return 0;
}
}
}
}
- if (!zend_jit_simple_assign(Dst, opline, op_array, ssa, res_addr, -1, opline->op1_type, opline->op1, op1_addr, op1_info, 0, 0)) {
+ if (!zend_jit_simple_assign(Dst, opline, op_array, ssa, res_addr, -1, -1, opline->op1_type, opline->op1, op1_addr, op1_info, 0, 0)) {
return 0;
}
if (ra && !zend_jit_store_ssa_var_if_necessary(Dst, ssa, ra, res_addr, ssa->ops[opline - op_array->opcodes].result_def, ssa->ops[opline - op_array->opcodes].result_use)) {
static int zend_jit_assign(dasm_State **Dst, const zend_op *opline, const zend_op_array *op_array, zend_ssa *ssa, zend_lifetime_interval **ra)
{
- uint32_t op1_info, op2_info;
+ uint32_t op1_info, op1_def_info, op2_info;
zend_jit_addr op1_addr, op2_addr, res_addr;
if (opline->op1_type != IS_CV) {
}
op1_info = OP1_INFO();
+ op1_def_info = OP1_DEF_INFO();
op2_info = OP2_INFO();
op1_addr = zend_jit_decode_op(op_array, opline->op1_type, opline->op1, opline, ra, ra ? ssa->ops[opline - op_array->opcodes].op1_def : -1);
}
}
- if (!zend_jit_assign_to_variable(Dst, opline, op_array, ssa, op1_addr, op1_info, opline->op2_type, opline->op2, op2_addr, op2_info, res_addr)) {
+ if (!zend_jit_assign_to_variable(Dst, opline, op_array, ssa, op1_addr, op1_info, op1_def_info, opline->op2_type, opline->op2, op2_addr, op2_info, res_addr)) {
return 0;
}
if (opline->op1_type == IS_CONST) {
zval *zv = RT_CONSTANT(opline, opline->op1);
- | ZVAL_COPY_CONST arg_addr, -1, zv, r0
+ | ZVAL_COPY_CONST arg_addr, -1, -1, zv, r0
if (Z_REFCOUNTED_P(zv)) {
| ADDREF_CONST zv, r0
}
if (opline->op1_type == IS_CONST) {
zval *zv = RT_CONSTANT(opline, opline->op1);
- | ZVAL_COPY_CONST ret_addr, -1, zv, r0
+ | ZVAL_COPY_CONST ret_addr, -1, -1, zv, r0
if (Z_REFCOUNTED_P(zv)) {
| ADDREF_CONST zv, r0
}
| cmp dword EX->This.u2.num_args, arg_num
| jae >5
- | ZVAL_COPY_CONST res_addr, -1, zv, r0
+ | ZVAL_COPY_CONST res_addr, -1, -1, zv, r0
if (Z_REFCOUNTED_P(zv)) {
| ADDREF_CONST zv, r0
}