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.

38 lines
1.4 KiB

  1. import type { RegAlloc } from '../regalloc'
  2. import { AbsInsn2, CopyInsn, GotoInsn, insnReduce2, LabelInsn, Operand, UnaryInsn } from '../ir/insn'
  3. import { Loc, LocType } from '../ir/loc'
  4. import { UnaryOp, BinaryOp } from '../ast'
  5. import { BasicBlock } from '../ir/block'
  6. export const allocate = (alloc: RegAlloc, block: BasicBlock): BasicBlock =>
  7. new BasicBlock(
  8. block.insns.map(insn => allocateInsn(alloc, insn))
  9. )
  10. export const allocateInsn = (alloc: RegAlloc, insn: AbsInsn2): AbsInsn2 => insnReduce2<AbsInsn2>(
  11. (dest: Loc, source: Operand) => CopyInsn(
  12. allocateInsnDest(alloc, dest),
  13. typeof source === 'number' ? source : allocateInsnDest(alloc, source),
  14. ),
  15. (name: string) => LabelInsn(name),
  16. (name: string) => GotoInsn(name),
  17. (dest: Loc, op: UnaryOp | BinaryOp, source: Operand) => UnaryInsn(
  18. allocateInsnDest(alloc, dest),
  19. op,
  20. typeof source === 'number' ? source : allocateInsnDest(alloc, source),
  21. ),
  22. insn,
  23. )
  24. export const allocateInsnDest = (alloc: RegAlloc, loc: Loc): Loc =>
  25. loc.type === LocType.TEMPORARY
  26. ? lookupAllocation(alloc, loc.ppName())
  27. : loc
  28. const lookupAllocation = (alloc: RegAlloc, name: string): Loc => {
  29. const loc = alloc[name]
  30. if (typeof loc === 'object') {
  31. throw new Error('stack offsets not supported yet')
  32. }
  33. return Loc.reg(loc)
  34. }