diff --git a/lib/ir/convert.ts b/lib/ir/convert.ts index 7f0d7bd..2973461 100644 --- a/lib/ir/convert.ts +++ b/lib/ir/convert.ts @@ -1,7 +1,7 @@ import type { AssignStmt, Expr, Stmt } from "../ast" import { R8 } from "../sm83/cpu" import { Loc, LocType } from "./loc" -import type { Operand, SSA } from "./ssa" +import type { Operand, SSA, SSAWithBinary } from "./ssa" type IRState = { nextID: number @@ -47,7 +47,7 @@ export const convertExpr = (state: IRState, dest: Loc, expr: Expr): Array = output.push( { dest: Loc.reg(R8.A), source: ssa.source }, - { dest: Loc.reg(R8.A), source: Loc.reg(R8.A), op: ssa.op, source1 }, + { dest: Loc.reg(R8.A), op: ssa.op, source: source1 }, { dest: ssa.dest, source: Loc.reg(R8.A) }, ) } else { @@ -62,8 +62,8 @@ export const convertExpr = (state: IRState, dest: Loc, expr: Expr): Array = return output } -export const convertExpr3 = (state: IRState, dest: Loc, expr: Expr): Array => { - let expr_stmts: Array = [] +export const convertExpr3 = (state: IRState, dest: Loc, expr: Expr): Array => { + let expr_stmts: Array = [] if (typeof expr === "number") { expr_stmts = [{ dest, source: expr }] @@ -96,7 +96,7 @@ export const convertExpr3 = (state: IRState, dest: Loc, expr: Expr): Array return expr_stmts } -const getSource = (state: IRState, expr: Expr): [Operand, Array] => { +const getSource = (state: IRState, expr: Expr): [Operand, Array] => { if (typeof expr === "number") { return [expr, []] } else if (typeof expr === "string") { diff --git a/lib/ir/pretty.ts b/lib/ir/pretty.ts index 7679a79..8e41742 100644 --- a/lib/ir/pretty.ts +++ b/lib/ir/pretty.ts @@ -1,11 +1,11 @@ import type { Loc } from "./loc" -import type { Operand, SSA } from "./ssa" +import type { Operand, SSA, SSAWithBinary } from "./ssa" export const prettyPrintBlock = (block: Array): string => { return block.map(prettyPrintSSA).join("\n") } -export const prettyPrintSSA = (ssa: SSA): string => { +export const prettyPrintSSA = (ssa: SSAWithBinary): string => { let output = "" if ("source1" in ssa) { diff --git a/lib/ir/ssa.d.ts b/lib/ir/ssa.d.ts index 3e9b08d..c17441a 100644 --- a/lib/ir/ssa.d.ts +++ b/lib/ir/ssa.d.ts @@ -9,9 +9,11 @@ type ASSA = { dest: Loc, source: Operand } & Data export type SSACopy = ASSA<{}> // dest = op(source) -export type SSAUnary = ASSA<{ op: UnaryOp }> +export type SSAUnary = ASSA<{ op: UnaryOp | BinaryOp }> // dest = op(source, source1) export type SSABinary = ASSA<{ op: BinaryOp, source1: Operand }> -export type SSA = SSACopy | SSAUnary | SSABinary +export type SSA = SSACopy | SSAUnary + +export type SSAWithBinary = SSA | SSABinary diff --git a/lib/regalloc.ts b/lib/regalloc.ts index 5c047d1..3679e26 100644 --- a/lib/regalloc.ts +++ b/lib/regalloc.ts @@ -19,10 +19,6 @@ export const liveness = (block: Array): LivenessInfo => { info[i].add(insn.source) } - if ("source1" in insn && typeof insn.source1 !== "number") { - info[i].add(insn.source1) - } - last.forEach(loc => { if (loc.toString() === insn.dest.toString()) { return @@ -44,10 +40,6 @@ export const locations = (block: Array): Set => { if (typeof ssa.source !== "number") { ls.add(ssa.source) } - - if ("source1" in ssa && typeof ssa.source1 !== "number") { - ls.add(ssa.source1) - } }) return ls diff --git a/lib/sm83/codegen.ts b/lib/sm83/codegen.ts index ecbe43a..55e7c49 100644 --- a/lib/sm83/codegen.ts +++ b/lib/sm83/codegen.ts @@ -2,7 +2,7 @@ import { R8 } from "../sm83/cpu" import { Loc, LocType } from "../ir/loc" import type { Operand, SSA, SSABinary, SSACopy, SSAUnary } from "../ir/ssa" import type { RegAlloc } from "../regalloc" -import { UnaryOp } from "../ast" +import { BinaryOp, UnaryOp } from "../ast" export const generateBlock = (alloc: RegAlloc, block: Array): Array => { const output: Array = [] @@ -17,9 +17,7 @@ export const generateBlock = (alloc: RegAlloc, block: Array): Array export const generateSSA = (alloc: RegAlloc, ssa: SSA): Array => { let output: Array = [] - if ("source1" in ssa) { - output = generateSSA_Binary(alloc, ssa) - } else if ("op" in ssa) { + if ("op" in ssa) { output = generateSSA_Unary(alloc, ssa) } else { output = generateSSA_Copy(alloc, ssa) @@ -83,40 +81,33 @@ export const generateSSA_Unary = (alloc: RegAlloc, ssa: SSAUnary): Array throw new Error("Unexpected form for unary operation") } - const output: Array = [] - if (typeof ssa.source === "number") { - output.push(`LD A, ${ssa.source}`) - } else if (ssa.source.type === LocType.REGISTER) { - if (!isA(ssa.dest)) { - output.push(`LD A, ${ssa.source.name}`) - } - } else { - // TODO: ?? - output.push(`LD A, ${alloc[ssa.source.toString()]}`) - } + const source = typeof ssa.source === 'number' + ? ssa.source.toString() + : getAlloc(alloc, ssa.source).name - const ops = unaryOps[ssa.op] - if (!ops) { - throw new Error(`unsupported unary op \`${ssa.op}'`) - } + switch (ssa.op) { + case "add": + return [`ADD ${source}`] - return output.concat(ops) -} + case "arith_negate": + return ["CPL", "INC A"] -const unaryOps = { - "arith_negate": ["CPL", "INC A"], - "bit_negate": ["CPL"] + case "bit_negate": + return ["CPL"] + + default: + throw new Error(`unsupported unary op \`${ssa.op}'`) + } } +/* export const generateSSA_Binary = (alloc: RegAlloc, ssa: SSABinary): Array => { if (!isA(ssa.dest) || !isA(ssa.source)) { throw new Error("Unexpected form for binary operation") } const output: Array = [] - const source = typeof ssa.source1 === 'number' - ? ssa.source1 - : getAlloc(alloc, ssa.source1).name + switch (ssa.op) { case "add": @@ -128,7 +119,7 @@ export const generateSSA_Binary = (alloc: RegAlloc, ssa: SSABinary): Array typeof loc === "object" && loc.type === LocType.REGISTER && loc.name === R8.A diff --git a/test/ir/pretty.spec.ts b/test/ir/pretty.spec.ts index e344cd2..1c674df 100644 --- a/test/ir/pretty.spec.ts +++ b/test/ir/pretty.spec.ts @@ -2,7 +2,7 @@ import { expect } from "chai" import { Loc } from "../../lib/ir/loc" import { prettyPrintSSA } from "../../lib/ir/pretty" -import type { SSA } from "../../lib/ir/ssa" +import type { SSA, SSAWithBinary } from "../../lib/ir/ssa" describe("ir", () => { describe("prettyPrintSSA", () => { @@ -53,7 +53,7 @@ describe("ir", () => { }) it("binary op", () => { - const ssa: SSA = { + const ssa: SSAWithBinary = { dest: Loc.vari("x"), source: Loc.vari("y"), source1: 42, diff --git a/test/regalloc.spec.ts b/test/regalloc.spec.ts index 070bde3..fdad006 100644 --- a/test/regalloc.spec.ts +++ b/test/regalloc.spec.ts @@ -13,10 +13,10 @@ describe("liveness", () => { const block: Array = [ { dest: x[0], source: 1 }, - { dest: x[1], source: x[0], op: "add", source1: x[0] }, - { dest: x[2], source: x[1], op: "add", source1: x[0] }, - { dest: y[0], source: x[0], op: "add", source1: x[1] }, - { dest: y[1], source: y[0], op: "add", source1: x[2] }, + { dest: x[1], source: x[0], op: "add" }, + { dest: x[2], source: x[1], op: "add" }, + { dest: y[0], source: x[0], op: "add" }, + { dest: y[1], source: y[0], op: "add" }, ] const info = liveness(block)