Skip to content

Commit

Permalink
Stack data alignment
Browse files Browse the repository at this point in the history
  • Loading branch information
dstogov committed Apr 10, 2024
1 parent 0a26181 commit 5c48ad1
Show file tree
Hide file tree
Showing 8 changed files with 47 additions and 52 deletions.
32 changes: 15 additions & 17 deletions ir_aarch64.dasc
Original file line number Diff line number Diff line change
Expand Up @@ -518,6 +518,9 @@ int ir_get_target_constraints(ir_ctx *ctx, ir_ref ref, ir_target_constraints *co
insn = &ctx->ir_base[insn->op3];
constraints->tmp_regs[0] = IR_TMP_REG(3, insn->type, IR_LOAD_SUB_REF, IR_DEF_SUB_REF);
n = 1;
} else if (ir_rule(ctx, insn->op3) == IR_STATIC_ALLOCA) {
constraints->tmp_regs[0] = IR_TMP_REG(3, IR_ADDR, IR_LOAD_SUB_REF, IR_DEF_SUB_REF);
n = 1;
}
break;
case IR_LOAD_FP:
Expand Down Expand Up @@ -919,6 +922,7 @@ binop_fp:
return insn->op;
}
case IR_CALL:
ctx->flags |= IR_USE_FRAME_POINTER;
ctx->flags2 |= IR_HAS_CALLS | IR_16B_FRAME_ALIGNMENT;
return IR_CALL;
case IR_VAR:
Expand All @@ -935,7 +939,7 @@ binop_fp:
}
}
ctx->flags |= IR_USE_FRAME_POINTER;
ctx->flags2 |= IR_HAS_ALLOCA;
ctx->flags2 |= IR_HAS_ALLOCA | IR_16B_FRAME_ALIGNMENT;
}
return IR_ALLOCA;
case IR_LOAD:
Expand Down Expand Up @@ -3755,7 +3759,10 @@ static void ir_emit_vstore(ir_ctx *ctx, ir_ref ref, ir_insn *insn)
fp = (ctx->flags & IR_USE_FRAME_POINTER) ? IR_REG_FRAME_POINTER : IR_REG_STACK_POINTER;
offset = IR_SPILL_POS_TO_OFFSET(var_insn->op3);
IR_ASSERT(op3_reg != IR_REG_NONE);
if (IR_REG_SPILLED(op3_reg) && ir_is_same_mem_var(ctx, insn->op3, var_insn->op3)) {
if (IR_REG_SPILLED(op3_reg)
&& !IR_IS_CONST_REF(insn->op3)
&& ir_rule(ctx, insn->op3) != IR_STATIC_ALLOCA
&& ir_is_same_mem_var(ctx, insn->op3, var_insn->op3)) {
return; // fake store
}
if (IR_REG_SPILLED(op3_reg)) {
Expand Down Expand Up @@ -4041,12 +4048,8 @@ static void ir_emit_alloca(ir_ctx *ctx, ir_ref def, ir_insn *insn)
IR_ASSERT(!IR_IS_SYM_CONST(val->op));
IR_ASSERT(IR_IS_TYPE_UNSIGNED(val->type) || val->val.i64 >= 0);

if (ctx->flags2 & IR_16B_FRAME_ALIGNMENT) {
/* Stack must be 16 byte aligned */
size = IR_ALIGNED_SIZE(size, 16);
} else {
size = IR_ALIGNED_SIZE(size, 8);
}
/* Stack must be 16 byte aligned */
size = IR_ALIGNED_SIZE(size, 16);
if (aarch64_may_encode_imm12(size)) {
| sub sp, sp, #size
} else {
Expand All @@ -4057,7 +4060,7 @@ static void ir_emit_alloca(ir_ctx *ctx, ir_ref def, ir_insn *insn)
ctx->call_stack_size += size;
}
} else {
int32_t alignment = (ctx->flags2 & IR_16B_FRAME_ALIGNMENT) ? 16 : 8;
int32_t alignment = 16;
ir_reg op2_reg = ctx->regs[def][2];
ir_type type = ctx->ir_base[insn->op2].type;

Expand Down Expand Up @@ -4095,18 +4098,14 @@ static void ir_emit_afree(ir_ctx *ctx, ir_ref def, ir_insn *insn)
IR_ASSERT(!IR_IS_SYM_CONST(val->op));
IR_ASSERT(IR_IS_TYPE_UNSIGNED(val->type) || val->val.i64 > 0);

if (ctx->flags2 & IR_16B_FRAME_ALIGNMENT) {
/* Stack must be 16 byte aligned */
size = IR_ALIGNED_SIZE(size, 16);
} else {
size = IR_ALIGNED_SIZE(size, 8);
}
/* Stack must be 16 byte aligned */
size = IR_ALIGNED_SIZE(size, 16);
| add sp, sp, #size
if (!(ctx->flags & IR_USE_FRAME_POINTER)) {
ctx->call_stack_size -= size;
}
} else {
// int32_t alignment = (ctx->flags2 & IR_16B_FRAME_ALIGNMENT) ? 16 : 8;
// int32_t alignment = 16;
ir_reg op2_reg = ctx->regs[def][2];
ir_type type = ctx->ir_base[insn->op2].type;

Expand Down Expand Up @@ -5766,7 +5765,6 @@ void ir_fix_stack_frame(ir_ctx *ctx)
ctx->stack_frame_alignment += sizeof(void*);
}
} else if (ctx->flags2 & IR_16B_FRAME_ALIGNMENT) {
ctx->flags |= IR_USE_FRAME_POINTER;
/* Stack must be 16 byte aligned */
if (!(ctx->flags & IR_FUNCTION)) {
while (IR_ALIGNED_SIZE(ctx->stack_frame_size, 16) != ctx->stack_frame_size) {
Expand Down
13 changes: 5 additions & 8 deletions ir_ra.c
Original file line number Diff line number Diff line change
Expand Up @@ -2609,14 +2609,11 @@ static int32_t ir_allocate_big_spill_slot(ir_ctx *ctx, int32_t size, ir_reg_allo
return ir_allocate_small_spill_slot(ctx, size, data);
}

if (ctx->flags2 & IR_16B_FRAME_ALIGNMENT) {
/* Stack must be 16 byte aligned */
size = IR_ALIGNED_SIZE(size, 16);
} else {
size = IR_ALIGNED_SIZE(size, 8);
}
ret = ctx->stack_frame_size;
ctx->stack_frame_size += size;
/* Align stack allocated data to 16 byte */
ctx->flags2 |= IR_16B_FRAME_ALIGNMENT;
ret = IR_ALIGNED_SIZE(ctx->stack_frame_size, 16);
size = IR_ALIGNED_SIZE(size, 8);
ctx->stack_frame_size = ret + size;

return ret;
}
Expand Down
33 changes: 16 additions & 17 deletions ir_x86.dasc
Original file line number Diff line number Diff line change
Expand Up @@ -1285,6 +1285,9 @@ op2_const:
insn = &ctx->ir_base[ref];
if (IR_IS_CONST_REF(insn->op3)) {
n = ir_add_const_tmp_reg(ctx, insn->op3, 3, n, constraints);
} else if (ir_rule(ctx, insn->op3) == IR_STATIC_ALLOCA) {
constraints->tmp_regs[n] = IR_TMP_REG(3, IR_ADDR, IR_LOAD_SUB_REF, IR_DEF_SUB_REF);
n++;
}
break;
case IR_STORE_INT:
Expand Down Expand Up @@ -2281,7 +2284,7 @@ binop_fp:
}
}
ctx->flags |= IR_USE_FRAME_POINTER;
ctx->flags2 |= IR_HAS_ALLOCA;
ctx->flags2 |= IR_HAS_ALLOCA | IR_16B_FRAME_ALIGNMENT;
}
return IR_ALLOCA;
case IR_VSTORE:
Expand Down Expand Up @@ -7431,7 +7434,9 @@ static void ir_emit_vstore_int(ir_ctx *ctx, ir_ref ref, ir_insn *insn)
fp = (ctx->flags & IR_USE_FRAME_POINTER) ? IR_REG_FRAME_POINTER : IR_REG_STACK_POINTER;
mem = IR_MEM_BO(fp, IR_SPILL_POS_TO_OFFSET(var_insn->op3));
if ((op3_reg == IR_REG_NONE || IR_REG_SPILLED(op3_reg))
&& !IR_IS_CONST_REF(insn->op3) && ir_is_same_mem_var(ctx, insn->op3, var_insn->op3)) {
&& !IR_IS_CONST_REF(insn->op3)
&& ir_rule(ctx, insn->op3) != IR_STATIC_ALLOCA
&& ir_is_same_mem_var(ctx, insn->op3, var_insn->op3)) {
return; // fake store
}
if (IR_IS_CONST_REF(insn->op3)) {
Expand All @@ -7458,7 +7463,9 @@ static void ir_emit_vstore_fp(ir_ctx *ctx, ir_ref ref, ir_insn *insn)
fp = (ctx->flags & IR_USE_FRAME_POINTER) ? IR_REG_FRAME_POINTER : IR_REG_STACK_POINTER;
mem = IR_MEM_BO(fp, IR_SPILL_POS_TO_OFFSET(var_insn->op3));
if ((op3_reg == IR_REG_NONE || IR_REG_SPILLED(op3_reg))
&& !IR_IS_CONST_REF(insn->op3) && ir_is_same_mem_var(ctx, insn->op3, var_insn->op3)) {
&& !IR_IS_CONST_REF(insn->op3)
&& ir_rule(ctx, insn->op3) != IR_STATIC_ALLOCA
&& ir_is_same_mem_var(ctx, insn->op3, var_insn->op3)) {
return; // fake store
}
if (IR_IS_CONST_REF(insn->op3)) {
Expand Down Expand Up @@ -7763,18 +7770,14 @@ static void ir_emit_alloca(ir_ctx *ctx, ir_ref def, ir_insn *insn)
IR_ASSERT(IR_IS_TYPE_UNSIGNED(val->type) || val->val.i64 >= 0);
IR_ASSERT(IR_IS_SIGNED_32BIT(val->val.i64));

if (ctx->flags2 & IR_16B_FRAME_ALIGNMENT) {
/* Stack must be 16 byte aligned */
size = IR_ALIGNED_SIZE(size, 16);
} else {
size = IR_ALIGNED_SIZE(size, 8);
}
/* Stack must be 16 byte aligned */
size = IR_ALIGNED_SIZE(size, 16);
| ASM_REG_IMM_OP sub, IR_ADDR, IR_REG_RSP, size
if (!(ctx->flags & IR_USE_FRAME_POINTER)) {
ctx->call_stack_size += size;
}
} else {
int32_t alignment = (ctx->flags2 & IR_16B_FRAME_ALIGNMENT) ? 16 : 8;
int32_t alignment = 16;
ir_reg op2_reg = ctx->regs[def][2];
ir_type type = ctx->ir_base[insn->op2].type;

Expand Down Expand Up @@ -7821,18 +7824,14 @@ static void ir_emit_afree(ir_ctx *ctx, ir_ref def, ir_insn *insn)
IR_ASSERT(IR_IS_TYPE_UNSIGNED(val->type) || val->val.i64 > 0);
IR_ASSERT(IR_IS_SIGNED_32BIT(val->val.i64));

if (ctx->flags2 & IR_16B_FRAME_ALIGNMENT) {
/* Stack must be 16 byte aligned */
size = IR_ALIGNED_SIZE(size, 16);
} else {
size = IR_ALIGNED_SIZE(size, 8);
}
/* Stack must be 16 byte aligned */
size = IR_ALIGNED_SIZE(size, 16);
| ASM_REG_IMM_OP add, IR_ADDR, IR_REG_RSP, size
if (!(ctx->flags & IR_USE_FRAME_POINTER)) {
ctx->call_stack_size -= size;
}
} else {
// int32_t alignment = (ctx->flags2 & IR_16B_FRAME_ALIGNMENT) ? 16 : 8;
// int32_t alignment = 16;
ir_reg op2_reg = ctx->regs[def][2];
ir_type type = ctx->ir_base[insn->op2].type;

Expand Down
4 changes: 2 additions & 2 deletions tests/aarch64/alloca_002.irt
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,8 @@ aarch64
test:
stp x29, x30, [sp, #-0x10]!
mov x29, sp
add x0, x0, #7
and x0, x0, #0xfffffffffffffff8
add x0, x0, #0xf
and x0, x0, #0xfffffffffffffff0
sub sp, sp, x0
mov x0, sp
mov sp, x29
Expand Down
4 changes: 2 additions & 2 deletions tests/x86/alloca_001.irt
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ x86
}
--EXPECT--
test:
subl $0x10, %esp
subl $0x1c, %esp
movl %esp, %eax
addl $0x10, %esp
addl $0x1c, %esp
retl
5 changes: 3 additions & 2 deletions tests/x86/alloca_002.irt
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,10 @@ x86
test:
pushl %ebp
movl %esp, %ebp
subl $8, %esp
movl 8(%ebp), %eax
addl $7, %eax
andl $0xfffffff8, %eax
addl $0xf, %eax
andl $0xfffffff0, %eax
subl %eax, %esp
movl %esp, %eax
movl %ebp, %esp
Expand Down
4 changes: 2 additions & 2 deletions tests/x86_64/alloca_001.irt
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ x86_64
}
--EXPECT--
test:
subq $0x10, %rsp
subq $0x18, %rsp
movq %rsp, %rax
addq $0x10, %rsp
addq $0x18, %rsp
retq
4 changes: 2 additions & 2 deletions tests/x86_64/alloca_002.irt
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,8 @@ test:
pushq %rbp
movq %rsp, %rbp
movl %edi, %eax
addq $7, %rax
andq $0xfffffffffffffff8, %rax
addq $0xf, %rax
andq $0xfffffffffffffff0, %rax
subq %rax, %rsp
movq %rsp, %rax
movq %rbp, %rsp
Expand Down

0 comments on commit 5c48ad1

Please sign in to comment.