mirror of
https://github.com/Mercantec-GHC/h4-projekt-gruppe-0-sm.git
synced 2025-04-27 16:24:07 +02:00
compiler: add alloca
This commit is contained in:
parent
f291516c87
commit
45205f33e5
@ -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;
|
||||||
|
@ -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":
|
||||||
|
@ -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;
|
||||||
|
@ -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":
|
||||||
|
Loading…
x
Reference in New Issue
Block a user