Exemplo n.º 1
0
        public void SrtReg685()
        {
            var m   = new SsaProcedureBuilder(nameof(SrtReg685));
            var i_1 = m.Reg32("i_1");
            var i_2 = m.Reg32("i_2");
            var i_3 = m.Reg32("i_3");

            m.Assign(i_1, m.Int32(0));

            m.Label("m1");
            m.Phi(i_2, i_1, i_3);
            m.SideEffect(m.Fn("foo", i_2));
            m.SideEffect(m.Fn("foo", m.IAdd(i_2, 1)));
            m.Assign(i_3, m.IAdd(i_2, 2));
            m.BranchIf(m.Eq(i_3, 10), "m1");

            m.Label("m2");
            m.Return();

            var dom = m.Procedure.CreateBlockDominatorGraph();
            var lif = new LinearInductionVariableFinder(m.Procedure, m.Ssa.Identifiers, dom);

            lif.Find();
            Assert.AreEqual("(0 0x00000002 0x0000000C)", lif.InductionVariables[0].ToString());

            var ctx = lif.Contexts[lif.InductionVariables[0]];

            var str = new StrengthReduction(m.Ssa, lif.InductionVariables[0], ctx);

            str.ClassifyUses();
            Assert.AreEqual(2, str.IncrementedUses.Count);
            str.ModifyUses();
        }
Exemplo n.º 2
0
        public void VpCopyPropagate()
        {
            var x    = m.Reg32("x");
            var y    = m.Reg32("y");
            var z    = m.Reg32("z");
            var w    = m.Reg32("w");
            var stmX = m.Assign(x, m.Mem32(Constant.Word32(0x10004000)));
            var stmY = m.Assign(y, x);
            var stmZ = m.Assign(z, m.IAdd(y, Constant.Word32(2)));
            var stmW = m.Assign(w, y);

            Assert.AreEqual("x = Mem4[0x10004000<32>:word32]", stmX.ToString());
            Assert.AreEqual("y = x", stmY.ToString());
            Assert.AreEqual("z = y + 2<32>", stmZ.ToString());
            Assert.AreEqual("w = y", stmW.ToString());

            RunValuePropagator();

            Assert.AreEqual("x = Mem4[0x10004000<32>:word32]", stmX.ToString());
            Assert.AreEqual("y = x", stmY.ToString());
            Assert.AreEqual("z = x + 2<32>", stmZ.ToString());
            Assert.AreEqual("w = x", stmW.ToString());
            Assert.AreEqual(3, m.Ssa.Identifiers[x].Uses.Count);
            Assert.AreEqual(0, m.Ssa.Identifiers[y].Uses.Count);
        }
Exemplo n.º 3
0
        public void CoaCallCallee()
        {
            var r2 = m.Reg32("r2");
            var r3 = m.Reg32("r3");

            m.Assign(r3, m.Fn(r2));
            var uses    = new Identifier[] { r2 };
            var defines = new Identifier[] { };

            m.Call(m.IAdd(r3, 4), 4, uses, defines);

            RunCoalescer();

            var expected =
                @"
call r2() + 4<32> (retsize: 4;)
	uses: r2:r2
";

            AssertProcedureCode(expected);
        }
Exemplo n.º 4
0
        public void CoaDoNotCoalesceInvalidConstant()
        {
            var a = m.Reg32("a");
            var b = m.Reg32("b");

            m.Assign(a, Constant.Invalid);
            m.Assign(b, m.IAdd(a, 4));

            RunCoalescer();

            var expected =
                @"
a = <invalid>
b = a + 0x00000004
";

            AssertProcedureCode(expected);
        }
Exemplo n.º 5
0
        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);
        }
Exemplo n.º 6
0
        public void VpCopyPropagate()
        {
            var x = m.Reg32("x");
            var y = m.Reg32("y");
            var z = m.Reg32("z");
            var w = m.Reg32("w");

            m.Assign(x, m.Mem32(Constant.Word32(0x10004000)));
            var stmX = m.Block.Statements.Last();

            m.Assign(y, x);
            var stmY = m.Block.Statements.Last();

            m.Assign(z, m.IAdd(y, Constant.Word32(2)));
            var stmZ = m.Block.Statements.Last();

            m.Assign(w, y);
            var stmW = m.Block.Statements.Last();

            Assert.AreEqual("x = Mem4[0x10004000:word32]", stmX.Instruction.ToString());
            Assert.AreEqual("y = x", stmY.Instruction.ToString());
            Assert.AreEqual("z = y + 0x00000002", stmZ.Instruction.ToString());
            Assert.AreEqual("w = y", stmW.Instruction.ToString());

            var vp = new ValuePropagator(segmentMap, m.Ssa, listener);

            vp.Transform(stmX);
            vp.Transform(stmY);
            vp.Transform(stmZ);
            vp.Transform(stmW);

            Assert.AreEqual("x = Mem4[0x10004000:word32]", stmX.Instruction.ToString());
            Assert.AreEqual("y = x", stmY.Instruction.ToString());
            Assert.AreEqual("z = x + 0x00000002", stmZ.Instruction.ToString());
            Assert.AreEqual("w = x", stmW.Instruction.ToString());
            Assert.AreEqual(3, m.Ssa.Identifiers[x].Uses.Count);
            Assert.AreEqual(0, m.Ssa.Identifiers[y].Uses.Count);
        }
Exemplo n.º 7
0
        public void Cab_GuessStackParameter()
        {
            var m  = new SsaProcedureBuilder(nameof(Cab_Sequence));
            var sp = m.Reg("sp", m.Procedure.Architecture.StackRegister);

            m.AddDefToEntryBlock(sp);
            var r2_1 = m.Reg("r2_1", reg2);
            var r3_2 = m.Reg("r3_2", reg3);

            m.MStore(sp, m.Word32(0x0001234));
            m.MStore(m.IAdd(sp, 4), m.Word32(0x5678ABCD));
            var sigCallee = FunctionType.Action(
                new Identifier("arg04", PrimitiveType.Word32,
                               new StackArgumentStorage(4, PrimitiveType.Word32)),
                new Identifier("arg08", PrimitiveType.Word32,
                               new StackArgumentStorage(8, PrimitiveType.Word32)));

            sigCallee.ReturnAddressOnStack = 4;
            var callee = new ProcedureConstant(
                PrimitiveType.Ptr32,
                new ExternalProcedure("callee", sigCallee));
            var stmCall = m.Call(callee, 0,
                                 new Identifier[] { sp },
                                 new Identifier[] { });

            m.Return();

            var cab = new CallApplicationBuilder(
                m.Ssa,
                stmCall,
                (CallInstruction)stmCall.Instruction,
                callee,
                true);
            var instr = cab.CreateInstruction(sigCallee, null);

            Assert.AreEqual("callee(Mem4[sp:word32], Mem4[sp + 4<i32>:word32])", instr.ToString());
            m.Ssa.Validate(s => Assert.Fail(s));
        }
        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);
        }
Exemplo n.º 9
0
        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);
        }
Exemplo n.º 10
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);
        }