mirror of
https://github.com/Mercantec-GHC/h4-projekt-gruppe-0-sm.git
synced 2025-04-27 16:24:07 +02:00
compiler: loops work
This commit is contained in:
parent
2dfd713e4e
commit
0b65a5841f
@ -163,14 +163,15 @@ export class AsmGen {
|
||||
this.writeIns(`jmp .L${ins.target}`);
|
||||
return;
|
||||
case "jnz_reg":
|
||||
this.writeIns(`jnz ${r(ins.reg)}, .L${ins.target}`);
|
||||
this.writeIns(`cmp ${r(ins.reg)}, 0`);
|
||||
this.writeIns(`jne .L${ins.target}`);
|
||||
return;
|
||||
case "ret":
|
||||
this.writeIns(`jmp .exit`);
|
||||
return;
|
||||
case "lt":
|
||||
this.writeIns(`cmp ${r(ins.dst)}, ${r(ins.src)}`);
|
||||
this.writeIns(`setle ${this.reg8(ins.dst)}`);
|
||||
this.writeIns(`setl ${this.reg8(ins.dst)}`);
|
||||
return;
|
||||
case "eq":
|
||||
this.writeIns(`cmp ${r(ins.dst)}, ${r(ins.src)}`);
|
||||
|
@ -1,6 +1,12 @@
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
|
||||
int64_t notice(void)
|
||||
{
|
||||
printf("NOTICE!\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
int64_t print_int(int64_t value)
|
||||
{
|
||||
printf("%ld\n", value);
|
||||
|
@ -81,19 +81,19 @@ export class ProgramStringifyer {
|
||||
case "pop":
|
||||
return `pop %${ins.reg}`;
|
||||
case "load":
|
||||
return `load %${ins.reg}, ${ins.offset}`;
|
||||
return `load %${ins.reg}, [${ins.offset}]`;
|
||||
case "store_reg":
|
||||
return `store_reg ${ins.offset}, %${ins.reg}`;
|
||||
return `store_reg [${ins.offset}], %${ins.reg}`;
|
||||
case "store_imm":
|
||||
return `store_val ${ins.offset}, ${ins.val}`;
|
||||
return `store_val [${ins.offset}], ${ins.val}`;
|
||||
case "call_reg":
|
||||
return `call_reg %${ins.reg}, ${ins.args}`;
|
||||
case "call_imm":
|
||||
return `call_fn ${ins.fn.label}, ${ins.args}`;
|
||||
case "jmp":
|
||||
return `jmp .b${ins.target}`;
|
||||
return `jmp .L${ins.target}`;
|
||||
case "jnz_reg":
|
||||
return `jmp %${ins.reg}, .b${ins.target}`;
|
||||
return `jnz_reg %${ins.reg}, .L${ins.target}`;
|
||||
case "ret":
|
||||
return "ret";
|
||||
case "lt":
|
||||
|
@ -204,10 +204,10 @@ class FnGen {
|
||||
case "eq":
|
||||
case "add":
|
||||
case "mul": {
|
||||
const dst = this.reg();
|
||||
const src = this.reg();
|
||||
this.pushIns({ tag: "pop", reg: dst });
|
||||
const dst = this.reg();
|
||||
this.pushIns({ tag: "pop", reg: src });
|
||||
this.pushIns({ tag: "pop", reg: dst });
|
||||
this.pushIns({ tag: k.tag, dst, src });
|
||||
this.pushIns({ tag: "push", reg: dst });
|
||||
this.pushIns({ tag: "kill", reg: src });
|
||||
@ -242,7 +242,7 @@ class FnGen {
|
||||
this.pushIns({
|
||||
tag: "jnz_reg",
|
||||
reg,
|
||||
target: this.blockLabels.get(k.falsy.id)!,
|
||||
target: this.blockLabels.get(k.truthy.id)!,
|
||||
});
|
||||
this.pushIns({ tag: "kill", reg });
|
||||
this.pushIns({
|
||||
|
@ -186,6 +186,13 @@ function eliminatePushPopShadowed(fn: Fn) {
|
||||
const toRemove = pop.ins.reg;
|
||||
const replacement = push.ins.reg;
|
||||
fn.lines.splice(popIdx, 1);
|
||||
for (let i = pushIdx + 1; i <= popIdx - 1; ++i) {
|
||||
const kill = fn.lines[i].ins;
|
||||
if (kill.tag === "kill" && kill.reg === push.ins.reg) {
|
||||
fn.lines.splice(i, 1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
fn.lines.splice(pushIdx, 1);
|
||||
replaceReg(fn, toRemove, replacement);
|
||||
}
|
||||
|
@ -97,13 +97,13 @@ export class FnMirGen {
|
||||
const exit = this.block();
|
||||
const loop = this.block();
|
||||
|
||||
entry.ter = Ter({ tag: "goto", target: loop });
|
||||
|
||||
this.loopExitBlocks.set(stmt.id, exit);
|
||||
|
||||
this.currentBlock = loop;
|
||||
this.lowerBlock(k.body);
|
||||
|
||||
entry.ter = Ter({ tag: "goto", target: loop });
|
||||
loop.ter = Ter({ tag: "goto", target: exit });
|
||||
this.currentBlock.ter = Ter({ tag: "goto", target: loop });
|
||||
|
||||
this.currentBlock = exit;
|
||||
return;
|
||||
@ -116,17 +116,18 @@ export class FnMirGen {
|
||||
|
||||
this.currentBlock = truthy;
|
||||
this.lowerBlock(k.truthy);
|
||||
truthy.ter = Ter({ tag: "goto", target: exit });
|
||||
this.currentBlock.ter = Ter({ tag: "goto", target: exit });
|
||||
|
||||
let falsy = exit;
|
||||
if (k.falsy) {
|
||||
falsy = this.block();
|
||||
this.currentBlock = falsy;
|
||||
this.lowerBlock(k.falsy);
|
||||
falsy.ter = Ter({ tag: "goto", target: exit });
|
||||
this.currentBlock.ter = Ter({ tag: "goto", target: exit });
|
||||
}
|
||||
|
||||
entry.ter = Ter({ tag: "if", truthy, falsy });
|
||||
this.currentBlock = exit;
|
||||
return;
|
||||
}
|
||||
case "return": {
|
||||
|
@ -1,4 +1,7 @@
|
||||
|
||||
#[c_function("notice")]
|
||||
fn notice() {}
|
||||
|
||||
#[c_function("print_int")]
|
||||
fn print_int(value) {}
|
||||
|
||||
@ -8,9 +11,17 @@ fn inner(value) {
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let i = 0;
|
||||
loop {
|
||||
if 10 < i + 1 {
|
||||
break;
|
||||
}
|
||||
let a = 4;
|
||||
inner(a + 2);
|
||||
return a;
|
||||
|
||||
i = i + 1;
|
||||
}
|
||||
return i;
|
||||
}
|
||||
|
||||
// vim: syntax=rust commentstring=//\ %s
|
||||
|
Loading…
x
Reference in New Issue
Block a user