@@ -531,8 +531,11 @@ static void* dasm_labels[zend_lb_MAX];
531
531
| brk #0 // TODO
532
532
|.endmacro
533
533
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
536
539
|.endmacro
537
540
538
541
// 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];
837
840
|| if (Z_MODE(dst_addr) == IS_MEM_ZVAL) {
838
841
|| if ((dst_info & (MAY_BE_ANY|MAY_BE_UNDEF|MAY_BE_GUARD)) != (src_info & (MAY_BE_ANY|MAY_BE_UNDEF|MAY_BE_GUARD))) {
839
842
|| zend_uchar type = concrete_type(src_info);
840
- | brk #0 // TODO: test
841
843
| SET_ZVAL_TYPE_INFO dst_addr, type, Rw(tmp_reg1), Rx(tmp_reg2)
842
844
|| }
843
845
|| }
@@ -852,7 +854,6 @@ static void* dasm_labels[zend_lb_MAX];
852
854
|| if ((src_info & (MAY_BE_ANY|MAY_BE_GUARD)) == MAY_BE_LONG) {
853
855
|| if (Z_MODE(src_addr) == IS_REG) {
854
856
|| if (Z_MODE(dst_addr) != IS_REG || Z_REG(dst_addr) != Z_REG(src_addr)) {
855
- | brk #0 // TODO: test
856
857
| SET_ZVAL_LVAL_FROM_REG dst_addr, Rx(Z_REG(src_addr)), Rx(tmp_reg)
857
858
|| }
858
859
|| } else if (Z_MODE(dst_addr) == IS_REG) {
@@ -1552,7 +1553,11 @@ static int zend_jit_undefined_function_stub(dasm_State **Dst)
1552
1553
static int zend_jit_negative_shift_stub(dasm_State **Dst)
1553
1554
{
1554
1555
|->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
1556
1561
return 1;
1557
1562
}
1558
1563
@@ -3264,7 +3269,120 @@ static int zend_jit_long_math_helper(dasm_State **Dst,
3264
3269
zend_reg result_reg;
3265
3270
zval tmp;
3266
3271
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:
3268
3386
3269
3387
return 1;
3270
3388
}
0 commit comments