From 2681a80064696aae443ee3571ca94775ccb7a51e Mon Sep 17 00:00:00 2001 From: Lenart Kos Date: Tue, 9 May 2023 20:59:22 +0200 Subject: [PATCH] Regall: Add template --- .gitignore | 2 + prev23/lib/xsl/regall.xsl | 132 ++++ prev23/src/prev23/Compiler.java | 12 +- prev23/src/prev23/phase/asmgen/AsmGen.java | 8 +- .../prev23/phase/asmgen/ExprGenerator.java | 628 +++++++++--------- prev23/src/prev23/phase/regall/RegAll.java | 78 +++ .../src/prev23/phase/regall/package-info.java | 4 + 7 files changed, 532 insertions(+), 332 deletions(-) create mode 100644 prev23/lib/xsl/regall.xsl create mode 100644 prev23/src/prev23/phase/regall/RegAll.java create mode 100644 prev23/src/prev23/phase/regall/package-info.java diff --git a/.gitignore b/.gitignore index 38a9bb8..317b1e3 100644 --- a/.gitignore +++ b/.gitignore @@ -44,6 +44,8 @@ hs_err_pid* **/*.asmgen.xml **/*.livean.html **/*.livean.xml +**/*.regall.html +**/*.regall.xml # antlr **/PrevLexer.tokens diff --git a/prev23/lib/xsl/regall.xsl b/prev23/lib/xsl/regall.xsl new file mode 100644 index 0000000..ddd957b --- /dev/null +++ b/prev23/lib/xsl/regall.xsl @@ -0,0 +1,132 @@ + + + + + + + + + +
+ + +
+ + + + + + + + + + + +
+ +
+ + entryLabel= + exitLabel= + temps= + +
+ +
+ + + + + + + + + + + + + + + + + + + : + + + + + + + + + + + + + + + + + + + + + +
+ + FRAME + label= + +
+ + depth= + size= + locs= + args= + +
+ + FP= + RV= + +
+
+ + + + + + + + + + + + +
+ + FRAME + label= + +
+ + depth= + size= + locs= + args= + +
+ + FP= + RV= + +
+
+ +
diff --git a/prev23/src/prev23/Compiler.java b/prev23/src/prev23/Compiler.java index ec1ed49..0d58b87 100644 --- a/prev23/src/prev23/Compiler.java +++ b/prev23/src/prev23/Compiler.java @@ -4,6 +4,7 @@ import prev23.common.report.*; import prev23.phase.lexan.*; +import prev23.phase.regall.RegAll; import prev23.phase.synan.*; import prev23.phase.abstr.*; import prev23.phase.seman.*; @@ -46,7 +47,7 @@ private Compiler() { // COMMAND LINE ARGUMENTS /** All valid phases of the compiler. */ - private static final String phases = "none|lexan|synan|abstr|seman|memory|imcgen|imclin|asmgen|livean"; + private static final String phases = "none|lexan|synan|abstr|seman|memory|imcgen|imclin|asmgen|livean|regall"; /** Values of command line arguments indexed by their command line switch. */ private static HashMap cmdLineArgs = new HashMap(); @@ -104,6 +105,7 @@ public static void main(String[] args) { if ((cmdLineArgs.get("--target-phase") == null) || (cmdLineArgs.get("--target-phase").equals("all"))) { cmdLineArgs.put("--target-phase", phases.replaceFirst("^.*\\|", "")); } + cmdLineArgs.putIfAbsent("--num-regs", "32"); // Compilation process carried out phase by phase. while (true) { @@ -195,6 +197,14 @@ public static void main(String[] args) { } if (Compiler.cmdLineArgValue("--target-phase").equals("livean")) break; + + // Register allocation. + try (RegAll regAll = new RegAll()) { + regAll.allocate(); + regAll.log(); + } + if (Compiler.cmdLineArgValue("--target-phase").equals("regall")) + break; } Report.info("Done."); diff --git a/prev23/src/prev23/phase/asmgen/AsmGen.java b/prev23/src/prev23/phase/asmgen/AsmGen.java index 4511786..2fd02f4 100644 --- a/prev23/src/prev23/phase/asmgen/AsmGen.java +++ b/prev23/src/prev23/phase/asmgen/AsmGen.java @@ -1,13 +1,14 @@ package prev23.phase.asmgen; -import java.util.*; - +import prev23.Compiler; import prev23.data.imc.code.stmt.*; import prev23.data.lin.*; import prev23.data.asm.*; import prev23.phase.*; import prev23.phase.imclin.*; +import java.util.*; + /** * Machine code generator. */ @@ -15,8 +16,11 @@ public class AsmGen extends Phase { public static Vector codes = new Vector(); + public static int num_regs; + public AsmGen() { super("asmgen"); + num_regs = Integer.parseInt(Compiler.cmdLineArgValue("--num-regs")); } public void genAsmCodes() { diff --git a/prev23/src/prev23/phase/asmgen/ExprGenerator.java b/prev23/src/prev23/phase/asmgen/ExprGenerator.java index 1b512a9..f877c78 100644 --- a/prev23/src/prev23/phase/asmgen/ExprGenerator.java +++ b/prev23/src/prev23/phase/asmgen/ExprGenerator.java @@ -49,408 +49,378 @@ static MatchingResult Invalid() { private final Vector tiles = new Vector<>( List.of( // Temps - new Tile() { - @Override - public MatchingResult try_match(ImcExpr expr) { - if (!(expr instanceof ImcTEMP temp)) return Tile.Invalid(); - return new MatchingResult(0, temp.temp, new Vector<>()); - } + expr -> { + if (!(expr instanceof ImcTEMP temp)) return Tile.Invalid(); + return new Tile.MatchingResult(0, temp.temp, new Vector<>()); }, // Addresses - new Tile() { - @Override - public MatchingResult try_match(ImcExpr expr) { - if (!(expr instanceof ImcNAME imc_name)) return Tile.Invalid(); - var name = imc_name.label.name; - - var dst = new MemTemp(); - return new MatchingResult( - 1, dst, new AsmOPER( - String.format("\t\tLDA\t`d0, %s", name), - new Vector<>(), - new Vector<>(List.of(dst)), - new Vector<>() - ) - ); - } + expr -> { + if (!(expr instanceof ImcNAME imc_name)) return Tile.Invalid(); + var name = imc_name.label.name; + + var dst = new MemTemp(); + return new Tile.MatchingResult( + 1, dst, new AsmOPER( + String.format("\t\tLDA\t`d0, %s", name), + new Vector<>(), + new Vector<>(List.of(dst)), + new Vector<>() + ) + ); }, // Memory - new Tile() { - @Override - public MatchingResult try_match(ImcExpr expr) { - if (!(expr instanceof ImcMEM mem)) return Tile.Invalid(); - var src_result = match_any_tile(mem.addr); - if (!src_result.is_valid()) return Tile.Invalid(); - - var dst = new MemTemp(); - - return new MatchingResult( - src_result.cost + 10, dst, src_result.instructions, new AsmOPER( - "\t\tLDO\t`d0, `s0, #0", - new Vector<>(List.of(src_result.temp)), - new Vector<>(List.of(dst)), - new Vector<>() - ) - ); - } + expr -> { + if (!(expr instanceof ImcMEM mem)) return Tile.Invalid(); + var src_result = match_any_tile(mem.addr); + if (!src_result.is_valid()) return Tile.Invalid(); + + var dst = new MemTemp(); + + return new Tile.MatchingResult( + src_result.cost + 10, dst, src_result.instructions, new AsmOPER( + "\t\tLDO\t`d0, `s0, #0", + new Vector<>(List.of(src_result.temp)), + new Vector<>(List.of(dst)), + new Vector<>() + ) + ); }, // ADDU - new Tile() { - @Override - public MatchingResult try_match(ImcExpr expr) { - if (!(expr instanceof ImcBINOP binop) || binop.oper != ImcBINOP.Oper.MUL) - return Tile.Invalid(); - - ImcCONST imc_const = null; - ImcExpr imc_other = null; - - if (binop.fstExpr instanceof ImcCONST _const) { - imc_const = _const; - imc_other = binop.sndExpr; - } else if (binop.sndExpr instanceof ImcCONST _const) { - imc_const = _const; - imc_other = binop.fstExpr; - } else { - return Tile.Invalid(); - } + expr -> { + if (!(expr instanceof ImcBINOP binop) || binop.oper != ImcBINOP.Oper.MUL) + return Tile.Invalid(); + + ImcCONST imc_const = null; + ImcExpr imc_other = null; + + if (binop.fstExpr instanceof ImcCONST _const) { + imc_const = _const; + imc_other = binop.sndExpr; + } else if (binop.sndExpr instanceof ImcCONST _const) { + imc_const = _const; + imc_other = binop.fstExpr; + } else { + return Tile.Invalid(); + } - if (imc_other instanceof ImcCONST other_const) { - var v = other_const.value; - if (v == 2 || v == 4 || v == 8 || v == 16) { - imc_other = imc_const; - imc_const = other_const; - } + if (imc_other instanceof ImcCONST other_const) { + var v = other_const.value; + if (v == 2 || v == 4 || v == 8 || v == 16) { + imc_other = imc_const; + imc_const = other_const; } + } - var addu_val = imc_const.value; + var addu_val = imc_const.value; - if (addu_val != 2 && addu_val != 4 && addu_val != 8 && addu_val != 16) - return Tile.Invalid(); + if (addu_val != 2 && addu_val != 4 && addu_val != 8 && addu_val != 16) + return Tile.Invalid(); - var const_result = match_any_tile(imc_const); - var other_result = match_any_tile(imc_other); + var const_result = match_any_tile(imc_const); + var other_result = match_any_tile(imc_other); - if (!const_result.is_valid() || !other_result.is_valid()) return Tile.Invalid(); + if (!const_result.is_valid() || !other_result.is_valid()) return Tile.Invalid(); - var instructions = new Vector(); - instructions.addAll(const_result.instructions); - instructions.addAll(other_result.instructions); + var instructions = new Vector(); + instructions.addAll(const_result.instructions); + instructions.addAll(other_result.instructions); - long cost = const_result.cost + other_result.cost; + long cost = const_result.cost + other_result.cost; - var dst = new MemTemp(); + var dst = new MemTemp(); - cost += 1; - instructions.add(new AsmOPER( - String.format("\t\t%dADDU\t`d0, `s0, `s1", addu_val), - new Vector<>(List.of(const_result.temp, other_result.temp)), - new Vector<>(List.of(dst)), - new Vector<>() - )); + cost += 1; + instructions.add(new AsmOPER( + String.format("\t\t%dADDU\t`d0, `s0, `s1", addu_val), + new Vector<>(List.of(const_result.temp, other_result.temp)), + new Vector<>(List.of(dst)), + new Vector<>() + )); - return new MatchingResult(cost, dst, instructions); - } + return new Tile.MatchingResult(cost, dst, instructions); }, // Binary operations - new Tile() { - @Override - public MatchingResult try_match(ImcExpr expr) { - if (!(expr instanceof ImcBINOP binop)) return Tile.Invalid(); - var lhs_result = match_any_tile(binop.fstExpr); - var rhs_result = match_any_tile(binop.sndExpr); - if (!lhs_result.is_valid() || !rhs_result.is_valid()) - return Tile.Invalid(); - - var instructions = new Vector(); - - instructions.addAll(lhs_result.instructions); - instructions.addAll(rhs_result.instructions); - - var dst = new MemTemp(); - - long cost = lhs_result.cost + rhs_result.cost; - switch (binop.oper) { - case EQU, NEQ, LTH, GTH, LEQ, GEQ -> { - cost += 2; - instructions.add(new AsmOPER( - "\t\tCMP\t`d0, `s0, `s1", - new Vector<>(List.of(lhs_result.temp, rhs_result.temp)), - new Vector<>(List.of(dst)), - new Vector<>() - )); - instructions.add(new AsmOPER( - String.format("\t\tZS%s\t`d0, `s0, #1", switch (binop.oper) { - case EQU -> "Z"; - case NEQ -> "NZ"; - case LTH -> "N"; - case GTH -> "P"; - case LEQ -> "NP"; - case GEQ -> "NN"; - default -> - throw new IllegalStateException("Unexpected value: " + binop.oper); - }), - new Vector<>(List.of(dst)), - new Vector<>(List.of(dst)), - new Vector<>() - )); - } - case OR, AND, ADD, SUB -> { - cost += 1; - instructions.add(new AsmOPER( - String.format("\t\t%s\t`d0, `s0, `s1", binop.oper), - new Vector<>(List.of(lhs_result.temp, rhs_result.temp)), - new Vector<>(List.of(dst)), - new Vector<>() - )); - } - case MUL -> { - cost += 10; - instructions.add(new AsmOPER( - "\t\tMUL\t`d0, `s0, `s1", - new Vector<>(List.of(lhs_result.temp, rhs_result.temp)), - new Vector<>(List.of(dst)), - new Vector<>() - )); - } - case DIV -> { - cost += 60; - instructions.add(new AsmOPER( - "\t\tDIV\t`d0, `s0, `s1", - new Vector<>(List.of(lhs_result.temp, rhs_result.temp)), - new Vector<>(List.of(dst)), - new Vector<>() - )); - } - case MOD -> { - cost += 61; - instructions.add(new AsmOPER( - "\t\tDIV\t`d0, `s0, `s1", - new Vector<>(List.of(lhs_result.temp, rhs_result.temp)), - new Vector<>(List.of(dst)), - new Vector<>() - )); - instructions.add(new AsmOPER( - "\t\tGET\t`d0, rR", - new Vector<>(), - new Vector<>(List.of(dst)), - new Vector<>() - )); - } - } + expr -> { + if (!(expr instanceof ImcBINOP binop)) return Tile.Invalid(); + var lhs_result = match_any_tile(binop.fstExpr); + var rhs_result = match_any_tile(binop.sndExpr); + if (!lhs_result.is_valid() || !rhs_result.is_valid()) + return Tile.Invalid(); + + var instructions = new Vector(); + + instructions.addAll(lhs_result.instructions); + instructions.addAll(rhs_result.instructions); + + var dst = new MemTemp(); - return new MatchingResult(cost, dst, instructions); + long cost = lhs_result.cost + rhs_result.cost; + switch (binop.oper) { + case EQU, NEQ, LTH, GTH, LEQ, GEQ -> { + cost += 2; + instructions.add(new AsmOPER( + "\t\tCMP\t`d0, `s0, `s1", + new Vector<>(List.of(lhs_result.temp, rhs_result.temp)), + new Vector<>(List.of(dst)), + new Vector<>() + )); + instructions.add(new AsmOPER( + String.format("\t\tZS%s\t`d0, `s0, #1", switch (binop.oper) { + case EQU -> "Z"; + case NEQ -> "NZ"; + case LTH -> "N"; + case GTH -> "P"; + case LEQ -> "NP"; + case GEQ -> "NN"; + default -> + throw new IllegalStateException("Unexpected value: " + binop.oper); + }), + new Vector<>(List.of(dst)), + new Vector<>(List.of(dst)), + new Vector<>() + )); + } + case OR, AND, ADD, SUB -> { + cost += 1; + instructions.add(new AsmOPER( + String.format("\t\t%s\t`d0, `s0, `s1", binop.oper), + new Vector<>(List.of(lhs_result.temp, rhs_result.temp)), + new Vector<>(List.of(dst)), + new Vector<>() + )); + } + case MUL -> { + cost += 10; + instructions.add(new AsmOPER( + "\t\tMUL\t`d0, `s0, `s1", + new Vector<>(List.of(lhs_result.temp, rhs_result.temp)), + new Vector<>(List.of(dst)), + new Vector<>() + )); + } + case DIV -> { + cost += 60; + instructions.add(new AsmOPER( + "\t\tDIV\t`d0, `s0, `s1", + new Vector<>(List.of(lhs_result.temp, rhs_result.temp)), + new Vector<>(List.of(dst)), + new Vector<>() + )); + } + case MOD -> { + cost += 61; + instructions.add(new AsmOPER( + "\t\tDIV\t`d0, `s0, `s1", + new Vector<>(List.of(lhs_result.temp, rhs_result.temp)), + new Vector<>(List.of(dst)), + new Vector<>() + )); + instructions.add(new AsmOPER( + "\t\tGET\t`d0, rR", + new Vector<>(), + new Vector<>(List.of(dst)), + new Vector<>() + )); + } } + + return new Tile.MatchingResult(cost, dst, instructions); }, // Fast twos division - new Tile() { - @Override - public MatchingResult try_match(ImcExpr expr) { - if (!(expr instanceof ImcBINOP binop) - || binop.oper != ImcBINOP.Oper.DIV - || !(binop.sndExpr instanceof ImcCONST div_const)) return Tile.Invalid(); + expr -> { + if (!(expr instanceof ImcBINOP binop) + || binop.oper != ImcBINOP.Oper.DIV + || !(binop.sndExpr instanceof ImcCONST div_const)) return Tile.Invalid(); - var val = div_const.value; + var val = div_const.value; - if (val <= 0 || (val & -val) != val) return Tile.Invalid(); + if (val <= 0 || (val & -val) != val) return Tile.Invalid(); - var shift_count = 63 - Long.numberOfLeadingZeros(val); + var shift_count = 63 - Long.numberOfLeadingZeros(val); - var lhs_result = match_any_tile(binop.fstExpr); + var lhs_result = match_any_tile(binop.fstExpr); - if (!lhs_result.is_valid()) - return Tile.Invalid(); + if (!lhs_result.is_valid()) + return Tile.Invalid(); - var instructions = new Vector(lhs_result.instructions); + var instructions = new Vector(lhs_result.instructions); - var dst = new MemTemp(); + var dst = new MemTemp(); - instructions.add( - new AsmOPER( - String.format("\t\tSR\t`d0, `s0, #%d", shift_count), - new Vector<>(List.of(lhs_result.temp)), - new Vector<>(List.of(dst)), - new Vector<>() - ) - ); + instructions.add( + new AsmOPER( + String.format("\t\tSR\t`d0, `s0, #%d", shift_count), + new Vector<>(List.of(lhs_result.temp)), + new Vector<>(List.of(dst)), + new Vector<>() + ) + ); - return new MatchingResult(1, dst, instructions); - } + return new Tile.MatchingResult(1, dst, instructions); }, // Call - new Tile() { - @Override - public MatchingResult try_match(ImcExpr expr) { - if (!(expr instanceof ImcCALL call)) return Tile.Invalid(); + expr -> { + if (!(expr instanceof ImcCALL call)) return Tile.Invalid(); - long cost = 0; - var instructions = new Vector(); + long cost = 0; + var instructions = new Vector(); - int i = 0; - for (var arg : call.args) { - var arg_result = match_any_tile(arg); - if (!arg_result.is_valid()) return Tile.Invalid(); + int i = 0; + for (var arg : call.args) { + var arg_result = match_any_tile(arg); + if (!arg_result.is_valid()) return Tile.Invalid(); - cost += arg_result.cost; - instructions.addAll(arg_result.instructions); + cost += arg_result.cost; + instructions.addAll(arg_result.instructions); - cost += 10; + cost += 10; - var offset = call.offs.get(i++); - if (offset < 256) { - instructions.add(new AsmOPER( - String.format("\t\tSTO\t`s0, $254, #%d", offset), - new Vector<>(List.of(arg_result.temp)), - new Vector<>(), - new Vector<>() - )); - } else { - var const_result = match_any_tile(new ImcCONST(offset)); - instructions.addAll(const_result.instructions); - instructions.add(new AsmOPER( - "\t\tSTO\t`s0, $254, `s1", - new Vector<>(List.of(arg_result.temp, const_result.temp)), - new Vector<>(), - new Vector<>() - )); - } + var offset = call.offs.get(i++); + if (offset < 256) { + instructions.add(new AsmOPER( + String.format("\t\tSTO\t`s0, $254, #%d", offset), + new Vector<>(List.of(arg_result.temp)), + new Vector<>(), + new Vector<>() + )); + } else { + var const_result = match_any_tile(new ImcCONST(offset)); + instructions.addAll(const_result.instructions); + instructions.add(new AsmOPER( + "\t\tSTO\t`s0, $254, `s1", + new Vector<>(List.of(arg_result.temp, const_result.temp)), + new Vector<>(), + new Vector<>() + )); } + } + cost += 1; + instructions.add(new AsmOPER( + String.format("\t\tPUSHJ\t$%d, %s", AsmGen.num_regs, call.label.name), + new Vector<>(), + new Vector<>(), + new Vector<>(List.of(call.label)) + )); + + var dst = new MemTemp(); + + cost += 10; + instructions.add(new AsmOPER( + "\t\tLDO\t`d0, $254, #0", + new Vector<>(), + new Vector<>(List.of(dst)), + new Vector<>() + )); + + return new Tile.MatchingResult(cost, dst, instructions); + }, + // Constants + expr -> { + if (!(expr instanceof ImcCONST cons)) return Tile.Invalid(); + + var value = cons.value; + + var instructions = new Vector(); + long cost = 0; + + var dst = new MemTemp(); + + cost += 1; + instructions.add(new AsmOPER( + String.format("\t\tSET\t`d0, #%d", value & 0xffff), + new Vector<>(), + new Vector<>(List.of(dst)), + new Vector<>() + )); + + if ((value & 0xffff0000L) != 0) { cost += 1; instructions.add(new AsmOPER( - String.format("\t\tPUSHJ\t$252, %s", call.label.name), - new Vector<>(), - new Vector<>(), - new Vector<>(List.of(call.label)) + String.format("\t\tORML\t`d0, #%d", (value & 0xffff0000L) >>> 16), + new Vector<>(List.of(dst)), + new Vector<>(List.of(dst)), + new Vector<>() )); + } - var dst = new MemTemp(); - - cost += 10; + if ((value & 0xffff00000000L) != 0) { + cost += 1; instructions.add(new AsmOPER( - "\t\tLDO\t`d0, $254, #0", - new Vector<>(), + String.format("\t\tORMH\t`d0, #%d", (value & 0xffff00000000L) >>> 32), + new Vector<>(List.of(dst)), new Vector<>(List.of(dst)), new Vector<>() )); - - return new MatchingResult(cost, dst, instructions); } - }, - // Constants - new Tile() { - @Override - public MatchingResult try_match(ImcExpr expr) { - if (!(expr instanceof ImcCONST cons)) return Tile.Invalid(); - - var value = cons.value; - var instructions = new Vector(); - long cost = 0; - - var dst = new MemTemp(); - + if ((value & 0xffff000000000000L) != 0) { cost += 1; instructions.add(new AsmOPER( - String.format("\t\tSET\t`d0, #%d", value & 0xffff), - new Vector<>(), + String.format("\t\tORH\t`d0, #%d", (value & 0xffff000000000000L) >>> 48), + new Vector<>(List.of(dst)), new Vector<>(List.of(dst)), new Vector<>() )); + } - if ((value & 0xffff0000L) != 0) { - cost += 1; - instructions.add(new AsmOPER( - String.format("\t\tORML\t`d0, #%d", (value & 0xffff0000L) >>> 16), - new Vector<>(), - new Vector<>(List.of(dst)), - new Vector<>() - )); - } + return new Tile.MatchingResult(cost, dst, instructions); + }, + // 8-bit negative constant + expr -> { + if (!(expr instanceof ImcCONST cons)) return Tile.Invalid(); + + var value = cons.value; + + if (value>=0 || value < -256) + return Tile.Invalid(); - if ((value & 0xffff00000000L) != 0) { + var dst = new MemTemp(); + + return new Tile.MatchingResult( + 1, dst, new AsmOPER( + String.format("\t\tNEG\t`d0, #%d", -value), + new Vector<>(), + new Vector<>(List.of(dst)), + new Vector<>() + ) + ); + }, + // Unary operations + expr -> { + if (!(expr instanceof ImcUNOP unop)) return Tile.Invalid(); + + var sub_result = match_any_tile(unop.subExpr); + + if (!sub_result.is_valid()) return Tile.Invalid(); + + var instructions = new Vector(sub_result.instructions); + long cost = sub_result.cost; + var dst = new MemTemp(); + + switch (unop.oper) { + case NOT -> { cost += 1; instructions.add(new AsmOPER( - String.format("\t\tORMH\t`d0, #%d", (value & 0xffff00000000L) >>> 32), - new Vector<>(), + "\t\tZSZ\t`d0, `s0, #1", + new Vector<>(List.of(sub_result.temp)), new Vector<>(List.of(dst)), new Vector<>() )); } - - if ((value & 0xffff000000000000L) != 0) { + case NEG -> { cost += 1; instructions.add(new AsmOPER( - String.format("\t\tORH\t`d0, #%d", (value & 0xffff000000000000L) >>> 48), - new Vector<>(), + "\t\tNEG\t`d0, `s0", + new Vector<>(List.of(sub_result.temp)), new Vector<>(List.of(dst)), new Vector<>() )); } - - return new MatchingResult(cost, dst, instructions); - } - }, - // 8-bit negative constant - new Tile() { - @Override - public MatchingResult try_match(ImcExpr expr) { - if (!(expr instanceof ImcCONST cons)) return Tile.Invalid(); - - var value = cons.value; - - if (value>=0 || value < -256) - return Tile.Invalid(); - - var dst = new MemTemp(); - - return new MatchingResult( - 1, dst, new AsmOPER( - String.format("\t\tNEG\t`d0, #%d", -value), - new Vector<>(), - new Vector<>(List.of(dst)), - new Vector<>() - ) - ); } - }, - // Unary operations - new Tile() { - @Override - public MatchingResult try_match(ImcExpr expr) { - if (!(expr instanceof ImcUNOP unop)) return Tile.Invalid(); - - var sub_result = match_any_tile(unop.subExpr); - - if (!sub_result.is_valid()) return Tile.Invalid(); - - var instructions = new Vector(sub_result.instructions); - long cost = sub_result.cost; - var dst = new MemTemp(); - - switch (unop.oper) { - case NOT -> { - cost += 1; - instructions.add(new AsmOPER( - "\t\tZSZ\t`d0, `s0, #1", - new Vector<>(List.of(dst)), - new Vector<>(List.of(dst)), - new Vector<>() - )); - } - case NEG -> { - cost += 1; - instructions.add(new AsmOPER( - "\t\tNEG\t`d0, `s0", - new Vector<>(List.of(sub_result.temp)), - new Vector<>(List.of(dst)), - new Vector<>() - )); - } - } - return new MatchingResult(cost, dst, instructions); - } + return new Tile.MatchingResult(cost, dst, instructions); } )); diff --git a/prev23/src/prev23/phase/regall/RegAll.java b/prev23/src/prev23/phase/regall/RegAll.java new file mode 100644 index 0000000..39b7986 --- /dev/null +++ b/prev23/src/prev23/phase/regall/RegAll.java @@ -0,0 +1,78 @@ +package prev23.phase.regall; + +import java.util.*; + +import prev23.data.mem.*; +import prev23.data.asm.*; +import prev23.phase.*; +import prev23.phase.asmgen.*; + +/** + * Register allocation. + */ +public class RegAll extends Phase { + + /** Mapping of temporary variables to registers. */ + public final HashMap tempToReg = new HashMap(); + + public RegAll() { + super("regall"); + } + + public void allocate() { + // TODO + } + + public void log() { + if (logger == null) + return; + for (Code code : AsmGen.codes) { + logger.begElement("code"); + logger.addAttribute("entrylabel", code.entryLabel.name); + logger.addAttribute("exitlabel", code.exitLabel.name); + logger.addAttribute("tempsize", Long.toString(code.tempSize)); + code.frame.log(logger); + logger.begElement("instructions"); + for (AsmInstr instr : code.instrs) { + logger.begElement("instruction"); + logger.addAttribute("code", instr.toString(tempToReg)); + logger.begElement("temps"); + logger.addAttribute("name", "use"); + for (MemTemp temp : instr.uses()) { + logger.begElement("temp"); + logger.addAttribute("name", temp.toString()); + logger.endElement(); + } + logger.endElement(); + logger.begElement("temps"); + logger.addAttribute("name", "def"); + for (MemTemp temp : instr.defs()) { + logger.begElement("temp"); + logger.addAttribute("name", temp.toString()); + logger.endElement(); + } + logger.endElement(); + logger.begElement("temps"); + logger.addAttribute("name", "in"); + for (MemTemp temp : instr.in()) { + logger.begElement("temp"); + logger.addAttribute("name", temp.toString()); + logger.endElement(); + } + logger.endElement(); + logger.begElement("temps"); + logger.addAttribute("name", "out"); + for (MemTemp temp : instr.out()) { + logger.begElement("temp"); + logger.addAttribute("name", temp.toString()); + logger.endElement(); + } + logger.endElement(); + logger.endElement(); + } + logger.endElement(); + logger.endElement(); + } + } + +} diff --git a/prev23/src/prev23/phase/regall/package-info.java b/prev23/src/prev23/phase/regall/package-info.java new file mode 100644 index 0000000..45488bd --- /dev/null +++ b/prev23/src/prev23/phase/regall/package-info.java @@ -0,0 +1,4 @@ +/** + * Register allocation. + */ +package prev23.phase.regall; \ No newline at end of file