Skip to content

Commit 426e74b

Browse files
committed
Support failed JIT test case: shift_left_001.phpt
This patch supports SL opcode. The range of the second operand is checked against 0 and 64. If the second operand is negative, exception would be raised. If the second operand is >= 64, the result is 0. Besides, new path in macro ZVAL_COPY_VLAUE is covered for RETURN opcode.
1 parent a2f7e13 commit 426e74b

File tree

1 file changed

+124
-6
lines changed

1 file changed

+124
-6
lines changed

ext/opcache/jit/zend_jit_arm64.dasc

+124-6
Original file line numberDiff line numberDiff line change
@@ -531,8 +531,11 @@ static void* dasm_labels[zend_lb_MAX];
531531
| brk #0 // TODO
532532
|.endmacro
533533

534-
|.macro UNDEF_OPLINE_RESULT
535-
| brk #0 // TODO
534+
|.macro UNDEF_OPLINE_RESULT, tmp_reg
535+
| ldr REG0, EX->opline
536+
| ldr REG0w, OP:REG0->result.var
537+
| add REG0, FP, REG0
538+
| SET_Z_TYPE_INFO REG0, IS_UNDEF, tmp_reg
536539
|.endmacro
537540

538541
// Define DOUBLE_CMP and DOUBLE_CMP to replace SSE_AVX_OP and SSE_OP in x86 implementation.
@@ -837,7 +840,6 @@ static void* dasm_labels[zend_lb_MAX];
837840
|| if (Z_MODE(dst_addr) == IS_MEM_ZVAL) {
838841
|| if ((dst_info & (MAY_BE_ANY|MAY_BE_UNDEF|MAY_BE_GUARD)) != (src_info & (MAY_BE_ANY|MAY_BE_UNDEF|MAY_BE_GUARD))) {
839842
|| zend_uchar type = concrete_type(src_info);
840-
| brk #0 // TODO: test
841843
| SET_ZVAL_TYPE_INFO dst_addr, type, Rw(tmp_reg1), Rx(tmp_reg2)
842844
|| }
843845
|| }
@@ -852,7 +854,6 @@ static void* dasm_labels[zend_lb_MAX];
852854
|| if ((src_info & (MAY_BE_ANY|MAY_BE_GUARD)) == MAY_BE_LONG) {
853855
|| if (Z_MODE(src_addr) == IS_REG) {
854856
|| if (Z_MODE(dst_addr) != IS_REG || Z_REG(dst_addr) != Z_REG(src_addr)) {
855-
| brk #0 // TODO: test
856857
| SET_ZVAL_LVAL_FROM_REG dst_addr, Rx(Z_REG(src_addr)), Rx(tmp_reg)
857858
|| }
858859
|| } else if (Z_MODE(dst_addr) == IS_REG) {
@@ -1552,7 +1553,11 @@ static int zend_jit_undefined_function_stub(dasm_State **Dst)
15521553
static int zend_jit_negative_shift_stub(dasm_State **Dst)
15531554
{
15541555
|->negative_shift:
1555-
| brk #0 // TODO
1556+
| UNDEF_OPLINE_RESULT TMP1w
1557+
| LOAD_ADDR CARG1, zend_ce_arithmetic_error
1558+
| LOAD_ADDR CARG2, "Bit shift by negative number"
1559+
| EXT_CALL zend_throw_error, REG0
1560+
| b ->exception_handler
15561561
return 1;
15571562
}
15581563

@@ -3264,7 +3269,120 @@ static int zend_jit_long_math_helper(dasm_State **Dst,
32643269
zend_reg result_reg;
32653270
zval tmp;
32663271

3267-
| brk #0 // TODO
3272+
if (op1_info & ((MAY_BE_ANY|MAY_BE_UNDEF)-MAY_BE_LONG)) {
3273+
| brk #0 // TODO
3274+
| IF_NOT_ZVAL_TYPE op1_addr, IS_LONG, >6, TMP1w, TMP2
3275+
}
3276+
if (!same_ops && (op2_info & ((MAY_BE_ANY|MAY_BE_UNDEF)-MAY_BE_LONG))) {
3277+
| brk #0 // TODO
3278+
| IF_NOT_ZVAL_TYPE op2_addr, IS_LONG, >6, TMP1w, TMP2
3279+
}
3280+
3281+
if (opcode == ZEND_MOD && Z_MODE(op2_addr) == IS_CONST_ZVAL &&
3282+
op1_range &&
3283+
op1_range->min >= 0) {
3284+
zend_long l = Z_LVAL_P(Z_ZV(op2_addr));
3285+
3286+
if (zend_long_is_power_of_two(l)) {
3287+
/* Optimisation for mod of power of 2 */
3288+
opcode = ZEND_BW_AND;
3289+
ZVAL_LONG(&tmp, l - 1);
3290+
op2_addr = ZEND_ADDR_CONST_ZVAL(&tmp);
3291+
}
3292+
}
3293+
3294+
if (opcode == ZEND_MOD) {
3295+
| brk #0 // TODO
3296+
} else if (Z_MODE(res_addr) == IS_REG) {
3297+
if ((opline->opcode == ZEND_SL || opline->opcode == ZEND_SR)
3298+
&& opline->op2_type != IS_CONST) {
3299+
result_reg = ZREG_REG0;
3300+
} else {
3301+
result_reg = Z_REG(res_addr);
3302+
}
3303+
} else if (Z_MODE(op1_addr) == IS_REG && Z_LAST_USE(op1_addr)) {
3304+
result_reg = Z_REG(op1_addr);
3305+
} else if (Z_REG(res_addr) != ZREG_REG0) {
3306+
result_reg = ZREG_REG0;
3307+
} else {
3308+
/* ASSIGN_DIM_OP */
3309+
result_reg = ZREG_FCARG1x;
3310+
}
3311+
3312+
if (opcode == ZEND_SL) {
3313+
if (Z_MODE(op2_addr) == IS_CONST_ZVAL) {
3314+
zend_long op2_lval = Z_LVAL_P(Z_ZV(op2_addr));
3315+
3316+
| brk #0 // TODO
3317+
} else {
3318+
if (Z_MODE(op2_addr) != IS_REG || Z_REG(op2_addr) != ZREG_REG1) {
3319+
| GET_ZVAL_LVAL ZREG_REG1, op2_addr, TMP1
3320+
}
3321+
if (!op2_range ||
3322+
op2_range->min < 0 ||
3323+
op2_range->max >= SIZEOF_ZEND_LONG * 8) {
3324+
3325+
| cmp REG1, #(SIZEOF_ZEND_LONG*8)
3326+
| bhs >1
3327+
|.cold_code
3328+
|1:
3329+
| mov Rx(result_reg), xzr
3330+
| cmp REG1, xzr
3331+
| bgt >1
3332+
| SET_EX_OPLINE opline, REG0
3333+
| b ->negative_shift
3334+
|.code
3335+
}
3336+
| GET_ZVAL_LVAL result_reg, op1_addr, TMP1
3337+
| lsl Rx(result_reg), Rx(result_reg), REG1
3338+
|1:
3339+
}
3340+
} else if (opcode == ZEND_SR) {
3341+
| brk #0 // TODO
3342+
} else if (opcode == ZEND_MOD) {
3343+
| brk #0 // TODO
3344+
} else if (same_ops) {
3345+
| brk #0 // TODO
3346+
} else {
3347+
| brk #0 // TODO
3348+
}
3349+
3350+
if (Z_MODE(res_addr) != IS_REG || Z_REG(res_addr) != result_reg) {
3351+
| SET_ZVAL_LVAL_FROM_REG res_addr, Rx(result_reg), TMP1
3352+
}
3353+
if (Z_MODE(res_addr) == IS_MEM_ZVAL) {
3354+
if (Z_MODE(op1_addr) != IS_MEM_ZVAL || Z_REG(op1_addr) != Z_REG(res_addr) || Z_OFFSET(op1_addr) != Z_OFFSET(res_addr)) {
3355+
if ((res_use_info & (MAY_BE_ANY|MAY_BE_UNDEF|MAY_BE_REF|MAY_BE_GUARD)) != MAY_BE_LONG) {
3356+
| brk #0 // TODO
3357+
| SET_ZVAL_TYPE_INFO res_addr, IS_LONG, TMP1w, TMP2
3358+
}
3359+
}
3360+
}
3361+
3362+
if ((op1_info & ((MAY_BE_ANY|MAY_BE_UNDEF)-MAY_BE_LONG)) ||
3363+
(op2_info & ((MAY_BE_ANY|MAY_BE_UNDEF)-MAY_BE_LONG))) {
3364+
if ((op1_info & MAY_BE_LONG) &&
3365+
(op2_info & MAY_BE_LONG)) {
3366+
|.cold_code
3367+
}
3368+
|6:
3369+
| brk #0 // TODO
3370+
if (may_throw) {
3371+
zend_jit_check_exception(Dst);
3372+
}
3373+
if (Z_MODE(res_addr) == IS_REG) {
3374+
zend_jit_addr real_addr = ZEND_ADDR_MEM_ZVAL(ZREG_FP, res_var);
3375+
if (!zend_jit_load_reg(Dst, real_addr, res_addr, res_info)) {
3376+
return 0;
3377+
}
3378+
}
3379+
if ((op1_info & MAY_BE_LONG) &&
3380+
(op2_info & MAY_BE_LONG)) {
3381+
| b >5
3382+
|.code
3383+
}
3384+
}
3385+
|5:
32683386

32693387
return 1;
32703388
}

0 commit comments

Comments
 (0)