mirror of
https://github.com/Mercantec-GHC/h4-projekt-gruppe-0-sm.git
synced 2025-04-27 16:24:07 +02:00
compiler: fix stack alignment
This commit is contained in:
parent
14d5afcaea
commit
43740eb9ee
@ -108,6 +108,10 @@ export class AsmGen {
|
|||||||
this.writeIns(`push rbp`);
|
this.writeIns(`push rbp`);
|
||||||
this.writeIns(`mov rbp, rsp`);
|
this.writeIns(`mov rbp, rsp`);
|
||||||
this.writeIns(`sub rsp, 8`);
|
this.writeIns(`sub rsp, 8`);
|
||||||
|
|
||||||
|
// By doing this, we avoid having to maintain 16-byte stack alignment.
|
||||||
|
this.writeIns(`and rsp, 0xFFFFFFFFFFFFFFF0`);
|
||||||
|
|
||||||
for (let i = 0; i < args; ++i) {
|
for (let i = 0; i < args; ++i) {
|
||||||
this.writeIns(`mov rax, ${this.relative((i + 2) * 8)}`);
|
this.writeIns(`mov rax, ${this.relative((i + 2) * 8)}`);
|
||||||
this.writeIns(`push rax`);
|
this.writeIns(`push rax`);
|
||||||
@ -130,7 +134,6 @@ export class AsmGen {
|
|||||||
|
|
||||||
this.writeIns(`push rbp`);
|
this.writeIns(`push rbp`);
|
||||||
this.writeIns(`mov rbp, rsp`);
|
this.writeIns(`mov rbp, rsp`);
|
||||||
this.writeIns(`sub rsp, 8`);
|
|
||||||
|
|
||||||
const args = fn.mir.paramLocals.size;
|
const args = fn.mir.paramLocals.size;
|
||||||
|
|
||||||
@ -168,7 +171,7 @@ export class AsmGen {
|
|||||||
this.writeIns(`push rbp`);
|
this.writeIns(`push rbp`);
|
||||||
this.writeIns(`mov rbp, rsp`);
|
this.writeIns(`mov rbp, rsp`);
|
||||||
|
|
||||||
this.writeIns(`sub rsp, ${this.layout.frameSize - 8}`);
|
this.writeIns(`sub rsp, ${this.layout.frameSize}`);
|
||||||
this.writeIns(`jmp .L${fn.mir.entry.id}`);
|
this.writeIns(`jmp .L${fn.mir.entry.id}`);
|
||||||
|
|
||||||
for (const line of fn.lines.slice(bodyIdx)) {
|
for (const line of fn.lines.slice(bodyIdx)) {
|
||||||
@ -404,6 +407,8 @@ class StackAllocator {
|
|||||||
public finalize(): StackLayout {
|
public finalize(): StackLayout {
|
||||||
const regOffsets = new Map<lir.Reg, number>();
|
const regOffsets = new Map<lir.Reg, number>();
|
||||||
|
|
||||||
|
// Last param is at [rbp+8]
|
||||||
|
// See: https://eli.thegreenplace.net/2011/09/06/stack-frame-layout-on-x86-64
|
||||||
let currentOffset = 8;
|
let currentOffset = 8;
|
||||||
|
|
||||||
for (const [reg, size] of [...this.paramRegs].toReversed()) {
|
for (const [reg, size] of [...this.paramRegs].toReversed()) {
|
||||||
@ -412,27 +417,17 @@ class StackAllocator {
|
|||||||
regOffsets.set(reg, currentOffset);
|
regOffsets.set(reg, currentOffset);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Start at 8 because rbp is pushed, and
|
// First local is at [rbp-8]
|
||||||
// therefore the *first value*, meaning
|
// See above.
|
||||||
// the return address is at stack[top - 1].
|
currentOffset = -8;
|
||||||
currentOffset = 8;
|
|
||||||
let frameSize = 0;
|
let frameSize = 0;
|
||||||
|
|
||||||
// return address
|
|
||||||
currentOffset -= 8;
|
|
||||||
// caller rbp
|
|
||||||
currentOffset -= 8;
|
|
||||||
frameSize += 8;
|
|
||||||
|
|
||||||
for (const [reg, size] of this.localRegs) {
|
for (const [reg, size] of this.localRegs) {
|
||||||
regOffsets.set(reg, currentOffset);
|
regOffsets.set(reg, currentOffset);
|
||||||
currentOffset -= align8(size);
|
currentOffset -= align8(size);
|
||||||
frameSize += align8(size);
|
frameSize += align8(size);
|
||||||
}
|
}
|
||||||
|
|
||||||
// frameSize - 8 is safe because frameSize is always >= 8.
|
|
||||||
frameSize = align(frameSize - 8, 16);
|
|
||||||
|
|
||||||
return new StackLayout(frameSize, regOffsets);
|
return new StackLayout(frameSize, regOffsets);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,8 +1,15 @@
|
|||||||
|
|
||||||
#[c_function("println")]
|
fn main() -> int {
|
||||||
fn println(value: *str) -> int {}
|
let i = 0;
|
||||||
#[c_function("print_int")]
|
|
||||||
fn print_int(value: int) -> int {}
|
while i < 10 {
|
||||||
|
print_int(factorial(i));
|
||||||
|
println("Hello\ world");
|
||||||
|
|
||||||
|
i = i + 1;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
fn factorial(v: int) -> int {
|
fn factorial(v: int) -> int {
|
||||||
if v == 0 {
|
if v == 0 {
|
||||||
@ -11,17 +18,10 @@ fn factorial(v: int) -> int {
|
|||||||
return v * factorial(v - 1);
|
return v * factorial(v - 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn main() -> int {
|
#[c_function("println")]
|
||||||
let i = 0;
|
fn println(value: *str) -> int {}
|
||||||
|
#[c_function("print_int")]
|
||||||
while i < 10 {
|
fn print_int(value: int) -> int {}
|
||||||
// print_int(i);
|
|
||||||
println("Hello\ world");
|
|
||||||
|
|
||||||
i = i + 1;
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
#[c_export("sbc_main")]
|
#[c_export("sbc_main")]
|
||||||
fn sbc_main() -> int {
|
fn sbc_main() -> int {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user