raise ValueError(f"instruction is part of a dependency loop or "
f"its inputs are never written: {op}")
return retval
+
+
+def generate_assembly(ops, assigned_registers=None):
+ # type: (list[Op], dict[SSAVal, RegLoc] | None) -> list[str]
+ if assigned_registers is None:
+ from bigint_presentation_code.register_allocator import \
+ allocate_registers
+ assigned_registers = allocate_registers(ops)
+ ctx = AsmContext(assigned_registers)
+ retval = [] # list[str]
+ for op in ops:
+ retval.extend(op.get_asm_lines(ctx))
+ retval.append("bclr 20, 0, 0")
+ return retval
import unittest
-from bigint_presentation_code.compiler_ir import (FixedGPRRangeType, Fn,
- GPRRange, GPRType,
+from bigint_presentation_code.compiler_ir import (VL, FixedGPRRangeType, Fn,
+ GlobalMem, GPRRange, GPRType,
OpBigIntAddSub, OpConcat,
OpCopy, OpFuncArg,
OpInputMem, OpLI, OpLoad,
OpSetCA, OpSetVLImm, OpStore,
+ RegLoc, SSAVal, XERBit,
+ generate_assembly,
op_set_to_list)
if ops != expected_ops:
self.assertEqual(repr(ops), repr(expected_ops))
+ def tst_generate_assembly(self, use_reg_alloc=False):
+ fn = Fn()
+ op0 = OpFuncArg(fn, FixedGPRRangeType(GPRRange(3)))
+ op1 = OpCopy(fn, op0.out, GPRType())
+ arg = op1.dest
+ op2 = OpInputMem(fn)
+ mem = op2.out
+ op3 = OpSetVLImm(fn, 32)
+ vl = op3.out
+ op4 = OpLoad(fn, arg, offset=0, mem=mem, vl=vl)
+ a = op4.RT
+ op5 = OpLI(fn, 0, vl=vl)
+ b = op5.out
+ op6 = OpSetCA(fn, True)
+ ca = op6.out
+ op7 = OpBigIntAddSub(fn, a, b, ca, is_sub=False, vl=vl)
+ s = op7.out
+ op8 = OpStore(fn, s, arg, offset=0, mem_in=mem, vl=vl)
+ mem = op8.mem_out
+
+ assigned_registers = {
+ op0.out: GPRRange(start=3, length=1),
+ op1.dest: GPRRange(start=3, length=1),
+ op2.out: GlobalMem.GlobalMem,
+ op3.out: VL.VL_MAXVL,
+ op4.RT: GPRRange(start=78, length=32),
+ op5.out: GPRRange(start=46, length=32),
+ op6.out: XERBit.CA,
+ op7.out: GPRRange(start=14, length=32),
+ op7.CA_out: XERBit.CA,
+ op8.mem_out: GlobalMem.GlobalMem,
+ } # type: dict[SSAVal, RegLoc] | None
+
+ if use_reg_alloc:
+ assigned_registers = None
+
+ asm = generate_assembly(fn.ops, assigned_registers)
+ self.assertEqual(asm, [
+ "setvl 0, 0, 32, 0, 1, 1",
+ "sv.ld *78, 0(3)",
+ "sv.addi *46, 0, 0",
+ "subfic 0, 0, -1",
+ "sv.adde *14, *78, *46",
+ "sv.std *14, 0(3)",
+ "bclr 20, 0, 0",
+ ])
+
+ def test_generate_assembly(self):
+ self.tst_generate_assembly()
+
+ def test_generate_assembly_with_register_allocator(self):
+ self.tst_generate_assembly(use_reg_alloc=True)
+
if __name__ == "__main__":
unittest.main()