19
19
#include "jit/ir/ir.h"
20
20
21
21
#if defined(IR_TARGET_X86)
22
- # define IR_REG_SP 4 /* IR_REG_RSP */
23
- # define ZREG_FP 6 /* IR_REG_RSI */
24
- # define ZREG_IP 7 /* IR_REG_RDI */
25
- # define ZREG_FIRST_FPR 8
22
+ # define IR_REG_SP 4 /* IR_REG_RSP */
23
+ # define ZREG_FP 6 /* IR_REG_RSI */
24
+ # define ZREG_IP 7 /* IR_REG_RDI */
25
+ # define ZREG_FIRST_FPR 8
26
+ # define IR_REGSET_PRESERVED ((1<<3) | (1<<5) | (1<<6) | (1<<7)) /* all preserved registers */
26
27
#elif defined(IR_TARGET_X64)
27
- # define IR_REG_SP 4 /* IR_REG_RSP */
28
- # define ZREG_FP 14 /* IR_REG_R14 */
29
- # define ZREG_IP 15 /* IR_REG_R15 */
30
- # define ZREG_FIRST_FPR 16
28
+ # define IR_REG_SP 4 /* IR_REG_RSP */
29
+ # define ZREG_FP 14 /* IR_REG_R14 */
30
+ # define ZREG_IP 15 /* IR_REG_R15 */
31
+ # define ZREG_FIRST_FPR 16
32
+ # define IR_REGSET_PRESERVED ((1<<3) | (1<<5) | (1<<12) | (1<<13) | (1<<14) | (1<<15)) /* all preserved registers */
31
33
#elif defined(IR_TARGET_AARCH64)
32
- # define IR_REG_SP 31 /* IR_REG_RSP */
33
- # define ZREG_FP 27 /* IR_REG_X27 */
34
- # define ZREG_IP 28 /* IR_REG_X28 */
35
- # define ZREG_FIRST_FPR 32
34
+ # define IR_REG_SP 31 /* IR_REG_RSP */
35
+ # define ZREG_FP 27 /* IR_REG_X27 */
36
+ # define ZREG_IP 28 /* IR_REG_X28 */
37
+ # define ZREG_FIRST_FPR 32
38
+ # define IR_REGSET_PRESERVED ((1<<19) | (1<<20) | (1<<21) | (1<<22) | (1<<23) | (1<<24) | \
39
+ (1<<25) | (1<<26) | (1<<27) | (1<<29) | (1<<30)) /* all preserved registers */
36
40
#else
37
41
# error "Unknown IR target"
38
42
#endif
39
43
40
- #define ZREG_RX ZREG_IP
44
+ #define ZREG_RX ZREG_IP
45
+
46
+ #if defined(IR_TARGET_X86) || defined(IR_TARGET_X64)
47
+ # define IR_REGSET_PHP_FIXED ((1<<ZREG_FP) | (1<<ZREG_IP) | (1<<5)) /* prevent %rbp (%r5) usage */
48
+ #else
49
+ # define IR_REGSET_PHP_FIXED ((1<<ZREG_FP) | (1<<ZREG_IP))
50
+ #endif
41
51
42
52
#ifdef ZEND_ENABLE_ZVAL_LONG64
43
53
# define IR_PHP_LONG IR_I64
47
57
# define ir_const_php_long ir_const_i32
48
58
#endif
49
59
50
- #if defined(IR_TARGET_X86) || defined(IR_TARGET_X64)
51
- # define IR_REGSET_PHP_FIXED \
52
- ((1<<ZREG_FP) | (1<<ZREG_IP) | (1<<5)) /* prevent %rbp (%r5) usage */
53
- #else
54
- # define IR_REGSET_PHP_FIXED \
55
- ((1<<ZREG_FP) | (1<<ZREG_IP))
56
- #endif
57
-
58
60
static size_t zend_jit_trace_prologue_size = (size_t)-1;
59
61
static uint32_t allowed_opt_flags = 0;
60
62
static bool delayed_call_chain = 0; // TODO: remove this var (use jit->delayed_call_level) ???
@@ -1390,7 +1392,7 @@ static int zend_jit_set_ip(zend_jit_ctx *jit, const zend_op *target)
1390
1392
if (jit->last_valid_opline) {
1391
1393
zend_jit_use_last_valid_opline(jit);
1392
1394
if (jit->last_valid_opline != target) {
1393
- if (zend_jit_vm_kind == ZEND_VM_KIND_HYBRID ) {
1395
+ if (GCC_GLOBAL_REGS ) {
1394
1396
ref = zend_jit_ip(jit);
1395
1397
} else {
1396
1398
addr = zend_jit_ex_opline_addr(jit);
@@ -1403,14 +1405,14 @@ static int zend_jit_set_ip(zend_jit_ctx *jit, const zend_op *target)
1403
1405
ref = ir_fold2(&jit->ctx, IR_OPT(IR_SUB, IR_ADDR), ref,
1404
1406
zend_jit_const_addr(jit, (uintptr_t)jit->last_valid_opline - (uintptr_t)target));
1405
1407
}
1406
- if (zend_jit_vm_kind == ZEND_VM_KIND_HYBRID ) {
1408
+ if (GCC_GLOBAL_REGS ) {
1407
1409
zend_jit_store_ip(jit, ref);
1408
1410
} else {
1409
1411
zend_jit_store(jit, addr, ref);
1410
1412
}
1411
1413
}
1412
1414
} else {
1413
- if (zend_jit_vm_kind == ZEND_VM_KIND_HYBRID ) {
1415
+ if (GCC_GLOBAL_REGS ) {
1414
1416
zend_jit_store_ip(jit,
1415
1417
zend_jit_const_addr(jit, (uintptr_t)target));
1416
1418
} else {
@@ -2572,7 +2574,7 @@ static int zend_jit_interrupt_handler_stub(zend_jit_ctx *jit)
2572
2574
{
2573
2575
ir_ref ref, if_timeout, timeout_path, if_exception, exception_path;
2574
2576
2575
- if (zend_jit_vm_kind == ZEND_VM_KIND_HYBRID ) {
2577
+ if (GCC_GLOBAL_REGS ) {
2576
2578
// EX(opline) = opline
2577
2579
zend_jit_store(jit,
2578
2580
zend_jit_ex_opline_addr(jit),
@@ -2612,10 +2614,7 @@ static int zend_jit_interrupt_handler_stub(zend_jit_ctx *jit)
2612
2614
zend_jit_store_ip(jit, ref);
2613
2615
}
2614
2616
2615
- if (zend_jit_vm_kind == ZEND_VM_KIND_HYBRID) {
2616
- zend_jit_tailcall_0(jit,
2617
- zend_jit_load(jit, IR_ADDR, zend_jit_ip(jit)));
2618
- } else if (GCC_GLOBAL_REGS) {
2617
+ if (GCC_GLOBAL_REGS) {
2619
2618
zend_jit_tailcall_0(jit,
2620
2619
zend_jit_load(jit, IR_ADDR, zend_jit_ip(jit)));
2621
2620
} else {
@@ -2628,14 +2627,14 @@ static int zend_jit_leave_function_handler_stub(zend_jit_ctx *jit)
2628
2627
{
2629
2628
ir_ref call_info = zend_jit_load_at_offset(jit, IR_U32,
2630
2629
zend_jit_fp(jit), offsetof(zend_execute_data, This.u1.type_info));
2630
+ ir_ref if_top = zend_jit_if(jit,
2631
+ ir_fold2(&jit->ctx, IR_OPT(IR_AND, IR_U32),
2632
+ call_info,
2633
+ ir_const_u32(&jit->ctx, ZEND_CALL_TOP)));
2631
2634
2632
- if (zend_jit_vm_kind == ZEND_VM_KIND_HYBRID) {
2633
- ir_ref if_top = zend_jit_if(jit,
2634
- ir_fold2(&jit->ctx, IR_OPT(IR_AND, IR_U32),
2635
- call_info,
2636
- ir_const_u32(&jit->ctx, ZEND_CALL_TOP)));
2635
+ zend_jit_if_false(jit, if_top);
2637
2636
2638
- zend_jit_if_false(jit, if_top);
2637
+ if (zend_jit_vm_kind == ZEND_VM_KIND_HYBRID) {
2639
2638
zend_jit_call_1(jit, IR_VOID,
2640
2639
zend_jit_const_func_addr(jit, (uintptr_t)zend_jit_leave_nested_func_helper, IR_CONST_FASTCALL_FUNC),
2641
2640
call_info);
@@ -2644,26 +2643,30 @@ static int zend_jit_leave_function_handler_stub(zend_jit_ctx *jit)
2644
2643
zend_jit_ex_opline_addr(jit)));
2645
2644
zend_jit_tailcall_0(jit,
2646
2645
zend_jit_load(jit, IR_ADDR, zend_jit_ip(jit)));
2647
-
2648
- zend_jit_if_true(jit, if_top);
2649
- zend_jit_call_1(jit, IR_VOID,
2650
- zend_jit_const_func_addr(jit, (uintptr_t)zend_jit_leave_top_func_helper, IR_CONST_FASTCALL_FUNC),
2646
+ } else if (GCC_GLOBAL_REGS) {
2647
+ zend_jit_tailcall_1(jit,
2648
+ zend_jit_const_func_addr(jit, (uintptr_t)zend_jit_leave_nested_func_helper, IR_CONST_FASTCALL_FUNC),
2651
2649
call_info);
2652
- zend_jit_tailcall_0(jit,
2653
- zend_jit_load(jit, IR_ADDR, zend_jit_ip(jit)));
2654
2650
} else {
2655
- ir_ref if_top = zend_jit_if(jit,
2656
- ir_fold2(&jit->ctx, IR_OPT(IR_AND, IR_U32),
2657
- call_info,
2658
- ir_const_u32(&jit->ctx, ZEND_CALL_TOP)));
2659
-
2660
- zend_jit_if_false(jit, if_top);
2661
2651
zend_jit_tailcall_2(jit,
2662
2652
zend_jit_const_func_addr(jit, (uintptr_t)zend_jit_leave_nested_func_helper, IR_CONST_FASTCALL_FUNC),
2663
2653
call_info,
2664
2654
zend_jit_fp(jit));
2655
+ }
2656
+
2657
+ zend_jit_if_true(jit, if_top);
2665
2658
2666
- zend_jit_if_true(jit, if_top);
2659
+ if (zend_jit_vm_kind == ZEND_VM_KIND_HYBRID) {
2660
+ zend_jit_call_1(jit, IR_VOID,
2661
+ zend_jit_const_func_addr(jit, (uintptr_t)zend_jit_leave_top_func_helper, IR_CONST_FASTCALL_FUNC),
2662
+ call_info);
2663
+ zend_jit_tailcall_0(jit,
2664
+ zend_jit_load(jit, IR_ADDR, zend_jit_ip(jit)));
2665
+ } else if (GCC_GLOBAL_REGS) {
2666
+ zend_jit_tailcall_1(jit,
2667
+ zend_jit_const_func_addr(jit, (uintptr_t)zend_jit_leave_top_func_helper, IR_CONST_FASTCALL_FUNC),
2668
+ call_info);
2669
+ } else {
2667
2670
zend_jit_tailcall_2(jit,
2668
2671
zend_jit_const_func_addr(jit, (uintptr_t)zend_jit_leave_top_func_helper, IR_CONST_FASTCALL_FUNC),
2669
2672
call_info,
@@ -3135,10 +3138,8 @@ static int zend_jit_trace_halt_stub(zend_jit_ctx *jit)
3135
3138
zend_jit_tailcall_0(jit,
3136
3139
zend_jit_const_func_addr(jit, (uintptr_t)zend_jit_halt_op->handler, IR_CONST_FASTCALL_FUNC));
3137
3140
} else if (GCC_GLOBAL_REGS) {
3138
- ZEND_ASSERT(0 && "NIY");
3139
- //??? | add r4, SPAD // stack alignment
3140
- //??? | xor IP, IP // PC must be zero
3141
- //??? | ret
3141
+ zend_jit_store_ip(jit, IR_NULL);
3142
+ zend_jit_ret(jit, IR_UNUSED);
3142
3143
} else {
3143
3144
zend_jit_ret(jit, ir_const_i32(&jit->ctx, -1)); // ZEND_VM_RETURN
3144
3145
}
@@ -3147,13 +3148,9 @@ static int zend_jit_trace_halt_stub(zend_jit_ctx *jit)
3147
3148
3148
3149
static int zend_jit_trace_escape_stub(zend_jit_ctx *jit)
3149
3150
{
3150
- if (zend_jit_vm_kind == ZEND_VM_KIND_HYBRID ) {
3151
+ if (GCC_GLOBAL_REGS ) {
3151
3152
zend_jit_tailcall_0(jit,
3152
3153
zend_jit_load(jit, IR_ADDR, zend_jit_ip(jit)));
3153
- } else if (GCC_GLOBAL_REGS) {
3154
- ZEND_ASSERT(0 && "NIY");
3155
- //??? | add r4, SPAD // stack alignment
3156
- //??? | JMP_IP
3157
3154
} else {
3158
3155
zend_jit_ret(jit, ir_const_i32(&jit->ctx, 1)); // ZEND_VM_ENTER
3159
3156
}
@@ -3186,15 +3183,8 @@ static int zend_jit_trace_exit_stub(zend_jit_ctx *jit)
3186
3183
ref = zend_jit_load(jit, IR_ADDR,
3187
3184
zend_jit_ex_opline_addr(jit));
3188
3185
zend_jit_store_ip(jit, ref);
3189
- }
3190
-
3191
- if (zend_jit_vm_kind == ZEND_VM_KIND_HYBRID) {
3192
3186
zend_jit_tailcall_0(jit,
3193
3187
zend_jit_load(jit, IR_ADDR, zend_jit_ip(jit)));
3194
- } else if (GCC_GLOBAL_REGS) {
3195
- ZEND_ASSERT(0 && "NIY");
3196
- // | add r4, SPAD // stack alignment
3197
- // | JMP_IP
3198
3188
} else {
3199
3189
zend_jit_ret(jit, ir_const_i32(&jit->ctx, 1)); // ZEND_VM_ENTER
3200
3190
}
@@ -3220,7 +3210,7 @@ static int zend_jit_trace_exit_stub(zend_jit_ctx *jit)
3220
3210
}
3221
3211
3222
3212
addr = zend_jit_orig_opline_handler(jit);
3223
- if (zend_jit_vm_kind == ZEND_VM_KIND_HYBRID || GCC_GLOBAL_REGS) {
3213
+ if (GCC_GLOBAL_REGS) {
3224
3214
zend_jit_tailcall_0(jit, addr);
3225
3215
} else {
3226
3216
#if defined(IR_TARGET_X86)
@@ -3357,16 +3347,11 @@ static void zend_jit_init_ctx(zend_jit_ctx *jit, uint32_t flags)
3357
3347
jit->ctx.flags |= IR_FUNCTION;
3358
3348
/* Stack must be 16 byte aligned */
3359
3349
jit->ctx.fixed_stack_frame_size = sizeof(void*) * 7; /* TODO: reduce stack size ??? */
3360
- #if defined(IR_TARGET_X86)
3361
- jit->ctx.fixed_save_regset = (1<<3) | (1<<5) | (1<<6) | (1<<7); /* all preserved registers ??? */
3362
- #elif defined(IR_TARGET_X64)
3363
- jit->ctx.fixed_save_regset = (1<<3) | (1<<5) | (1<<12) | (1<<13) | (1<<14) | (1<<15); /* all preserved registers ??? */
3364
- #elif defined(IR_TARGET_AARCH64)
3365
- jit->ctx.fixed_save_regset = (1<<19) | (1<<20) | (1<<21) | (1<<22) | (1<<23) | (1<<24)
3366
- | (1<<25) | (1<<26) | (1<<27) | (1<<27) | (1<<28) | (1<<29) | (1<<30); /* all preserved registers ??? */
3367
- #else
3368
- ZEND_ASSERT(0 && "NIY");
3369
- #endif
3350
+ if (GCC_GLOBAL_REGS) {
3351
+ jit->ctx.fixed_save_regset = IR_REGSET_PRESERVED & ~((1<<ZREG_FP) | (1<<ZREG_IP));
3352
+ } else {
3353
+ jit->ctx.fixed_save_regset = IR_REGSET_PRESERVED;
3354
+ }
3370
3355
} else {
3371
3356
#ifdef ZEND_VM_HYBRID_JIT_RED_ZONE_SIZE
3372
3357
jit->ctx.fixed_stack_red_zone = ZEND_VM_HYBRID_JIT_RED_ZONE_SIZE;
@@ -3375,9 +3360,6 @@ static void zend_jit_init_ctx(zend_jit_ctx *jit, uint32_t flags)
3375
3360
jit->ctx.fixed_stack_red_zone = 0;
3376
3361
jit->ctx.fixed_stack_frame_size = 0;
3377
3362
#endif
3378
- if (!GCC_GLOBAL_REGS) {
3379
- jit->ctx.fixed_save_regset = 1 << ZREG_FP;
3380
- }
3381
3363
}
3382
3364
}
3383
3365
jit->ctx.fixed_regset = IR_REGSET_PHP_FIXED;
@@ -4371,15 +4353,15 @@ static int zend_jit_cmp_ip(zend_jit_ctx *jit, ir_op op, const zend_op *next_opli
4371
4353
ir_ref ref;
4372
4354
4373
4355
#if 1
4374
- if (zend_jit_vm_kind == ZEND_VM_KIND_HYBRID ) {
4356
+ if (GCC_GLOBAL_REGS ) {
4375
4357
ref = zend_jit_ip32(jit);
4376
4358
} else {
4377
4359
ref = zend_jit_ex_opline_addr(jit);
4378
4360
ref = zend_jit_load(jit, IR_U32, ref);
4379
4361
}
4380
4362
ref = ir_fold2(&jit->ctx, IR_OPT(op, IR_BOOL), ref, ir_const_u32(&jit->ctx, (uint32_t)(uintptr_t)next_opline));
4381
4363
#else
4382
- if (zend_jit_vm_kind == ZEND_VM_KIND_HYBRID ) {
4364
+ if (GCC_GLOBAL_REGS ) {
4383
4365
ref = zend_jit_ip(jit);
4384
4366
} else {
4385
4367
ref = zend_jit_ex_opline_addr(jit);
@@ -11846,10 +11828,7 @@ static int zend_jit_leave_func(zend_jit_ctx *jit,
11846
11828
}
11847
11829
}
11848
11830
11849
- if (zend_jit_vm_kind == ZEND_VM_KIND_HYBRID) {
11850
- zend_jit_tailcall_0(jit,
11851
- zend_jit_load(jit, IR_ADDR, zend_jit_ip(jit)));
11852
- } else if (GCC_GLOBAL_REGS) {
11831
+ if (GCC_GLOBAL_REGS) {
11853
11832
zend_jit_tailcall_0(jit,
11854
11833
zend_jit_load(jit, IR_ADDR, zend_jit_ip(jit)));
11855
11834
} else {
@@ -17564,9 +17543,9 @@ static int zend_jit_trace_handler(zend_jit_ctx *jit, const zend_op_array *op_arr
17564
17543
zend_jit_stub_addr(jit, jit_stub_trace_halt));
17565
17544
}
17566
17545
} else if (GCC_GLOBAL_REGS) {
17567
- ZEND_ASSERT(0 && "NIY");
17568
- //??? | test IP, IP
17569
- //??? | je ->trace_halt
17546
+ zend_jit_guard(jit,
17547
+ zend_jit_ip(jit),
17548
+ zend_jit_stub_addr(jit, jit_stub_trace_halt));
17570
17549
} else {
17571
17550
zend_jit_guard(jit,
17572
17551
ir_fold2(&jit->ctx, IR_OPT(IR_GE, IR_BOOL),
@@ -17797,7 +17776,7 @@ static int zend_jit_trace_end_loop(zend_jit_ctx *jit, int loop_ref, const void *
17797
17776
17798
17777
static int zend_jit_trace_return(zend_jit_ctx *jit, bool original_handler, const zend_op *opline)
17799
17778
{
17800
- if (zend_jit_vm_kind == ZEND_VM_KIND_HYBRID || GCC_GLOBAL_REGS) {
17779
+ if (GCC_GLOBAL_REGS) {
17801
17780
if (!original_handler) {
17802
17781
zend_jit_tailcall_0(jit,
17803
17782
zend_jit_load(jit, IR_ADDR, zend_jit_ip(jit)));
0 commit comments