|
import type { RegAlloc } from '../regalloc'
|
|
import { AbsInsn2, CopyInsn, insnReduce2, Operand, UnaryInsn } from '../ir/insn'
|
|
import { Loc, LocType } from '../ir/loc'
|
|
import { UnaryOp, BinaryOp } from '../ast'
|
|
|
|
export const allocate = (alloc: RegAlloc, block: Array<AbsInsn2>): Array<AbsInsn2> =>
|
|
block.map(insn => allocateInsn(alloc, insn))
|
|
|
|
export const allocateInsn = (alloc: RegAlloc, insn: AbsInsn2): AbsInsn2 => insnReduce2<AbsInsn2>(
|
|
(dest: Loc, source: Operand) => CopyInsn(
|
|
allocateInsnDest(alloc, dest),
|
|
typeof source === 'number' ? source : allocateInsnDest(alloc, source),
|
|
),
|
|
(dest: Loc, op: UnaryOp | BinaryOp, source: Operand) => UnaryInsn(
|
|
allocateInsnDest(alloc, dest),
|
|
op,
|
|
typeof source === 'number' ? source : allocateInsnDest(alloc, source),
|
|
),
|
|
insn,
|
|
)
|
|
|
|
export const allocateInsnDest = (alloc: RegAlloc, loc: Loc): Loc =>
|
|
loc.type === LocType.TEMPORARY
|
|
? lookupAllocation(alloc, loc.ppName())
|
|
: loc
|
|
|
|
const lookupAllocation = (alloc: RegAlloc, name: string): Loc => {
|
|
const loc = alloc[name]
|
|
if (typeof loc === 'object') {
|
|
throw new Error('stack offsets not supported yet')
|
|
}
|
|
return Loc.reg(loc)
|
|
}
|