예제 #1
0
        // 1. a_2 = a_1 >> 1
        // 2. C_2 = cond(a_2)
        // 3. b_2 = b_1 rorc 1, C
        // 4. flags_3 = cond(b_2)

        // 1.  tmp_1 = a_1
        // 3.  tmp_2 = b_2
        // *.  tmp_3 = (tmp1:tmp2) >> 1
        // 1'. a_2 = slice(tmp3,16)
        // 2'. b_2 = (cast) tmp3
        // 4.  flags_3 = cond(b_2)
        private Instruction TransformRorC(Application rorc, Assignment a)
        {
            var sidOrigLo = ssaIds[a.Dst];
            var sidCarry  = ssaIds[(Identifier)rorc.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 sidOrigHi = ssaIds[condId];
            var shift     = sidOrigHi.DefExpression as BinaryExpression;

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

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

            var stmGrf = sidGrf.DefStatement;

            block.Statements.Remove(stmGrf);

            var tmpHi    = ssa.Procedure.Frame.CreateTemporary(expShrSrc.DataType);
            var sidTmpHi = ssaIds.Add(tmpHi, sidOrigHi.DefStatement, expShrSrc, false);

            sidOrigHi.DefStatement.Instruction = new Assignment(sidTmpHi.Identifier, expShrSrc);

            var tmpLo    = ssa.Procedure.Frame.CreateTemporary(rorc.Arguments[0].DataType);
            var sidTmpLo = ssaIds.Add(tmpLo, sidOrigLo.DefStatement, rorc.Arguments[0], false);

            sidOrigLo.DefStatement.Instruction = new Assignment(sidTmpLo.Identifier, rorc.Arguments[0]);

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

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

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

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

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

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

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

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

            ssa.DebugDump(true);
            Debug.Print("sidGrf: *** {0}", sidGrf);
            return(sidOrigLo.DefStatement.Instruction);
        }