mirror of
https://github.com/Mercantec-GHC/h4-projekt-gruppe-0-sm.git
synced 2025-04-27 16:24:07 +02:00
compiler: fix pop parameters
This commit is contained in:
parent
d5541c46fa
commit
827e26577a
@ -168,7 +168,7 @@ export class AsmGen {
|
||||
this.writeIns(`push rbp`);
|
||||
this.writeIns(`mov rbp, rsp`);
|
||||
|
||||
this.writeIns(`sub rsp, ${this.layout.frameSize}`);
|
||||
this.writeIns(`sub rsp, ${this.layout.frameSize - 8}`);
|
||||
this.writeIns(`jmp .L${fn.mir.entry.id}`);
|
||||
|
||||
for (const line of fn.lines.slice(bodyIdx)) {
|
||||
@ -422,6 +422,7 @@ class StackAllocator {
|
||||
currentOffset -= 8;
|
||||
// caller rbp
|
||||
currentOffset -= 8;
|
||||
frameSize += 8;
|
||||
|
||||
for (const [reg, size] of this.localRegs) {
|
||||
regOffsets.set(reg, currentOffset);
|
||||
|
@ -12,6 +12,10 @@ import * as ast from "./ast.ts";
|
||||
import * as mir from "./mir.ts";
|
||||
import { optimizeMirFn } from "./mir_optimize.ts";
|
||||
|
||||
export type LirGenOpts = {
|
||||
optimize?: boolean;
|
||||
};
|
||||
|
||||
export class LirGen {
|
||||
private strings = new StringIntern();
|
||||
|
||||
@ -22,6 +26,7 @@ export class LirGen {
|
||||
public constructor(
|
||||
private ast: ast.Stmt[],
|
||||
private mirGen: MirGen,
|
||||
private opts: LirGenOpts = {},
|
||||
) {}
|
||||
|
||||
public generate(): Program {
|
||||
@ -30,7 +35,9 @@ export class LirGen {
|
||||
throw new Error("only functions can compile top level");
|
||||
}
|
||||
const mir = this.mirGen.fnMir(stmt, stmt.kind);
|
||||
optimizeMirFn(mir);
|
||||
if (this.opts.optimize !== false) {
|
||||
optimizeMirFn(mir);
|
||||
}
|
||||
const id = this.fnIds++;
|
||||
const label = `sbc__${stmt.kind.ident}`;
|
||||
const fn: Fn = {
|
||||
@ -189,6 +196,16 @@ class FnGen {
|
||||
this.pushIns({ tag: "pop", reg });
|
||||
this.pushIns({ tag: "call_reg", reg, args: k.args });
|
||||
this.pushIns({ tag: "kill", reg });
|
||||
|
||||
const rval = this.reg();
|
||||
this.pushIns({ tag: "pop", reg: rval });
|
||||
for (let i = 0; i < k.args; ++i) {
|
||||
const reg = this.reg();
|
||||
this.pushIns({ tag: "pop", reg });
|
||||
this.pushIns({ tag: "kill", reg });
|
||||
}
|
||||
this.pushIns({ tag: "push", reg: rval });
|
||||
this.pushIns({ tag: "kill", reg: rval });
|
||||
return;
|
||||
}
|
||||
case "lt":
|
||||
|
10
sbc/main.ts
10
sbc/main.ts
@ -17,6 +17,8 @@ async function main() {
|
||||
const re = new Resolver(ast).resolve();
|
||||
const ch = new Checker(re);
|
||||
|
||||
const optimize = true;
|
||||
|
||||
const mirGen = new MirGen(re, ch);
|
||||
|
||||
// console.log("=== MIR ===");
|
||||
@ -28,11 +30,15 @@ async function main() {
|
||||
// console.log(new FnStringifyer(fnMir).stringify());
|
||||
// }
|
||||
|
||||
const lir = new LirGen(ast, mirGen).generate();
|
||||
const lir = new LirGen(ast, mirGen, {
|
||||
optimize,
|
||||
}).generate();
|
||||
// console.log("=== LIR ===");
|
||||
// console.log(new ProgramStringifyer(lir).stringify());
|
||||
|
||||
optimizeLir(lir);
|
||||
if (optimize) {
|
||||
optimizeLir(lir);
|
||||
}
|
||||
|
||||
const asm = new AsmGen(lir).generate();
|
||||
// console.log("=== ASM ===");
|
||||
|
@ -110,15 +110,18 @@ export class FnMirGen {
|
||||
}
|
||||
case "while": {
|
||||
const entry = this.currentBlock;
|
||||
|
||||
const cond = this.block();
|
||||
const loop = this.block();
|
||||
const exit = this.block();
|
||||
this.currentBlock = cond;
|
||||
this.lowerExpr(k.expr);
|
||||
const condExit = this.currentBlock;
|
||||
|
||||
entry.ter = Ter({ tag: "goto", target: cond });
|
||||
|
||||
this.currentBlock = cond;
|
||||
this.lowerExpr(k.expr);
|
||||
this.currentBlock.ter = Ter({
|
||||
const loop = this.block();
|
||||
const exit = this.block();
|
||||
|
||||
condExit.ter = Ter({
|
||||
tag: "if",
|
||||
truthy: loop,
|
||||
falsy: exit,
|
||||
@ -128,7 +131,8 @@ export class FnMirGen {
|
||||
|
||||
this.currentBlock = loop;
|
||||
this.lowerBlock(k.body);
|
||||
this.currentBlock.ter = Ter({ tag: "goto", target: cond });
|
||||
const loopExit = this.currentBlock;
|
||||
loopExit.ter = Ter({ tag: "goto", target: cond });
|
||||
|
||||
this.currentBlock = exit;
|
||||
return;
|
||||
@ -136,23 +140,31 @@ export class FnMirGen {
|
||||
case "if": {
|
||||
this.lowerExpr(k.expr);
|
||||
const entry = this.currentBlock;
|
||||
const exit = this.block();
|
||||
const truthy = this.block();
|
||||
|
||||
const truthy = this.block();
|
||||
this.currentBlock = truthy;
|
||||
this.lowerBlock(k.truthy);
|
||||
this.currentBlock.ter = Ter({ tag: "goto", target: exit });
|
||||
const truthyExit = this.currentBlock;
|
||||
|
||||
let falsy = exit;
|
||||
if (k.falsy) {
|
||||
falsy = this.block();
|
||||
const falsy = this.block();
|
||||
this.currentBlock = falsy;
|
||||
this.lowerBlock(k.falsy);
|
||||
this.currentBlock.ter = Ter({ tag: "goto", target: exit });
|
||||
}
|
||||
const falsyExit = this.currentBlock;
|
||||
|
||||
entry.ter = Ter({ tag: "if", truthy, falsy });
|
||||
this.currentBlock = exit;
|
||||
const exit = this.block();
|
||||
truthyExit.ter = Ter({ tag: "goto", target: exit });
|
||||
falsyExit.ter = Ter({ tag: "goto", target: exit });
|
||||
|
||||
entry.ter = Ter({ tag: "if", truthy, falsy });
|
||||
this.currentBlock = exit;
|
||||
} else {
|
||||
const exit = this.block();
|
||||
truthyExit.ter = Ter({ tag: "goto", target: exit });
|
||||
|
||||
entry.ter = Ter({ tag: "if", truthy, falsy: exit });
|
||||
this.currentBlock = exit;
|
||||
}
|
||||
return;
|
||||
}
|
||||
case "return": {
|
||||
|
@ -2,9 +2,9 @@ import * as ast from "./ast.ts";
|
||||
import { Block, Fn, FnStringifyer } from "./mir.ts";
|
||||
|
||||
export function optimizeMirFn(fn: Fn) {
|
||||
console.log(`=== OPTIMIZING ${(fn.stmt.kind as ast.FnStmt).ident} ===`);
|
||||
console.log("=== BEFORE OPTIMIZATION ===");
|
||||
console.log(new FnStringifyer(fn).stringify());
|
||||
// console.log(`=== OPTIMIZING ${(fn.stmt.kind as ast.FnStmt).ident} ===`);
|
||||
// console.log("=== BEFORE OPTIMIZATION ===");
|
||||
// console.log(new FnStringifyer(fn).stringify());
|
||||
|
||||
const blockSize = fn.blocks
|
||||
.map((block) => block.stmts.length)
|
||||
@ -27,8 +27,8 @@ export function optimizeMirFn(fn: Fn) {
|
||||
sizeHistory.add(sizeBefore);
|
||||
}
|
||||
|
||||
console.log("=== AFTER OPTIMIZATION ===");
|
||||
console.log(new FnStringifyer(fn).stringify());
|
||||
// console.log("=== AFTER OPTIMIZATION ===");
|
||||
// console.log(new FnStringifyer(fn).stringify());
|
||||
}
|
||||
|
||||
function fnSize(fn: Fn, blockSize: number): number {
|
||||
|
@ -4,16 +4,27 @@ fn println(value: *str) -> int {}
|
||||
#[c_function("print_int")]
|
||||
fn print_int(value: int) -> int {}
|
||||
|
||||
fn factorial(v: int) -> int {
|
||||
if v == 0 {
|
||||
return 1;
|
||||
}
|
||||
return v * factorial(v - 1);
|
||||
}
|
||||
|
||||
#[c_export("sbc_main")]
|
||||
fn main() -> int {
|
||||
let i = 0;
|
||||
|
||||
while i < 10 {
|
||||
// while i < 10 {
|
||||
//
|
||||
// println("Hello\ world");
|
||||
//
|
||||
// i = i + 1;
|
||||
// }
|
||||
|
||||
println("Hello\ world");
|
||||
let a = factorial(5);
|
||||
|
||||
i = i + 1;
|
||||
}
|
||||
print_int(a);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user