Skip to content

Commit 2bacd4e

Browse files
committed
Update IR
IR commit: 34aeda97a5febe81fb53a679800f8c6cd802c847
1 parent 822769f commit 2bacd4e

File tree

8 files changed

+473
-166
lines changed

8 files changed

+473
-166
lines changed

ext/opcache/jit/ir/ir.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1730,7 +1730,7 @@ static ir_ref ir_find_aliasing_load(ir_ctx *ctx, ir_ref ref, ir_type type, ir_re
17301730
}
17311731
} else if (insn->op == IR_RSTORE) {
17321732
modified_regset |= (1 << insn->op3);
1733-
} else if (insn->op >= IR_START || insn->op == IR_CALL) {
1733+
} else if (insn->op >= IR_START || insn->op == IR_CALL || insn->op == IR_VSTORE) {
17341734
return IR_UNUSED;
17351735
}
17361736
ref = insn->op1;

ext/opcache/jit/ir/ir_aarch64.dasc

Lines changed: 174 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,13 @@ static bool aarch64_may_encode_logical_imm(uint64_t value, uint32_t type_size)
9494
return 0;
9595
}
9696

97+
static bool aarch64_may_encode_imm7_addr_offset(const int64_t offset, uint32_t type_size)
98+
{
99+
return (uintptr_t)(offset) % type_size == 0
100+
&& offset < 63 * (int32_t)type_size
101+
&& offset >= -64 * (int32_t)type_size;
102+
}
103+
97104
static bool aarch64_may_encode_addr_offset(int64_t offset, uint32_t type_size)
98105
{
99106
return (uintptr_t)(offset) % type_size == 0 && (uintptr_t)(offset) < 0xfff * type_size;
@@ -352,7 +359,20 @@ int ir_get_target_constraints(const ir_ctx *ctx, ir_ref ref, ir_target_constrain
352359
constraints->tmp_regs[n] = IR_TMP_REG(1, insn->type, IR_LOAD_SUB_REF, IR_DEF_SUB_REF);
353360
n++;
354361
}
355-
if (rule == IR_SHIFT && insn->op == IR_ROL) {
362+
if (rule == IR_SHIFT_CONST
363+
&& (insn->op == IR_ROL || insn->op == IR_ROR)
364+
&& ir_type_size[insn->type] < 4) {
365+
constraints->tmp_regs[n] = IR_TMP_REG(3, insn->type, IR_LOAD_SUB_REF, IR_DEF_SUB_REF);
366+
n++;
367+
} else if (rule == IR_SHIFT
368+
&& (insn->op == IR_ROL || insn->op == IR_ROR)
369+
&& ir_type_size[insn->type] < 4) {
370+
if (insn->op == IR_ROL) {
371+
flags |= IR_DEF_CONFLICTS_WITH_INPUT_REGS;
372+
}
373+
constraints->tmp_regs[n] = IR_TMP_REG(3, insn->type, IR_LOAD_SUB_REF, IR_SAVE_SUB_REF);
374+
n++;
375+
} else if (rule == IR_SHIFT && insn->op == IR_ROL) {
356376
constraints->tmp_regs[n] = IR_TMP_REG(3, insn->type, IR_LOAD_SUB_REF, IR_DEF_SUB_REF);
357377
n++;
358378
}
@@ -1341,9 +1361,16 @@ static void ir_emit_prologue(ir_ctx *ctx)
13411361
{
13421362
ir_backend_data *data = ctx->data;
13431363
dasm_State **Dst = &data->dasm_state;
1364+
int offset;
13441365

13451366
if (ctx->flags & IR_USE_FRAME_POINTER) {
1346-
| stp x29, x30, [sp, # (-(ctx->stack_frame_size+16))]!
1367+
offset = -(ctx->stack_frame_size+16);
1368+
if (aarch64_may_encode_imm7_addr_offset(offset, 8)) {
1369+
| stp x29, x30, [sp, #offset]!
1370+
} else {
1371+
| sub sp, sp, #(ctx->stack_frame_size+16)
1372+
| stp x29, x30, [sp]
1373+
}
13471374
| mov x29, sp
13481375
if (ctx->call_stack_size) {
13491376
| sub sp, sp, #(ctx->call_stack_size)
@@ -1357,7 +1384,6 @@ static void ir_emit_prologue(ir_ctx *ctx)
13571384
}
13581385
if (ctx->used_preserved_regs) {
13591386
ir_reg fp;
1360-
int offset;
13611387
uint32_t i;
13621388
ir_reg prev = IR_REG_NONE;
13631389
ir_regset used_preserved_regs = (ir_regset)ctx->used_preserved_regs;
@@ -1375,7 +1401,13 @@ static void ir_emit_prologue(ir_ctx *ctx)
13751401
prev = i;
13761402
} else if (i < IR_REG_FP_FIRST) {
13771403
offset -= sizeof(void*) * 2;
1378-
| stp Rx(prev), Rx(i), [Rx(fp), #offset]
1404+
if (aarch64_may_encode_imm7_addr_offset(offset, 8)) {
1405+
| stp Rx(prev), Rx(i), [Rx(fp), #offset]
1406+
} else {
1407+
IR_ASSERT(aarch64_may_encode_addr_offset(offset, 8));
1408+
| str Rx(prev), [Rx(fp), #offset]
1409+
| str Rx(i), [Rx(fp), #(offset+8)]
1410+
}
13791411
prev = IR_REG_NONE;
13801412
} else {
13811413
if (prev < IR_REG_FP_FIRST) {
@@ -1385,7 +1417,13 @@ static void ir_emit_prologue(ir_ctx *ctx)
13851417
| str Rd(i-IR_REG_FP_FIRST), [Rx(fp), #offset]
13861418
} else {
13871419
offset -= sizeof(void*) * 2;
1388-
| stp Rd(prev-IR_REG_FP_FIRST), Rd(i-IR_REG_FP_FIRST), [Rx(fp), #offset]
1420+
if (aarch64_may_encode_imm7_addr_offset(offset, 8)) {
1421+
| stp Rd(prev-IR_REG_FP_FIRST), Rd(i-IR_REG_FP_FIRST), [Rx(fp), #offset]
1422+
} else {
1423+
IR_ASSERT(aarch64_may_encode_addr_offset(offset, 8));
1424+
| str Rd(prev-IR_REG_FP_FIRST), [Rx(fp), #offset]
1425+
| str Rd(i-IR_REG_FP_FIRST), [Rx(fp), #(offset+8)]
1426+
}
13891427
}
13901428
prev = IR_REG_NONE;
13911429
}
@@ -1425,7 +1463,13 @@ static void ir_emit_prologue(ir_ctx *ctx)
14251463
offset += sizeof(void*) * ctx->gp_reg_params;
14261464
for (i = ctx->gp_reg_params; i < IR_REG_INT_ARGS; i++) {
14271465
if (prev != IR_REG_NONE) {
1428-
| stp Rx(prev), Rx(int_reg_params[i]), [Rx(fp), #offset]
1466+
if (aarch64_may_encode_imm7_addr_offset(offset, 8)) {
1467+
| stp Rx(prev), Rx(int_reg_params[i]), [Rx(fp), #offset]
1468+
} else {
1469+
IR_ASSERT(aarch64_may_encode_addr_offset(offset, 8));
1470+
| str Rx(prev), [Rx(fp), #offset]
1471+
| str Rx(int_reg_params[i]), [Rx(fp), #(offset+8)]
1472+
}
14291473
prev = IR_REG_NONE;
14301474
offset += sizeof(void*) * 2;
14311475
} else {
@@ -1473,7 +1517,13 @@ static void ir_emit_epilogue(ir_ctx *ctx)
14731517
prev = i;
14741518
} else if (i < IR_REG_FP_FIRST) {
14751519
offset -= sizeof(void*) * 2;
1476-
| ldp Rx(prev), Rx(i), [Rx(fp), #offset]
1520+
if (aarch64_may_encode_imm7_addr_offset(offset, 8)) {
1521+
| ldp Rx(prev), Rx(i), [Rx(fp), #offset]
1522+
} else {
1523+
IR_ASSERT(aarch64_may_encode_addr_offset(offset, 8));
1524+
| ldr Rx(prev), [Rx(fp), #offset]
1525+
| ldr Rx(i), [Rx(fp), #(offset+8)]
1526+
}
14771527
prev = IR_REG_NONE;
14781528
} else {
14791529
if (prev < IR_REG_FP_FIRST) {
@@ -1483,7 +1533,13 @@ static void ir_emit_epilogue(ir_ctx *ctx)
14831533
| ldr Rd(i-IR_REG_FP_FIRST), [Rx(fp), #offset]
14841534
} else {
14851535
offset -= sizeof(void*) * 2;
1486-
| ldp Rd(prev-IR_REG_FP_FIRST), Rd(i-IR_REG_FP_FIRST), [Rx(fp), #offset]
1536+
if (aarch64_may_encode_imm7_addr_offset(offset, 8)) {
1537+
| ldp Rd(prev-IR_REG_FP_FIRST), Rd(i-IR_REG_FP_FIRST), [Rx(fp), #offset]
1538+
} else {
1539+
IR_ASSERT(aarch64_may_encode_addr_offset(offset, 8));
1540+
| ldr Rd(prev-IR_REG_FP_FIRST), [Rx(fp), #offset]
1541+
| ldr Rd(i-IR_REG_FP_FIRST), [Rx(fp), #(offset+8)]
1542+
}
14871543
}
14881544
prev = IR_REG_NONE;
14891545
}
@@ -1504,7 +1560,12 @@ static void ir_emit_epilogue(ir_ctx *ctx)
15041560
if (ctx->call_stack_size || (ctx->flags2 & IR_HAS_ALLOCA)) {
15051561
| mov sp, x29
15061562
}
1507-
| ldp x29, x30, [sp], # (ctx->stack_frame_size+16)
1563+
if (aarch64_may_encode_imm7_addr_offset(ctx->stack_frame_size+16, 8)) {
1564+
| ldp x29, x30, [sp], #(ctx->stack_frame_size+16)
1565+
} else {
1566+
| ldp x29, x30, [sp]
1567+
| add sp, sp, #(ctx->stack_frame_size+16)
1568+
}
15081569
} else if (ctx->stack_frame_size + ctx->call_stack_size) {
15091570
if (ctx->fixed_stack_red_zone) {
15101571
IR_ASSERT(ctx->stack_frame_size + ctx->call_stack_size <= ctx->fixed_stack_red_zone);
@@ -1922,18 +1983,55 @@ static void ir_emit_shift(ir_ctx *ctx, ir_ref def, ir_insn *insn)
19221983
default:
19231984
IR_ASSERT(0);
19241985
case IR_SHL:
1925-
| ASM_REG_REG_REG_OP lsl, type, def_reg, op1_reg, op2_reg
1986+
if (ir_type_size[type] == 1) {
1987+
| and Rw(def_reg), Rw(op1_reg), #0xff
1988+
| lsl Rw(def_reg), Rw(def_reg), Rw(op2_reg)
1989+
} else if (ir_type_size[type] == 2) {
1990+
| and Rw(def_reg), Rw(op1_reg), #0xffff
1991+
| lsl Rw(def_reg), Rw(def_reg), Rw(op2_reg)
1992+
} else {
1993+
| ASM_REG_REG_REG_OP lsl, type, def_reg, op1_reg, op2_reg
1994+
}
19261995
break;
19271996
case IR_SHR:
1928-
| ASM_REG_REG_REG_OP lsr, type, def_reg, op1_reg, op2_reg
1997+
if (ir_type_size[type] == 1) {
1998+
| and Rw(def_reg), Rw(op1_reg), #0xff
1999+
| lsr Rw(def_reg), Rw(def_reg), Rw(op2_reg)
2000+
} else if (ir_type_size[type] == 2) {
2001+
| and Rw(def_reg), Rw(op1_reg), #0xffff
2002+
| lsr Rw(def_reg), Rw(def_reg), Rw(op2_reg)
2003+
} else {
2004+
| ASM_REG_REG_REG_OP lsr, type, def_reg, op1_reg, op2_reg
2005+
}
19292006
break;
19302007
case IR_SAR:
1931-
| ASM_REG_REG_REG_OP asr, type, def_reg, op1_reg, op2_reg
2008+
if (ir_type_size[type] == 1) {
2009+
| sxtb Rw(def_reg), Rw(op1_reg)
2010+
| asr Rw(def_reg), Rw(def_reg), Rw(op2_reg)
2011+
} else if (ir_type_size[type] == 2) {
2012+
| sxth Rw(def_reg), Rw(op1_reg)
2013+
| asr Rw(def_reg), Rw(def_reg), Rw(op2_reg)
2014+
} else {
2015+
| ASM_REG_REG_REG_OP asr, type, def_reg, op1_reg, op2_reg
2016+
}
19322017
break;
19332018
case IR_ROL:
19342019
tmp_reg = ctx->regs[def][3];
19352020
IR_ASSERT(tmp_reg != IR_REG_NONE);
1936-
if (ir_type_size[type] == 8) {
2021+
if (ir_type_size[type] == 1) {
2022+
| and Rw(def_reg), Rw(op1_reg), #0xff
2023+
| add Rw(def_reg), Rw(def_reg), Rw(def_reg), lsl #8
2024+
| add Rw(def_reg), Rw(def_reg), Rw(def_reg), lsl #16
2025+
| neg Rw(tmp_reg), Rw(op2_reg)
2026+
| ror Rw(def_reg), Rw(def_reg), Rw(tmp_reg)
2027+
| and Rw(def_reg), Rw(def_reg), #0xff
2028+
} else if (ir_type_size[type] == 2) {
2029+
| and Rw(def_reg), Rw(op1_reg), #0xffff
2030+
| add Rw(def_reg), Rw(def_reg), Rw(def_reg), lsl #16
2031+
| neg Rw(tmp_reg), Rw(op2_reg)
2032+
| ror Rw(def_reg), Rw(def_reg), Rw(tmp_reg)
2033+
| and Rw(def_reg), Rw(def_reg), #0xffff
2034+
} else if (ir_type_size[type] == 8) {
19372035
| neg Rx(tmp_reg), Rx(op2_reg)
19382036
| ror Rx(def_reg), Rx(op1_reg), Rx(tmp_reg)
19392037
} else {
@@ -1942,7 +2040,24 @@ static void ir_emit_shift(ir_ctx *ctx, ir_ref def, ir_insn *insn)
19422040
}
19432041
break;
19442042
case IR_ROR:
1945-
| ASM_REG_REG_REG_OP ror, type, def_reg, op1_reg, op2_reg
2043+
if (ir_type_size[type] == 1) {
2044+
tmp_reg = ctx->regs[def][3];
2045+
IR_ASSERT(tmp_reg != IR_REG_NONE);
2046+
| and Rw(tmp_reg), Rw(op1_reg), #0xff
2047+
| add Rw(tmp_reg), Rw(tmp_reg), Rw(tmp_reg), lsl #8
2048+
| add Rw(tmp_reg), Rw(tmp_reg), Rw(tmp_reg), lsl #16
2049+
| ror Rw(def_reg), Rw(tmp_reg), Rw(op2_reg)
2050+
| and Rw(def_reg), Rw(def_reg), #0xff
2051+
} else if (ir_type_size[type] == 2) {
2052+
tmp_reg = ctx->regs[def][3];
2053+
IR_ASSERT(tmp_reg != IR_REG_NONE);
2054+
| and Rw(tmp_reg), Rw(op1_reg), #0xffff
2055+
| add Rw(tmp_reg), Rw(tmp_reg), Rw(tmp_reg), lsl #16
2056+
| ror Rw(def_reg), Rw(tmp_reg), Rw(op2_reg)
2057+
| and Rw(def_reg), Rw(def_reg), #0xffff
2058+
} else {
2059+
| ASM_REG_REG_REG_OP ror, type, def_reg, op1_reg, op2_reg
2060+
}
19462061
break;
19472062
}
19482063
if (IR_REG_SPILLED(ctx->regs[def][0])) {
@@ -1959,6 +2074,7 @@ static void ir_emit_shift_const(ir_ctx *ctx, ir_ref def, ir_insn *insn)
19592074
ir_ref op1 = insn->op1;
19602075
ir_reg def_reg = IR_REG_NUM(ctx->regs[def][0]);
19612076
ir_reg op1_reg = ctx->regs[def][1];
2077+
ir_reg tmp_reg;
19622078

19632079
IR_ASSERT(IR_IS_CONST_REF(insn->op2));
19642080
IR_ASSERT(!IR_IS_SYM_CONST(ctx->ir_base[insn->op2].op));
@@ -1972,16 +2088,42 @@ static void ir_emit_shift_const(ir_ctx *ctx, ir_ref def, ir_insn *insn)
19722088
default:
19732089
IR_ASSERT(0);
19742090
case IR_SHL:
1975-
| ASM_REG_REG_IMM_OP lsl, type, def_reg, op1_reg, shift
2091+
if (ir_type_size[type] == 1) {
2092+
| ubfiz Rw(def_reg), Rw(op1_reg), #shift, #(8-shift)
2093+
} else if (ir_type_size[type] == 2) {
2094+
| ubfiz Rw(def_reg), Rw(op1_reg), #shift, #(16-shift)
2095+
} else {
2096+
| ASM_REG_REG_IMM_OP lsl, type, def_reg, op1_reg, shift
2097+
}
19762098
break;
19772099
case IR_SHR:
1978-
| ASM_REG_REG_IMM_OP lsr, type, def_reg, op1_reg, shift
2100+
if (ir_type_size[type] == 1) {
2101+
| ubfx Rw(def_reg), Rw(op1_reg), #shift, #(8-shift)
2102+
} else if (ir_type_size[type] == 2) {
2103+
| ubfx Rw(def_reg), Rw(op1_reg), #shift, #(16-shift)
2104+
} else {
2105+
| ASM_REG_REG_IMM_OP lsr, type, def_reg, op1_reg, shift
2106+
}
19792107
break;
19802108
case IR_SAR:
1981-
| ASM_REG_REG_IMM_OP asr, type, def_reg, op1_reg, shift
2109+
if (ir_type_size[type] == 1) {
2110+
| sbfx Rw(def_reg), Rw(op1_reg), #shift, #(8-shift)
2111+
} else if (ir_type_size[type] == 2) {
2112+
| sbfx Rw(def_reg), Rw(op1_reg), #shift, #(16-shift)
2113+
} else {
2114+
| ASM_REG_REG_IMM_OP asr, type, def_reg, op1_reg, shift
2115+
}
19822116
break;
19832117
case IR_ROL:
1984-
if (ir_type_size[type] == 8) {
2118+
if (ir_type_size[type] == 1) {
2119+
tmp_reg = ctx->regs[def][3];
2120+
| ubfx Rw(tmp_reg), Rw(op1_reg), #(8-shift), #shift
2121+
| orr Rw(def_reg), Rw(tmp_reg), Rw(op1_reg), lsl #shift
2122+
} else if (ir_type_size[type] == 2) {
2123+
tmp_reg = ctx->regs[def][3];
2124+
| ubfx Rw(tmp_reg), Rw(op1_reg), #(16-shift), #shift
2125+
| orr Rw(def_reg), Rw(tmp_reg), Rw(op1_reg), lsl #shift
2126+
} else if (ir_type_size[type] == 8) {
19852127
shift = (64 - shift) % 64;
19862128
| ror Rx(def_reg), Rx(op1_reg), #shift
19872129
} else {
@@ -1990,7 +2132,17 @@ static void ir_emit_shift_const(ir_ctx *ctx, ir_ref def, ir_insn *insn)
19902132
}
19912133
break;
19922134
case IR_ROR:
1993-
| ASM_REG_REG_IMM_OP ror, type, def_reg, op1_reg, shift
2135+
if (ir_type_size[type] == 1) {
2136+
tmp_reg = ctx->regs[def][3];
2137+
| ubfx Rw(tmp_reg), Rw(op1_reg), #shift, #(8-shift)
2138+
| orr Rw(def_reg), Rw(tmp_reg), Rw(op1_reg), lsl #(8-shift)
2139+
} else if (ir_type_size[type] == 2) {
2140+
tmp_reg = ctx->regs[def][3];
2141+
| ubfx Rw(tmp_reg), Rw(op1_reg), #shift, #(16-shift)
2142+
| orr Rw(def_reg), Rw(tmp_reg), Rw(op1_reg), lsl #(16-shift)
2143+
} else {
2144+
| ASM_REG_REG_IMM_OP ror, type, def_reg, op1_reg, shift
2145+
}
19942146
break;
19952147
}
19962148
if (IR_REG_SPILLED(ctx->regs[def][0])) {
@@ -3653,7 +3805,7 @@ static void ir_emit_alloca(ir_ctx *ctx, ir_ref def, ir_insn *insn)
36533805

36543806
IR_ASSERT(IR_IS_TYPE_INT(val->type));
36553807
IR_ASSERT(!IR_IS_SYM_CONST(val->op));
3656-
IR_ASSERT(IR_IS_TYPE_UNSIGNED(val->type) || val->val.i64 > 0);
3808+
IR_ASSERT(IR_IS_TYPE_UNSIGNED(val->type) || val->val.i64 >= 0);
36573809

36583810
if (ctx->flags2 & IR_HAS_CALLS) {
36593811
/* Stack must be 16 byte aligned */
@@ -4971,7 +5123,7 @@ static void ir_emit_load_params(ir_ctx *ctx)
49715123
if (ctx->flags & IR_USE_FRAME_POINTER) {
49725124
stack_offset = sizeof(void*) * 2; /* skip old frame pointer and return address */
49735125
} else {
4974-
stack_offset = sizeof(void*) + ctx->stack_frame_size + ctx->call_stack_size; /* skip return address */
5126+
stack_offset = ctx->stack_frame_size + ctx->call_stack_size;
49755127
}
49765128
n = use_list->count;
49775129
for (i = 0, p = &ctx->use_edges[use_list->refs]; i < n; i++, p++) {
@@ -5079,8 +5231,7 @@ static void ir_fix_param_spills(ir_ctx *ctx)
50795231
/* skip old frame pointer and return address */
50805232
stack_offset = sizeof(void*) * 2 + (ctx->stack_frame_size - ctx->stack_frame_alignment);
50815233
} else {
5082-
/* skip return address */
5083-
stack_offset = sizeof(void*) + ctx->stack_frame_size;
5234+
stack_offset = ctx->stack_frame_size;
50845235
}
50855236
n = use_list->count;
50865237
for (i = 0, p = &ctx->use_edges[use_list->refs]; i < n; i++, p++) {

0 commit comments

Comments
 (0)