Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit d77f3c3

Browse files
shqkingdstogov
authored andcommittedMay 12, 2021
Support failed JIT test case: shift_right_003.phpt
The following opcodes would be generated: ... BB1: 0003 JMP BB3 BB2: 0004 INIT_FCALL 1 96 string("chr") 0005 #10.T3 [long] = SR #3.CV0($int) [long] #7.CV2($i) ... 0006 #11.T4 [long] RANGE[0..127] = BW_AND #10.T3 [long] ... 0007 #12.T3 [long] RANGE[128..255] = BW_OR #11.T4 [long] ... 0008 SEND_VAL #12.T3 [long] RANGE[128..255] 1 0009 #13.V3 [ref, rc1, rcn, any] = DO_ICALL 0010 ASSIGN_OP (CONCAT) #6.CV1($out) [rc1, rcn, string] 0011 ADD #7.CV2($i)... int(7) #7.CV2($i) ... -> #15.CV2($i) ... BB3: 0012 #8.T4 [long] = SR #3.CV0($int) #7.CV2($i) [long, double] 0013 #9.T3 [bool] RANGE[0..1] = IS_SMALLER int(128) #8.T4 0014 JMPNZ #9.T3 [bool] RANGE[0..1] BB2 ... Main changes are: 1. SR opcode covers new path in function zend_jit_long_math_helper(). 2. BW_AND and BW_OR opcodes are supported. See macro LONG_OP. 3. Function zend_jit_concat_helper() is added to support ASSIGN_OP opcode. Speficically, CONCAT and FAST_CONCAT is supported for statements "$out .= ...". 4. New path is covered in function zend_jit_cmp_long_long() by IS_SMALLER opcode. 5. New path is covered in macros ZVAL_PTR_DTOR and ZVAL_DTOR_FUNC when leaving.
1 parent e95ed06 commit d77f3c3

File tree

1 file changed

+91
-11
lines changed

1 file changed

+91
-11
lines changed
 

‎ext/opcache/jit/zend_jit_arm64.dasc

+91-11
Original file line numberDiff line numberDiff line change
@@ -728,13 +728,14 @@ static void* dasm_labels[zend_lb_MAX];
728728
| brk #0 // LONG_OP imul, reg, addr
729729
|| break;
730730
|| case ZEND_BW_OR:
731-
| brk #0 // LONG_OP or, reg, addr
731+
| LONG_OP orr, reg, addr, tmp_reg1, tmp_reg2
732732
|| break;
733733
|| case ZEND_BW_AND:
734-
| brk #0 // LONG_OP and, reg, addr
734+
| LONG_OP and, reg, addr, tmp_reg1, tmp_reg2
735735
|| break;
736736
|| case ZEND_BW_XOR:
737-
| brk #0 // LONG_OP xor, reg, addr
737+
| brk #0 // TODO
738+
| LONG_OP eor, reg, addr, tmp_reg1, tmp_reg2
738739
|| break;
739740
|| default:
740741
|| ZEND_UNREACHABLE();
@@ -1062,7 +1063,7 @@ static void* dasm_labels[zend_lb_MAX];
10621063
|| if (has_concrete_type((var_info) & (MAY_BE_STRING|MAY_BE_ARRAY|MAY_BE_OBJECT|MAY_BE_RESOURCE|MAY_BE_INDIRECT))) {
10631064
|| zend_uchar type = concrete_type((var_info) & (MAY_BE_STRING|MAY_BE_ARRAY|MAY_BE_OBJECT|MAY_BE_RESOURCE));
10641065
|| if (type == IS_STRING && !ZEND_DEBUG) {
1065-
| brk #0 // TODO
1066+
| EXT_CALL _efree, tmp_reg
10661067
|| break;
10671068
|| } else if (type == IS_ARRAY) {
10681069
|| if ((var_info) & (MAY_BE_ARRAY_KEY_STRING|MAY_BE_ARRAY_OF_STRING|MAY_BE_ARRAY_OF_ARRAY|MAY_BE_ARRAY_OF_OBJECT|MAY_BE_ARRAY_OF_RESOURCE|MAY_BE_ARRAY_OF_REF)) {
@@ -1109,7 +1110,6 @@ static void* dasm_labels[zend_lb_MAX];
11091110
|| if (gc && RC_MAY_BE_N(op_info) && ((op_info) & (MAY_BE_REF|MAY_BE_ARRAY|MAY_BE_OBJECT)) != 0) {
11101111
| bne >3
11111112
|| } else {
1112-
| brk #0 // TODO: test
11131113
| bne >4
11141114
|| }
11151115
|| }
@@ -3274,7 +3274,6 @@ static int zend_jit_long_math_helper(dasm_State **Dst,
32743274
| IF_NOT_ZVAL_TYPE op1_addr, IS_LONG, >6, TMP1w, TMP2
32753275
}
32763276
if (!same_ops && (op2_info & ((MAY_BE_ANY|MAY_BE_UNDEF)-MAY_BE_LONG))) {
3277-
| brk #0 // TODO
32783277
| IF_NOT_ZVAL_TYPE op2_addr, IS_LONG, >6, TMP1w, TMP2
32793278
}
32803279

@@ -3392,7 +3391,8 @@ static int zend_jit_long_math_helper(dasm_State **Dst,
33923391
} else if (same_ops) {
33933392
| brk #0 // TODO
33943393
} else {
3395-
| brk #0 // TODO
3394+
| GET_ZVAL_LVAL result_reg, op1_addr, TMP1
3395+
| LONG_MATH opcode, result_reg, op2_addr, TMP1, TMP2
33963396
}
33973397

33983398
if (Z_MODE(res_addr) != IS_REG || Z_REG(res_addr) != result_reg) {
@@ -3401,7 +3401,6 @@ static int zend_jit_long_math_helper(dasm_State **Dst,
34013401
if (Z_MODE(res_addr) == IS_MEM_ZVAL) {
34023402
if (Z_MODE(op1_addr) != IS_MEM_ZVAL || Z_REG(op1_addr) != Z_REG(res_addr) || Z_OFFSET(op1_addr) != Z_OFFSET(res_addr)) {
34033403
if ((res_use_info & (MAY_BE_ANY|MAY_BE_UNDEF|MAY_BE_REF|MAY_BE_GUARD)) != MAY_BE_LONG) {
3404-
| brk #0 // TODO
34053404
| SET_ZVAL_TYPE_INFO res_addr, IS_LONG, TMP1w, TMP2
34063405
}
34073406
}
@@ -3465,7 +3464,50 @@ static int zend_jit_concat_helper(dasm_State **Dst,
34653464
zend_jit_addr res_addr,
34663465
int may_throw)
34673466
{
3468-
| brk #0 // TODO
3467+
if ((op1_info & MAY_BE_STRING) && (op2_info & MAY_BE_STRING)) {
3468+
if (op1_info & ((MAY_BE_UNDEF|MAY_BE_ANY|MAY_BE_REF) - MAY_BE_STRING)) {
3469+
| brk #0 // TODO
3470+
| IF_NOT_ZVAL_TYPE op1_addr, IS_STRING, >6, TMP1w, TMP2
3471+
}
3472+
if (op2_info & ((MAY_BE_UNDEF|MAY_BE_ANY|MAY_BE_REF) - MAY_BE_STRING)) {
3473+
| IF_NOT_ZVAL_TYPE op2_addr, IS_STRING, >6, TMP1w, TMP2
3474+
}
3475+
if (Z_MODE(op1_addr) == IS_MEM_ZVAL && Z_REG(op1_addr) == Z_REG(res_addr) && Z_OFFSET(op1_addr) == Z_OFFSET(res_addr)) {
3476+
if (Z_REG(res_addr) != ZREG_FCARG1x || Z_OFFSET(res_addr) != 0) {
3477+
| LOAD_ZVAL_ADDR FCARG1x, res_addr
3478+
}
3479+
| LOAD_ZVAL_ADDR FCARG2x, op2_addr
3480+
| EXT_CALL zend_jit_fast_assign_concat_helper, REG0
3481+
} else {
3482+
if (Z_REG(res_addr) != ZREG_FCARG1x || Z_OFFSET(res_addr) != 0) {
3483+
| LOAD_ZVAL_ADDR FCARG1x, res_addr
3484+
}
3485+
| LOAD_ZVAL_ADDR FCARG2x, op1_addr
3486+
| LOAD_ZVAL_ADDR CARG3, op2_addr
3487+
| EXT_CALL zend_jit_fast_concat_helper, REG0
3488+
}
3489+
/* concatination with empty string may increase refcount */
3490+
op1_info |= MAY_BE_RCN;
3491+
op2_info |= MAY_BE_RCN;
3492+
| FREE_OP op1_type, op1, op1_info, 0, opline, ZREG_TMP1, ZREG_TMP2
3493+
| FREE_OP op2_type, op2, op2_info, 0, opline, ZREG_TMP1, ZREG_TMP2
3494+
|5:
3495+
}
3496+
if ((op1_info & ((MAY_BE_UNDEF|MAY_BE_ANY|MAY_BE_REF) - MAY_BE_STRING)) ||
3497+
(op2_info & ((MAY_BE_UNDEF|MAY_BE_ANY|MAY_BE_REF) - MAY_BE_STRING))) {
3498+
if ((op1_info & MAY_BE_STRING) && (op2_info & MAY_BE_STRING)) {
3499+
|.cold_code
3500+
|6:
3501+
}
3502+
| brk #0 // TODO
3503+
if (may_throw) {
3504+
zend_jit_check_exception(Dst);
3505+
}
3506+
if ((op1_info & MAY_BE_STRING) && (op2_info & MAY_BE_STRING)) {
3507+
| b <5
3508+
|.code
3509+
}
3510+
}
34693511

34703512
return 1;
34713513
}
@@ -4273,7 +4315,41 @@ static int zend_jit_assign_op(dasm_State **Dst, const zend_op *opline, uint32_t
42734315
ZEND_ASSERT(opline->op1_type == IS_CV && opline->result_type == IS_UNUSED);
42744316
ZEND_ASSERT(!(op1_info & MAY_BE_UNDEF) && !(op2_info & MAY_BE_UNDEF));
42754317

4276-
| brk #0 // TODO
4318+
op1_addr = OP1_ADDR();
4319+
op2_addr = OP2_ADDR();
4320+
4321+
if (op1_info & MAY_BE_REF) {
4322+
binary_op_type binary_op = get_binary_op(opline->extended_value);
4323+
| brk #0 // TODO
4324+
op1_addr = ZEND_ADDR_MEM_ZVAL(ZREG_FCARG1x, 0);
4325+
}
4326+
4327+
int result;
4328+
switch (opline->extended_value) {
4329+
case ZEND_ADD:
4330+
case ZEND_SUB:
4331+
case ZEND_MUL:
4332+
case ZEND_DIV:
4333+
result = zend_jit_math_helper(Dst, opline, opline->extended_value, opline->op1_type, opline->op1, op1_addr, op1_info, opline->op2_type, opline->op2, op2_addr, op2_info, opline->op1.var, op1_addr, op1_def_info, op1_info, may_overflow, may_throw);
4334+
break;
4335+
case ZEND_BW_OR:
4336+
case ZEND_BW_AND:
4337+
case ZEND_BW_XOR:
4338+
case ZEND_SL:
4339+
case ZEND_SR:
4340+
case ZEND_MOD:
4341+
result = zend_jit_long_math_helper(Dst, opline, opline->extended_value,
4342+
opline->op1_type, opline->op1, op1_addr, op1_info, op1_range,
4343+
opline->op2_type, opline->op2, op2_addr, op2_info, op2_range,
4344+
opline->op1.var, op1_addr, op1_def_info, op1_info, may_throw);
4345+
break;
4346+
case ZEND_CONCAT:
4347+
result = zend_jit_concat_helper(Dst, opline, opline->op1_type, opline->op1, op1_addr, op1_info, opline->op2_type, opline->op2, op2_addr, op2_info, op1_addr, may_throw);
4348+
break;
4349+
default:
4350+
ZEND_UNREACHABLE();
4351+
}
4352+
|9:
42774353
return 1;
42784354
}
42794355

@@ -4476,7 +4552,11 @@ static int zend_jit_cmp_long_long(dasm_State **Dst,
44764552
break;
44774553
case ZEND_IS_SMALLER:
44784554
if (swap) {
4479-
| brk #0 // TODO
4555+
if (exit_addr) {
4556+
| brk #0 // TODO
4557+
} else {
4558+
| bgt => target_label
4559+
}
44804560
} else {
44814561
if (exit_addr) {
44824562
| brk #0 // TODO

0 commit comments

Comments
 (0)
Failed to load comments.