mirror of
https://github.com/php/php-src.git
synced 2026-03-24 00:02:20 +01:00
Merge branch 'PHP-8.4'
* PHP-8.4: Update IR
This commit is contained in:
@@ -650,6 +650,26 @@ IR_ALWAYS_INLINE ir_mem IR_MEM(ir_reg base, int32_t offset, ir_reg index, int32_
|
||||
|| }
|
||||
|.endmacro
|
||||
|
||||
/* Like ASM_REG_IMM_OP, but op1 accepts r16,r32,r64 (not r8) */
|
||||
|.macro ASM_REG16_IMM_OP, op, type, op1, op2
|
||||
|| switch (ir_type_size[type]) {
|
||||
|| default:
|
||||
|| IR_ASSERT(0);
|
||||
|| case 1:
|
||||
|| case 2:
|
||||
| op Rw(op1), (op2 & 0xffff)
|
||||
|| break;
|
||||
|| case 4:
|
||||
| op Rd(op1), op2
|
||||
|| break;
|
||||
|.if X64
|
||||
|| case 8:
|
||||
| op Rq(op1), op2
|
||||
|| break;
|
||||
|.endif
|
||||
|| }
|
||||
|.endmacro
|
||||
|
||||
|.macro ASM_MEM_REG_OP, op, type, op1, op2
|
||||
| ASM_EXPAND_OP1_MEM ASM_EXPAND_TYPE_MEM_REG, op, type, op1, op2
|
||||
|.endmacro
|
||||
@@ -1066,6 +1086,7 @@ const char *ir_reg_name(int8_t reg, ir_type type)
|
||||
_(SSE_CEIL) \
|
||||
_(SSE_TRUNC) \
|
||||
_(SSE_NEARBYINT) \
|
||||
_(BIT_OP) \
|
||||
|
||||
#define IR_LEA_FIRST IR_LEA_OB
|
||||
#define IR_LEA_LAST IR_LEA_O_SYM
|
||||
@@ -1400,6 +1421,7 @@ op2_const:
|
||||
case IR_DIV_PWR2:
|
||||
case IR_OP_INT:
|
||||
case IR_OP_FP:
|
||||
case IR_BIT_OP:
|
||||
flags = IR_DEF_REUSES_OP1_REG | IR_USE_MUST_BE_IN_REG | IR_OP1_SHOULD_BE_IN_REG;
|
||||
break;
|
||||
case IR_MOD_PWR2:
|
||||
@@ -2280,6 +2302,9 @@ binop_fp:
|
||||
// return IR_COPY_INT;
|
||||
} else if (op2_insn->val.i64 == -1) {
|
||||
// -1
|
||||
} else if (IR_IS_POWER_OF_TWO(op2_insn->val.u64) && !IR_IS_SIGNED_32BIT(op2_insn->val.i64)) {
|
||||
/* OR(X, PWR2) => BTS */
|
||||
return IR_BIT_OP;
|
||||
}
|
||||
}
|
||||
goto binop_int;
|
||||
@@ -2294,6 +2319,9 @@ binop_fp:
|
||||
// 0
|
||||
} else if (op2_insn->val.i64 == -1) {
|
||||
// return IR_COPY_INT;
|
||||
} else if (IR_IS_POWER_OF_TWO(~op2_insn->val.u64) && !IR_IS_SIGNED_32BIT(op2_insn->val.i64)) {
|
||||
/* AND(X, ~PWR2) => BTR */
|
||||
return IR_BIT_OP;
|
||||
}
|
||||
}
|
||||
goto binop_int;
|
||||
@@ -4341,6 +4369,45 @@ static void ir_emit_mul_div_mod_pwr2(ir_ctx *ctx, ir_ref def, ir_insn *insn)
|
||||
}
|
||||
}
|
||||
|
||||
static void ir_emit_bit_op(ir_ctx *ctx, ir_ref def, ir_insn *insn)
|
||||
{
|
||||
ir_backend_data *data = ctx->data;
|
||||
dasm_State **Dst = &data->dasm_state;
|
||||
ir_type type = insn->type;
|
||||
ir_ref op1 = insn->op1;
|
||||
ir_reg def_reg = IR_REG_NUM(ctx->regs[def][0]);
|
||||
ir_reg op1_reg = ctx->regs[def][1];
|
||||
|
||||
IR_ASSERT(IR_IS_CONST_REF(insn->op2));
|
||||
IR_ASSERT(!IR_IS_SYM_CONST(ctx->ir_base[insn->op2].op));
|
||||
IR_ASSERT(def_reg != IR_REG_NONE);
|
||||
|
||||
if (op1_reg != IR_REG_NONE && IR_REG_SPILLED(op1_reg)) {
|
||||
op1_reg = IR_REG_NUM(op1_reg);
|
||||
ir_emit_load(ctx, type, op1_reg, op1);
|
||||
}
|
||||
if (def_reg != op1_reg) {
|
||||
if (op1_reg != IR_REG_NONE) {
|
||||
ir_emit_mov(ctx, type, def_reg, op1_reg);
|
||||
} else {
|
||||
ir_emit_load(ctx, type, def_reg, op1);
|
||||
}
|
||||
}
|
||||
if (insn->op == IR_OR) {
|
||||
uint32_t bit = IR_LOG2(ctx->ir_base[insn->op2].val.u64);
|
||||
|
||||
| ASM_REG16_IMM_OP, bts, type, def_reg, bit
|
||||
} else {
|
||||
IR_ASSERT(insn->op == IR_AND);
|
||||
uint32_t bit = IR_LOG2(~ctx->ir_base[insn->op2].val.u64);
|
||||
|
||||
| ASM_REG16_IMM_OP, btr, type, def_reg, bit
|
||||
}
|
||||
if (IR_REG_SPILLED(ctx->regs[def][0])) {
|
||||
ir_emit_store(ctx, type, def, def_reg);
|
||||
}
|
||||
}
|
||||
|
||||
static void ir_emit_sdiv_pwr2(ir_ctx *ctx, ir_ref def, ir_insn *insn)
|
||||
{
|
||||
ir_backend_data *data = ctx->data;
|
||||
@@ -10668,6 +10735,9 @@ void *ir_emit_code(ir_ctx *ctx, size_t *size_ptr)
|
||||
case IR_MOD_PWR2:
|
||||
ir_emit_mul_div_mod_pwr2(ctx, i, insn);
|
||||
break;
|
||||
case IR_BIT_OP:
|
||||
ir_emit_bit_op(ctx, i, insn);
|
||||
break;
|
||||
case IR_SDIV_PWR2:
|
||||
ir_emit_sdiv_pwr2(ctx, i, insn);
|
||||
break;
|
||||
|
||||
Reference in New Issue
Block a user