A "high-level" language for the Gameboy
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

40 lines
1.3 KiB

  1. import { R8 } from "./cpu"
  2. import { Loc, LocType } from "../ir/loc"
  3. import { Operand, AbsInsn2, insnReduce2 } from "../ir/insn"
  4. import { BinaryOp, UnaryOp } from "../ast"
  5. import type { SM83Insn } from "./insn"
  6. export const realizeBlock = (block: Array<AbsInsn2>): Array<SM83Insn> => block.flatMap(realizeInsn)
  7. export const realizeInsn = (insn: AbsInsn2): Array<SM83Insn> => insnReduce2(realizeCopy, realizeUnary, insn)
  8. const getSourceName = (source: Operand): string => typeof source === "number"
  9. ? source.toString()
  10. : source.asmName()
  11. export const realizeCopy = (dest: Loc, source: Operand): Array<SM83Insn> => [
  12. `LD ${dest.asmName()}, ${getSourceName(source)}`
  13. ]
  14. export const realizeUnary = (dest: Loc, op: UnaryOp | BinaryOp, source: Operand): Array<SM83Insn> => {
  15. if (!isA(dest)) {
  16. throw new Error("unexpected form for unary operation")
  17. }
  18. switch (op) {
  19. case "add":
  20. return [`ADD ${getSourceName(source)}`]
  21. case "arith_negate":
  22. return ["CPL", "INC A"]
  23. case "bit_negate":
  24. return ["CPL"]
  25. default:
  26. throw new Error(`unsupported unary op \`${op}'`)
  27. }
  28. }
  29. const isA = (loc: Operand): boolean =>
  30. typeof loc === "object" && loc.type === LocType.REGISTER && loc.name === R8.A