mirror of
https://github.com/danog/ir.git
synced 2025-01-21 21:21:19 +01:00
Fix previous commit. We still need a temporary register for indirect calls.
This commit is contained in:
parent
9eb366698d
commit
60802d942f
@ -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);
|
||||
|
17
ir_x86.dasc
17
ir_x86.dasc
@ -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) {
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
Loading…
x
Reference in New Issue
Block a user