public void VpLoop() { var b = new ProgramBuilder(); b.Add("main", m => { var r = m.Reg32("r0", 0); var zf = m.Flags("Z"); m.Label("l0000"); m.MStore(r, m.Word32(0)); m.Assign(r, m.ISub(r, 4)); m.Assign(zf, m.Cond(r)); m.BranchIf(m.Test(ConditionCode.NE, zf), "l0000"); m.Label("l0001"); m.Assign(r, 42); m.Label("l0002"); m.MStore(r, m.Word32(12)); m.Assign(r, m.ISub(r, 4)); m.BranchIf(m.Eq0(r), "l0002"); m.Return(); }); RunFileTest(b.BuildProgram(), "Analysis/VpLoop.txt"); }
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 DeadCallDefinition() { var sExp = #region Expected @"// ProcedureBuilder // Return size: 0 define ProcedureBuilder ProcedureBuilder_entry: def r1 // succ: l1 l1: call foo (retsize: 4;) uses: r1:r1 defs: r1:r1_2 Mem4[0x00123400<p32>:word32] = r1_2 return // succ: ProcedureBuilder_exit ProcedureBuilder_exit: "; #endregion RunTest(sExp, m => { var _r1 = new RegisterStorage("r1", 1, 0, PrimitiveType.Word32); var _r2 = new RegisterStorage("r2", 2, 0, PrimitiveType.Word32); var foo = Given_Procedure_With_Flow(m, "foo", new Storage[] { _r1 }, new Storage[] { _r1, _r2 }); var r1 = m.Frame.EnsureRegister(_r1); var r2 = m.Frame.EnsureRegister(_r2); var call = m.Call(foo, 4); m.MStore(m.Ptr32(0x123400), r1); m.Return(); }); }
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); }