compiler: add alloca

This commit is contained in:
SimonFJ20 2025-03-26 16:21:46 +01:00
parent f291516c87
commit 45205f33e5
4 changed files with 40 additions and 0 deletions

View File

@ -160,6 +160,12 @@ export class AsmGen {
case "nop": case "nop":
this.writeIns(`nop`); this.writeIns(`nop`);
return; return;
case "alloc_param":
// should already be handled
return;
case "alloc_local":
// should already be handled
return;
case "mov_int": case "mov_int":
this.writeIns(`mov ${r(ins.reg)}, ${ins.val}`); this.writeIns(`mov ${r(ins.reg)}, ${ins.val}`);
return; return;

View File

@ -12,6 +12,8 @@ export type Fn = {
lines: Line[]; lines: Line[];
frameSize: number; frameSize: number;
localOffsets: Map<number, number>; localOffsets: Map<number, number>;
localRegs: Map<number, Reg>;
}; };
export type Line = { export type Line = {
@ -22,6 +24,8 @@ export type Line = {
export type Ins = export type Ins =
| { tag: "error" } | { tag: "error" }
| { tag: "nop" } | { 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_int"; reg: Reg; val: number }
| { tag: "mov_string"; reg: Reg; stringId: number } | { tag: "mov_string"; reg: Reg; stringId: number }
| { tag: "mov_fn"; reg: Reg; fn: Fn } | { tag: "mov_fn"; reg: Reg; fn: Fn }
@ -70,6 +74,10 @@ export class ProgramStringifyer {
return "<error>"; return "<error>";
case "nop": case "nop":
return "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": case "mov_int":
return `mov_int %${ins.reg}, ${ins.val}`; return `mov_int %${ins.reg}, ${ins.val}`;
case "mov_string": case "mov_string":

View File

@ -38,6 +38,7 @@ export class LirGen {
lines: [], lines: [],
frameSize: 0, frameSize: 0,
localOffsets: new Map(), localOffsets: new Map(),
localRegs: new Map(),
}; };
this.fns.set(id, fn); this.fns.set(id, fn);
this.stmtFns.set(stmt.id, fn); this.stmtFns.set(stmt.id, fn);
@ -77,6 +78,7 @@ class FnGen {
private currentLabels: Label[] = []; private currentLabels: Label[] = [];
private localOffsets = new Map<number, number>(); private localOffsets = new Map<number, number>();
private localRegs = new Map<number, Reg>();
public constructor( public constructor(
private fn: Fn, private fn: Fn,
@ -96,6 +98,9 @@ class FnGen {
for (const local of this.fn.mir.paramLocals.values()) { for (const local of this.fn.mir.paramLocals.values()) {
this.localOffsets.set(local.id, currentOffset); this.localOffsets.set(local.id, currentOffset);
currentOffset -= 8; currentOffset -= 8;
const reg = this.reg();
this.pushIns({ tag: "alloc_param", reg, size: 8 });
} }
// return address // return address
currentOffset -= 8; currentOffset -= 8;
@ -104,6 +109,13 @@ class FnGen {
// return value // return value
this.localOffsets.set(this.fn.mir.returnLocal.id, currentOffset); this.localOffsets.set(this.fn.mir.returnLocal.id, currentOffset);
currentOffset -= 8; 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; frameSize += 8;
for (const local of this.fn.mir.locals) { for (const local of this.fn.mir.locals) {
if (this.localOffsets.has(local.id)) { if (this.localOffsets.has(local.id)) {
@ -113,6 +125,14 @@ class FnGen {
currentOffset -= 8; currentOffset -= 8;
frameSize += 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) { if (frameSize % 16 !== 8) {
frameSize += 8; frameSize += 8;

View File

@ -207,6 +207,10 @@ function replaceReg(fn: Fn, cand: Reg, replacement: Reg) {
break; break;
case "nop": case "nop":
break; break;
case "alloc_param":
case "alloc_local":
ins.reg = r(ins.reg);
break;
case "mov_int": case "mov_int":
case "mov_string": case "mov_string":
case "mov_fn": case "mov_fn":
@ -255,6 +259,8 @@ function pollutesStack(ins: Ins): boolean {
switch (ins.tag) { switch (ins.tag) {
case "error": case "error":
case "nop": case "nop":
case "alloc_param":
case "alloc_local":
case "mov_int": case "mov_int":
case "mov_string": case "mov_string":
case "mov_fn": case "mov_fn":