Fix stack parameters loading

This commit is contained in:
Dmitry Stogov 2022-05-17 15:00:58 +03:00
parent da5de8a390
commit 4e917faaba
5 changed files with 110 additions and 16 deletions

View File

@ -3956,12 +3956,11 @@ static int ir_emit_dessa_move(ir_ctx *ctx, uint8_t type, ir_ref from, ir_ref to)
return 1; return 1;
} }
static void ir_emit_param_move(ir_ctx *ctx, uint8_t type, ir_reg from_reg, ir_reg to_reg, ir_ref to) static void ir_emit_param_move(ir_ctx *ctx, uint8_t type, ir_reg from_reg, ir_reg to_reg, ir_ref to, int32_t offset)
{ {
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 fp = (ctx->flags & IR_USE_FRAME_POINTER) ? IR_REG_RBP : IR_REG_RSP; ir_reg fp = (ctx->flags & IR_USE_FRAME_POINTER) ? IR_REG_RBP : IR_REG_RSP;
int32_t offset;
IR_ASSERT(from_reg != IR_REG_NONE || to_reg != IR_REG_NONE); IR_ASSERT(from_reg != IR_REG_NONE || to_reg != IR_REG_NONE);
@ -3973,7 +3972,6 @@ static void ir_emit_param_move(ir_ctx *ctx, uint8_t type, ir_reg from_reg, ir_re
ir_emit_store(ctx, type, to, from_reg); ir_emit_store(ctx, type, to, from_reg);
} }
} else { } else {
offset = (ctx->flags & IR_USE_FRAME_POINTER) ? -8 : -8; // TODO:
| ASM_REG_MEM_OP mov, type, to_reg, [Ra(fp)+offset] | ASM_REG_MEM_OP mov, type, to_reg, [Ra(fp)+offset]
} }
} else { } else {
@ -3984,7 +3982,6 @@ static void ir_emit_param_move(ir_ctx *ctx, uint8_t type, ir_reg from_reg, ir_re
ir_emit_store(ctx, type, to, from_reg); ir_emit_store(ctx, type, to, from_reg);
} }
} else { } else {
offset = (ctx->flags & IR_USE_FRAME_POINTER) ? -8 : -8; // TODO:
| ASM_FP_REG_MEM_OP movss, movsd, vmovss, vmovsd, type, to_reg, [Ra(fp)+offset] | ASM_FP_REG_MEM_OP movss, movsd, vmovss, vmovsd, type, to_reg, [Ra(fp)+offset]
} }
} }
@ -3992,6 +3989,7 @@ static void ir_emit_param_move(ir_ctx *ctx, uint8_t type, ir_reg from_reg, ir_re
static void ir_emit_load_params(ir_ctx *ctx) static void ir_emit_load_params(ir_ctx *ctx)
{ {
ir_backend_data *data = ctx->data;
ir_use_list *use_list = &ctx->use_lists[1]; ir_use_list *use_list = &ctx->use_lists[1];
ir_insn *insn; ir_insn *insn;
ir_ref i, n, *p, use; ir_ref i, n, *p, use;
@ -4004,7 +4002,13 @@ static void ir_emit_load_params(ir_ctx *ctx)
int fp_reg_params_count = IR_REG_FP_ARGS; int fp_reg_params_count = IR_REG_FP_ARGS;
const int8_t *int_reg_params = _ir_int_reg_params; const int8_t *int_reg_params = _ir_int_reg_params;
const int8_t *fp_reg_params = _ir_fp_reg_params; const int8_t *fp_reg_params = _ir_fp_reg_params;
int32_t stack_offset = 0;
if (ctx->flags & IR_USE_FRAME_POINTER) {
stack_offset = sizeof(void*); /* skip old frame pointer */
} else {
stack_offset = data->stack_frame_size + data->stack_frame_alignment;
}
n = use_list->count; n = use_list->count;
for (i = 0, p = &ctx->use_edges[use_list->refs]; i < n; i++, p++) { for (i = 0, p = &ctx->use_edges[use_list->refs]; i < n; i++, p++) {
use = *p; use = *p;
@ -4015,23 +4019,22 @@ static void ir_emit_load_params(ir_ctx *ctx)
if (int_param_num < int_reg_params_count) { if (int_param_num < int_reg_params_count) {
src_reg = int_reg_params[int_param_num]; src_reg = int_reg_params[int_param_num];
} else { } else {
// TODO: replace IR_REG_NONE by stack slot
src_reg = IR_REG_NONE; src_reg = IR_REG_NONE;
stack_offset += sizeof(void*);
} }
int_param_num++; int_param_num++;
} else { } else {
if (fp_param_num < fp_reg_params_count) { if (fp_param_num < fp_reg_params_count) {
src_reg = fp_reg_params[fp_param_num]; src_reg = fp_reg_params[fp_param_num];
} else { } else {
// TODO: replace IR_REG_NONE by stack slot
src_reg = IR_REG_NONE; src_reg = IR_REG_NONE;
stack_offset += sizeof(void*);
} }
fp_param_num++; fp_param_num++;
} }
dst_reg = IR_REG_NUM(ctx->regs[use][0]); dst_reg = IR_REG_NUM(ctx->regs[use][0]);
if (src_reg != dst_reg) { if (src_reg != dst_reg) {
// TODO: parallel move ir_emit_param_move(ctx, insn->type, src_reg, dst_reg, use, stack_offset);
ir_emit_param_move(ctx, insn->type, src_reg, dst_reg, use);
} }
if (dst_reg != IR_REG_NONE && (ctx->regs[use][0] & IR_REG_SPILL_STORE)) { if (dst_reg != IR_REG_NONE && (ctx->regs[use][0] & IR_REG_SPILL_STORE)) {
ir_emit_store(ctx, insn->type, use, dst_reg); ir_emit_store(ctx, insn->type, use, dst_reg);

View File

@ -72,13 +72,13 @@ test:
movl %edx, 8(%rsp) movl %edx, 8(%rsp)
movl %ecx, 0xc(%rsp) movl %ecx, 0xc(%rsp)
movl %r9d, 0x10(%rsp) movl %r9d, 0x10(%rsp)
movl -8(%rsp), %eax movl 0xa0(%rsp), %eax
movl %eax, 0x14(%rsp) movl %eax, 0x14(%rsp)
movl -8(%rsp), %eax movl 0xa8(%rsp), %eax
movl %eax, 0x18(%rsp) movl %eax, 0x18(%rsp)
movl -8(%rsp), %eax movl 0xb0(%rsp), %eax
movl %eax, 0x1c(%rsp) movl %eax, 0x1c(%rsp)
movl -8(%rsp), %eax movl 0xb8(%rsp), %eax
movl %eax, 0x20(%rsp) movl %eax, 0x20(%rsp)
movl (%rsp), %eax movl (%rsp), %eax
movl %eax, 0x24(%rsp) movl %eax, 0x24(%rsp)

View File

@ -69,10 +69,10 @@ test:
subq $0x10, %rsp subq $0x10, %rsp
movq %rbx, 8(%rsp) movq %rbx, 8(%rsp)
movq %rbp, (%rsp) movq %rbp, (%rsp)
movl -8(%rsp), %eax movl 0x18(%rsp), %eax
movl -8(%rsp), %r8d movl 0x20(%rsp), %r8d
movl -8(%rsp), %r10d movl 0x28(%rsp), %r10d
movl -8(%rsp), %r11d movl 0x30(%rsp), %r11d
movl %edx, %ebx movl %edx, %ebx
imull %esi, %ebx imull %esi, %ebx
leal 4(%rbx), %ebp leal 4(%rbx), %ebp

View File

@ -0,0 +1,48 @@
--TEST--
001: Parameter Loading
--ARGS--
-S
--CODE--
{
l_1 = START(l_2);
int32_t p_1 = PARAM(l_1, "p_1", 1);
int32_t p_2 = PARAM(l_1, "p_2", 1);
int32_t p_3 = PARAM(l_1, "p_3", 1);
int32_t p_4 = PARAM(l_1, "p_4", 1);
int32_t p_5 = PARAM(l_1, "p_5", 1);
int32_t p_6 = PARAM(l_1, "p_6", 1);
int32_t p_7 = PARAM(l_1, "p_7", 1);
int32_t p_8 = PARAM(l_1, "p_8", 1);
int32_t p_9 = PARAM(l_1, "p_9", 1);
int32_t p_10 = PARAM(l_1, "p_10", 1);
int32_t r1 = ADD(p_1, p_2);
int32_t r2 = ADD(r1, p_3);
int32_t r3 = ADD(r2, p_4);
int32_t r4 = ADD(r3, p_5);
int32_t r5 = ADD(r4, p_6);
int32_t r6 = ADD(r5, p_7);
int32_t r7 = ADD(r6, p_8);
int32_t r8 = ADD(r7, p_9);
int32_t ret = SUB(r8, p_10);
l_2 = RETURN(l_1, ret);
}
--EXPECT--
test:
subq $8, %rsp
movq %rbx, (%rsp)
movl 0x10(%rsp), %eax
movl 0x18(%rsp), %r10d
movl 0x20(%rsp), %r11d
movl 0x28(%rsp), %ebx
leal (%rsi, %rdi), %esi
leal (%rsi, %rdx), %edx
leal (%rdx, %rcx), %ecx
leal (%rcx, %r8), %ecx
leal (%rcx, %r9), %ecx
leal (%rcx, %rax), %eax
leal (%rax, %r10), %eax
leal (%rax, %r11), %eax
subl %ebx, %eax
movq (%rsp), %rbx
addq $8, %rsp
retq

View File

@ -0,0 +1,43 @@
--TEST--
002: Parameter Loading
--ARGS--
-S
--CODE--
{
l_1 = START(l_2);
double p_1 = PARAM(l_1, "p_1", 1);
double p_2 = PARAM(l_1, "p_2", 1);
double p_3 = PARAM(l_1, "p_3", 1);
double p_4 = PARAM(l_1, "p_4", 1);
double p_5 = PARAM(l_1, "p_5", 1);
double p_6 = PARAM(l_1, "p_6", 1);
double p_7 = PARAM(l_1, "p_7", 1);
double p_8 = PARAM(l_1, "p_8", 1);
double p_9 = PARAM(l_1, "p_9", 1);
double p_10 = PARAM(l_1, "p_10", 1);
double r1 = ADD(p_1, p_2);
double r2 = ADD(r1, p_3);
double r3 = ADD(r2, p_4);
double r4 = ADD(r3, p_5);
double r5 = ADD(r4, p_6);
double r6 = ADD(r5, p_7);
double r7 = ADD(r6, p_8);
double r8 = ADD(r7, p_9);
double ret = SUB(r8, p_10);
l_2 = RETURN(l_1, ret);
}
--EXPECT--
test:
movsd 8(%rsp), %xmm8
movsd 0x10(%rsp), %xmm9
addsd %xmm0, %xmm1
addsd %xmm2, %xmm1
addsd %xmm3, %xmm1
addsd %xmm4, %xmm1
addsd %xmm5, %xmm1
addsd %xmm6, %xmm1
addsd %xmm7, %xmm1
movapd %xmm1, %xmm0
addsd %xmm8, %xmm0
subsd %xmm9, %xmm0
retq