Ejemplo n.º 1
0
        private void FuseStorePair(Tuple <UnalignedAccess, UnalignedAccess> pair)
        {
            Statement stmL, stmR;

            if (pair.Item1.isLeft)
            {
                stmL = pair.Item1.stm !;
                stmR = pair.Item2.stm !;
            }
            else
            {
                stmL = pair.Item2.stm !;
                stmR = pair.Item1.stm !;
            }

            ssa.RemoveUses(stmL);
            ssa.RemoveUses(stmR);

            if (pair.Item1.mem is Identifier id)
            {
                stmR.Instruction = new Assignment(id, pair.Item1.value !);
            }
            else
            {
                var memId  = ((MemoryAccess)((Store)pair.Item2.stm !.Instruction).Dst).MemoryId;
                var sidMem = ssa.Identifiers[memId];
                sidMem.DefStatement = null;
                stmR.Instruction    = new Store(
                    pair.Item1.mem !,
                    pair.Item1.value !);
            }
            stmL.Block.Statements.Remove(stmL);
            ssa.AddUses(stmR);
        }
Ejemplo n.º 2
0
 public void AdjustSsa(Statement stm, CallInstruction call)
 {
     ssa.ReplaceDefinitions(stm, null);
     ssa.RemoveUses(stm);
     ssa.AddDefinitions(stm);
     ssa.AddUses(stm);
     DefineUninitializedIdentifiers(stm, call);
 }
Ejemplo n.º 3
0
        private void RemoveImplicitRegistersFromHellNode(
            SsaState ssa,
            Statement stm)
        {
            if (!(stm.Instruction is CallInstruction ci))
            {
                return;
            }
            if (ci.Callee is ProcedureConstant pc)
            {
                if (!(pc.Procedure is ExternalProcedure))
                {
                    return;
                }
            }
            var trashedRegisters = program.Platform.CreateTrashedRegisters();
            var implicitRegs     = program.Platform.CreateImplicitArgumentRegisters();

            foreach (var use in ci.Uses.ToList())
            {
                if (IsPreservedRegister(trashedRegisters, use.Storage) ||
                    IsStackStorageOfPreservedRegister(
                        ssa,
                        trashedRegisters,
                        use) ||
                    implicitRegs.Contains(use.Storage))
                {
                    ci.Uses.Remove(use);
                    ssa.RemoveUses(stm, use.Expression);
                }
            }
        }
Ejemplo n.º 4
0
 public void Transform(Statement stm, CallInstruction call)
 {
     this.stm  = stm;
     this.call = call;
     ssa.ReplaceDefinitions(stm, null);
     ssa.RemoveUses(stm);
     Transform(stm.Instruction);
 }
Ejemplo n.º 5
0
            private Expression RewriteSeqOfPhi(SsaIdentifier[] sids, PhiAssignment[] phis, Identifier idWide)
            {
                // We have
                //     a_3 = PHI(a_1, a_2)
                //     b_3 = PHI(b_1, a_2)
                //     ...SEQ(a_3,b_3)
                // and we want
                //    ab_3 = PHI(ab_1, ab_2)
                //    a_3 = SLICE(ab_3, ...)
                //    b_3 = SLICE(ab_3, ...)
                //    ...ab_3

                foreach (var s in sids)
                {
                    s.Uses.Remove(this.Statement);
                }

                // Insert a PHI statement placeholder at the beginning
                // of the basic block.
                var stmPhi = sids[0].DefStatement.Block.Statements.Insert(
                    0,
                    sids[0].DefStatement.LinearAddress,
                    null);

                // Generate fused identifiers for all phi slots.
                var widePhiArgs = new List <PhiArgument>();

                for (var iBlock = 0; iBlock < phis[0].Src.Arguments.Length; ++iBlock)
                {
                    // Make a fused identifier in each predecessor block and "push"
                    // the SEQ statements into the predecessors.
                    var pred    = phis[0].Src.Arguments[iBlock].Block;
                    var sidPred = MakeFusedIdentifierInPredecessorBlock(sids, phis, idWide, stmPhi, iBlock, pred);
                    widePhiArgs.Add(new PhiArgument(pred, sidPred.Identifier));
                }

                var sidDst = ssa.Identifiers.Add(idWide, stmPhi, null, false);

                stmPhi.Instruction = new PhiAssignment(
                    sidDst.Identifier,
                    widePhiArgs.ToArray());
                sidDst.Uses.Add(this.Statement);

                // Replace all the "unfused" phis with slices of the "fused" phi.
                foreach (var sid in sids)
                {
                    ssa.RemoveUses(sid.DefStatement);
                    sid.DefStatement.Instruction = new AliasAssignment(
                        sid.Identifier,
                        new Slice(sid.Identifier.DataType, sidDst.Identifier, idWide.Storage.OffsetOf(sid.Identifier.Storage)));
                    sidDst.Uses.Add(sid.DefStatement);
                }
                return(sidDst.Identifier);
            }
Ejemplo n.º 6
0
        public void RewriteCall(Statement stm, CallInstruction call, FunctionType ft)
        {
            ssam.AdjustRegisterAfterCall(
                stm,
                call,
                ssa.Procedure.Architecture.StackRegister,
                ft.StackDelta - call.CallSite.SizeOfReturnAddressOnStack);
            ssam.AdjustRegisterAfterCall(
                stm,
                call,
                program.Architecture.FpuStackRegister,
                -ft.FpuStackDelta);
            var ab = program.Architecture.CreateFrameApplicationBuilder(
                proc.Frame, call.CallSite, call.Callee);

            ssa.RemoveUses(stm);
            stm.Instruction = ab.CreateInstruction(ft, null);
            ssaIdTransformer.Transform(stm, call);
            ssam.DefineUninitializedIdentifiers(stm, call);
        }
Ejemplo n.º 7
0
        // On MIPS-LE the sequence
        //   lwl rx,K+3(ry)
        //   lwr rx,K(ry)
        // is an unaligned read. On MIPS-BE it instead is:
        //   lwl rx,K(ry)
        //   lwr rx,K+3(ry)
        public void FuseUnalignedLoads(Assignment assR)
        {
            var appR = MatchIntrinsicApplication(assR.Src, unalignedLoadsLe);

            if (appR == null)
            {
                return;
            }

            var regR = assR.Dst;
            var stmR = ssa.Identifiers[regR].DefStatement;

            var memR = appR.Item2.Arguments[1];
            var offR = GetOffsetOf(memR);

            var        appL = appR.Item2.Arguments[0] as Application;
            Statement  stmL = null;
            Assignment assL = null;

            if (appL == null)
            {
                var regL = (Identifier)appR.Item2.Arguments[0];
                stmL = ssa.Identifiers[regL].DefStatement;
                if (stmL == null)
                {
                    return;
                }
                assL = stmL.Instruction as Assignment;
                if (assL == null)
                {
                    return;
                }

                appL = assL.Src as Application;
            }
            var pairL = MatchIntrinsicApplication(appL, unalignedLoadsBe);

            if (pairL == null)
            {
                return;
            }

            var applL = pairL.Item2;
            var memL  = appL.Arguments[1];
            var offL  = GetOffsetOf(memL);

            Expression mem;

            if (offR + 3 == offL)
            {
                // Little endian use
                mem = memR;
            }
            else if (offL + 3 == offR)
            {
                // Big endian use
                mem = memL;
            }
            else
            {
                return;
            }

            ssa.RemoveUses(stmL);
            ssa.RemoveUses(stmR);
            if (assL != null)
            {
                assL.Src = appL.Arguments[0];
                ssa.AddUses(stmL);
            }
            assR.Src = mem;
            if (stmL != null)
            {
                stmL.Block.Statements.Remove(stmL);
            }
            ssa.AddUses(stmR);
        }
Ejemplo n.º 8
0
        private Instruction TransformRolC(Application rolc, Assignment a)
        {
            var sidOrigHi = ssaIds[a.Dst];
            var sidCarry  = ssaIds[(Identifier)rolc.Arguments[2]];
            var cond      = sidCarry.DefExpression as ConditionOf;

            if (cond == null)
            {
                return(a);
            }
            var condId = cond.Expression as Identifier;

            if (condId == null)
            {
                return(a);
            }
            var sidOrigLo = ssaIds[condId];
            var shift     = sidOrigLo.DefExpression as BinaryExpression;

            if (shift == null || shift.Operator != Operator.Shl)
            {
                return(a);
            }

            var block     = sidOrigHi.DefStatement.Block;
            var sidShift  = sidOrigLo.DefStatement;
            var expShrSrc = shift.Left;
            var expRorSrc = rolc.Arguments[0];

            var stmGrf = sidGrf.DefStatement;

            block.Statements.Remove(stmGrf);

            // xx = lo
            var tmpLo    = ssa.Procedure.Frame.CreateTemporary(expShrSrc.DataType);
            var sidTmpLo = ssaIds.Add(tmpLo, sidOrigLo.DefStatement, expShrSrc, false);

            sidOrigLo.DefStatement.Instruction = new Assignment(sidTmpLo.Identifier, expShrSrc);

            var tmpHi    = ssa.Procedure.Frame.CreateTemporary(rolc.Arguments[0].DataType);
            var sidTmpHi = ssaIds.Add(tmpHi, sidOrigHi.DefStatement, rolc.Arguments[0], false);

            sidOrigHi.DefStatement.Instruction = new Assignment(sidTmpHi.Identifier, rolc.Arguments[0]);

            var iRolc         = block.Statements.IndexOf(sidOrigHi.DefStatement);
            var dt            = PrimitiveType.Create(Domain.Integer, expShrSrc.DataType.Size + expRorSrc.DataType.Size);
            var tmp           = ssa.Procedure.Frame.CreateTemporary(dt);
            var expMkLongword = m.Shl(m.Seq(sidTmpHi.Identifier, sidTmpLo.Identifier), 1);
            var sidTmp        = ssaIds.Add(tmp, sidGrf.DefStatement, expMkLongword, false);
            var stmTmp        = block.Statements.Insert(iRolc + 1, sidOrigHi.DefStatement.LinearAddress,
                                                        new Assignment(sidTmp.Identifier, expMkLongword));

            sidTmp.DefStatement = stmTmp;
            sidTmpLo.Uses.Add(stmTmp);
            sidTmpHi.Uses.Add(stmTmp);

            ssa.RemoveUses(sidCarry.DefStatement);
            block.Statements.Remove(sidCarry.DefStatement);
            ssaIds.Remove(sidCarry);

            var expNewLo = m.Cast(
                PrimitiveType.CreateWord(tmpHi.DataType.Size),
                sidTmp.Identifier);
            var stmNewLo = block.Statements.Insert(
                iRolc + 2,
                sidOrigLo.DefStatement.LinearAddress,
                new Assignment(sidOrigLo.Identifier, expNewLo));

            sidTmp.Uses.Add(stmNewLo);
            sidOrigLo.DefStatement  = stmNewLo;
            sidOrigLo.DefExpression = expNewLo;

            var expNewHi = m.Slice(
                PrimitiveType.CreateWord(tmpLo.DataType.Size),
                sidTmp.Identifier,
                (uint)tmpHi.DataType.BitSize);
            var stmNewHi = block.Statements.Insert(
                iRolc + 3,
                sidOrigHi.DefStatement.LinearAddress,
                new Assignment(sidOrigHi.Identifier, expNewHi));

            sidTmp.Uses.Add(stmNewHi);
            sidOrigHi.DefStatement = stmNewHi;
            sidOrigHi.DefStatement = stmNewHi;

            sidGrf.DefExpression            = m.Cond(sidTmp.Identifier);
            sidGrf.DefStatement.Instruction = new Assignment(
                sidGrf.Identifier, sidGrf.DefExpression);
            sidTmp.Uses.Add(sidGrf.DefStatement);

            return(sidOrigHi.DefStatement.Instruction);
        }