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.

35 lines
1.3 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. export const allocate = (alloc: RegAlloc, block: Array<AbsInsn2>): Array<AbsInsn2> =>
  6. block.map(insn => allocateInsn(alloc, insn))
  7. export const allocateInsn = (alloc: RegAlloc, insn: AbsInsn2): AbsInsn2 => insnReduce2<AbsInsn2>(
  8. (dest: Loc, source: Operand) => CopyInsn(
  9. allocateInsnDest(alloc, dest),
  10. typeof source === 'number' ? source : allocateInsnDest(alloc, source),
  11. ),
  12. (name: string) => LabelInsn(name),
  13. (name: string) => GotoInsn(name),
  14. (dest: Loc, op: UnaryOp | BinaryOp, source: Operand) => UnaryInsn(
  15. allocateInsnDest(alloc, dest),
  16. op,
  17. typeof source === 'number' ? source : allocateInsnDest(alloc, source),
  18. ),
  19. insn,
  20. )
  21. export const allocateInsnDest = (alloc: RegAlloc, loc: Loc): Loc =>
  22. loc.type === LocType.TEMPORARY
  23. ? lookupAllocation(alloc, loc.ppName())
  24. : loc
  25. const lookupAllocation = (alloc: RegAlloc, name: string): Loc => {
  26. const loc = alloc[name]
  27. if (typeof loc === 'object') {
  28. throw new Error('stack offsets not supported yet')
  29. }
  30. return Loc.reg(loc)
  31. }