Skip to content

Commit c0a0612

Browse files
committed
Initial aarch64 support
1 parent 01dfb80 commit c0a0612

File tree

4 files changed

+123
-11
lines changed

4 files changed

+123
-11
lines changed

ext/opcache/jit/ir/ir_aarch64.dasc

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -262,6 +262,34 @@ static const int8_t _ir_fp_reg_params[IR_REG_FP_ARGS] = {
262262
IR_REG_FP_ARG8,
263263
};
264264

265+
#ifdef IR_HAVE_PRESERVE_NONE
266+
static const int8_t _ir_int_pn_reg_params[IR_REG_INT_PNARGS] = {
267+
IR_REG_INT_PNARG1,
268+
IR_REG_INT_PNARG2,
269+
IR_REG_INT_PNARG3,
270+
IR_REG_INT_PNARG4,
271+
IR_REG_INT_PNARG5,
272+
IR_REG_INT_PNARG6,
273+
IR_REG_INT_PNARG7,
274+
IR_REG_INT_PNARG8,
275+
IR_REG_INT_PNARG9,
276+
IR_REG_INT_PNARG10,
277+
IR_REG_INT_PNARG11,
278+
IR_REG_INT_PNARG12,
279+
IR_REG_INT_PNARG13,
280+
IR_REG_INT_PNARG14,
281+
IR_REG_INT_PNARG15,
282+
IR_REG_INT_PNARG16,
283+
IR_REG_INT_PNARG17,
284+
IR_REG_INT_PNARG18,
285+
IR_REG_INT_PNARG19,
286+
IR_REG_INT_PNARG20,
287+
IR_REG_INT_PNARG21,
288+
IR_REG_INT_PNARG22,
289+
IR_REG_INT_PNARG23,
290+
};
291+
#endif
292+
265293
const char *ir_reg_name(int8_t reg, ir_type type)
266294
{
267295
if (reg >= IR_REG_NUM) {
@@ -1054,6 +1082,9 @@ binop_fp:
10541082
}
10551083
return insn->op;
10561084
case IR_VA_START:
1085+
#ifdef IR_HAVE_PRESERVE_NONE
1086+
IR_ASSERT(!(ctx->flags & IR_PRESERVE_NONE_FUNC) && "preserve_none does not support var args");
1087+
#endif
10571088
ctx->flags2 |= IR_HAS_VA_START;
10581089
if ((ctx->ir_base[insn->op2].op == IR_ALLOCA) || (ctx->ir_base[insn->op2].op == IR_VADDR)) {
10591090
ir_use_list *use_list = &ctx->use_lists[insn->op2];
@@ -4637,6 +4668,12 @@ static int32_t ir_call_used_stack(ir_ctx *ctx, ir_insn *insn)
46374668
int last_named_input = (proto && (proto->flags & IR_VARARG_FUNC)) ? proto->params_count + 2 : insn->inputs_count;
46384669
#endif
46394670

4671+
#ifdef IR_HAVE_PRESERVE_NONE
4672+
if (ir_is_preserve_none(ctx, insn)) {
4673+
int_reg_params_count = IR_REG_INT_PNARGS;
4674+
}
4675+
#endif
4676+
46404677
n = insn->inputs_count;
46414678
for (j = 3; j <= n; j++) {
46424679
type = ctx->ir_base[ir_insn_op(insn, j)].type;
@@ -4693,6 +4730,13 @@ static int32_t ir_emit_arguments(ir_ctx *ctx, ir_ref def, ir_insn *insn, ir_reg
46934730
tmp_reg = IR_REG_IP0;
46944731
}
46954732

4733+
#ifdef IR_HAVE_PRESERVE_NONE
4734+
if (ir_is_preserve_none(ctx, insn)) {
4735+
int_reg_params_count = IR_REG_INT_PNARGS;
4736+
int_reg_params = _ir_int_pn_reg_params;
4737+
}
4738+
#endif
4739+
46964740
if (insn->op == IR_CALL && (ctx->flags & IR_PREALLOCATED_STACK)) {
46974741
// TODO: support for preallocated stack
46984742
used_stack = 0;
@@ -5397,6 +5441,13 @@ static void ir_emit_load_params(ir_ctx *ctx)
53975441
const int8_t *fp_reg_params = _ir_fp_reg_params;
53985442
int32_t stack_offset = 0;
53995443

5444+
#ifdef IR_HAVE_PRESERVE_NONE
5445+
if (ctx->flags & IR_PRESERVE_NONE_FUNC) {
5446+
int_reg_params_count = IR_REG_INT_PNARGS;
5447+
int_reg_params = _ir_int_pn_reg_params;
5448+
}
5449+
#endif
5450+
54005451
if (ctx->flags & IR_USE_FRAME_POINTER) {
54015452
stack_offset = sizeof(void*) * 2; /* skip old frame pointer and return address */
54025453
} else {
@@ -5506,6 +5557,13 @@ static void ir_fix_param_spills(ir_ctx *ctx)
55065557
int32_t stack_offset = 0;
55075558
int32_t param_stack_size = 0;
55085559

5560+
#ifdef HAVE_PRESERVE_NONE
5561+
if (ctx->flags & IR_PRESERVE_NONE_FUNC) {
5562+
int_reg_params_count = IR_REG_INT_PNARGS;
5563+
int_reg_params = _ir_int_pn_reg_params;
5564+
}
5565+
#endif
5566+
55095567
if (ctx->flags & IR_USE_FRAME_POINTER) {
55105568
/* skip old frame pointer and return address */
55115569
stack_offset = sizeof(void*) * 2 + (ctx->stack_frame_size - ctx->stack_frame_alignment);

ext/opcache/jit/ir/ir_aarch64.h

Lines changed: 35 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -146,7 +146,6 @@ enum _ir_reg {
146146
#define IR_REG_FP_ARG6 IR_REG_V5
147147
#define IR_REG_FP_ARG7 IR_REG_V6
148148
#define IR_REG_FP_ARG8 IR_REG_V7
149-
#define IR_MAX_REG_ARGS 16
150149
#define IR_SHADOW_ARGS 0
151150

152151
# define IR_REGSET_SCRATCH \
@@ -158,6 +157,41 @@ enum _ir_reg {
158157
(IR_REGSET_INTERVAL(IR_REG_X19, IR_REG_X30) \
159158
| IR_REGSET_INTERVAL(IR_REG_V8, IR_REG_V15))
160159

160+
#if __has_attribute(preserve_none)
161+
162+
# define IR_HAVE_PRESERVE_NONE 1
163+
164+
/* https://github.com/llvm/llvm-project/blob/68bfe91b5a34f80dbcc4f0a7fa5d7aa1cdf959c2/llvm/lib/Target/AArch64/AArch64CallingConvention.td#L541 */
165+
# define IR_REG_INT_PNARGS 23
166+
# define IR_REG_INT_PNARG1 IR_REG_X20
167+
# define IR_REG_INT_PNARG2 IR_REG_X21
168+
# define IR_REG_INT_PNARG3 IR_REG_X22
169+
# define IR_REG_INT_PNARG4 IR_REG_X23
170+
# define IR_REG_INT_PNARG5 IR_REG_X24
171+
# define IR_REG_INT_PNARG6 IR_REG_X25
172+
# define IR_REG_INT_PNARG7 IR_REG_X26
173+
# define IR_REG_INT_PNARG8 IR_REG_X27
174+
# define IR_REG_INT_PNARG9 IR_REG_X28
175+
# define IR_REG_INT_PNARG10 IR_REG_X0
176+
# define IR_REG_INT_PNARG11 IR_REG_X1
177+
# define IR_REG_INT_PNARG12 IR_REG_X2
178+
# define IR_REG_INT_PNARG13 IR_REG_X3
179+
# define IR_REG_INT_PNARG14 IR_REG_X4
180+
# define IR_REG_INT_PNARG15 IR_REG_X5
181+
# define IR_REG_INT_PNARG16 IR_REG_X6
182+
# define IR_REG_INT_PNARG17 IR_REG_X7
183+
# define IR_REG_INT_PNARG18 IR_REG_X10
184+
# define IR_REG_INT_PNARG19 IR_REG_X11
185+
# define IR_REG_INT_PNARG20 IR_REG_X12
186+
# define IR_REG_INT_PNARG21 IR_REG_X13
187+
# define IR_REG_INT_PNARG22 IR_REG_X14
188+
# define IR_REG_INT_PNARG23 IR_REG_X9
189+
190+
# define IR_MAX_REG_ARGS 31 /* IR_REG_INT_PNARGS + IR_REG_FP_ARGS */
191+
#else /* !preserve_none */
192+
# define IR_MAX_REG_ARGS 16 /* IR_REG_INT_ARGS + IR_REG_FP_ARGS */
193+
#endif
194+
161195
#ifndef __APPLE__
162196
typedef struct _ir_va_list {
163197
void *stack;

ext/opcache/jit/ir/ir_x86.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -183,7 +183,7 @@ enum _ir_reg {
183183
# define IR_HAVE_PRESERVE_NONE 1
184184

185185
/* https://github.com/llvm/llvm-project/blob/68bfe91b5a34f80dbcc4f0a7fa5d7aa1cdf959c2/llvm/lib/Target/X86/X86CallingConv.td#L1029 */
186-
# define IR_REG_INT_PNARGS 12
186+
# define IR_REG_INT_PNARGS 12
187187
# define IR_REG_INT_PNARG1 IR_REG_R12
188188
# define IR_REG_INT_PNARG2 IR_REG_R13
189189
# define IR_REG_INT_PNARG3 IR_REG_R14

ext/opcache/jit/zend_jit_ir.c

Lines changed: 29 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -26,13 +26,15 @@
2626
# define ZREG_IP 7 /* IR_REG_RDI */
2727
# define ZREG_FIRST_FPR 8
2828
# define IR_REGSET_PRESERVED ((1<<3) | (1<<5) | (1<<6) | (1<<7)) /* all preserved registers */
29+
# if ZEND_VM_TAIL_CALL_DISPATCH
30+
# error
31+
# endif
2932
#elif defined(IR_TARGET_X64)
3033
# define IR_REG_SP 4 /* IR_REG_RSP */
3134
# define IR_REG_FP 5 /* IR_REG_RBP */
3235
# if ZEND_VM_TAIL_CALL_DISPATCH
33-
/* Args 1 and 2 in preserve_none:
36+
/* Use preserve_none first two arg registers for FP/IP
3437
* https://github.com/llvm/llvm-project/blob/68bfe91b5a34f80dbcc4f0a7fa5d7aa1cdf959c2/llvm/lib/Target/X86/X86CallingConv.td#L1029
35-
* TODO: other archs
3638
*/
3739
# define ZREG_FP 12 /* IR_REG_R12 */
3840
# define ZREG_IP 13 /* IR_REG_R13 */
@@ -41,9 +43,7 @@
4143
# define ZREG_IP 15 /* IR_REG_R15 */
4244
# endif
4345
# define ZREG_FIRST_FPR 16
44-
# if ZEND_VM_TAIL_CALL_DISPATCH
45-
# define IR_REGSET_PRESERVED 0
46-
# elif defined(_WIN64)
46+
# if defined(_WIN64)
4747
# define IR_REGSET_PRESERVED ((1<<3) | (1<<5) | (1<<6) | (1<<7) | (1<<12) | (1<<13) | (1<<14) | (1<<15))
4848
/*
4949
# define IR_REGSET_PRESERVED ((1<<3) | (1<<5) | (1<<6) | (1<<7) | (1<<12) | (1<<13) | (1<<14) | (1<<15) | \
@@ -56,9 +56,18 @@
5656
# endif
5757
#elif defined(IR_TARGET_AARCH64)
5858
# define IR_REG_SP 31 /* IR_REG_RSP */
59+
# define IR_REG_LR 30 /* IR_REG_X30 */
5960
# define IR_REG_FP 29 /* IR_REG_X29 */
60-
# define ZREG_FP 27 /* IR_REG_X27 */
61-
# define ZREG_IP 28 /* IR_REG_X28 */
61+
# if ZEND_VM_TAIL_CALL_DISPATCH
62+
/* Use preserve_none first two arg registers for FP/IP
63+
* https://github.com/llvm/llvm-project/blob/68bfe91b5a34f80dbcc4f0a7fa5d7aa1cdf959c2/llvm/lib/Target/AArch64/AArch64CallingConvention.td#L541
64+
*/
65+
# define ZREG_FP 20 /* IR_REG_X20 */
66+
# define ZREG_IP 21 /* IR_REG_X21 */
67+
# else
68+
# define ZREG_FP 27 /* IR_REG_X27 */
69+
# define ZREG_IP 28 /* IR_REG_X28 */
70+
# endif
6271
# define ZREG_FIRST_FPR 32
6372
# define IR_REGSET_PRESERVED ((1<<19) | (1<<20) | (1<<21) | (1<<22) | (1<<23) | \
6473
(1<<24) | (1<<25) | (1<<26) | (1<<27) | (1<<28)) /* all preserved registers */
@@ -2738,11 +2747,22 @@ static void zend_jit_init_ctx(zend_jit_ctx *jit, uint32_t flags)
27382747
if (GCC_GLOBAL_REGS) {
27392748
jit->ctx.fixed_save_regset = IR_REGSET_PRESERVED & ~((1<<ZREG_FP) | (1<<ZREG_IP));
27402749
} else if (ZEND_VM_TAIL_CALL_DISPATCH) {
2741-
/* The only preserved register is RBP:
2750+
/* The only preserved register on x86 is RBP:
27422751
* https://github.com/llvm/llvm-project/blob/a414877a7a5f000d01370acb1162eb1dea87f48c/llvm/lib/Target/X86/X86RegisterInfo.cpp#L319
27432752
* https://github.com/llvm/llvm-project/blob/68bfe91b5a34f80dbcc4f0a7fa5d7aa1cdf959c2/llvm/lib/Target/X86/X86CallingConv.td#L1183
2753+
* On AArch64 it's LR, FP:
2754+
* https://github.com/llvm/llvm-project/blob/68bfe91b5a34f80dbcc4f0a7fa5d7aa1cdf959c2/llvm/lib/Target/AArch64/AArch64CallingConvention.td#L681
2755+
*
2756+
* Add them to the fixed_regset to prevent usage or these regs.
2757+
* It's cheaper to not use them than to save them.
27442758
*/
2745-
jit->ctx.fixed_regset |= (1<<5);
2759+
#if defined(IR_TARGET_X64)
2760+
jit->ctx.fixed_regset |= (1<<IR_REG_FP);
2761+
#elif defined(IR_TARGET_AARCH64)
2762+
jit->ctx.fixed_regset |= (1<<IR_REG_FP) | (1<<IR_REG_LR);
2763+
#else
2764+
# error
2765+
#endif
27462766
} else {
27472767
jit->ctx.fixed_save_regset = IR_REGSET_PRESERVED;
27482768
//#ifdef _WIN64

0 commit comments

Comments
 (0)