mirror of
https://github.com/danog/ir.git
synced 2025-01-22 05:31:32 +01:00
Fix ALLOCA to align stack frame
This commit is contained in:
parent
5cb0af8cd9
commit
4a6c8d60a6
2
TODO
2
TODO
@ -66,7 +66,7 @@
|
||||
- CAST
|
||||
+ TAILCALL
|
||||
+ VLOAD, VSTORE, VADDR
|
||||
? ALLOCA, LOAD, STORE
|
||||
+ ALLOCA, LOAD, STORE
|
||||
+ SWITCH
|
||||
? ir_last_use
|
||||
+ binop_int $imm, mem
|
||||
|
36
ir_x86.dasc
36
ir_x86.dasc
@ -3241,10 +3241,40 @@ static void ir_emit_alloca(ir_ctx *ctx, ir_ref def, ir_insn *insn)
|
||||
ir_backend_data *data = ctx->data;
|
||||
dasm_State **Dst = &data->dasm_state;
|
||||
|
||||
// TODO: alignment
|
||||
| ASM_REG_REF_OP sub, IR_ADDR, IR_REG_RSP, insn->op2
|
||||
if (IR_IS_CONST_REF(insn->op2)) {
|
||||
ir_insn *val = &ctx->ir_base[insn->op2];
|
||||
int32_t size = val->val.i32;
|
||||
|
||||
IR_ASSERT(IR_IS_TYPE_INT(val->type));
|
||||
IR_ASSERT(IR_IS_TYPE_UNSIGNED(val->type) || val->val.i64 > 0);
|
||||
IR_ASSERT(IR_IS_SIGNED_32BIT(val->val.i64));
|
||||
|
||||
if (ctx->flags & IR_HAS_CALLS) {
|
||||
/* Stack must be 16 byte aligned */
|
||||
size = IR_ALIGNED_SIZE(size, 16);
|
||||
} else {
|
||||
size = IR_ALIGNED_SIZE(size, 8);
|
||||
}
|
||||
| ASM_REG_IMM_OP sub, IR_ADDR, IR_REG_RSP, size
|
||||
} else {
|
||||
int32_t alignment = (ctx->flags & IR_HAS_CALLS) ? 16 : 8;
|
||||
ir_reg op2_reg = ir_ref_reg(ctx, insn->op2);
|
||||
ir_reg reg;
|
||||
|
||||
if (op2_reg >=0 && ir_last_use(ctx, insn->op2, def)) {
|
||||
reg = op2_reg;
|
||||
} else {
|
||||
reg = IR_REG_RAX; // TODO: temporary register
|
||||
}
|
||||
if (reg != op2_reg) {
|
||||
ir_emit_load(ctx, IR_ADDR, insn->op2, reg);
|
||||
}
|
||||
|
||||
| ASM_REG_IMM_OP add, IR_ADDR, reg, (alignment-1)
|
||||
| ASM_REG_IMM_OP and, IR_ADDR, reg, ~(alignment-1)
|
||||
| ASM_REG_REG_OP sub, IR_ADDR, IR_REG_RSP, reg
|
||||
}
|
||||
ir_emit_store(ctx, IR_ADDR, IR_REG_RSP, def);
|
||||
// TODO: stack frame alignment
|
||||
}
|
||||
|
||||
static void ir_emit_switch(ir_ctx *ctx, ir_ref def, ir_insn *insn)
|
||||
|
67
tests/debug/call_alloca.irt
Normal file
67
tests/debug/call_alloca.irt
Normal file
@ -0,0 +1,67 @@
|
||||
--TEST--
|
||||
Simple CALL with ALLOCA
|
||||
--ARGS--
|
||||
-S --run
|
||||
--CODE--
|
||||
{
|
||||
uintptr_t c_1 = 0;
|
||||
bool c_2 = 0;
|
||||
bool c_3 = 1;
|
||||
int32_t c_4 = 42;
|
||||
char h = 'h';
|
||||
char i = 'i';
|
||||
char sp = ' ';
|
||||
char pc = '%';
|
||||
char d = 'd';
|
||||
char nl = '\n';
|
||||
char zero = 0;
|
||||
uint32_t len = 7;
|
||||
uintptr_t one = 1;
|
||||
uintptr_t c_5 = func(printf);
|
||||
l_1 = START(l_4);
|
||||
uintptr_t a_0, s_0 = ALLOCA(l_1, len);
|
||||
s_1 = STORE(s_0, a_0, h);
|
||||
uintptr_t a_1 = ADD(a_0, one);
|
||||
s_2 = STORE(s_1, a_1, i);
|
||||
uintptr_t a_2 = ADD(a_1, one);
|
||||
s_3 = STORE(s_2, a_2, sp);
|
||||
uintptr_t a_3 = ADD(a_2, one);
|
||||
s_4 = STORE(s_3, a_3, pc);
|
||||
uintptr_t a_4 = ADD(a_3, one);
|
||||
s_5 = STORE(s_4, a_4, d);
|
||||
uintptr_t a_5 = ADD(a_4, one);
|
||||
s_6 = STORE(s_5, a_5, nl);
|
||||
uintptr_t a_6 = ADD(a_5, one);
|
||||
s_7 = STORE(s_6, a_6, zero);
|
||||
int32_t d_2, l_2 = CALL/2(s_7, c_5, a_0, c_4);
|
||||
l_4 = RETURN(l_2, d_2);
|
||||
}
|
||||
--EXPECT--
|
||||
test:
|
||||
pushq %rbp
|
||||
movq %rsp, %rbp
|
||||
subq $0x10, %rsp
|
||||
movq %rsp, %rdi
|
||||
movb $0x68, (%rdi)
|
||||
leaq 1(%rdi), %rax
|
||||
movb $0x69, (%rax)
|
||||
leaq 2(%rdi), %rax
|
||||
movb $0x20, (%rax)
|
||||
leaq 3(%rdi), %rax
|
||||
movb $0x25, (%rax)
|
||||
leaq 4(%rdi), %rax
|
||||
movb $0x64, (%rax)
|
||||
leaq 5(%rdi), %rax
|
||||
movb $0xa, (%rax)
|
||||
leaq 6(%rdi), %rax
|
||||
movb $0, (%rax)
|
||||
movl $0x2a, %esi
|
||||
movabsq $_IO_printf, %rax
|
||||
callq *%rax
|
||||
movq %rbp, %rsp
|
||||
popq %rbp
|
||||
retq
|
||||
|
||||
hi 42
|
||||
|
||||
exit code = 6
|
@ -88,7 +88,7 @@ test:
|
||||
movsd %xmm7, -0x28(%rbp)
|
||||
xorpd %xmm7, %xmm7
|
||||
movsd %xmm7, -0x20(%rbp)
|
||||
subq $4, %rsp
|
||||
subq $8, %rsp
|
||||
movq %rsp, %rax
|
||||
movl $0, (%rax)
|
||||
.L1:
|
||||
|
Loading…
x
Reference in New Issue
Block a user