@@ -13474,106 +13474,182 @@ static int zend_jit_assign_dim_op(zend_jit_ctx *jit,
13474
13474
}
13475
13475
13476
13476
#ifdef HAVE_FFI
13477
- static int zend_jit_ffi_assign_dim_op(zend_jit_ctx *jit,
13478
- const zend_op *opline,
13479
- uint32_t op1_info,
13480
- uint32_t op1_def_info,
13481
- zend_jit_addr op1_addr,
13482
- uint32_t op2_info,
13483
- zend_jit_addr op2_addr,
13484
- zend_ssa_range *op2_range,
13485
- uint32_t op1_data_info,
13486
- zend_jit_addr op3_addr,
13487
- zend_ssa_range *op1_data_range,
13488
- zend_ffi_type *op1_ffi_type)
13477
+ static int zend_jit_ffi_assign_op_helper(zend_jit_ctx *jit,
13478
+ const zend_op *opline,
13479
+ uint8_t opcode,
13480
+ zend_ffi_type *el_type,
13481
+ ir_ref op1,
13482
+ uint32_t op2_info,
13483
+ zend_jit_addr op2_addr)
13489
13484
{
13490
- zend_ffi_type *el_type = ZEND_FFI_TYPE(op1_ffi_type->array.type);
13491
-
13492
- // TODO: ce guard ???
13493
- // TODO: ffi type guard ???
13485
+ ir_op op;
13486
+ ir_type type;
13487
+ ir_ref op2;
13494
13488
13495
- if (!zend_jit_ffi_abc(jit, opline, op1_ffi_type, op2_info, op2_addr, op2_range)) {
13496
- return 0;
13489
+ switch (opcode) {
13490
+ case ZEND_ADD:
13491
+ op = IR_ADD;
13492
+ break;
13493
+ case ZEND_SUB:
13494
+ op = IR_SUB;
13495
+ break;
13496
+ case ZEND_MUL:
13497
+ op = IR_MUL;
13498
+ break;
13499
+ case ZEND_BW_OR:
13500
+ op = IR_OR;
13501
+ break;
13502
+ case ZEND_BW_AND:
13503
+ op = IR_AND;
13504
+ break;
13505
+ case ZEND_BW_XOR:
13506
+ op = IR_XOR;
13507
+ break;
13508
+ case ZEND_SL:
13509
+ // TODO: negative shift
13510
+ op = IR_SHL;
13511
+ break;
13512
+ case ZEND_SR:
13513
+ // TODO: negative shift
13514
+ op = IR_SAR; /* TODO: SAR or SHR */
13515
+ break;
13516
+ case ZEND_MOD:
13517
+ // TODO: mod by zero and -1
13518
+ op = IR_MOD;
13519
+ break;
13520
+ default:
13521
+ ZEND_UNREACHABLE();
13522
+ return 0;
13497
13523
}
13498
13524
13499
- ir_ref obj_ref = jit_Z_PTR(jit, op1_addr);
13500
- ir_ref cdata_ref = ir_LOAD_A(ir_ADD_OFFSET(obj_ref, offsetof(zend_ffi_cdata, ptr)));
13501
- ir_ref ptr = ir_ADD_A(cdata_ref, ir_MUL_L(jit_Z_LVAL(jit, op2_addr), ir_CONST_LONG(el_type->size)));
13502
-
13503
-
13504
- ZEND_ASSERT(opline->extended_value == ZEND_ADD);
13505
-
13506
13525
switch (el_type->kind) {
13507
13526
case ZEND_FFI_TYPE_FLOAT:
13508
- if (op1_data_info == MAY_BE_LONG) {
13509
- ir_STORE(ptr, ir_ADD_F(ir_LOAD_F(ptr), ir_INT2F(jit_Z_LVAL(jit, op3_addr))));
13510
- } else if (op1_data_info == MAY_BE_DOUBLE) {
13511
- ir_STORE(ptr, ir_ADD_F(ir_LOAD_F(ptr), ir_D2F(jit_Z_DVAL(jit, op3_addr))));
13527
+ ZEND_ASSERT(op == IR_ADD || op == IR_SUB || op == IR_MUL);
13528
+ type = IR_FLOAT;
13529
+ if (op2_info == MAY_BE_LONG) {
13530
+ op2 = ir_INT2F(jit_Z_LVAL(jit, op2_addr));
13531
+ } else if (op2_info == MAY_BE_DOUBLE) {
13532
+ op2 = ir_D2F(jit_Z_DVAL(jit, op2_addr));
13512
13533
} else {
13513
13534
ZEND_UNREACHABLE();
13535
+ return 0;
13514
13536
}
13515
13537
break;
13516
13538
case ZEND_FFI_TYPE_DOUBLE:
13517
- if (op1_data_info == MAY_BE_LONG) {
13518
- ir_STORE(ptr, ir_ADD_D(ir_LOAD_D(ptr), ir_INT2D(jit_Z_LVAL(jit, op3_addr))));
13519
- } else if (op1_data_info == MAY_BE_DOUBLE) {
13520
- ir_STORE(ptr, ir_ADD_D(ir_LOAD_D(ptr), jit_Z_DVAL(jit, op3_addr)));
13539
+ ZEND_ASSERT(op == IR_ADD || op == IR_SUB || op == IR_MUL);
13540
+ type = IR_DOUBLE;
13541
+ if (op2_info == MAY_BE_LONG) {
13542
+ op2 = ir_INT2D(jit_Z_LVAL(jit, op2_addr));
13543
+ } else if (op2_info == MAY_BE_DOUBLE) {
13544
+ op2 = jit_Z_DVAL(jit, op2_addr);
13521
13545
} else {
13522
13546
ZEND_UNREACHABLE();
13547
+ return 0;
13523
13548
}
13524
13549
break;
13525
13550
case ZEND_FFI_TYPE_UINT8:
13526
- if (op1_data_info == MAY_BE_LONG) {
13527
- ir_STORE(ptr, ir_ADD_U8(ir_LOAD_U8(ptr), ir_TRUNC_U8(jit_Z_LVAL(jit, op3_addr))));
13551
+ type = IR_U8;
13552
+ if (op2_info == MAY_BE_LONG) {
13553
+ op2 = ir_TRUNC_U8(jit_Z_LVAL(jit, op2_addr));
13528
13554
} else {
13529
13555
ZEND_UNREACHABLE();
13556
+ return 0;
13530
13557
}
13531
13558
break;
13532
13559
case ZEND_FFI_TYPE_SINT8:
13533
- if (op1_data_info == MAY_BE_LONG) {
13534
- ir_STORE(ptr, ir_ADD_I8(ir_LOAD_I8(ptr), ir_TRUNC_I8(jit_Z_LVAL(jit, op3_addr))));
13560
+ type = IR_I8;
13561
+ if (op2_info == MAY_BE_LONG) {
13562
+ op2 = ir_TRUNC_I8(jit_Z_LVAL(jit, op2_addr));
13535
13563
} else {
13536
13564
ZEND_UNREACHABLE();
13565
+ return 0;
13537
13566
}
13538
13567
break;
13539
13568
case ZEND_FFI_TYPE_UINT16:
13540
- if (op1_data_info == MAY_BE_LONG) {
13541
- ir_STORE(ptr, ir_ADD_U16(ir_LOAD_U16(ptr), ir_TRUNC_U16(jit_Z_LVAL(jit, op3_addr))));
13569
+ type = IR_U16;
13570
+ if (op2_info == MAY_BE_LONG) {
13571
+ op2 = ir_TRUNC_U16(jit_Z_LVAL(jit, op2_addr));
13542
13572
} else {
13543
13573
ZEND_UNREACHABLE();
13574
+ return 0;
13544
13575
}
13545
13576
break;
13546
13577
case ZEND_FFI_TYPE_SINT16:
13547
- if (op1_data_info == MAY_BE_LONG) {
13548
- ir_STORE(ptr, ir_ADD_I16(ir_LOAD_I16(ptr), ir_TRUNC_I16(jit_Z_LVAL(jit, op3_addr))));
13578
+ type = IR_I16;
13579
+ if (op2_info == MAY_BE_LONG) {
13580
+ op2 = ir_TRUNC_I16(jit_Z_LVAL(jit, op2_addr));
13549
13581
} else {
13550
13582
ZEND_UNREACHABLE();
13583
+ return 0;
13551
13584
}
13552
13585
break;
13553
13586
case ZEND_FFI_TYPE_UINT32:
13554
- if (op1_data_info == MAY_BE_LONG) {
13555
- ir_STORE(ptr, ir_ADD_U32(ir_LOAD_U32(ptr), ir_TRUNC_U32(jit_Z_LVAL(jit, op3_addr))));
13587
+ type = IR_U32;
13588
+ if (op2_info == MAY_BE_LONG) {
13589
+ op2 = ir_TRUNC_U32(jit_Z_LVAL(jit, op2_addr));
13556
13590
} else {
13557
13591
ZEND_UNREACHABLE();
13592
+ return 0;
13558
13593
}
13559
13594
break;
13560
13595
case ZEND_FFI_TYPE_SINT32:
13561
- if (op1_data_info == MAY_BE_LONG) {
13562
- ir_STORE(ptr, ir_ADD_I32(ir_LOAD_I32(ptr), ir_TRUNC_I32(jit_Z_LVAL(jit, op3_addr))));
13596
+ type = IR_I32;
13597
+ if (op2_info == MAY_BE_LONG) {
13598
+ op2 = ir_TRUNC_I32(jit_Z_LVAL(jit, op2_addr));
13563
13599
} else {
13564
13600
ZEND_UNREACHABLE();
13601
+ return 0;
13565
13602
}
13566
13603
break;
13567
13604
case ZEND_FFI_TYPE_UINT64:
13568
13605
case ZEND_FFI_TYPE_SINT64:
13569
- if (op1_data_info == MAY_BE_LONG) {
13570
- ir_STORE(ptr, ir_ADD_I64(ir_LOAD_I64(ptr), jit_Z_LVAL(jit, op3_addr)));
13606
+ type = IR_I64;
13607
+ if (op2_info == MAY_BE_LONG) {
13608
+ op2 = jit_Z_LVAL(jit, op2_addr);
13571
13609
} else {
13572
13610
ZEND_UNREACHABLE();
13611
+ return 0;
13573
13612
}
13574
13613
break;
13575
13614
default:
13576
13615
ZEND_UNREACHABLE();
13616
+ return 0;
13617
+ }
13618
+
13619
+ ir_STORE(op1, ir_BINARY_OP(op, type, ir_LOAD(type, op1), op2));
13620
+
13621
+ return 1;
13622
+ }
13623
+
13624
+ static int zend_jit_ffi_assign_dim_op(zend_jit_ctx *jit,
13625
+ const zend_op *opline,
13626
+ uint32_t op1_info,
13627
+ uint32_t op1_def_info,
13628
+ zend_jit_addr op1_addr,
13629
+ uint32_t op2_info,
13630
+ zend_jit_addr op2_addr,
13631
+ zend_ssa_range *op2_range,
13632
+ uint32_t op1_data_info,
13633
+ zend_jit_addr op3_addr,
13634
+ zend_ssa_range *op1_data_range,
13635
+ zend_ffi_type *op1_ffi_type)
13636
+ {
13637
+ zend_ffi_type *el_type = ZEND_FFI_TYPE(op1_ffi_type->array.type);
13638
+
13639
+ // TODO: ce guard ???
13640
+ // TODO: ffi type guard ???
13641
+
13642
+ if (!zend_jit_ffi_abc(jit, opline, op1_ffi_type, op2_info, op2_addr, op2_range)) {
13643
+ return 0;
13644
+ }
13645
+
13646
+ ir_ref obj_ref = jit_Z_PTR(jit, op1_addr);
13647
+ ir_ref cdata_ref = ir_LOAD_A(ir_ADD_OFFSET(obj_ref, offsetof(zend_ffi_cdata, ptr)));
13648
+ ir_ref ptr = ir_ADD_A(cdata_ref, ir_MUL_L(jit_Z_LVAL(jit, op2_addr), ir_CONST_LONG(el_type->size)));
13649
+
13650
+ if (!zend_jit_ffi_assign_op_helper(jit, opline, opline->extended_value,
13651
+ el_type, ptr, op1_data_info, op3_addr)) {
13652
+ return 0;
13577
13653
}
13578
13654
13579
13655
return 1;
0 commit comments