Exemplo n.º 1
0
        public void Spbp_TwoExits()
        {
            var m = new SsaProcedureBuilder(nameof(Spbp_TwoExits));

            Given_FramePointer(m);
            Given_StackPointer(m);
            var sp_1 = m.Reg("sp_1", m.Architecture.StackRegister);
            var sp_2 = m.Reg("sp_2", m.Architecture.StackRegister);
            var sp_3 = m.Reg("sp_3", m.Architecture.StackRegister);
            var sp_4 = m.Reg("sp_4", m.Architecture.StackRegister);
            var sp_5 = m.Reg("sp_5", m.Architecture.StackRegister);
            var sp_6 = m.Reg("sp_6", m.Architecture.StackRegister);

            m.AddDefToEntryBlock(fp);

            m.Assign(sp_1, m.ISub(fp, m.Int32(4)));
            m.BranchIf(m.Eq0(m.Mem32(m.Word32(0x1))), "m_eq0");

            m.Label("m_ne0");
            // Indirect call = hell node
            m.Call(m.Mem32(m.Word32(0x4)), 4,
                   new[] { sp_1 },
                   new[] { sp_2 });
            m.Assign(sp_3, m.IAdd(sp_2, m.Int32(4)));
            m.Return();

            m.Label("m_eq0");
            // Indirect call = hell node
            m.Call(m.Mem32(m.Word32(0x8)), 4,
                   new[] { sp_1 },
                   new[] { sp_4 });
            m.Assign(sp_5, m.IAdd(sp_4, m.Int32(4)));
            m.Return();

            m.AddPhiToExitBlock(sp_6, (sp_3, "m_ne0"), (sp_5, "m_eq0"));
            m.AddUseToExitBlock(sp_6);

            RunTest(m.Ssa);

            var sExp =
                #region Expected
                @"Spbp_TwoExits_entry:
	def fp
l1:
	sp_1 = fp - 4
	branch Mem7[0x00000001:word32] == 0x00000000 m_eq0
	goto m_ne0
m_eq0:
	call Mem9[0x00000008:word32] (retsize: 4;)
		uses: sp:sp_1
	sp_4 = fp - 4
	sp_5 = fp
	return
m_ne0:
	call Mem8[0x00000004:word32] (retsize: 4;)
		uses: sp:sp_1
	sp_2 = fp - 4
	sp_3 = fp
	return
Spbp_TwoExits_exit:
	sp_6 = PHI((sp_3, m_ne0), (sp_5, m_eq0))
	use sp_6
";

            #endregion
            AssertStringsEqual(sExp, m.Ssa);
        }