Fix previous commit. We still need a temporary register for indirect calls.

This commit is contained in:
Dmitry Stogov 2023-04-26 14:10:58 +03:00
parent 9eb366698d
commit 60802d942f
4 changed files with 32 additions and 18 deletions

View File

@ -436,6 +436,10 @@ int ir_get_target_constraints(const ir_ctx *ctx, ir_ref ref, ir_target_constrain
if (insn->inputs_count > 2) {
constraints->hints[2] = IR_REG_NONE;
constraints->hints_count = ir_get_args_regs(ctx, insn, constraints->hints);
if (!IR_IS_CONST_REF(insn->op2)) {
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;
break;
@ -3471,7 +3475,7 @@ static int32_t ir_call_used_stack(ir_ctx *ctx, ir_insn *insn)
return used_stack;
}
static int32_t ir_emit_arguments(ir_ctx *ctx, ir_ref def, ir_insn *insn)
static int32_t ir_emit_arguments(ir_ctx *ctx, ir_ref def, ir_insn *insn, ir_reg tmp_reg)
{
ir_backend_data *data = ctx->data;
dasm_State **Dst = &data->dasm_state;
@ -3490,8 +3494,7 @@ static int32_t ir_emit_arguments(ir_ctx *ctx, ir_ref def, ir_insn *insn)
int32_t used_stack, stack_offset = 0;
ir_copy *copies;
bool do_pass3 = 0;
/* For temporaries may use any scratch registers except for argunebts used for parameters */
ir_reg tmp_reg = IR_REG_IP0;
/* For temporaries we may use any scratch registers except for registers used for parameters */
ir_reg tmp_fp_reg = IR_REG_FP_LAST; /* Temporary register for FP loads and swap */
n = ir_input_edges_count(ctx, insn);
@ -3499,6 +3502,10 @@ static int32_t ir_emit_arguments(ir_ctx *ctx, ir_ref def, ir_insn *insn)
return 0;
}
if (tmp_reg == IR_REG_NONE) {
tmp_reg = IR_REG_IP0;
}
if (insn->op == IR_CALL && (ctx->flags & IR_PREALLOCATED_STACK)) {
// TODO: support for preallocated stack
used_stack = 0;
@ -3682,7 +3689,7 @@ static void ir_emit_call(ir_ctx *ctx, ir_ref def, ir_insn *insn)
ir_backend_data *data = ctx->data;
dasm_State **Dst = &data->dasm_state;
ir_reg def_reg;
int32_t used_stack = ir_emit_arguments(ctx, def, insn);
int32_t used_stack = ir_emit_arguments(ctx, def, insn, ctx->regs[def][1]);
if (IR_IS_CONST_REF(insn->op2)) {
ir_insn *addr_insn = &ctx->ir_base[insn->op2];
@ -3751,7 +3758,7 @@ static void ir_emit_tailcall(ir_ctx *ctx, ir_ref def, ir_insn *insn)
{
ir_backend_data *data = ctx->data;
dasm_State **Dst = &data->dasm_state;
int32_t used_stack = ir_emit_arguments(ctx, def, insn);
int32_t used_stack = ir_emit_arguments(ctx, def, insn, ctx->regs[def][1]);
if (used_stack != 0) {
ir_emit_call(ctx, def, insn);

View File

@ -739,6 +739,10 @@ op2_const:
if (insn->inputs_count > 2) {
constraints->hints[2] = IR_REG_NONE;
constraints->hints_count = ir_get_args_regs(ctx, insn, constraints->hints);
if (!IR_IS_CONST_REF(insn->op2)) {
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;
break;
@ -5849,7 +5853,7 @@ static int32_t ir_call_used_stack(ir_ctx *ctx, ir_insn *insn)
return used_stack;
}
static int32_t ir_emit_arguments(ir_ctx *ctx, ir_ref def, ir_insn *insn)
static int32_t ir_emit_arguments(ir_ctx *ctx, ir_ref def, ir_insn *insn, ir_reg tmp_reg)
{
ir_backend_data *data = ctx->data;
dasm_State **Dst = &data->dasm_state;
@ -5868,8 +5872,7 @@ static int32_t ir_emit_arguments(ir_ctx *ctx, ir_ref def, ir_insn *insn)
int32_t used_stack, stack_offset = IR_SHADOW_ARGS;
ir_copy *copies;
bool do_pass3 = 0;
/* For temporaries may use any scratch registers except for argunebts used for parameters */
ir_reg tmp_reg = IR_REG_RAX;
/* For temporaries we may use any scratch registers except for registers used for parameters */
ir_reg tmp_fp_reg = IR_REG_FP_LAST; /* Temporary register for FP loads and swap */
n = ir_input_edges_count(ctx, insn);
@ -5877,6 +5880,10 @@ static int32_t ir_emit_arguments(ir_ctx *ctx, ir_ref def, ir_insn *insn)
return 0;
}
if (tmp_reg == IR_REG_NONE) {
tmp_reg = IR_REG_RAX;
}
#ifdef IR_HAVE_FASTCALL
if (sizeof(void*) == 4 && ir_is_fastcall(ctx, insn)) {
int_reg_params_count = IR_REG_INT_FCARGS;
@ -6159,7 +6166,7 @@ static void ir_emit_call(ir_ctx *ctx, ir_ref def, ir_insn *insn)
ir_backend_data *data = ctx->data;
dasm_State **Dst = &data->dasm_state;
ir_reg def_reg;
int32_t used_stack = ir_emit_arguments(ctx, def, insn);
int32_t used_stack = ir_emit_arguments(ctx, def, insn, ctx->regs[def][1]);
if (IR_IS_CONST_REF(insn->op2)) {
ir_insn *addr_insn = &ctx->ir_base[insn->op2];
@ -6262,7 +6269,7 @@ static void ir_emit_tailcall(ir_ctx *ctx, ir_ref def, ir_insn *insn)
{
ir_backend_data *data = ctx->data;
dasm_State **Dst = &data->dasm_state;
int32_t used_stack = ir_emit_arguments(ctx, def, insn);
int32_t used_stack = ir_emit_arguments(ctx, def, insn, ctx->regs[def][1]);
(void) used_stack;
if (used_stack != 0) {

View File

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

View File

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