+ def test_simple_mul_192x192_pre_ra_sim(self):
+ # test multiplying:
+ # 0x000191acb262e15b_4c6b5f2b19e1a53e_821a2342132c5b57
+ # * 0x4a37c0567bcbab53_cf1f597598194ae6_208a49071aeec507
+ # ==
+ # int("0x00074736574206e_6f69746163696c70"
+ # "_69746c756d207469_622d3438333e2d32"
+ # "_3931783239312079_7261727469627261", base=0)
+ # == int.from_bytes(b"arbitrary 192x192->384-bit multiplication test",
+ # 'little')
+ code = SimpleMul192x192()
+ dest_ptr = 0x100
+ state = PreRASimState(
+ gprs={}, VLs={}, CAs={}, global_mems={code.mem_in: FMap()},
+ stack_slots={}, fixed_gprs={
+ code.dest_ptr_in: (dest_ptr,),
+ code.lhs_in: (0x821a2342132c5b57, 0x4c6b5f2b19e1a53e,
+ 0x000191acb262e15b),
+ code.rhs_in: (0x208a49071aeec507, 0xcf1f597598194ae6,
+ 0x4a37c0567bcbab53)
+ })
+ code.fn.pre_ra_sim(state)
+ expected_bytes = b"arbitrary 192x192->384-bit multiplication test"
+ OUT_BYTE_COUNT = 6 * GPR_SIZE_IN_BYTES
+ expected_bytes = expected_bytes.ljust(OUT_BYTE_COUNT, b'\0')
+ mem_out = state.global_mems[code.mem_out]
+ out_bytes = bytes(
+ mem_out.get(dest_ptr + i, 0) for i in range(OUT_BYTE_COUNT))
+ self.assertEqual(out_bytes, expected_bytes)
+
+ def test_simple_mul_192x192_ops(self):
+ code = SimpleMul192x192()
+ fn = code.fn
+ self.assertEqual([repr(v) for v in fn.ops], [
+ 'OpInputMem(#0, <#0.out: GlobalMemType()>)',
+ 'OpFuncArg(#1, <#1.out: <fixed(<r3>)>>)',
+ 'OpFuncArg(#2, <#2.out: <fixed(<r4..len=3>)>>)',
+ 'OpFuncArg(#3, <#3.out: <fixed(<r7..len=3>)>>)',
+ 'OpCopy(#4, <#4.dest: <gpr_ty[1]>>, src=<#1.out: <fixed(<r3>)>>, '
+ 'vl=None)',
+ 'OpSetVLImm(#5, <#5.out: KnownVLType(length=3)>)',
+ 'OpCopy(#6, <#6.dest: <gpr_ty[3]>>, '
+ 'src=<#2.out: <fixed(<r4..len=3>)>>, '
+ 'vl=<#5.out: KnownVLType(length=3)>)',
+ 'OpCopy(#7, <#7.dest: <gpr_ty[3]>>, '
+ 'src=<#3.out: <fixed(<r7..len=3>)>>, '
+ 'vl=<#5.out: KnownVLType(length=3)>)',
+ 'OpSplit(#8, results=(<#8.results[0]: <gpr_ty[1]>>, '
+ '<#8.results[1]: <gpr_ty[1]>>, <#8.results[2]: <gpr_ty[1]>>), '
+ 'src=<#7.dest: <gpr_ty[3]>>)',
+ 'OpSetVLImm(#9, <#9.out: KnownVLType(length=3)>)',
+ 'OpLI(#10, <#10.out: <gpr_ty[1]>>, value=0, vl=None)',
+ 'OpBigIntMulDiv(#11, <#11.RT: <gpr_ty[3]>>, '
+ 'RA=<#6.dest: <gpr_ty[3]>>, RB=<#8.results[0]: <gpr_ty[1]>>, '
+ 'RC=<#10.out: <gpr_ty[1]>>, <#11.RS: <gpr_ty[1]>>, is_div=False, '
+ 'vl=<#9.out: KnownVLType(length=3)>)',
+ 'OpConcat(#12, <#12.dest: <gpr_ty[4]>>, sources=('
+ '<#11.RT: <gpr_ty[3]>>, <#11.RS: <gpr_ty[1]>>))',
+ 'OpBigIntMulDiv(#13, <#13.RT: <gpr_ty[3]>>, '
+ 'RA=<#6.dest: <gpr_ty[3]>>, RB=<#8.results[1]: <gpr_ty[1]>>, '
+ 'RC=<#10.out: <gpr_ty[1]>>, <#13.RS: <gpr_ty[1]>>, is_div=False, '
+ 'vl=<#9.out: KnownVLType(length=3)>)',
+ 'OpSplit(#14, results=(<#14.results[0]: <gpr_ty[1]>>, '
+ '<#14.results[1]: <gpr_ty[3]>>), src=<#12.dest: <gpr_ty[4]>>)',
+ 'OpSetCA(#15, <#15.out: CAType()>, value=False)',
+ 'OpBigIntAddSub(#16, <#16.out: <gpr_ty[3]>>, '
+ 'lhs=<#13.RT: <gpr_ty[3]>>, rhs=<#14.results[1]: <gpr_ty[3]>>, '
+ 'CA_in=<#15.out: CAType()>, <#16.CA_out: CAType()>, is_sub=False, '
+ 'vl=<#9.out: KnownVLType(length=3)>)',
+ 'OpBigIntAddSub(#17, <#17.out: <gpr_ty[1]>>, '
+ 'lhs=<#13.RS: <gpr_ty[1]>>, rhs=<#10.out: <gpr_ty[1]>>, '
+ 'CA_in=<#16.CA_out: CAType()>, <#17.CA_out: CAType()>, '
+ 'is_sub=False, vl=None)',
+ 'OpConcat(#18, <#18.dest: <gpr_ty[5]>>, sources=('
+ '<#14.results[0]: <gpr_ty[1]>>, <#16.out: <gpr_ty[3]>>, '
+ '<#17.out: <gpr_ty[1]>>))',
+ 'OpBigIntMulDiv(#19, <#19.RT: <gpr_ty[3]>>, '
+ 'RA=<#6.dest: <gpr_ty[3]>>, RB=<#8.results[2]: <gpr_ty[1]>>, '
+ 'RC=<#10.out: <gpr_ty[1]>>, <#19.RS: <gpr_ty[1]>>, is_div=False, '
+ 'vl=<#9.out: KnownVLType(length=3)>)',
+ 'OpSplit(#20, results=(<#20.results[0]: <gpr_ty[2]>>, '
+ '<#20.results[1]: <gpr_ty[3]>>), src=<#18.dest: <gpr_ty[5]>>)',
+ 'OpSetCA(#21, <#21.out: CAType()>, value=False)',
+ 'OpBigIntAddSub(#22, <#22.out: <gpr_ty[3]>>, '
+ 'lhs=<#19.RT: <gpr_ty[3]>>, rhs=<#20.results[1]: <gpr_ty[3]>>, '
+ 'CA_in=<#21.out: CAType()>, <#22.CA_out: CAType()>, is_sub=False, '
+ 'vl=<#9.out: KnownVLType(length=3)>)',
+ 'OpBigIntAddSub(#23, <#23.out: <gpr_ty[1]>>, '
+ 'lhs=<#19.RS: <gpr_ty[1]>>, rhs=<#10.out: <gpr_ty[1]>>, '
+ 'CA_in=<#22.CA_out: CAType()>, <#23.CA_out: CAType()>, '
+ 'is_sub=False, vl=None)',
+ 'OpConcat(#24, <#24.dest: <gpr_ty[6]>>, sources=('
+ '<#20.results[0]: <gpr_ty[2]>>, <#22.out: <gpr_ty[3]>>, '
+ '<#23.out: <gpr_ty[1]>>))',
+ 'OpSetVLImm(#25, <#25.out: KnownVLType(length=6)>)',
+ 'OpStore(#26, RS=<#24.dest: <gpr_ty[6]>>, '
+ 'RA=<#4.dest: <gpr_ty[1]>>, offset=0, '
+ 'mem_in=<#0.out: GlobalMemType()>, '
+ '<#26.mem_out: GlobalMemType()>, '
+ 'vl=<#25.out: KnownVLType(length=6)>)'
+ ])
+
+ # FIXME: register allocator currently allocates wrong registers
+ @unittest.expectedFailure
+ def test_simple_mul_192x192_reg_alloc(self):
+ code = SimpleMul192x192()
+ fn = code.fn
+ assigned_registers = allocate_registers(fn.ops)
+ self.assertEqual(assigned_registers, {
+ fn.ops[13].RS: GPRRange(9), # type: ignore
+ fn.ops[14].results[0]: GPRRange(6), # type: ignore
+ fn.ops[14].results[1]: GPRRange(7, length=3), # type: ignore
+ fn.ops[15].out: XERBit.CA, # type: ignore
+ fn.ops[16].out: GPRRange(7, length=3), # type: ignore
+ fn.ops[16].CA_out: XERBit.CA, # type: ignore
+ fn.ops[17].out: GPRRange(10), # type: ignore
+ fn.ops[17].CA_out: XERBit.CA, # type: ignore
+ fn.ops[18].dest: GPRRange(6, length=5), # type: ignore
+ fn.ops[19].RT: GPRRange(3, length=3), # type: ignore
+ fn.ops[19].RS: GPRRange(9), # type: ignore
+ fn.ops[20].results[0]: GPRRange(6, length=2), # type: ignore
+ fn.ops[20].results[1]: GPRRange(8, length=3), # type: ignore
+ fn.ops[21].out: XERBit.CA, # type: ignore
+ fn.ops[22].out: GPRRange(8, length=3), # type: ignore
+ fn.ops[22].CA_out: XERBit.CA, # type: ignore
+ fn.ops[23].out: GPRRange(11), # type: ignore
+ fn.ops[23].CA_out: XERBit.CA, # type: ignore
+ fn.ops[24].dest: GPRRange(6, length=6), # type: ignore
+ fn.ops[25].out: VL.VL_MAXVL, # type: ignore
+ fn.ops[26].mem_out: GlobalMem.GlobalMem, # type: ignore
+ fn.ops[0].out: GlobalMem.GlobalMem, # type: ignore
+ fn.ops[1].out: GPRRange(3), # type: ignore
+ fn.ops[2].out: GPRRange(4, length=3), # type: ignore
+ fn.ops[3].out: GPRRange(7, length=3), # type: ignore
+ fn.ops[4].dest: GPRRange(12), # type: ignore
+ fn.ops[5].out: VL.VL_MAXVL, # type: ignore
+ fn.ops[6].dest: GPRRange(17, length=3), # type: ignore
+ fn.ops[7].dest: GPRRange(14, length=3), # type: ignore
+ fn.ops[8].results[0]: GPRRange(14), # type: ignore
+ fn.ops[8].results[1]: GPRRange(15), # type: ignore
+ fn.ops[8].results[2]: GPRRange(16), # type: ignore
+ fn.ops[9].out: VL.VL_MAXVL, # type: ignore
+ fn.ops[10].out: GPRRange(9), # type: ignore
+ fn.ops[11].RT: GPRRange(6, length=3), # type: ignore
+ fn.ops[11].RS: GPRRange(9), # type: ignore
+ fn.ops[12].dest: GPRRange(6, length=4), # type: ignore
+ fn.ops[13].RT: GPRRange(3, length=3) # type: ignore
+ })
+ self.fail("register allocator currently allocates wrong registers")
+
+ # FIXME: register allocator currently allocates wrong registers
+ @unittest.expectedFailure
+ def test_simple_mul_192x192_asm(self):
+ code = SimpleMul192x192()
+ asm = generate_assembly(code.fn.ops)
+ self.assertEqual(asm, [
+ 'or 12, 3, 3',
+ 'setvl 0, 0, 3, 0, 1, 1',
+ 'sv.or *17, *4, *4',
+ 'sv.or *14, *7, *7',
+ 'setvl 0, 0, 3, 0, 1, 1',
+ 'addi 9, 0, 0',
+ 'sv.maddedu *6, *17, 14, 9',
+ 'sv.maddedu *3, *17, 15, 9',
+ 'addic 0, 0, 0',
+ 'sv.adde *7, *3, *7',
+ 'adde 10, 9, 9',
+ 'sv.maddedu *3, *17, 16, 9',
+ 'addic 0, 0, 0',
+ 'sv.adde *8, *3, *8',
+ 'adde 11, 9, 9',
+ 'setvl 0, 0, 6, 0, 1, 1',
+ 'sv.std *6, 0(12)',
+ 'bclr 20, 0, 0'
+ ])
+ self.fail("register allocator currently allocates wrong registers")
+