|| }
| .if X64
|| } else if (!IS_32BIT(zv)) {
-| mov64 tmp_reg, ((uintptr_t)zv)
-| SSE_AVX_INS movsd, vmovsd, xmm(dst_reg-ZREG_XMM0), qword [tmp_reg]
+| mov64 Ra(tmp_reg), ((uintptr_t)zv)
+| SSE_AVX_INS movsd, vmovsd, xmm(dst_reg-ZREG_XMM0), qword [Ra(tmp_reg)]
| .endif
|| } else {
| SSE_AVX_INS movsd, vmovsd, xmm(dst_reg-ZREG_XMM0), qword [((uint32_t)(uintptr_t)zv)]
|| if (Z_MODE(dst_addr) == IS_REG) {
| mov64 Ra(Z_REG(dst_addr)), ((uintptr_t)Z_LVAL_P(zv))
|| } else {
-| mov64 tmp_reg, ((uintptr_t)Z_LVAL_P(zv))
-| SET_ZVAL_LVAL dst_addr, tmp_reg
+| mov64 Ra(tmp_reg), ((uintptr_t)Z_LVAL_P(zv))
+| SET_ZVAL_LVAL dst_addr, Ra(tmp_reg)
|| }
|| } else {
| SET_ZVAL_LVAL dst_addr, Z_LVAL_P(zv)
|| }
| .if X64
|| } else if (!IS_32BIT(zv)) {
-| mov64 tmp_reg, ((uintptr_t)zv)
-| SSE_AVX_INS movsd, vmovsd, xmm(dst_reg-ZREG_XMM0), qword [tmp_reg]
+| mov64 Ra(tmp_reg), ((uintptr_t)zv)
+| SSE_AVX_INS movsd, vmovsd, xmm(dst_reg-ZREG_XMM0), qword [Ra(tmp_reg)]
| .endif
|| } else {
| SSE_AVX_INS movsd, vmovsd, xmm(dst_reg-ZREG_XMM0), qword [((uint32_t)(uintptr_t)zv)]
| mov64 Ra(Z_REG(res_addr)), ((uintptr_t)Z_LVAL_P(zv))
| SET_ZVAL_LVAL dst_addr, Ra(Z_REG(res_addr))
|| } else {
-| mov64 tmp_reg, ((uintptr_t)Z_LVAL_P(zv))
-| SET_ZVAL_LVAL dst_addr, tmp_reg
-| SET_ZVAL_LVAL res_addr, tmp_reg
+| mov64 Ra(tmp_reg), ((uintptr_t)Z_LVAL_P(zv))
+| SET_ZVAL_LVAL dst_addr, Ra(tmp_reg)
+| SET_ZVAL_LVAL res_addr, Ra(tmp_reg)
|| }
|| } else if (Z_MODE(dst_addr) == IS_REG) {
| SET_ZVAL_LVAL dst_addr, Z_LVAL_P(zv)
int save_r1)
/* Labels: 1,2,3 */
{
- ZEND_ASSERT(Z_MODE(var_addr) == IS_REG || Z_REG(var_addr) != ZREG_R0);
+ zend_reg tmp_reg;
+
+ if (Z_MODE(var_addr) == IS_REG || Z_REG(var_addr) != ZREG_R0) {
+ tmp_reg = ZREG_R0;
+ } else {
+ /* ASSIGN_DIM */
+ tmp_reg = ZREG_FCARG1a;
+ }
+
if (Z_MODE(val_addr) == IS_CONST_ZVAL) {
zval *zv = Z_ZV(val_addr);
if (!res_addr) {
- | ZVAL_COPY_CONST var_addr, var_info, var_def_info, zv, r0
+ | ZVAL_COPY_CONST var_addr, var_info, var_def_info, zv, tmp_reg
} else {
- | ZVAL_COPY_CONST_2 var_addr, res_addr, var_info, var_def_info, zv, r0
+ | ZVAL_COPY_CONST_2 var_addr, res_addr, var_info, var_def_info, zv, tmp_reg
}
if (Z_REFCOUNTED_P(zv)) {
if (!res_addr) {
- | ADDREF_CONST zv, r0
+ | ADDREF_CONST zv, Ra(tmp_reg)
} else {
- | ADDREF_CONST_2 zv, r0
+ | ADDREF_CONST_2 zv, Ra(tmp_reg)
}
}
} else {
if (res_addr) {
| SET_ZVAL_TYPE_INFO res_addr, IS_NULL
}
- | SAVE_VALID_OPLINE opline, r0
+ | SAVE_VALID_OPLINE opline, Ra(tmp_reg)
| mov FCARG1d, val.var
| EXT_CALL zend_jit_undefined_op_helper, r0
if (save_r1) {
| // ZVAL_COPY_VALUE(return_value, &ref->value);
ref_addr = ZEND_ADDR_MEM_ZVAL(ZREG_R2, 8);
if (!res_addr) {
- | ZVAL_COPY_VALUE var_addr, var_info, ref_addr, val_info, ZREG_R2, ZREG_R0
+ | ZVAL_COPY_VALUE var_addr, var_info, ref_addr, val_info, ZREG_R2, tmp_reg
} else {
- | ZVAL_COPY_VALUE_2 var_addr, var_info, res_addr, ref_addr, val_info, ZREG_R2, ZREG_R0
+ | ZVAL_COPY_VALUE_2 var_addr, var_info, res_addr, ref_addr, val_info, ZREG_R2, tmp_reg
}
| je >2
| IF_NOT_REFCOUNTED dh, >3
if (!res_addr) {
- | GC_ADDREF r0
+ | GC_ADDREF Ra(tmp_reg)
} else {
- | add dword [r0], 2
+ | add dword [Ra(tmp_reg)], 2
}
| jmp >3
|2:
if (res_addr) {
| IF_NOT_REFCOUNTED dh, >2
- | GC_ADDREF r0
+ | GC_ADDREF Ra(tmp_reg)
|2:
}
if (save_r1) {
}
if (!res_addr) {
- | ZVAL_COPY_VALUE var_addr, var_info, val_addr, val_info, ZREG_R2, ZREG_R0
+ | ZVAL_COPY_VALUE var_addr, var_info, val_addr, val_info, ZREG_R2, tmp_reg
} else {
- | ZVAL_COPY_VALUE_2 var_addr, var_info, res_addr, val_addr, val_info, ZREG_R2, ZREG_R0
+ | ZVAL_COPY_VALUE_2 var_addr, var_info, res_addr, val_addr, val_info, ZREG_R2, tmp_reg
}
if (val_type == IS_CV) {
if (!res_addr) {
- | TRY_ADDREF val_info, dh, r0
+ | TRY_ADDREF val_info, dh, Ra(tmp_reg)
} else {
- | TRY_ADDREF_2 val_info, dh, r0
+ | TRY_ADDREF_2 val_info, dh, Ra(tmp_reg)
}
} else {
if (res_addr) {
- | TRY_ADDREF val_info, dh, r0
+ | TRY_ADDREF val_info, dh, Ra(tmp_reg)
}
}
|3:
/* Labels: 1,2,3,4,5,8 */
{
int done = 0;
+ zend_reg ref_reg, tmp_reg;
+
+ if (Z_MODE(var_addr) == IS_REG || Z_REG(var_use_addr) != ZREG_R0) {
+ ref_reg = ZREG_FCARG1a;
+ tmp_reg = ZREG_R0;
+ } else {
+ /* ASSIGN_DIM */
+ ref_reg = ZREG_R0;
+ tmp_reg = ZREG_FCARG1a;
+ }
if (var_info & MAY_BE_REF) {
- if (Z_MODE(var_use_addr) != IS_MEM_ZVAL || Z_REG(var_use_addr) != ZREG_FCARG1a || Z_OFFSET(var_use_addr) != 0) {
- | LOAD_ZVAL_ADDR FCARG1a, var_use_addr
- var_addr = var_use_addr = ZEND_ADDR_MEM_ZVAL(ZREG_FCARG1a, 0);
+ if (Z_MODE(var_use_addr) != IS_MEM_ZVAL || Z_REG(var_use_addr) != ref_reg || Z_OFFSET(var_use_addr) != 0) {
+ | LOAD_ZVAL_ADDR Ra(ref_reg), var_use_addr
+ var_addr = var_use_addr = ZEND_ADDR_MEM_ZVAL(ref_reg, 0);
}
| // if (Z_ISREF_P(variable_ptr)) {
- | IF_NOT_Z_TYPE, FCARG1a, IS_REFERENCE, >1
+ | IF_NOT_Z_TYPE, Ra(ref_reg), IS_REFERENCE, >1
| // if (UNEXPECTED(ZEND_REF_HAS_TYPE_SOURCES(Z_REF_P(variable_ptr)))) {
- | GET_Z_PTR FCARG1a, FCARG1a
+ | GET_Z_PTR FCARG1a, Ra(ref_reg)
if (!zend_jit_assign_to_typed_ref(Dst, opline, val_type, val_addr, check_exception)) {
return 0;
}
- | add FCARG1a, offsetof(zend_reference, val)
+ | lea Ra(ref_reg), [FCARG1a + offsetof(zend_reference, val)]
|1:
}
if (var_info & (MAY_BE_STRING|MAY_BE_ARRAY|MAY_BE_OBJECT|MAY_BE_RESOURCE)) {
- ZEND_ASSERT(Z_REG(var_use_addr) != ZREG_R0);
if (RC_MAY_BE_1(var_info)) {
int in_cold = 0;
|1:
in_cold = 1;
}
- if (Z_REG(var_use_addr) == ZREG_FCARG1a) {
- | GET_ZVAL_PTR r0, var_use_addr
- | mov aword T1, r0 // save
+ if (Z_REG(var_use_addr) == ZREG_FCARG1a || Z_REG(var_use_addr) == ZREG_R0) {
+ zend_bool keep_gc = 0;
+
+ | GET_ZVAL_PTR Ra(tmp_reg), var_use_addr
+ if (tmp_reg == ZREG_FCARG1a) {
+ if (Z_MODE(val_addr) == IS_REG) {
+ keep_gc = 1;
+ } else if ((val_info & ((MAY_BE_UNDEF|MAY_BE_ANY|MAY_BE_GUARD)-(MAY_BE_NULL|MAY_BE_FALSE|MAY_BE_TRUE))) == 0) {
+ keep_gc = 1;
+ } else if (Z_MODE(val_addr) == IS_CONST_ZVAL) {
+ if (sizeof(void*) == 4) {
+ keep_gc = 1;
+ } else {
+ zval *zv = Z_ZV(val_addr);
+
+ if (Z_TYPE_P(zv) == IS_DOUBLE) {
+ if (Z_DVAL_P(zv) == 0 || IS_32BIT(zv)) {
+ keep_gc = 1;
+ }
+ } else if (IS_SIGNED_32BIT(Z_LVAL_P(zv))) {
+ keep_gc = 1;
+ }
+ }
+ } else if (Z_MODE(val_addr) == IS_MEM_ZVAL) {
+ if ((val_info & (MAY_BE_UNDEF|MAY_BE_ANY|MAY_BE_GUARD)) == MAY_BE_DOUBLE) {
+ keep_gc = 1;
+ }
+ }
+ }
+ if (!keep_gc) {
+ | mov aword T1, Ra(tmp_reg) // save
+ }
if (!zend_jit_simple_assign(Dst, opline, var_addr, var_info, var_def_info, val_type, val, val_addr, val_info, res_addr, in_cold, 0)) {
return 0;
}
- if (Z_REG(var_use_addr) == ZREG_FCARG1a) {
+ if (!keep_gc) {
| mov FCARG1a, aword T1 // restore
}
} else {
if (var_info & ((MAY_BE_ANY|MAY_BE_UNDEF)-(MAY_BE_OBJECT|MAY_BE_RESOURCE))) {
| IF_NOT_ZVAL_REFCOUNTED var_use_addr, >5
}
- | GET_ZVAL_PTR r0, var_use_addr
- | GC_DELREF r0
if (var_info & (MAY_BE_ARRAY|MAY_BE_OBJECT)) {
if (Z_REG(var_use_addr) == ZREG_FP) {
- | GET_ZVAL_PTR FCARG1a, var_use_addr
- | IF_GC_MAY_NOT_LEAK FCARG1a, >5
- } else if (Z_REG(var_use_addr) != ZREG_FCARG1a) {
- | GET_ZVAL_PTR FCARG1a, var_use_addr
- | IF_GC_MAY_NOT_LEAK FCARG1a, >5
- | mov T1, Ra(Z_REG(var_use_addr)) // save
- } else {
- | GET_ZVAL_PTR r0, var_use_addr
- | IF_GC_MAY_NOT_LEAK r0, >5
| mov T1, Ra(Z_REG(var_use_addr)) // save
- | GET_ZVAL_PTR FCARG1a, var_use_addr
}
+ | GET_ZVAL_PTR FCARG1a, var_use_addr
+ | GC_DELREF FCARG1a
+ | IF_GC_MAY_NOT_LEAK FCARG1a, >5
| EXT_CALL gc_possible_root, r0
if (Z_REG(var_use_addr) != ZREG_FP) {
| mov Ra(Z_REG(var_use_addr)), T1 // restore
}
+ } else {
+ | GET_ZVAL_PTR Ra(tmp_reg), var_use_addr
+ | GC_DELREF Ra(tmp_reg)
}
|5:
}
|6:
if (opline->op2_type == IS_UNUSED) {
uint32_t var_info = MAY_BE_NULL;
- zend_jit_addr var_addr = ZEND_ADDR_MEM_ZVAL(ZREG_FCARG1a, 0);
+ zend_jit_addr var_addr = ZEND_ADDR_MEM_ZVAL(ZREG_R0, 0);
| // var_ptr = zend_hash_next_index_insert(Z_ARRVAL_P(container), &EG(uninitialized_zval));
| LOAD_ADDR_ZTS FCARG2a, executor_globals, uninitialized_zval
| //ZEND_VM_C_GOTO(assign_dim_op_ret_null);
| jmp >9
|.code
- | mov FCARG1a, r0
if (!zend_jit_simple_assign(Dst, opline, var_addr, var_info, -1, (opline+1)->op1_type, (opline+1)->op1, op3_addr, val_info, res_addr, 0, 0)) {
return 0;
}
} else {
uint32_t var_info = zend_array_element_type(op1_info, opline->op1_type, 0, 0);
- zend_jit_addr var_addr = ZEND_ADDR_MEM_ZVAL(ZREG_FCARG1a, 0);
+ zend_jit_addr var_addr = ZEND_ADDR_MEM_ZVAL(ZREG_R0, 0);
if (!zend_jit_fetch_dimension_address_inner(Dst, opline, BP_VAR_W, op1_info, op2_info, NULL, NULL, NULL)) {
return 0;
}
- |8:
- | mov FCARG1a, r0
-
if (op1_info & (MAY_BE_ARRAY_OF_REF|MAY_BE_OBJECT)) {
var_info |= MAY_BE_REF;
}
if (var_info & (MAY_BE_STRING|MAY_BE_ARRAY|MAY_BE_OBJECT|MAY_BE_RESOURCE)) {
var_info |= MAY_BE_RC1;
}
+
+ |8:
| // value = zend_assign_to_variable(variable_ptr, value, OP_DATA_TYPE);
if (!zend_jit_assign_to_variable(Dst, opline, var_addr, var_addr, var_info, -1, (opline+1)->op1_type, (opline+1)->op1, op3_addr, val_info, res_addr, 0)) {
return 0;
if (opline->op1_type == IS_CONST) {
zval *zv = RT_CONSTANT(opline, opline->op1);
- | ZVAL_COPY_CONST arg_addr, MAY_BE_ANY, MAY_BE_ANY, zv, r0
+ | ZVAL_COPY_CONST arg_addr, MAY_BE_ANY, MAY_BE_ANY, zv, ZREG_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, MAY_BE_ANY, MAY_BE_ANY, zv, r0
+ | ZVAL_COPY_CONST ret_addr, MAY_BE_ANY, MAY_BE_ANY, zv, ZREG_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, -1, zv, r0
+ | ZVAL_COPY_CONST res_addr, -1, -1, zv, ZREG_R0
if (Z_REFCOUNTED_P(zv)) {
| ADDREF_CONST zv, r0
}