public void CoaAcrossComment() { var a = m.Reg32("a"); var b = m.Reg32("b"); m.Assign(a, m.Mem32(m.Word32(0x00123400))); m.Comment("This is a comment"); m.Assign(b, m.Mem32(a)); RunCoalescer(); var sExp = @" // This is a comment b = Mem3[Mem2[0x123400<32>:word32]:word32] "; AssertProcedureCode(sExp); }
public void VpEquality2() { // Makes sure that // y = x - 2 // if (y == 0) ... // doesn't get munged into // y = x - 2 // if (x == 2) var x = m.Reg32("x"); var y = m.Reg32("y"); var stmX = m.Assign(x, m.Mem32(Constant.Word32(0x1000300))); var stmY = m.Assign(y, m.ISub(x, 2)); var stm = m.BranchIf(m.Eq(y, 0), "test"); Assert.AreEqual("x = Mem2[0x1000300<32>:word32]", stmX.ToString()); Assert.AreEqual("y = x - 2<32>", stmY.ToString()); Assert.AreEqual("branch y == 0<32> test", stm.ToString()); RunValuePropagator(); Assert.AreEqual("branch x == 2<32> test", stm.Instruction.ToString()); }
public void VpEquality2() { // Makes sure that // y = x - 2 // if (y == 0) ... // doesn't get munged into // y = x - 2 // if (x == 2) var x = m.Reg32("x"); var y = m.Reg32("y"); var stmX = m.Assign(x, m.Mem32(Constant.Word32(0x1000300))); var stmY = m.Assign(y, m.ISub(x, 2)); var stm = m.BranchIf(m.Eq(y, 0), "test"); Assert.AreEqual("x = Mem2[0x01000300:word32]", stmX.ToString()); Assert.AreEqual("y = x - 0x00000002", stmY.ToString()); Assert.AreEqual("branch y == 0x00000000 test", stm.ToString()); var vp = new ValuePropagator(segmentMap, m.Ssa, listener); vp.Transform(stm); Assert.AreEqual("branch x == 0x00000002 test", stm.Instruction.ToString()); }
public void Spbp_LinearProcedure() { var m = new SsaProcedureBuilder(nameof(Spbp_LinearProcedure)); var fp = m.Ssa.Identifiers.Add(m.Frame.FramePointer, null, null, false).Identifier; 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); m.AddDefToEntryBlock(fp); m.Assign(sp_1, m.ISub(fp, m.Int32(4))); // Indirect call = hell node var ci = m.Call(m.Mem32(m.Word32(0x2)), 4, new[] { sp_1 }, new[] { sp_2 }); m.Assign(sp_3, m.IAdd(sp_2, m.Int32(4))); m.Return(); m.AddUseToExitBlock(sp_3); RunTest(m.Ssa); var sExp = #region Expected @"Spbp_LinearProcedure_entry: def fp l1: sp_1 = fp - 4 call Mem4[0x00000002:word32] (retsize: 4;) uses: sp:sp_1 sp_2 = fp - 4 sp_3 = fp return Spbp_LinearProcedure_exit: use sp_3 "; #endregion AssertStringsEqual(sExp, m.Ssa); }
public void UfuserMipsLittleEndianUnalignedWordLoad() { var r4 = m.Reg32("r4"); var r8 = m.Reg32("r8"); __lwl(r8, m.Mem32(m.IAdd(r4, 0x2B))); __lwr(r8, m.Mem32(m.IAdd(r4, 0x28))); var ssa = RunTest(m); var sExp = #region Expected @"r8:r8 def: def r8 uses: r8_3 = r8 r4:r4 def: def r4 uses: r8_5 = Mem3[r4 + 0x00000028:word32] Mem2:Global memory def: def Mem2 r8_3: orig: r8 def: r8_3 = r8 Mem3:Global memory def: def Mem3 uses: r8_5 = Mem3[r4 + 0x00000028:word32] r8_5: orig: r8 def: r8_5 = Mem3[r4 + 0x00000028:word32] // SsaProcedureBuilder // Return size: 0 void SsaProcedureBuilder() SsaProcedureBuilder_entry: def r8 def r4 def Mem2 def Mem3 // succ: l1 l1: r8_5 = Mem3[r4 + 0x00000028:word32] SsaProcedureBuilder_exit: "; #endregion AssertStringsEqual(sExp, ssa); }
public void Spbp_SpaceOnStack() { var m = new SsaProcedureBuilder(nameof(Spbp_SpaceOnStack)); var fp = m.Ssa.Identifiers.Add(m.Frame.FramePointer, null, null, false).Identifier; Given_StackPointer(m); var sp_1 = m.Reg("sp_1", sp); var sp_2 = m.Reg("sp_2", sp); var sp_3 = m.Reg("sp_3", sp); var sp_4 = m.Reg("sp_4", sp); var sp_5 = m.Reg("sp_5", sp); var sp_6 = m.Reg("sp_6", sp); var sp_7 = m.Reg("sp_7", sp); var sp_8 = m.Reg("sp_8", sp); var a = m.Reg("a", new RegisterStorage("a", 1, 0, PrimitiveType.Word32)); var b = m.Reg("b", new RegisterStorage("b", 2, 0, PrimitiveType.Word32)); var a_1 = m.Reg("a_1", (RegisterStorage)a.Storage); var b_1 = m.Reg("b_1", (RegisterStorage)b.Storage); m.AddDefToEntryBlock(fp); m.Assign(sp_2, m.ISub(fp, 4)); // space for a m.MStore(sp_2, a); m.Assign(sp_3, m.ISub(fp, 4)); // space for b m.MStore(sp_3, b); m.Assign(sp_4, m.ISub(fp, 40)); // 40 bytes of stack space m.MStore(sp_4, m.Word32(0xDEADBABE)); m.Call(m.Mem32(m.Word32(0x00123400)), 4, new[] { sp_4 }, new[] { sp_5 }); m.Assign(sp_6, m.IAdd(sp_5, 40)); m.Assign(b_1, m.Mem32(sp_6)); m.Assign(sp_7, m.IAdd(sp_6, 4)); m.Assign(a_1, m.Mem32(sp_7)); m.Assign(sp_8, m.IAdd(sp_7, 4)); m.Return(); m.AddUseToExitBlock(sp_8); RunTest(m.Ssa); var sExp = #region Expected @"Spbp_SpaceOnStack_entry: def fp l1: sp_2 = fp - 0x00000004 Mem13[sp_2:word32] = a sp_3 = fp - 0x00000004 Mem14[sp_3:word32] = b sp_4 = fp - 0x00000028 Mem15[sp_4:word32] = 0xDEADBABE call Mem16[0x00123400:word32] (retsize: 4;) uses: sp:sp_4 sp_5 = fp - 48 sp_6 = fp - 8 b_1 = Mem17[sp_6:word32] sp_7 = fp - 4 a_1 = Mem18[sp_7:word32] sp_8 = fp return Spbp_SpaceOnStack_exit: use sp_8 "; #endregion this.AssertStringsEqual(sExp, m.Ssa); }
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); }