Skip to content

Commit c032804

Browse files
committed
JIT: Separate FFI assing_op helper. Add support for all SUB, AND, etc
1 parent 8ec7fbe commit c032804

File tree

1 file changed

+123
-47
lines changed

1 file changed

+123
-47
lines changed

ext/opcache/jit/zend_jit_ir.c

Lines changed: 123 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -13474,106 +13474,182 @@ static int zend_jit_assign_dim_op(zend_jit_ctx *jit,
1347413474
}
1347513475

1347613476
#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)
1348913484
{
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;
1349413488

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;
1349713523
}
1349813524

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-
1350613525
switch (el_type->kind) {
1350713526
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));
1351213533
} else {
1351313534
ZEND_UNREACHABLE();
13535+
return 0;
1351413536
}
1351513537
break;
1351613538
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);
1352113545
} else {
1352213546
ZEND_UNREACHABLE();
13547+
return 0;
1352313548
}
1352413549
break;
1352513550
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));
1352813554
} else {
1352913555
ZEND_UNREACHABLE();
13556+
return 0;
1353013557
}
1353113558
break;
1353213559
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));
1353513563
} else {
1353613564
ZEND_UNREACHABLE();
13565+
return 0;
1353713566
}
1353813567
break;
1353913568
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));
1354213572
} else {
1354313573
ZEND_UNREACHABLE();
13574+
return 0;
1354413575
}
1354513576
break;
1354613577
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));
1354913581
} else {
1355013582
ZEND_UNREACHABLE();
13583+
return 0;
1355113584
}
1355213585
break;
1355313586
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));
1355613590
} else {
1355713591
ZEND_UNREACHABLE();
13592+
return 0;
1355813593
}
1355913594
break;
1356013595
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));
1356313599
} else {
1356413600
ZEND_UNREACHABLE();
13601+
return 0;
1356513602
}
1356613603
break;
1356713604
case ZEND_FFI_TYPE_UINT64:
1356813605
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);
1357113609
} else {
1357213610
ZEND_UNREACHABLE();
13611+
return 0;
1357313612
}
1357413613
break;
1357513614
default:
1357613615
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;
1357713653
}
1357813654

1357913655
return 1;

0 commit comments

Comments
 (0)