@@ -728,13 +728,14 @@ static void* dasm_labels[zend_lb_MAX];
728
728
| brk #0 // LONG_OP imul, reg, addr
729
729
|| break;
730
730
|| case ZEND_BW_OR:
731
- | brk #0 // LONG_OP or , reg, addr
731
+ | LONG_OP orr , reg, addr, tmp_reg1, tmp_reg2
732
732
|| break;
733
733
|| case ZEND_BW_AND:
734
- | brk #0 // LONG_OP and, reg, addr
734
+ | LONG_OP and, reg, addr, tmp_reg1, tmp_reg2
735
735
|| break;
736
736
|| 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
738
739
|| break;
739
740
|| default:
740
741
|| ZEND_UNREACHABLE();
@@ -1062,7 +1063,7 @@ static void* dasm_labels[zend_lb_MAX];
1062
1063
|| if (has_concrete_type((var_info) & (MAY_BE_STRING|MAY_BE_ARRAY|MAY_BE_OBJECT|MAY_BE_RESOURCE|MAY_BE_INDIRECT))) {
1063
1064
|| zend_uchar type = concrete_type((var_info) & (MAY_BE_STRING|MAY_BE_ARRAY|MAY_BE_OBJECT|MAY_BE_RESOURCE));
1064
1065
|| if (type == IS_STRING && !ZEND_DEBUG) {
1065
- | brk #0 // TODO
1066
+ | EXT_CALL _efree, tmp_reg
1066
1067
|| break;
1067
1068
|| } else if (type == IS_ARRAY) {
1068
1069
|| 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];
1109
1110
|| if (gc && RC_MAY_BE_N(op_info) && ((op_info) & (MAY_BE_REF|MAY_BE_ARRAY|MAY_BE_OBJECT)) != 0) {
1110
1111
| bne >3
1111
1112
|| } else {
1112
- | brk #0 // TODO: test
1113
1113
| bne >4
1114
1114
|| }
1115
1115
|| }
@@ -3274,7 +3274,6 @@ static int zend_jit_long_math_helper(dasm_State **Dst,
3274
3274
| IF_NOT_ZVAL_TYPE op1_addr, IS_LONG, >6, TMP1w, TMP2
3275
3275
}
3276
3276
if (!same_ops && (op2_info & ((MAY_BE_ANY|MAY_BE_UNDEF)-MAY_BE_LONG))) {
3277
- | brk #0 // TODO
3278
3277
| IF_NOT_ZVAL_TYPE op2_addr, IS_LONG, >6, TMP1w, TMP2
3279
3278
}
3280
3279
@@ -3392,7 +3391,8 @@ static int zend_jit_long_math_helper(dasm_State **Dst,
3392
3391
} else if (same_ops) {
3393
3392
| brk #0 // TODO
3394
3393
} else {
3395
- | brk #0 // TODO
3394
+ | GET_ZVAL_LVAL result_reg, op1_addr, TMP1
3395
+ | LONG_MATH opcode, result_reg, op2_addr, TMP1, TMP2
3396
3396
}
3397
3397
3398
3398
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,
3401
3401
if (Z_MODE(res_addr) == IS_MEM_ZVAL) {
3402
3402
if (Z_MODE(op1_addr) != IS_MEM_ZVAL || Z_REG(op1_addr) != Z_REG(res_addr) || Z_OFFSET(op1_addr) != Z_OFFSET(res_addr)) {
3403
3403
if ((res_use_info & (MAY_BE_ANY|MAY_BE_UNDEF|MAY_BE_REF|MAY_BE_GUARD)) != MAY_BE_LONG) {
3404
- | brk #0 // TODO
3405
3404
| SET_ZVAL_TYPE_INFO res_addr, IS_LONG, TMP1w, TMP2
3406
3405
}
3407
3406
}
@@ -3465,7 +3464,50 @@ static int zend_jit_concat_helper(dasm_State **Dst,
3465
3464
zend_jit_addr res_addr,
3466
3465
int may_throw)
3467
3466
{
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
+ }
3469
3511
3470
3512
return 1;
3471
3513
}
@@ -4273,7 +4315,41 @@ static int zend_jit_assign_op(dasm_State **Dst, const zend_op *opline, uint32_t
4273
4315
ZEND_ASSERT(opline->op1_type == IS_CV && opline->result_type == IS_UNUSED);
4274
4316
ZEND_ASSERT(!(op1_info & MAY_BE_UNDEF) && !(op2_info & MAY_BE_UNDEF));
4275
4317
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:
4277
4353
return 1;
4278
4354
}
4279
4355
@@ -4476,7 +4552,11 @@ static int zend_jit_cmp_long_long(dasm_State **Dst,
4476
4552
break;
4477
4553
case ZEND_IS_SMALLER:
4478
4554
if (swap) {
4479
- | brk #0 // TODO
4555
+ if (exit_addr) {
4556
+ | brk #0 // TODO
4557
+ } else {
4558
+ | bgt => target_label
4559
+ }
4480
4560
} else {
4481
4561
if (exit_addr) {
4482
4562
| brk #0 // TODO
0 commit comments