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}`);
|
this.writeIns(`jmp .L${ins.target}`);
|
||||||
return;
|
return;
|
||||||
case "jnz_reg":
|
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;
|
return;
|
||||||
case "ret":
|
case "ret":
|
||||||
this.writeIns(`jmp .exit`);
|
this.writeIns(`jmp .exit`);
|
||||||
return;
|
return;
|
||||||
case "lt":
|
case "lt":
|
||||||
this.writeIns(`cmp ${r(ins.dst)}, ${r(ins.src)}`);
|
this.writeIns(`cmp ${r(ins.dst)}, ${r(ins.src)}`);
|
||||||
this.writeIns(`setle ${this.reg8(ins.dst)}`);
|
this.writeIns(`setl ${this.reg8(ins.dst)}`);
|
||||||
return;
|
return;
|
||||||
case "eq":
|
case "eq":
|
||||||
this.writeIns(`cmp ${r(ins.dst)}, ${r(ins.src)}`);
|
this.writeIns(`cmp ${r(ins.dst)}, ${r(ins.src)}`);
|
||||||
|
@ -1,6 +1,12 @@
|
|||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
|
int64_t notice(void)
|
||||||
|
{
|
||||||
|
printf("NOTICE!\n");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
int64_t print_int(int64_t value)
|
int64_t print_int(int64_t value)
|
||||||
{
|
{
|
||||||
printf("%ld\n", value);
|
printf("%ld\n", value);
|
||||||
|
@ -81,19 +81,19 @@ export class ProgramStringifyer {
|
|||||||
case "pop":
|
case "pop":
|
||||||
return `pop %${ins.reg}`;
|
return `pop %${ins.reg}`;
|
||||||
case "load":
|
case "load":
|
||||||
return `load %${ins.reg}, ${ins.offset}`;
|
return `load %${ins.reg}, [${ins.offset}]`;
|
||||||
case "store_reg":
|
case "store_reg":
|
||||||
return `store_reg ${ins.offset}, %${ins.reg}`;
|
return `store_reg [${ins.offset}], %${ins.reg}`;
|
||||||
case "store_imm":
|
case "store_imm":
|
||||||
return `store_val ${ins.offset}, ${ins.val}`;
|
return `store_val [${ins.offset}], ${ins.val}`;
|
||||||
case "call_reg":
|
case "call_reg":
|
||||||
return `call_reg %${ins.reg}, ${ins.args}`;
|
return `call_reg %${ins.reg}, ${ins.args}`;
|
||||||
case "call_imm":
|
case "call_imm":
|
||||||
return `call_fn ${ins.fn.label}, ${ins.args}`;
|
return `call_fn ${ins.fn.label}, ${ins.args}`;
|
||||||
case "jmp":
|
case "jmp":
|
||||||
return `jmp .b${ins.target}`;
|
return `jmp .L${ins.target}`;
|
||||||
case "jnz_reg":
|
case "jnz_reg":
|
||||||
return `jmp %${ins.reg}, .b${ins.target}`;
|
return `jnz_reg %${ins.reg}, .L${ins.target}`;
|
||||||
case "ret":
|
case "ret":
|
||||||
return "ret";
|
return "ret";
|
||||||
case "lt":
|
case "lt":
|
||||||
|
@ -204,10 +204,10 @@ class FnGen {
|
|||||||
case "eq":
|
case "eq":
|
||||||
case "add":
|
case "add":
|
||||||
case "mul": {
|
case "mul": {
|
||||||
const dst = this.reg();
|
|
||||||
const src = 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: src });
|
||||||
|
this.pushIns({ tag: "pop", reg: dst });
|
||||||
this.pushIns({ tag: k.tag, dst, src });
|
this.pushIns({ tag: k.tag, dst, src });
|
||||||
this.pushIns({ tag: "push", reg: dst });
|
this.pushIns({ tag: "push", reg: dst });
|
||||||
this.pushIns({ tag: "kill", reg: src });
|
this.pushIns({ tag: "kill", reg: src });
|
||||||
@ -242,7 +242,7 @@ class FnGen {
|
|||||||
this.pushIns({
|
this.pushIns({
|
||||||
tag: "jnz_reg",
|
tag: "jnz_reg",
|
||||||
reg,
|
reg,
|
||||||
target: this.blockLabels.get(k.falsy.id)!,
|
target: this.blockLabels.get(k.truthy.id)!,
|
||||||
});
|
});
|
||||||
this.pushIns({ tag: "kill", reg });
|
this.pushIns({ tag: "kill", reg });
|
||||||
this.pushIns({
|
this.pushIns({
|
||||||
|
@ -186,6 +186,13 @@ function eliminatePushPopShadowed(fn: Fn) {
|
|||||||
const toRemove = pop.ins.reg;
|
const toRemove = pop.ins.reg;
|
||||||
const replacement = push.ins.reg;
|
const replacement = push.ins.reg;
|
||||||
fn.lines.splice(popIdx, 1);
|
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);
|
fn.lines.splice(pushIdx, 1);
|
||||||
replaceReg(fn, toRemove, replacement);
|
replaceReg(fn, toRemove, replacement);
|
||||||
}
|
}
|
||||||
|
@ -97,13 +97,13 @@ export class FnMirGen {
|
|||||||
const exit = this.block();
|
const exit = this.block();
|
||||||
const loop = this.block();
|
const loop = this.block();
|
||||||
|
|
||||||
|
entry.ter = Ter({ tag: "goto", target: loop });
|
||||||
|
|
||||||
this.loopExitBlocks.set(stmt.id, exit);
|
this.loopExitBlocks.set(stmt.id, exit);
|
||||||
|
|
||||||
this.currentBlock = loop;
|
this.currentBlock = loop;
|
||||||
this.lowerBlock(k.body);
|
this.lowerBlock(k.body);
|
||||||
|
this.currentBlock.ter = Ter({ tag: "goto", target: loop });
|
||||||
entry.ter = Ter({ tag: "goto", target: loop });
|
|
||||||
loop.ter = Ter({ tag: "goto", target: exit });
|
|
||||||
|
|
||||||
this.currentBlock = exit;
|
this.currentBlock = exit;
|
||||||
return;
|
return;
|
||||||
@ -116,17 +116,18 @@ export class FnMirGen {
|
|||||||
|
|
||||||
this.currentBlock = truthy;
|
this.currentBlock = truthy;
|
||||||
this.lowerBlock(k.truthy);
|
this.lowerBlock(k.truthy);
|
||||||
truthy.ter = Ter({ tag: "goto", target: exit });
|
this.currentBlock.ter = Ter({ tag: "goto", target: exit });
|
||||||
|
|
||||||
let falsy = exit;
|
let falsy = exit;
|
||||||
if (k.falsy) {
|
if (k.falsy) {
|
||||||
falsy = this.block();
|
falsy = this.block();
|
||||||
this.currentBlock = falsy;
|
this.currentBlock = falsy;
|
||||||
this.lowerBlock(k.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 });
|
entry.ter = Ter({ tag: "if", truthy, falsy });
|
||||||
|
this.currentBlock = exit;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
case "return": {
|
case "return": {
|
||||||
|
@ -1,4 +1,7 @@
|
|||||||
|
|
||||||
|
#[c_function("notice")]
|
||||||
|
fn notice() {}
|
||||||
|
|
||||||
#[c_function("print_int")]
|
#[c_function("print_int")]
|
||||||
fn print_int(value) {}
|
fn print_int(value) {}
|
||||||
|
|
||||||
@ -8,9 +11,17 @@ fn inner(value) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
let a = 4;
|
let i = 0;
|
||||||
inner(a + 2);
|
loop {
|
||||||
return a;
|
if 10 < i + 1 {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
let a = 4;
|
||||||
|
inner(a + 2);
|
||||||
|
|
||||||
|
i = i + 1;
|
||||||
|
}
|
||||||
|
return i;
|
||||||
}
|
}
|
||||||
|
|
||||||
// vim: syntax=rust commentstring=//\ %s
|
// vim: syntax=rust commentstring=//\ %s
|
||||||
|
Loading…
x
Reference in New Issue
Block a user