Improve argument passing

This commit is contained in:
Dmitry Stogov 2022-05-17 17:30:04 +03:00
parent f08386b379
commit 445dd65c78
3 changed files with 40 additions and 27 deletions

View File

@ -733,9 +733,11 @@ ir_reg ir_uses_fixed_reg(ir_ctx *ctx, ir_ref ref, int op_num)
return IR_REG_NONE; return IR_REG_NONE;
} }
static bool ir_may_need_tmp_reg_for_int_args_swap(ir_ctx *ctx, ir_ref ref) static bool ir_call_needs_tmp_int_reg(ir_ctx *ctx, ir_ref ref)
{ {
ir_insn *insn = &ctx->ir_base[ref]; ir_insn *insn = &ctx->ir_base[ref];
ir_ref arg;
ir_insn *arg_insn;
int j, n; int j, n;
ir_type type; ir_type type;
int int_param = 0; int int_param = 0;
@ -743,16 +745,22 @@ static bool ir_may_need_tmp_reg_for_int_args_swap(ir_ctx *ctx, ir_ref ref)
n = ir_input_edges_count(ctx, insn); n = ir_input_edges_count(ctx, insn);
for (j = 3; j <= n; j++) { for (j = 3; j <= n; j++) {
type = ctx->ir_base[insn->ops[j]].type; arg = insn->ops[j];
arg_insn = &ctx->ir_base[arg];
type = arg_insn->type;
if (IR_IS_TYPE_INT(type)) { if (IR_IS_TYPE_INT(type)) {
if (int_param < int_reg_params_count) { if (int_param < int_reg_params_count) {
if (int_param > 0) { if (int_param > 0) {
return 1; return 1; /* for swap */
} }
} else { } else {
return 0; return 0;
} }
int_param++; int_param++;
} else if (type == IR_DOUBLE) {
if (IR_IS_CONST_REF(arg) && arg_insn->val.i64 != 0) {
return 1;
}
} }
} }
return 0; return 0;
@ -1012,7 +1020,7 @@ cmp_fp:
return n; return n;
case IR_CALL: case IR_CALL:
case IR_TAILCALL: case IR_TAILCALL:
if (ir_may_need_tmp_reg_for_int_args_swap(ctx, ref)) { if (ir_call_needs_tmp_int_reg(ctx, ref)) {
tmp_regs[0].num = 1; tmp_regs[0].num = 1;
tmp_regs[0].type = IR_ADDR; tmp_regs[0].type = IR_ADDR;
tmp_regs[0].start = IR_LOAD_SUB_REF; tmp_regs[0].start = IR_LOAD_SUB_REF;
@ -3619,7 +3627,7 @@ static int32_t ir_emit_arguments(ir_ctx *ctx, ir_ref def, ir_insn *insn, ir_reg
} else { } else {
used_stack = ir_call_used_stack(ctx, insn); used_stack = ir_call_used_stack(ctx, insn);
if (used_stack) { if (used_stack) {
| lea rsp, [rsp-used_stack] | sub rsp, used_stack
} }
} }
@ -3690,16 +3698,22 @@ static int32_t ir_emit_arguments(ir_ctx *ctx, ir_ref def, ir_insn *insn, ir_reg
} }
} else { } else {
if (IR_IS_CONST_REF(arg)) { if (IR_IS_CONST_REF(arg)) {
ir_emit_load(ctx, type, tmp_fp_reg, arg); ir_val *val = &ctx->ir_base[arg].val;
src_reg = tmp_fp_reg; if (ir_type_size[type] == 4 || val->i64 == 0) {
| mov qword [rsp+stack_offset], val->i32
} else {
IR_ASSERT(tmp_reg != IR_REG_NONE);
| mov64 Rq(tmp_reg), val->i64
| mov qword [rsp+stack_offset], Ra(tmp_reg)
}
} else { } else {
IR_ASSERT(src_reg != IR_REG_NONE); IR_ASSERT(src_reg != IR_REG_NONE);
if (src_reg & IR_REG_SPILL_LOAD) { if (src_reg & IR_REG_SPILL_LOAD) {
src_reg &= ~IR_REG_SPILL_LOAD; src_reg &= ~IR_REG_SPILL_LOAD;
ir_emit_load(ctx, type, src_reg, arg); ir_emit_load(ctx, type, src_reg, arg);
} }
| ASM_FP_MEM_REG_OP movss, movsd, vmovss, vmovsd, type, [rsp+stack_offset], src_reg
} }
| ASM_FP_MEM_REG_OP movss, movsd, vmovss, vmovsd, type, [rsp+stack_offset], src_reg
} }
stack_offset += sizeof(void*); stack_offset += sizeof(void*);
} }
@ -3783,7 +3797,7 @@ static void ir_emit_call(ir_ctx *ctx, ir_ref def, ir_insn *insn)
} }
if (used_stack) { if (used_stack) {
| lea rsp, [rsp+used_stack] | add rsp, used_stack
} }
if (insn->type != IR_VOID) { if (insn->type != IR_VOID) {

View File

@ -23,14 +23,14 @@
--EXPECT-- --EXPECT--
test: test:
subq $8, %rsp subq $8, %rsp
leaq -0x30(%rsp), %rsp subq $0x30, %rsp
movl $6, (%rsp) movl $6, (%rsp)
movl $7, 8(%rsp) movl $7, 8(%rsp)
movl $8, 0x10(%rsp) movl $8, 0x10(%rsp)
movq $9, 0x18(%rsp) movq $9, 0x18(%rsp)
movabsq $0x100000000, %rax movabsq $0x100000000, %rax
movq %rax, 0x20(%rsp) movq %rax, 0x20(%rsp)
leaq 0x39(%rip), %rdi leaq 0x3a(%rip), %rdi
movq $1, %rsi movq $1, %rsi
movw $2, %dx movw $2, %dx
movl $3, %ecx movl $3, %ecx
@ -38,7 +38,7 @@ test:
movabsq $0x100000000, %r9 movabsq $0x100000000, %r9
movabsq $_IO_printf, %rax movabsq $_IO_printf, %rax
callq *%rax callq *%rax
leaq 0x30(%rsp), %rsp addq $0x30, %rsp
addq $8, %rsp addq $8, %rsp
retq retq

View File

@ -23,23 +23,22 @@
--EXPECT-- --EXPECT--
test: test:
subq $8, %rsp subq $8, %rsp
leaq -0x10(%rsp), %rsp subq $0x10, %rsp
movsd 0xb6(%rip), %xmm15 movabsq $0x3feccccccccccccd, %rax
movsd %xmm15, (%rsp) movq %rax, (%rsp)
xorpd %xmm15, %xmm15 movq $0, 8(%rsp)
movsd %xmm15, 8(%rsp) leaq 0x9a(%rip), %rdi
leaq 0xa5(%rip), %rdi movsd 0x52(%rip), %xmm0
movsd 0x55(%rip), %xmm0 movsd 0x52(%rip), %xmm1
movsd 0x55(%rip), %xmm1 movsd 0x52(%rip), %xmm2
movsd 0x55(%rip), %xmm2 movsd 0x52(%rip), %xmm3
movsd 0x55(%rip), %xmm3 movsd 0x52(%rip), %xmm4
movsd 0x55(%rip), %xmm4 movsd 0x52(%rip), %xmm5
movsd 0x55(%rip), %xmm5 movsd 0x52(%rip), %xmm6
movsd 0x55(%rip), %xmm6 movsd 0x52(%rip), %xmm7
movsd 0x55(%rip), %xmm7
movabsq $_IO_printf, %rax movabsq $_IO_printf, %rax
callq *%rax callq *%rax
leaq 0x10(%rsp), %rsp addq $0x10, %rsp
addq $8, %rsp addq $8, %rsp
retq retq