Skip to content

Commit 3bbabcd

Browse files
shqkingdstogov
authored andcommitted
Support failed JIT test case: cmp_004.phpt
The following opcodes would be generated for $foo: 0000 #2.CV0($test) [bool] RANGE[0..1] = RECV 1 0001 #3.CV1($x) [long] RANGE[MIN..MAX] = RECV 2 0002 JMPZ #2.CV0($test) [bool] RANGE[0..1] BB4 0003 #4.T2 [bool] ... = IS_SMALLER_OR_EQUAL int(1) #3.CV1($x) ... 0004 JMP BB5 ... The updates in function zend_jit_verify_arg_type() are made to support RECV opcode. The updates in function zend_jit_bool_jmpznz() are made to support JMPZ opcode. New path is covered in functions zend_jit_cmp() and zend_jit_cmp_long_long() for IS_SMALLER_OR_EQUAL opcode.
1 parent f21586a commit 3bbabcd

File tree

1 file changed

+164
-8
lines changed

1 file changed

+164
-8
lines changed

ext/opcache/jit/zend_jit_arm64.dasc

Lines changed: 164 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -671,8 +671,28 @@ static void* dasm_labels[zend_lb_MAX];
671671
| brk #0 // TODO
672672
|.endmacro
673673

674-
|.macro LONG_OP_WITH_CONST, long_ins, op1_addr, lval
675-
| brk #0 // TODO
674+
// Define LONG_CMP_WITH_CONST to replace LONG_OP_WITH_CONST in the x86 implementation.
675+
// Note that the 'long_ins' in all use sites of LONG_OP_WITH_CONST are always 'cmp'.
676+
// Note that this macro is different from LONG_CMP.
677+
|.macro LONG_CMP_WITH_CONST, cmp_ins, op1_addr, lval, tmp_reg1, tmp_reg2
678+
|| if (Z_MODE(op1_addr) == IS_MEM_ZVAL) {
679+
| SAFE_MEM_ACC_WITH_UOFFSET ldr, tmp_reg1, Rx(Z_REG(op1_addr)), Z_OFFSET(op1_addr), tmp_reg2
680+
|| if (lval >=0 && lval <= MAX_IMM12) {
681+
| cmp_ins tmp_reg1, #lval
682+
|| } else {
683+
| LOAD_64BIT_VAL tmp_reg2, lval
684+
| cmp_ins tmp_reg1, tmp_reg2
685+
|| }
686+
|| } else if (Z_MODE(op1_addr) == IS_REG) {
687+
|| if (lval >=0 && lval <= MAX_IMM12) {
688+
| cmp_ins Rx(Z_REG(op1_addr)), #lval
689+
|| } else {
690+
| LOAD_64BIT_VAL tmp_reg1, lval
691+
| cmp_ins Rx(Z_REG(op1_addr)), tmp_reg1
692+
|| }
693+
|| } else {
694+
|| ZEND_UNREACHABLE();
695+
|| }
676696
|.endmacro
677697

678698
|.macro GET_ZVAL_LVAL, reg, addr, tmp_reg
@@ -895,9 +915,11 @@ static void* dasm_labels[zend_lb_MAX];
895915
| IF_NOT_TYPE tmp_reg, val, label
896916
|.endmacro
897917

898-
|.macro CMP_ZVAL_TYPE, addr, val
918+
|.macro CMP_ZVAL_TYPE, addr, val, tmp_reg1, tmp_reg2
899919
|| ZEND_ASSERT(Z_MODE(addr) == IS_MEM_ZVAL);
900-
| cmp byte [Ra(Z_REG(addr))+Z_OFFSET(addr)+offsetof(zval, u1.v.type)], val
920+
|| ZEND_ASSERT(val <= MAX_IMM12);
921+
| SAFE_MEM_ACC_WITH_UOFFSET ldrb, tmp_reg1, Rx(Z_REG(addr)), Z_OFFSET(addr)+offsetof(zval, u1.v.type), tmp_reg2
922+
| cmp tmp_reg1, #val
901923
|.endmacro
902924

903925
|.macro IF_ZVAL_TYPE, addr, val, label, tmp_reg1, tmp_reg2
@@ -4218,7 +4240,7 @@ static int zend_jit_cmp_long_long(dasm_State **Dst,
42184240
}
42194241
swap = 1;
42204242
} else if (Z_MODE(op1_addr) == IS_CONST_ZVAL && Z_MODE(op2_addr) != IS_CONST_ZVAL) {
4221-
| brk #0 // TODO
4243+
| LONG_CMP_WITH_CONST cmp, op2_addr, Z_LVAL_P(Z_ZV(op1_addr)), TMP1, TMP2
42224244
swap = 1;
42234245
} else if (Z_MODE(op2_addr) == IS_CONST_ZVAL && Z_MODE(op1_addr) != IS_CONST_ZVAL) {
42244246
| brk #0 // TODO
@@ -4311,7 +4333,36 @@ static int zend_jit_cmp_long_long(dasm_State **Dst,
43114333
ZEND_UNREACHABLE();
43124334
}
43134335
} else {
4314-
| brk #0 // TODO
4336+
switch (opline->opcode) {
4337+
case ZEND_IS_EQUAL:
4338+
case ZEND_IS_IDENTICAL:
4339+
case ZEND_CASE:
4340+
case ZEND_CASE_STRICT:
4341+
| brk #0 // TODO
4342+
break;
4343+
case ZEND_IS_NOT_EQUAL:
4344+
case ZEND_IS_NOT_IDENTICAL:
4345+
| brk #0 // TODO
4346+
break;
4347+
case ZEND_IS_SMALLER:
4348+
if (swap) {
4349+
| brk #0 // TODO
4350+
} else {
4351+
| brk #0 // TODO
4352+
}
4353+
break;
4354+
case ZEND_IS_SMALLER_OR_EQUAL:
4355+
if (swap) {
4356+
| cset REG0w, ge
4357+
} else {
4358+
| brk #0 // TODO
4359+
}
4360+
break;
4361+
default:
4362+
ZEND_UNREACHABLE();
4363+
}
4364+
| add REG0w, REG0w, #2
4365+
| SET_ZVAL_TYPE_INFO_FROM_REG res_addr, REG0w, TMP1
43154366
}
43164367

43174368
return 1;
@@ -4608,7 +4659,107 @@ static int zend_jit_bool_jmpznz(dasm_State **Dst, const zend_op *opline, uint32_
46084659
bool set_delayed = 0;
46094660
bool jmp_done = 0;
46104661

4611-
| brk #0 // TODO
4662+
if (branch_opcode == ZEND_BOOL) {
4663+
set_bool = 1;
4664+
} else if (branch_opcode == ZEND_BOOL_NOT) {
4665+
set_bool = 1;
4666+
set_bool_not = 1;
4667+
} else if (branch_opcode == ZEND_JMPZ) {
4668+
false_label = target_label;
4669+
} else if (branch_opcode == ZEND_JMPNZ) {
4670+
true_label = target_label;
4671+
} else if (branch_opcode == ZEND_JMPZNZ) {
4672+
true_label = target_label2;
4673+
false_label = target_label;
4674+
} else if (branch_opcode == ZEND_JMPZ_EX) {
4675+
set_bool = 1;
4676+
false_label = target_label;
4677+
} else if (branch_opcode == ZEND_JMPNZ_EX) {
4678+
set_bool = 1;
4679+
true_label = target_label;
4680+
} else {
4681+
ZEND_UNREACHABLE();
4682+
}
4683+
4684+
if (Z_MODE(op1_addr) == IS_CONST_ZVAL) {
4685+
if (zend_is_true(Z_ZV(op1_addr))) {
4686+
/* Always TRUE */
4687+
| brk #0 // TODO
4688+
} else {
4689+
/* Always FALSE */
4690+
| brk #0 // TODO
4691+
}
4692+
return 1;
4693+
}
4694+
4695+
if (op1_info & MAY_BE_REF) {
4696+
| brk #0 // TODO
4697+
op1_addr = ZEND_ADDR_MEM_ZVAL(ZREG_FCARG1x, 0);
4698+
}
4699+
4700+
if (op1_info & (MAY_BE_UNDEF|MAY_BE_NULL|MAY_BE_FALSE|MAY_BE_TRUE)) {
4701+
if (!(op1_info & ((MAY_BE_UNDEF|MAY_BE_ANY)-MAY_BE_TRUE))) {
4702+
/* Always TRUE */
4703+
| brk #0 // TODO
4704+
} else {
4705+
if (!(op1_info & (MAY_BE_ANY-(MAY_BE_NULL|MAY_BE_FALSE)))) {
4706+
/* Always FALSE */
4707+
if (set_bool) {
4708+
| brk #0 // TODO
4709+
}
4710+
} else {
4711+
| CMP_ZVAL_TYPE op1_addr, IS_TRUE, TMP1w, TMP2
4712+
if (op1_info & (MAY_BE_ANY-(MAY_BE_NULL|MAY_BE_FALSE|MAY_BE_TRUE))) {
4713+
| brk #0 // TODO
4714+
}
4715+
if (!(op1_info & MAY_BE_TRUE)) {
4716+
/* It's FALSE */
4717+
| brk #0 // TODO
4718+
} else {
4719+
if (exit_addr) {
4720+
| brk #0 // TODO
4721+
} else if (true_label != (uint32_t)-1 || false_label != (uint32_t)-1) {
4722+
if (set_bool) {
4723+
| brk #0 // TODO
4724+
} else {
4725+
if (true_label != (uint32_t)-1) {
4726+
| brk #0 // TODO
4727+
} else if (!(op1_info & (MAY_BE_UNDEF|MAY_BE_LONG))) {
4728+
| bne =>false_label
4729+
jmp_done = 1;
4730+
} else {
4731+
| brk #0 // TODO
4732+
}
4733+
}
4734+
} else if (set_bool) {
4735+
| brk #0 // TODO
4736+
}
4737+
}
4738+
}
4739+
4740+
/* It's FALSE, but may be UNDEF */
4741+
if (op1_info & MAY_BE_UNDEF) {
4742+
| brk #0 // TODO
4743+
}
4744+
4745+
if (!jmp_done) {
4746+
| brk #0 // TODO
4747+
}
4748+
}
4749+
}
4750+
4751+
if (op1_info & MAY_BE_LONG) {
4752+
| brk #0 // TODO
4753+
}
4754+
4755+
if ((op1_info & MAY_BE_ANY) == MAY_BE_DOUBLE) {
4756+
| brk #0 // TODO
4757+
} else if (op1_info & (MAY_BE_ANY - (MAY_BE_NULL|MAY_BE_FALSE|MAY_BE_TRUE|MAY_BE_LONG))) {
4758+
| brk #0 // TODO
4759+
}
4760+
4761+
|9:
4762+
46124763
return 1;
46134764
}
46144765

@@ -7023,7 +7174,12 @@ static int zend_jit_verify_arg_type(dasm_State **Dst, const zend_op *opline, zen
70237174
|| ZEND_ASSERT(type_code <= MAX_IMM12);
70247175
| IF_NOT_ZVAL_TYPE res_addr, type_code, >1, TMP1w, TMP2
70257176
} else {
7026-
| brk #0 // TODO
7177+
| mov REG2w, #1
7178+
| SAFE_MEM_ACC_WITH_UOFFSET ldrb, REG1w, Rx(Z_REG(res_addr)), Z_OFFSET(res_addr)+offsetof(zval, u1.v.type), TMP1
7179+
| lsl REG2w, REG2w, REG1w
7180+
| LOAD_32BIT_VAL TMP1w, type_mask
7181+
| tst REG2w, TMP1w
7182+
| beq >1
70277183
}
70287184

70297185
|.cold_code

0 commit comments

Comments
 (0)