|
@ -2,7 +2,7 @@ import { R8 } from "../sm83/cpu" |
|
|
import { Loc, LocType } from "../ir/loc" |
|
|
import { Loc, LocType } from "../ir/loc" |
|
|
import type { Operand, SSA, SSABinary, SSACopy, SSAUnary } from "../ir/ssa" |
|
|
import type { Operand, SSA, SSABinary, SSACopy, SSAUnary } from "../ir/ssa" |
|
|
import type { RegAlloc } from "../regalloc" |
|
|
import type { RegAlloc } from "../regalloc" |
|
|
import { UnaryOp } from "../ast" |
|
|
|
|
|
|
|
|
import { BinaryOp, UnaryOp } from "../ast" |
|
|
|
|
|
|
|
|
export const generateBlock = (alloc: RegAlloc, block: Array<SSA>): Array<string> => { |
|
|
export const generateBlock = (alloc: RegAlloc, block: Array<SSA>): Array<string> => { |
|
|
const output: Array<string> = [] |
|
|
const output: Array<string> = [] |
|
@ -17,9 +17,7 @@ export const generateBlock = (alloc: RegAlloc, block: Array): Array |
|
|
export const generateSSA = (alloc: RegAlloc, ssa: SSA): Array<string> => { |
|
|
export const generateSSA = (alloc: RegAlloc, ssa: SSA): Array<string> => { |
|
|
let output: Array<string> = [] |
|
|
let output: Array<string> = [] |
|
|
|
|
|
|
|
|
if ("source1" in ssa) { |
|
|
|
|
|
output = generateSSA_Binary(alloc, ssa) |
|
|
|
|
|
} else if ("op" in ssa) { |
|
|
|
|
|
|
|
|
if ("op" in ssa) { |
|
|
output = generateSSA_Unary(alloc, ssa) |
|
|
output = generateSSA_Unary(alloc, ssa) |
|
|
} else { |
|
|
} else { |
|
|
output = generateSSA_Copy(alloc, ssa) |
|
|
output = generateSSA_Copy(alloc, ssa) |
|
@ -83,40 +81,33 @@ export const generateSSA_Unary = (alloc: RegAlloc, ssa: SSAUnary): Array |
|
|
throw new Error("Unexpected form for unary operation") |
|
|
throw new Error("Unexpected form for unary operation") |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
const output: Array<string> = [] |
|
|
|
|
|
if (typeof ssa.source === "number") { |
|
|
|
|
|
output.push(`LD A, ${ssa.source}`) |
|
|
|
|
|
} else if (ssa.source.type === LocType.REGISTER) { |
|
|
|
|
|
if (!isA(ssa.dest)) { |
|
|
|
|
|
output.push(`LD A, ${ssa.source.name}`) |
|
|
|
|
|
} |
|
|
|
|
|
} else { |
|
|
|
|
|
// TODO: ??
|
|
|
|
|
|
output.push(`LD A, ${alloc[ssa.source.toString()]}`) |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
const source = typeof ssa.source === 'number' |
|
|
|
|
|
? ssa.source.toString() |
|
|
|
|
|
: getAlloc(alloc, ssa.source).name |
|
|
|
|
|
|
|
|
const ops = unaryOps[ssa.op] |
|
|
|
|
|
if (!ops) { |
|
|
|
|
|
throw new Error(`unsupported unary op \`${ssa.op}'`) |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
switch (ssa.op) { |
|
|
|
|
|
case "add": |
|
|
|
|
|
return [`ADD ${source}`] |
|
|
|
|
|
|
|
|
return output.concat(ops) |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
case "arith_negate": |
|
|
|
|
|
return ["CPL", "INC A"] |
|
|
|
|
|
|
|
|
const unaryOps = { |
|
|
|
|
|
"arith_negate": ["CPL", "INC A"], |
|
|
|
|
|
"bit_negate": ["CPL"] |
|
|
|
|
|
|
|
|
case "bit_negate": |
|
|
|
|
|
return ["CPL"] |
|
|
|
|
|
|
|
|
|
|
|
default: |
|
|
|
|
|
throw new Error(`unsupported unary op \`${ssa.op}'`) |
|
|
|
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/* |
|
|
export const generateSSA_Binary = (alloc: RegAlloc, ssa: SSABinary): Array<string> => { |
|
|
export const generateSSA_Binary = (alloc: RegAlloc, ssa: SSABinary): Array<string> => { |
|
|
if (!isA(ssa.dest) || !isA(ssa.source)) { |
|
|
if (!isA(ssa.dest) || !isA(ssa.source)) { |
|
|
throw new Error("Unexpected form for binary operation") |
|
|
throw new Error("Unexpected form for binary operation") |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
const output: Array<string> = [] |
|
|
const output: Array<string> = [] |
|
|
const source = typeof ssa.source1 === 'number' |
|
|
|
|
|
? ssa.source1 |
|
|
|
|
|
: getAlloc(alloc, ssa.source1).name |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
switch (ssa.op) { |
|
|
switch (ssa.op) { |
|
|
case "add": |
|
|
case "add": |
|
@ -128,7 +119,7 @@ export const generateSSA_Binary = (alloc: RegAlloc, ssa: SSABinary): Array |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
return output |
|
|
return output |
|
|
} |
|
|
|
|
|
|
|
|
} */ |
|
|
|
|
|
|
|
|
const isA = (loc: Operand): boolean => |
|
|
const isA = (loc: Operand): boolean => |
|
|
typeof loc === "object" && loc.type === LocType.REGISTER && loc.name === R8.A |
|
|
typeof loc === "object" && loc.type === LocType.REGISTER && loc.name === R8.A |