예제 #1
0
            /// <summary>
            /// Inserts the assignment <paramref name="ass"/> before the statement
            /// <paramref name="stm"/> if it is in the same block. Otherwise append
            /// it to the end of the statements in the block.
            /// </summary>
            public SsaIdentifier InsertBeforeStatement(Block block, Statement stm, Assignment ass)
            {
                Statement stmNew;

                if (stm.Block == block)
                {
                    int i = stm.Block.Statements.IndexOf(stm);
                    stmNew = new Statement(stm.LinearAddress, ass, stm.Block);
                    stm.Block.Statements.Insert(i, stmNew);
                }
                else
                {
                    ulong uAddr = block.Address.ToLinear();
                    int   i     = -1;
                    if (block.Statements.Count > 0)
                    {
                        i = block.Statements.Count - 1;
                        if (block.Statements[i].Instruction.IsControlFlow)
                        {
                            --i;
                        }
                        if (i >= 0)
                        {
                            uAddr = block.Statements[i].LinearAddress;
                        }
                    }
                    stmNew = block.Statements.Insert(i + 1, uAddr, ass);
                }

                var sidTo = ssaIds.Add(ass.Dst, stmNew, ass.Src, false);

                ass.Dst = sidTo.Identifier;
                return(sidTo);
            }
예제 #2
0
        private Instruction TransformRolC(Application rolc, Assignment a)
        {
            var sidOrigHi = ssaIds[a.Dst];
            var sidCarry  = ssaIds[(Identifier)rolc.Arguments[2]];

            if (!(sidCarry.DefExpression is ConditionOf cond))
            {
                return(a);
            }
            if (!(cond.Expression is Identifier condId))
            {
                return(a);
            }
            var sidOrigLo = ssaIds[condId];

            if (!(sidOrigLo.DefExpression is BinaryExpression shift) || shift.Operator != Operator.Shl)
            {
                return(a);
            }

            var block     = sidOrigHi.DefStatement !.Block;
            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.BitSize + expRorSrc.DataType.BitSize);
            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.BitSize),
                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.BitSize),
                sidTmp.Identifier,
                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 = null;
            sidGrf.DefStatement  = null;

            return(sidOrigHi.DefStatement.Instruction);
        }