|
|
- import { R8 } from "./cpu"
- import { Loc, LocType } from "../ir/loc"
- import { Operand, AbsInsn2, insnReduce2 } from "../ir/insn"
- import { BinaryOp, UnaryOp } from "../ast"
- import type { SM83Insn } from "./insn"
- import { BasicBlock } from "../ir/block"
-
- export const realizeBlock = (block: BasicBlock): Array<SM83Insn> => block.insns.flatMap(realizeInsn)
-
- export const realizeInsn = (insn: AbsInsn2): Array<SM83Insn> => insnReduce2(
- realizeCopy,
- realizeLabel,
- realizeGoto,
- realizeUnary,
- insn,
- )
-
- const getSourceName = (source: Operand): string => typeof source === "number"
- ? source.toString()
- : source.asmName()
-
- export const realizeCopy = (dest: Loc, source: Operand): Array<SM83Insn> => [
- `LD ${dest.asmName()}, ${getSourceName(source)}`
- ]
-
- export const realizeLabel = (name: string): Array<SM83Insn> => [
- `${name}:`,
- ]
-
- export const realizeGoto = (name: string): Array<SM83Insn> => [
- `JR ${name}`,
- ]
-
- export const realizeUnary = (dest: Loc, op: UnaryOp | BinaryOp, source: Operand): Array<SM83Insn> => {
- if (!isA(dest)) {
- throw new Error("unexpected form for unary operation")
- }
-
- let output: Array<SM83Insn> = []
-
- switch (op) {
- case "add":
- return [`ADD ${getSourceName(source)}`]
-
- case "subtract":
- return [`SUB ${getSourceName(source)}`]
-
- case "bit_and":
- return [`AND ${getSourceName(source)}`]
-
- case "bit_or":
- return [`OR ${getSourceName(source)}`]
-
- case "bit_xor":
- return [`XOR ${getSourceName(source)}`]
-
- case "shift_left":
- for (let i = 0; i < source; ++i) {
- output.push("SLA A")
- }
- return output
-
- case "shift_right":
- for (let i = 0; i < source; ++i) {
- output.push("SRL A")
- }
- return output
-
- case "arith_negate":
- return ["CPL", "INC A"]
-
- case "bit_negate":
- return ["CPL"]
- }
- }
-
- const isA = (loc: Operand): boolean =>
- typeof loc === "object" && loc.type === LocType.REGISTER && loc.name === R8.A
|