Avoid reservaton of temporary resiser for argument passing

We may use any scratch register that is not used for parameters
This commit is contained in:
Dmitry Stogov 2023-04-26 12:16:05 +03:00
parent 0de0c1d0fa
commit 9eb366698d
20 changed files with 38 additions and 132 deletions

View File

@ -252,36 +252,6 @@ enum _ir_rule {
}; };
/* register allocation */ /* register allocation */
static bool ir_call_needs_tmp_int_reg(const ir_ctx *ctx, const ir_insn *insn)
{
ir_ref arg;
ir_insn *arg_insn;
int j, n;
ir_type type;
int int_param = 0;
int int_reg_params_count = IR_REG_INT_ARGS;
n = insn->inputs_count;
for (j = 3; j <= n; j++) {
arg = ir_insn_op(insn, j);
arg_insn = &ctx->ir_base[arg];
type = arg_insn->type;
if (IR_IS_TYPE_INT(type)) {
if (IR_IS_CONST_REF(arg)) {
return 1;
} else if (int_param < int_reg_params_count) {
if (int_param > 0) {
return 1; /* for swap */
}
} else {
return 1; /* for mem -> stack copy */
}
int_param++;
}
}
return 0;
}
int ir_get_target_constraints(const ir_ctx *ctx, ir_ref ref, ir_target_constraints *constraints) int ir_get_target_constraints(const ir_ctx *ctx, ir_ref ref, ir_target_constraints *constraints)
{ {
uint32_t rule = ir_rule(ctx, ref); uint32_t rule = ir_rule(ctx, ref);
@ -466,10 +436,6 @@ int ir_get_target_constraints(const ir_ctx *ctx, ir_ref ref, ir_target_constrain
if (insn->inputs_count > 2) { if (insn->inputs_count > 2) {
constraints->hints[2] = IR_REG_NONE; constraints->hints[2] = IR_REG_NONE;
constraints->hints_count = ir_get_args_regs(ctx, insn, constraints->hints); constraints->hints_count = ir_get_args_regs(ctx, insn, constraints->hints);
if (ir_call_needs_tmp_int_reg(ctx, insn)) {
constraints->tmp_regs[n] = IR_TMP_REG(1, IR_ADDR, IR_LOAD_SUB_REF, IR_USE_SUB_REF);
n++;
}
} }
flags = IR_USE_MUST_BE_IN_REG | IR_OP2_SHOULD_BE_IN_REG | IR_OP3_SHOULD_BE_IN_REG; flags = IR_USE_MUST_BE_IN_REG | IR_OP2_SHOULD_BE_IN_REG | IR_OP3_SHOULD_BE_IN_REG;
break; break;
@ -3505,7 +3471,7 @@ static int32_t ir_call_used_stack(ir_ctx *ctx, ir_insn *insn)
return used_stack; return used_stack;
} }
static int32_t ir_emit_arguments(ir_ctx *ctx, ir_ref def, ir_insn *insn, ir_reg tmp_reg) static int32_t ir_emit_arguments(ir_ctx *ctx, ir_ref def, ir_insn *insn)
{ {
ir_backend_data *data = ctx->data; ir_backend_data *data = ctx->data;
dasm_State **Dst = &data->dasm_state; dasm_State **Dst = &data->dasm_state;
@ -3524,6 +3490,8 @@ static int32_t ir_emit_arguments(ir_ctx *ctx, ir_ref def, ir_insn *insn, ir_reg
int32_t used_stack, stack_offset = 0; int32_t used_stack, stack_offset = 0;
ir_copy *copies; ir_copy *copies;
bool do_pass3 = 0; bool do_pass3 = 0;
/* For temporaries may use any scratch registers except for argunebts used for parameters */
ir_reg tmp_reg = IR_REG_IP0;
ir_reg tmp_fp_reg = IR_REG_FP_LAST; /* Temporary register for FP loads and swap */ ir_reg tmp_fp_reg = IR_REG_FP_LAST; /* Temporary register for FP loads and swap */
n = ir_input_edges_count(ctx, insn); n = ir_input_edges_count(ctx, insn);
@ -3714,7 +3682,7 @@ static void ir_emit_call(ir_ctx *ctx, ir_ref def, ir_insn *insn)
ir_backend_data *data = ctx->data; ir_backend_data *data = ctx->data;
dasm_State **Dst = &data->dasm_state; dasm_State **Dst = &data->dasm_state;
ir_reg def_reg; ir_reg def_reg;
int32_t used_stack = ir_emit_arguments(ctx, def, insn, ctx->regs[def][1]); int32_t used_stack = ir_emit_arguments(ctx, def, insn);
if (IR_IS_CONST_REF(insn->op2)) { if (IR_IS_CONST_REF(insn->op2)) {
ir_insn *addr_insn = &ctx->ir_base[insn->op2]; ir_insn *addr_insn = &ctx->ir_base[insn->op2];
@ -3783,7 +3751,7 @@ static void ir_emit_tailcall(ir_ctx *ctx, ir_ref def, ir_insn *insn)
{ {
ir_backend_data *data = ctx->data; ir_backend_data *data = ctx->data;
dasm_State **Dst = &data->dasm_state; dasm_State **Dst = &data->dasm_state;
int32_t used_stack = ir_emit_arguments(ctx, def, insn, ctx->regs[def][1]); int32_t used_stack = ir_emit_arguments(ctx, def, insn);
if (used_stack != 0) { if (used_stack != 0) {
ir_emit_call(ctx, def, insn); ir_emit_call(ctx, def, insn);

View File

@ -515,50 +515,6 @@ enum _ir_rule {
}; };
/* register allocation */ /* register allocation */
static bool ir_call_needs_tmp_int_reg(const ir_ctx *ctx, const ir_insn *insn)
{
ir_ref arg;
ir_insn *arg_insn;
int j, n;
ir_type type;
int int_param = 0;
int int_reg_params_count = IR_REG_INT_ARGS;
#ifdef IR_HAVE_FASTCALL
if (sizeof(void*) == 4 && ir_is_fastcall(ctx, insn)) {
int_reg_params_count = IR_REG_INT_FCARGS;
}
#endif
n = insn->inputs_count;
for (j = 3; j <= n; j++) {
arg = ir_insn_op(insn, j);
arg_insn = &ctx->ir_base[arg];
type = arg_insn->type;
if (IR_IS_TYPE_INT(type)) {
if (IR_IS_CONST_REF(arg)) {
if (arg_insn->op == IR_STR || !IR_IS_SIGNED_32BIT(arg_insn->val.i64)) {
return 1;
}
} else {
if (int_param < int_reg_params_count) {
if (int_param > 0) {
return 1; /* for swap */
}
} else {
return 1; /* for mem -> stack copy */
}
}
int_param++;
} else if (type == IR_DOUBLE) {
if (IR_IS_CONST_REF(arg) && arg_insn->val.i64 != 0) {
return 1;
}
}
}
return 0;
}
int ir_get_target_constraints(const ir_ctx *ctx, ir_ref ref, ir_target_constraints *constraints) int ir_get_target_constraints(const ir_ctx *ctx, ir_ref ref, ir_target_constraints *constraints)
{ {
uint32_t rule = ir_rule(ctx, ref); uint32_t rule = ir_rule(ctx, ref);
@ -783,10 +739,6 @@ op2_const:
if (insn->inputs_count > 2) { if (insn->inputs_count > 2) {
constraints->hints[2] = IR_REG_NONE; constraints->hints[2] = IR_REG_NONE;
constraints->hints_count = ir_get_args_regs(ctx, insn, constraints->hints); constraints->hints_count = ir_get_args_regs(ctx, insn, constraints->hints);
if (ir_call_needs_tmp_int_reg(ctx, insn)) {
constraints->tmp_regs[n] = IR_TMP_REG(1, IR_ADDR, IR_LOAD_SUB_REF, IR_USE_SUB_REF);
n++;
}
} }
flags = IR_USE_MUST_BE_IN_REG | IR_OP2_SHOULD_BE_IN_REG | IR_OP3_SHOULD_BE_IN_REG; flags = IR_USE_MUST_BE_IN_REG | IR_OP2_SHOULD_BE_IN_REG | IR_OP3_SHOULD_BE_IN_REG;
break; break;
@ -5897,7 +5849,7 @@ static int32_t ir_call_used_stack(ir_ctx *ctx, ir_insn *insn)
return used_stack; return used_stack;
} }
static int32_t ir_emit_arguments(ir_ctx *ctx, ir_ref def, ir_insn *insn, ir_reg tmp_reg) static int32_t ir_emit_arguments(ir_ctx *ctx, ir_ref def, ir_insn *insn)
{ {
ir_backend_data *data = ctx->data; ir_backend_data *data = ctx->data;
dasm_State **Dst = &data->dasm_state; dasm_State **Dst = &data->dasm_state;
@ -5916,6 +5868,8 @@ static int32_t ir_emit_arguments(ir_ctx *ctx, ir_ref def, ir_insn *insn, ir_reg
int32_t used_stack, stack_offset = IR_SHADOW_ARGS; int32_t used_stack, stack_offset = IR_SHADOW_ARGS;
ir_copy *copies; ir_copy *copies;
bool do_pass3 = 0; bool do_pass3 = 0;
/* For temporaries may use any scratch registers except for argunebts used for parameters */
ir_reg tmp_reg = IR_REG_RAX;
ir_reg tmp_fp_reg = IR_REG_FP_LAST; /* Temporary register for FP loads and swap */ ir_reg tmp_fp_reg = IR_REG_FP_LAST; /* Temporary register for FP loads and swap */
n = ir_input_edges_count(ctx, insn); n = ir_input_edges_count(ctx, insn);
@ -6205,7 +6159,7 @@ static void ir_emit_call(ir_ctx *ctx, ir_ref def, ir_insn *insn)
ir_backend_data *data = ctx->data; ir_backend_data *data = ctx->data;
dasm_State **Dst = &data->dasm_state; dasm_State **Dst = &data->dasm_state;
ir_reg def_reg; ir_reg def_reg;
int32_t used_stack = ir_emit_arguments(ctx, def, insn, ctx->regs[def][1]); int32_t used_stack = ir_emit_arguments(ctx, def, insn);
if (IR_IS_CONST_REF(insn->op2)) { if (IR_IS_CONST_REF(insn->op2)) {
ir_insn *addr_insn = &ctx->ir_base[insn->op2]; ir_insn *addr_insn = &ctx->ir_base[insn->op2];
@ -6308,7 +6262,7 @@ static void ir_emit_tailcall(ir_ctx *ctx, ir_ref def, ir_insn *insn)
{ {
ir_backend_data *data = ctx->data; ir_backend_data *data = ctx->data;
dasm_State **Dst = &data->dasm_state; dasm_State **Dst = &data->dasm_state;
int32_t used_stack = ir_emit_arguments(ctx, def, insn, ctx->regs[def][1]); int32_t used_stack = ir_emit_arguments(ctx, def, insn);
(void) used_stack; (void) used_stack;
if (used_stack != 0) { if (used_stack != 0) {

View File

@ -60,7 +60,6 @@ Windows-x86_64
{ # LIVE-RANGES (vregs_count=3) { # LIVE-RANGES (vregs_count=3)
TMP TMP
[%xmm0]: [2.2-2.3)/3 [%xmm0]: [2.2-2.3)/3
[%rax]: [11.0-11.1)/1
[%xmm0]: [13.2-13.3)/3 [%xmm0]: [13.2-13.3)/3
R1 (d_4) [%xmm0]: [3.0-10.1), DEF(4.2), USE(9.1/2), USE(10.1/2) R1 (d_4) [%xmm0]: [3.0-10.1), DEF(4.2), USE(9.1/2), USE(10.1/2)
R2 (d_5, d_9) [SPILL=0x0] R2 (d_5, d_9) [SPILL=0x0]

View File

@ -60,8 +60,6 @@ Windows-x86_64
{ # LIVE-RANGES (vregs_count=3) { # LIVE-RANGES (vregs_count=3)
TMP TMP
[%xmm0]: [2.2-2.3)/3 [%xmm0]: [2.2-2.3)/3
[%rax]: [11.0-11.1)/1
[%rax]: [13.0-13.1)/1
[%xmm0]: [15.2-15.3)/3 [%xmm0]: [15.2-15.3)/3
R1 (d_4) [%xmm0]: [3.0-10.1), DEF(4.2), USE(9.1/2), USE(10.1/2) R1 (d_4) [%xmm0]: [3.0-10.1), DEF(4.2), USE(9.1/2), USE(10.1/2)
R2 (d_5, d_9) [SPILL=0x0] R2 (d_5, d_9) [SPILL=0x0]

View File

@ -55,7 +55,6 @@ Windows-x86_64
{ # LIVE-RANGES (vregs_count=3) { # LIVE-RANGES (vregs_count=3)
TMP TMP
[%eax]: [2.2-2.3)/1 [%eax]: [2.2-2.3)/1
[%rax]: [10.0-10.1)/1
[%eax]: [12.2-12.3)/1 [%eax]: [12.2-12.3)/1
R1 (d_4) [%eax]: [3.0-9.1), DEF(4.2), USE(9.1/2)! R1 (d_4) [%eax]: [3.0-9.1), DEF(4.2), USE(9.1/2)!
R2 (d_5) [%ebx]: [3.0-13.0), DEF(5.2), USE(7.1/6.1), USE(9.1/1)!, USE(10.0/4, hint=%edx), PHI_USE(12.2, phi=d_4/3) R2 (d_5) [%ebx]: [3.0-13.0), DEF(5.2), USE(7.1/6.1), USE(9.1/1)!, USE(10.0/4, hint=%edx), PHI_USE(12.2, phi=d_4/3)

View File

@ -35,12 +35,12 @@ test:
movz x5, #0x1, lsl #32 movz x5, #0x1, lsl #32
movz x6, #0x6 movz x6, #0x6
movz w7, #0x7 movz w7, #0x7
movz w8, #0x8 movz w16, #0x8
str x8, [sp] str x16, [sp]
movz x8, #0x9 movz x16, #0x9
str x8, [sp, #8] str x16, [sp, #8]
movz x8, #0x1, lsl #32 movz x16, #0x1, lsl #32
str x8, [sp, #0x10] str x16, [sp, #0x10]
bl _IO_printf bl _IO_printf
add sp, sp, #0x20 add sp, sp, #0x20
ldp x29, x30, [sp], #0x10 ldp x29, x30, [sp], #0x10

View File

@ -27,10 +27,10 @@ test:
mov x29, sp mov x29, sp
str x19, [x29, #0x18] str x19, [x29, #0x18]
mov w19, w0 mov w19, w0
mov w4, w1 mov w16, w1
mov w1, w2 mov w1, w2
mov w2, w3 mov w2, w3
mov w3, w4 mov w3, w16
adr x0, .L1 adr x0, .L1
bl _IO_printf bl _IO_printf
add w0, w0, w19 add w0, w0, w19

View File

@ -25,10 +25,10 @@ test:
str x19, [x29, #0x18] str x19, [x29, #0x18]
mov w19, w0 mov w19, w0
ldr x4, [x4] ldr x4, [x4]
mov w5, w1 mov w16, w1
mov w1, w2 mov w1, w2
mov w2, w3 mov w2, w3
mov w3, w5 mov w3, w16
adr x0, .L1 adr x0, .L1
blr x4 blr x4
add w0, w0, w19 add w0, w0, w19

View File

@ -37,10 +37,10 @@ test:
mov w2, w1 mov w2, w1
mov w1, w0 mov w1, w0
adr x0, .L1 adr x0, .L1
ldr w9, [x29, #0x20] ldr w16, [x29, #0x20]
str w9, [sp, #8] str w16, [sp, #8]
ldr w9, [x29, #0x28] ldr w16, [x29, #0x28]
str w9, [sp, #0x10] str w16, [sp, #0x10]
bl _IO_printf bl _IO_printf
add sp, sp, #0x20 add sp, sp, #0x20
ldp x29, x30, [sp], #0x10 ldp x29, x30, [sp], #0x10

View File

@ -61,7 +61,6 @@ aarch64
TMP TMP
[%d0]: [2.2-2.3)/3 [%d0]: [2.2-2.3)/3
[%d0]: [7.0-7.2)/6.2 [%d0]: [7.0-7.2)/6.2
[%x1]: [11.0-11.1)/1
R1 (d_4, d_10) [SPILL=0x0] R1 (d_4, d_10) [SPILL=0x0]
[%d0]: [3.0-7.0), DEF(4.2) [%d0]: [3.0-7.0), DEF(4.2)
: [7.0-8.0) : [7.0-8.0)

View File

@ -61,8 +61,6 @@ aarch64
TMP TMP
[%d0]: [2.2-2.3)/3 [%d0]: [2.2-2.3)/3
[%d0]: [7.0-7.2)/6.2 [%d0]: [7.0-7.2)/6.2
[%x1]: [11.0-11.1)/1
[%x1]: [13.0-13.1)/1
R1 (d_4, d_10) [SPILL=0x0] R1 (d_4, d_10) [SPILL=0x0]
[%d0]: [3.0-7.0), DEF(4.2) [%d0]: [3.0-7.0), DEF(4.2)
: [7.0-8.0) : [7.0-8.0)

View File

@ -56,7 +56,6 @@ aarch64
TMP TMP
[%w0]: [2.2-2.3)/1 [%w0]: [2.2-2.3)/1
[%w1]: [7.0-7.2)/6.2 [%w1]: [7.0-7.2)/6.2
[%x2]: [10.0-10.1)/1
[%w0]: [12.2-12.3)/1 [%w0]: [12.2-12.3)/1
R1 (d_4) [%w0]: [3.0-9.1), DEF(4.2), USE(9.1/2)! R1 (d_4) [%w0]: [3.0-9.1), DEF(4.2), USE(9.1/2)!
R2 (d_5) [%w18]: [3.0-13.0), DEF(5.2), USE(7.1/6.1)!, USE(9.1/1)!, USE(10.0/4, hint=%w1), PHI_USE(12.2, phi=d_4/3) R2 (d_5) [%w18]: [3.0-13.0), DEF(5.2), USE(7.1/6.1)!, USE(9.1/1)!, USE(10.0/4, hint=%w1), PHI_USE(12.2, phi=d_4/3)

View File

@ -25,12 +25,12 @@ test:
movl 0x20(%esp), %ebx movl 0x20(%esp), %ebx
movl 0x30(%esp), %eax movl 0x30(%esp), %eax
movl $.L1, (%esp) movl $.L1, (%esp)
movl 0x28(%esp), %ecx movl 0x28(%esp), %eax
movl %ecx, 4(%esp) movl %eax, 4(%esp)
movl 0x2c(%esp), %ecx movl 0x2c(%esp), %eax
movl %ecx, 8(%esp) movl %eax, 8(%esp)
movl 0x24(%esp), %ecx movl 0x24(%esp), %eax
movl %ecx, 0xc(%esp) movl %eax, 0xc(%esp)
calll *(%eax) calll *(%eax)
addl %ebx, %eax addl %ebx, %eax
movl 0x18(%esp), %ebx movl 0x18(%esp), %ebx

View File

@ -60,7 +60,6 @@ x86
{ # LIVE-RANGES (vregs_count=3) { # LIVE-RANGES (vregs_count=3)
TMP TMP
[%xmm0]: [2.2-2.3)/3 [%xmm0]: [2.2-2.3)/3
[%eax]: [11.0-11.1)/1
[%xmm0]: [13.2-13.3)/3 [%xmm0]: [13.2-13.3)/3
R1 (d_4) [%xmm1]: [3.0-10.1), DEF(4.2), USE(9.1/2), USE(10.1/2) R1 (d_4) [%xmm1]: [3.0-10.1), DEF(4.2), USE(9.1/2), USE(10.1/2)
R2 (d_5, d_9) [SPILL=0x0] R2 (d_5, d_9) [SPILL=0x0]

View File

@ -60,8 +60,6 @@ x86
{ # LIVE-RANGES (vregs_count=3) { # LIVE-RANGES (vregs_count=3)
TMP TMP
[%xmm0]: [2.2-2.3)/3 [%xmm0]: [2.2-2.3)/3
[%eax]: [11.0-11.1)/1
[%eax]: [13.0-13.1)/1
[%xmm0]: [15.2-15.3)/3 [%xmm0]: [15.2-15.3)/3
R1 (d_4) [%xmm1]: [3.0-10.1), DEF(4.2), USE(9.1/2), USE(10.1/2) R1 (d_4) [%xmm1]: [3.0-10.1), DEF(4.2), USE(9.1/2), USE(10.1/2)
R2 (d_5, d_9) [SPILL=0x0] R2 (d_5, d_9) [SPILL=0x0]

View File

@ -55,7 +55,6 @@ x86
{ # LIVE-RANGES (vregs_count=3) { # LIVE-RANGES (vregs_count=3)
TMP TMP
[%eax]: [2.2-2.3)/1 [%eax]: [2.2-2.3)/1
[%eax]: [10.0-10.1)/1
[%eax]: [12.2-12.3)/1 [%eax]: [12.2-12.3)/1
R1 (d_4) [%eax]: [3.0-9.1), DEF(4.2), USE(9.1/2)! R1 (d_4) [%eax]: [3.0-9.1), DEF(4.2), USE(9.1/2)!
R2 (d_5) [%ebx]: [3.0-13.0), DEF(5.2), USE(7.1/6.1), USE(9.1/1)!, USE(10.1/4), PHI_USE(12.2, phi=d_4/3) R2 (d_5) [%ebx]: [3.0-13.0), DEF(5.2), USE(7.1/6.1), USE(9.1/1)!, USE(10.1/4), PHI_USE(12.2, phi=d_4/3)

View File

@ -33,14 +33,14 @@ test:
movl %esi, %edx movl %esi, %edx
movl %edi, %esi movl %edi, %esi
leaq .L1(%rip), %rdi leaq .L1(%rip), %rdi
movl 0x30(%rsp), %r10d movl 0x30(%rsp), %eax
movl %r10d, 8(%rsp) movl %eax, 8(%rsp)
movl 0x38(%rsp), %r10d movl 0x38(%rsp), %eax
movl %r10d, 0x10(%rsp) movl %eax, 0x10(%rsp)
movl 0x40(%rsp), %r10d movl 0x40(%rsp), %eax
movl %r10d, 0x18(%rsp) movl %eax, 0x18(%rsp)
movl 0x48(%rsp), %r10d movl 0x48(%rsp), %eax
movl %r10d, 0x20(%rsp) movl %eax, 0x20(%rsp)
movabsq $_IO_printf, %rax movabsq $_IO_printf, %rax
callq *%rax callq *%rax
addq $0x28, %rsp addq $0x28, %rsp

View File

@ -60,7 +60,6 @@ x86_64
{ # LIVE-RANGES (vregs_count=3) { # LIVE-RANGES (vregs_count=3)
TMP TMP
[%xmm0]: [2.2-2.3)/3 [%xmm0]: [2.2-2.3)/3
[%rax]: [11.0-11.1)/1
[%xmm0]: [13.2-13.3)/3 [%xmm0]: [13.2-13.3)/3
R1 (d_4) [%xmm1]: [3.0-10.1), DEF(4.2), USE(9.1/2), USE(10.1/2) R1 (d_4) [%xmm1]: [3.0-10.1), DEF(4.2), USE(9.1/2), USE(10.1/2)
R2 (d_5, d_9) [SPILL=0x0] R2 (d_5, d_9) [SPILL=0x0]

View File

@ -60,8 +60,6 @@ x86_64
{ # LIVE-RANGES (vregs_count=3) { # LIVE-RANGES (vregs_count=3)
TMP TMP
[%xmm0]: [2.2-2.3)/3 [%xmm0]: [2.2-2.3)/3
[%rax]: [11.0-11.1)/1
[%rax]: [13.0-13.1)/1
[%xmm0]: [15.2-15.3)/3 [%xmm0]: [15.2-15.3)/3
R1 (d_4) [%xmm1]: [3.0-10.1), DEF(4.2), USE(9.1/2), USE(10.1/2) R1 (d_4) [%xmm1]: [3.0-10.1), DEF(4.2), USE(9.1/2), USE(10.1/2)
R2 (d_5, d_9) [SPILL=0x0] R2 (d_5, d_9) [SPILL=0x0]

View File

@ -55,7 +55,6 @@ x86_64
{ # LIVE-RANGES (vregs_count=3) { # LIVE-RANGES (vregs_count=3)
TMP TMP
[%eax]: [2.2-2.3)/1 [%eax]: [2.2-2.3)/1
[%rax]: [10.0-10.1)/1
[%eax]: [12.2-12.3)/1 [%eax]: [12.2-12.3)/1
R1 (d_4) [%eax]: [3.0-9.1), DEF(4.2), USE(9.1/2)! R1 (d_4) [%eax]: [3.0-9.1), DEF(4.2), USE(9.1/2)!
R2 (d_5) [%ebx]: [3.0-13.0), DEF(5.2), USE(7.1/6.1), USE(9.1/1)!, USE(10.0/4, hint=%esi), PHI_USE(12.2, phi=d_4/3) R2 (d_5) [%ebx]: [3.0-13.0), DEF(5.2), USE(7.1/6.1), USE(9.1/1)!, USE(10.0/4, hint=%esi), PHI_USE(12.2, phi=d_4/3)