Skip to content

Commit

Permalink
Remove stack position counting
Browse files Browse the repository at this point in the history
On x64,
stack pointer is aligned to 16
if the function contains function call in it.
  • Loading branch information
tyfkda committed Oct 6, 2024
1 parent 1be4254 commit f96fa84
Show file tree
Hide file tree
Showing 7 changed files with 25 additions and 50 deletions.
11 changes: 6 additions & 5 deletions src/cc/arch/aarch64/ir_aarch64.c
Original file line number Diff line number Diff line change
Expand Up @@ -670,8 +670,9 @@ static void ei_precall(IR *ir) {
int align_stack = (16 - (ir->precall.stack_args_size)) & 15;
ir->precall.stack_aligned = align_stack;

if (align_stack > 0) {
SUB(SP, SP, IM(align_stack));
int total = align_stack + ir->precall.stack_args_size;
if (total > 0) {
SUB(SP, SP, IM(total));
}
}

Expand Down Expand Up @@ -706,9 +707,9 @@ static void ei_call(IR *ir) {
}

IR *precall = ir->call.precall;
int align_stack = precall->precall.stack_aligned + precall->precall.stack_args_size;
if (align_stack != 0) {
ADD(SP, SP, IM(align_stack));
int total = precall->precall.stack_aligned + precall->precall.stack_args_size;
if (total != 0) {
ADD(SP, SP, IM(total));
}

// Resore caller save registers.
Expand Down
11 changes: 6 additions & 5 deletions src/cc/arch/riscv64/ir_riscv64.c
Original file line number Diff line number Diff line change
Expand Up @@ -646,8 +646,9 @@ static void ei_precall(IR *ir) {
int align_stack = (16 - (ir->precall.stack_args_size)) & 15;
ir->precall.stack_aligned = align_stack;

if (align_stack > 0) {
ADDI(SP, SP, IM(-align_stack));
int total = align_stack + ir->precall.stack_args_size;
if (total > 0) {
ADDI(SP, SP, IM(-total));
}
}

Expand Down Expand Up @@ -691,9 +692,9 @@ static void ei_call(IR *ir) {
}

IR *precall = ir->call.precall;
int align_stack = precall->precall.stack_aligned + precall->precall.stack_args_size;
if (align_stack != 0) {
ADDI(SP, SP, IM(align_stack));
int total = precall->precall.stack_aligned + precall->precall.stack_args_size;
if (total != 0) {
ADDI(SP, SP, IM(total));
}

// Resore caller save registers.
Expand Down
18 changes: 5 additions & 13 deletions src/cc/arch/x64/emit_code.c
Original file line number Diff line number Diff line change
Expand Up @@ -153,8 +153,6 @@ void emit_defun(Function *func) {
func->extra == NULL) // Code emission is omitted.
return;

assert(stackpos == 8);

emit_comment(NULL);
_TEXT();

Expand Down Expand Up @@ -197,16 +195,17 @@ void emit_defun(Function *func) {
FuncBackend *fnbe = func->extra;
size_t frame_size = 0;
bool rbp_saved = false;
int callee_saved_count = 0;
if (!no_stmt) {
// Callee save.
int callee_saved_count = push_callee_save_regs(fnbe->ra->used_reg_bits, fnbe->ra->used_freg_bits);
callee_saved_count = push_callee_save_regs(fnbe->ra->used_reg_bits, fnbe->ra->used_freg_bits);

// When function is called, return address is pused onto the stack by caller,
// so default offset is 8.
size_t frame_offset = 8;

if (fnbe->frame_size > 0 || fnbe->ra->flag & RAF_STACK_FRAME) {
PUSH(RBP); PUSH_STACK_POS();
PUSH(RBP);
MOV(RSP, RBP);
rbp_saved = true;
// RBP is pushed so the 16-bytes-align offset becomes 0.
Expand All @@ -215,13 +214,12 @@ void emit_defun(Function *func) {

size_t callee_saved_size = callee_saved_count * TARGET_POINTER_SIZE;
frame_size = fnbe->frame_size;
if (func->flag & FUNCF_HAS_FUNCALL) {
if (func->flag & (FUNCF_HAS_FUNCALL | FUNCF_STACK_MODIFIED)) {
// Align frame size to 16 only it contains funcall.
frame_size += -(fnbe->frame_size + callee_saved_size + frame_offset) & 15;
}
if (frame_size > 0) {
SUB(IM(frame_size), RSP);
stackpos += frame_size;
}

move_params_to_assigned(func);
Expand All @@ -234,21 +232,15 @@ void emit_defun(Function *func) {
if (!no_stmt) {
if (rbp_saved) {
MOV(RBP, RSP);
stackpos -= frame_size;
POP(RBP); POP_STACK_POS();
POP(RBP);
} else if (frame_size > 0) {
ADD(IM(frame_size), RSP);
stackpos -= frame_size;
}

pop_callee_save_regs(fnbe->ra->used_reg_bits, fnbe->ra->used_freg_bits);
}

RET();

assert(stackpos == 8);
} else {
stackpos = 8;
}

// Static variables are emitted through global variables.
Expand Down
5 changes: 0 additions & 5 deletions src/cc/arch/x64/emit_code.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,6 @@

typedef struct Vector Vector;

extern int stackpos;

#define PUSH_STACK_POS() do { stackpos += TARGET_POINTER_SIZE; } while (0)
#define POP_STACK_POS() do { stackpos -= TARGET_POINTER_SIZE; } while (0)

char *im(int64_t x); // $x
char *indirect(const char *base, const char *index, int scale);
char *offset_indirect(int offset, const char *base, const char *index, int scale);
Expand Down
24 changes: 7 additions & 17 deletions src/cc/arch/x64/ir_x64.c
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,6 @@
static Vector *push_caller_save_regs(unsigned long living);
static void pop_caller_save_regs(Vector *saves);

int stackpos = 8;

// Register allocator

const char *kRegSizeTable[][PHYSICAL_REG_MAX] = {
Expand Down Expand Up @@ -715,12 +713,12 @@ static void ei_precall(IR *ir) {
// so safely saved before calculating argument values.
ir->precall.caller_saves = push_caller_save_regs(ir->precall.living_pregs);

int align_stack = (16 - (stackpos + ir->precall.stack_args_size)) & 15;
int align_stack = (16 - (ir->precall.caller_saves->len * TARGET_POINTER_SIZE + ir->precall.stack_args_size)) & 15;
ir->precall.stack_aligned = align_stack;

if (align_stack > 0) {
SUB(IM(align_stack), RSP);
stackpos += align_stack;
int total = align_stack + ir->precall.stack_args_size;
if (total > 0) {
SUB(IM(total), RSP);
}
}

Expand Down Expand Up @@ -775,10 +773,9 @@ static void ei_call(IR *ir) {
}

IR *precall = ir->call.precall;
int align_stack = precall->precall.stack_aligned + precall->precall.stack_args_size;
if (align_stack != 0) {
ADD(IM(align_stack), RSP);
stackpos -= precall->precall.stack_aligned;
int total = precall->precall.stack_aligned + precall->precall.stack_args_size;
if (total != 0) {
ADD(IM(total), RSP);
}

// Resore caller save registers.
Expand Down Expand Up @@ -834,7 +831,6 @@ static void ei_subsp(IR *ir) {
SUB(IM(ir->opr1->fixnum), RSP);
else if (ir->opr1->fixnum < 0)
ADD(IM(-ir->opr1->fixnum), RSP);
// stackpos += ir->opr1->fixnum;
} else {
SUB(kReg64s[ir->opr1->phys], RSP);
}
Expand Down Expand Up @@ -1008,7 +1004,6 @@ int push_callee_save_regs(unsigned long used, unsigned long fused) {
int ireg = kCalleeSaveRegs[i];
if (used & (1 << ireg)) {
PUSH(kReg64s[ireg]);
PUSH_STACK_POS();
++count;
}
}
Expand All @@ -1023,7 +1018,6 @@ void pop_callee_save_regs(unsigned long used, unsigned long fused) {
int ireg = kCalleeSaveRegs[i];
if (used & (1 << ireg)) {
POP(kReg64s[ireg]);
POP_STACK_POS();
}
}
}
Expand All @@ -1044,7 +1038,6 @@ static Vector *push_caller_save_regs(unsigned long living) {
if (living & (1UL << ireg)) {
const char *reg = kReg64s[ireg];
PUSH(reg);
PUSH_STACK_POS();
vec_push(saves, reg);
}
}
Expand All @@ -1062,7 +1055,6 @@ static Vector *push_caller_save_regs(unsigned long living) {
if (n > 0) {
int ofs = n * TARGET_POINTER_SIZE;
SUB(IM(ofs), RSP);
stackpos += ofs;
for (int i = 0; i < n; ++i) {
ofs -= TARGET_POINTER_SIZE;
MOVSD(saves->data[i + fstart], OFFSET_INDIRECT(ofs, RSP, NULL, 1));
Expand All @@ -1085,14 +1077,12 @@ static void pop_caller_save_regs(Vector *saves) {
}
if (ofs > 0) {
ADD(IM(ofs), RSP);
stackpos -= ofs;
}
++i;

while (--i >= 0) {
const char *reg = saves->data[i];
POP(reg);
POP_STACK_POS();
}
}

Expand Down
4 changes: 0 additions & 4 deletions src/cc/backend/codegen_expr.c
Original file line number Diff line number Diff line change
Expand Up @@ -410,13 +410,9 @@ static VReg *gen_funcall(Expr *expr) {
}
}
}
offset = ALIGN(offset, 16);

IR *precall = new_ir_precall(arg_count - stack_arg_count, offset);

if (offset > 0)
new_ir_subsp(new_const_vreg(offset, to_vsize(&tySSize)), NULL);

int total_arg_count = arg_count + (ret_varinfo != NULL ? 1 : 0);
VReg **arg_vregs = total_arg_count == 0 ? NULL : calloc_or_die(total_arg_count * sizeof(*arg_vregs));

Expand Down
2 changes: 1 addition & 1 deletion src/cc/backend/ir.c
Original file line number Diff line number Diff line change
Expand Up @@ -270,7 +270,7 @@ IR *new_ir_precall(int arg_count, int stack_args_size) {
IR *ir = new_ir(IR_PRECALL);
ir->precall.arg_count = arg_count;
ir->precall.stack_args_size = stack_args_size;
ir->precall.stack_aligned = false;
ir->precall.stack_aligned = 0;
ir->precall.living_pregs = 0;
ir->precall.caller_saves = NULL;
return ir;
Expand Down

0 comments on commit f96fa84

Please sign in to comment.