From 45205f33e508e7990e11411f693961ce37ad7e79 Mon Sep 17 00:00:00 2001 From: SimonFJ20 Date: Wed, 26 Mar 2025 16:21:46 +0100 Subject: [PATCH] compiler: add alloca --- backup-compiler/asm_gen.ts | 6 ++++++ backup-compiler/lir.ts | 8 ++++++++ backup-compiler/lir_gen.ts | 20 ++++++++++++++++++++ backup-compiler/lir_optimize.ts | 6 ++++++ 4 files changed, 40 insertions(+) diff --git a/backup-compiler/asm_gen.ts b/backup-compiler/asm_gen.ts index 70d30fa..d7947e5 100644 --- a/backup-compiler/asm_gen.ts +++ b/backup-compiler/asm_gen.ts @@ -160,6 +160,12 @@ export class AsmGen { case "nop": this.writeIns(`nop`); return; + case "alloc_param": + // should already be handled + return; + case "alloc_local": + // should already be handled + return; case "mov_int": this.writeIns(`mov ${r(ins.reg)}, ${ins.val}`); return; diff --git a/backup-compiler/lir.ts b/backup-compiler/lir.ts index d2021b2..c3bf897 100644 --- a/backup-compiler/lir.ts +++ b/backup-compiler/lir.ts @@ -12,6 +12,8 @@ export type Fn = { lines: Line[]; frameSize: number; localOffsets: Map; + + localRegs: Map; }; export type Line = { @@ -22,6 +24,8 @@ export type Line = { export type Ins = | { tag: "error" } | { tag: "nop" } + | { tag: "alloc_param"; reg: Reg; size: number } + | { tag: "alloc_local"; reg: Reg; size: number } | { tag: "mov_int"; reg: Reg; val: number } | { tag: "mov_string"; reg: Reg; stringId: number } | { tag: "mov_fn"; reg: Reg; fn: Fn } @@ -70,6 +74,10 @@ export class ProgramStringifyer { return ""; case "nop": return "nop"; + case "alloc_param": + return `alloc_param %${ins.reg}, ${ins.size}`; + case "alloc_local": + return `alloc_local %${ins.reg}, ${ins.size}`; case "mov_int": return `mov_int %${ins.reg}, ${ins.val}`; case "mov_string": diff --git a/backup-compiler/lir_gen.ts b/backup-compiler/lir_gen.ts index 095e5f0..3b0a2c6 100644 --- a/backup-compiler/lir_gen.ts +++ b/backup-compiler/lir_gen.ts @@ -38,6 +38,7 @@ export class LirGen { lines: [], frameSize: 0, localOffsets: new Map(), + localRegs: new Map(), }; this.fns.set(id, fn); this.stmtFns.set(stmt.id, fn); @@ -77,6 +78,7 @@ class FnGen { private currentLabels: Label[] = []; private localOffsets = new Map(); + private localRegs = new Map(); public constructor( private fn: Fn, @@ -96,6 +98,9 @@ class FnGen { for (const local of this.fn.mir.paramLocals.values()) { this.localOffsets.set(local.id, currentOffset); currentOffset -= 8; + + const reg = this.reg(); + this.pushIns({ tag: "alloc_param", reg, size: 8 }); } // return address currentOffset -= 8; @@ -104,6 +109,13 @@ class FnGen { // return value this.localOffsets.set(this.fn.mir.returnLocal.id, currentOffset); currentOffset -= 8; + + { + const reg = this.reg(); + this.pushIns({ tag: "alloc_local", reg, size: 8 }); + this.localRegs.set(this.fn.mir.returnLocal.id, reg); + } + frameSize += 8; for (const local of this.fn.mir.locals) { if (this.localOffsets.has(local.id)) { @@ -113,6 +125,14 @@ class FnGen { currentOffset -= 8; frameSize += 8; } + for (const local of this.fn.mir.locals) { + if (this.localRegs.has(local.id)) { + continue; + } + const reg = this.reg(); + this.pushIns({ tag: "alloc_local", reg, size: 8 }); + this.localRegs.set(local.id, reg); + } if (frameSize % 16 !== 8) { frameSize += 8; diff --git a/backup-compiler/lir_optimize.ts b/backup-compiler/lir_optimize.ts index da8ecf9..a4f55d6 100644 --- a/backup-compiler/lir_optimize.ts +++ b/backup-compiler/lir_optimize.ts @@ -207,6 +207,10 @@ function replaceReg(fn: Fn, cand: Reg, replacement: Reg) { break; case "nop": break; + case "alloc_param": + case "alloc_local": + ins.reg = r(ins.reg); + break; case "mov_int": case "mov_string": case "mov_fn": @@ -255,6 +259,8 @@ function pollutesStack(ins: Ins): boolean { switch (ins.tag) { case "error": case "nop": + case "alloc_param": + case "alloc_local": case "mov_int": case "mov_string": case "mov_fn":