コード例 #1
0
 private void RewriteCvttsd2si()
 {
     instrCur.op1.Width = PrimitiveType.Create(Domain.SignedInt, instrCur.op1.Width.Size);
     emitter.Assign(SrcOp(instrCur.op1), emitter.Cast(instrCur.op1.Width, SrcOp(instrCur.op2)));
 }
コード例 #2
0
        public bool VisitBinaryExpression(BinaryExpression binExp, TypeVariable tv)
        {
            var eLeft  = binExp.Left;
            var eRight = binExp.Right;

            if (binExp.Operator == Operator.IAdd)
            {
                var dt = PushAddendDataType(binExp.TypeVariable !.DataType, eRight.TypeVariable !.DataType);
                if (dt != null)
                {
                    MeetDataType(eLeft, dt);
                }
                dt = PushAddendDataType(binExp.TypeVariable !.DataType, eLeft.TypeVariable !.DataType);
                if (dt != null)
                {
                    MeetDataType(eRight, dt);
                }
            }
            else if (binExp.Operator == Operator.ISub || binExp.Operator == Operator.USub)
            {
                var dt = PushMinuendDataType(binExp.TypeVariable !.DataType, eRight.TypeVariable !.DataType);
                MeetDataType(eLeft, dt);
                dt = PushSubtrahendDataType(binExp.TypeVariable !.DataType, eLeft.TypeVariable !.DataType);
                MeetDataType(eRight, dt);
            }
            else if (binExp.Operator == Operator.And || binExp.Operator == Operator.Or)
            {
                //$REVIEW: need a push-logical-Data type to push [[a & 3]] = char into its left and right halves.
                var dt = PrimitiveType.CreateWord(tv.DataType.BitSize).MaskDomain(Domain.Boolean | Domain.Integer | Domain.Character);
                MeetDataType(eLeft, dt);
                MeetDataType(eRight, dt);
            }
            else if (
                binExp.Operator == Operator.IMul ||
                binExp.Operator == Operator.IMod)
            {
                var dt = PrimitiveType.CreateWord(DataTypeOf(eLeft).BitSize).MaskDomain(Domain.Boolean | Domain.Integer);
                MeetDataType(eLeft, dt);
                dt = PrimitiveType.CreateWord(DataTypeOf(eRight).BitSize).MaskDomain(Domain.Boolean | Domain.Integer);
                MeetDataType(eRight, dt);
            }
            else if (
                binExp.Operator == Operator.SMul ||
                binExp.Operator == Operator.SDiv)
            {
                var dt = PrimitiveType.CreateWord(DataTypeOf(eLeft).BitSize).MaskDomain(Domain.Boolean | Domain.SignedInt);
                MeetDataType(eLeft, dt);
                dt = PrimitiveType.CreateWord(DataTypeOf(eRight).BitSize).MaskDomain(Domain.Boolean | Domain.SignedInt);
                MeetDataType(eRight, dt);
            }
            else if (
                binExp.Operator == Operator.UMul ||
                binExp.Operator == Operator.UDiv)
            {
                var dt = PrimitiveType.CreateWord(DataTypeOf(eLeft).BitSize).MaskDomain(Domain.Boolean | Domain.UnsignedInt);
                MeetDataType(eLeft, dt);
                dt = PrimitiveType.CreateWord(DataTypeOf(eRight).BitSize).MaskDomain(Domain.Boolean | Domain.UnsignedInt);
                MeetDataType(eRight, dt);
            }
            else if (binExp.Operator == Operator.FAdd ||
                     binExp.Operator == Operator.FSub ||
                     binExp.Operator == Operator.FMul ||
                     binExp.Operator == Operator.FDiv)
            {
                var dt = PrimitiveType.Create(Domain.Real, eLeft.DataType.BitSize);
                MeetDataType(eLeft, dt);
                dt = PrimitiveType.Create(Domain.Real, eRight.DataType.BitSize);
                MeetDataType(eRight, dt);
            }
            else if (binExp.Operator is SignedIntOperator)
            {
                var dt = PrimitiveType.CreateWord(eRight.TypeVariable !.DataType.BitSize).MaskDomain(Domain.SignedInt | Domain.Character);
                MeetDataType(eLeft, dt);
                dt = PrimitiveType.CreateWord(eRight.TypeVariable !.DataType.BitSize).MaskDomain(Domain.SignedInt | Domain.Character);
                MeetDataType(eRight, dt);
            }
            else if (binExp.Operator is UnsignedIntOperator)
            {
                var dt = PrimitiveType.CreateWord(eRight.TypeVariable !.DataType.BitSize).MaskDomain(Domain.Pointer | Domain.UnsignedInt | Domain.Character);
                MeetDataType(eLeft, dt);
                dt = PrimitiveType.CreateWord(eRight.TypeVariable !.DataType.BitSize).MaskDomain(Domain.Pointer | Domain.UnsignedInt | Domain.Character);
                MeetDataType(eRight, dt);
            }
            else if (binExp.Operator == Operator.Eq || binExp.Operator == Operator.Ne ||
                     binExp.Operator == Operator.Xor || binExp.Operator == Operator.Cand ||
                     binExp.Operator == Operator.Cor)
            {
                // Not much can be deduced here, except that the operands should have the same size. Earlier passes
                // already did that work, so just continue with the operands.
            }
            else if (binExp.Operator is RealConditionalOperator)
            {
                // We know leaves must be floats
                var dt = PrimitiveType.Create(Domain.Real, eLeft.DataType.BitSize);
                MeetDataType(eLeft, dt);
                dt = PrimitiveType.Create(Domain.Real, eLeft.DataType.BitSize);
                MeetDataType(eRight, dt);
            }
            else if (binExp.Operator == Operator.Shl)
            {
                var dt = PrimitiveType.CreateWord(tv.DataType.BitSize).MaskDomain(Domain.Boolean | Domain.Integer | Domain.Character);
                MeetDataType(eLeft, dt);
                dt = PrimitiveType.Create(Domain.Integer, DataTypeOf(eRight).BitSize);
            }
            else if (binExp.Operator == Operator.Shr)
            {
                var dt = PrimitiveType.CreateWord(tv.DataType.BitSize).MaskDomain(Domain.Boolean | Domain.UnsignedInt | Domain.Character);
                MeetDataType(eLeft, dt);
                dt = PrimitiveType.Create(Domain.Integer, DataTypeOf(eRight).BitSize);
            }
            else if (binExp.Operator == Operator.Sar)
            {
                var dt = PrimitiveType.CreateWord(tv.DataType.BitSize).MaskDomain(Domain.Boolean | Domain.SignedInt | Domain.Character);
                MeetDataType(eLeft, dt);
                dt = PrimitiveType.Create(Domain.Integer, DataTypeOf(eRight).BitSize);
            }
            else
            {
                throw new TypeInferenceException($"Unhandled binary operator {binExp.Operator} in expression {binExp}.");
            }
            eLeft.Accept(this, eLeft.TypeVariable !);
            eRight.Accept(this, eRight.TypeVariable !);
            return(false);
        }
コード例 #3
0
 private DataType UInteger(int bitSize)
 {
     return(PrimitiveType.Create(Domain.UnsignedInt, bitSize));
 }
コード例 #4
0
        /*
         * We need to handle the case when seeing
         * 1) ptr(mem(a)) = ptr(mem(a)) + C and
         * 2) ptr(mem(a)) = ptr(mem(b)) + C expressions.
         * In the first instance, we may be seeing the increment of an array pointer, where the stride is C. However
         * if mem(a) has a size > C, then this is actually an expression of the type:
         * a = &a->fC, where C is the offset of the field fC. This is equivalent to case 2.
         *
         * If we see t = x and later t = x + 4, then
         * [[t]] = [[x]] and [[t]] = [[x + 4]]. If [[t]] is a ptr(mem(Q)),
         * then we have a problem!
         *
         * This analysis is probably best done after TraitCollection, since by then we have discovered max sizes of mems.
         */
        public DataType VisitBinaryExpression(BinaryExpression binExp)
        {
            binExp.Left.Accept(this);
            var ivLeft = ivCur;

            binExp.Right.Accept(this);
            var ivRight = ivCur;

            ivCur = null;
            if (ivLeft != null)
            {
                if (binExp.Operator == Operator.SMul || binExp.Operator == Operator.UMul || binExp.Operator == Operator.IMul || binExp.Operator == Operator.Shl)
                {
                    ivCur = MergeInductionVariableConstant(ivLeft, binExp.Operator, binExp.Right as Constant);
                }
            }

            TypeVariable tvExp = binExp.TypeVariable;

            //$BUGBUG: This needs to be redone because the domain of the operation is now in the OPERATOR, not the operands.
            if (binExp.Operator == Operator.IAdd ||
                binExp.Operator == Operator.ISub ||
                binExp.Operator == Operator.And ||
                binExp.Operator == Operator.Or ||
                binExp.Operator == Operator.Xor)
            {
                return(handler.DataTypeTrait(binExp, binExp.DataType));
            }
            else if (binExp.Operator == Operator.SMul ||
                     binExp.Operator == Operator.SDiv)
            {
                handler.DataTypeTrait(binExp, MakeNonPointer(binExp.DataType));
                var dt = handler.DataTypeTrait(binExp, binExp.DataType);
                handler.DataTypeTrait(binExp.Left, PrimitiveType.Create(DomainOf(binExp.DataType), binExp.Left.DataType.Size));
                handler.DataTypeTrait(binExp.Right, PrimitiveType.Create(DomainOf(binExp.DataType), binExp.Right.DataType.Size));
                return(dt);
            }
            else if (binExp.Operator == Operator.UMul ||
                     binExp.Operator == Operator.UDiv ||
                     binExp.Operator == Operator.Shr)
            {
                handler.DataTypeTrait(binExp, MakeNonPointer(binExp.DataType));
                var dt = handler.DataTypeTrait(binExp, MakeUnsigned(binExp.DataType));
                handler.DataTypeTrait(binExp.Left, MakeUnsigned(binExp.Left.DataType));
                handler.DataTypeTrait(binExp.Right, MakeUnsigned(binExp.Right.DataType));
                return(dt);
            }
            else if (binExp.Operator == Operator.IMul)
            {
                handler.DataTypeTrait(binExp.Left, MakeIntegral(binExp.Left.DataType));
                handler.DataTypeTrait(binExp.Right, MakeIntegral(binExp.Right.DataType));
                return(handler.DataTypeTrait(binExp, MakeIntegral(binExp.DataType)));
            }
            else if (binExp.Operator == Operator.Sar)
            {
                var dt = handler.DataTypeTrait(binExp, MakeSigned(binExp.DataType));
                handler.DataTypeTrait(binExp.Left, MakeSigned(binExp.Left.DataType));
                handler.DataTypeTrait(binExp.Right, MakeUnsigned(binExp.Right.DataType));
                return(dt);
            }
            else if (binExp.Operator == Operator.Shl)
            {
                return(handler.DataTypeTrait(binExp, MakeIntegral(binExp.DataType)));
            }
            else if (binExp.Operator == Operator.IMod)
            {
                var dt = handler.DataTypeTrait(binExp, binExp.DataType);
                handler.DataTypeTrait(binExp.Left, binExp.Left.DataType);
                handler.DataTypeTrait(binExp.Right, binExp.Right.DataType);
                return(dt);
            }
            else if (binExp.Operator == Operator.Eq ||
                     binExp.Operator == Operator.Ne)
            {
                handler.EqualTrait(binExp.Left, binExp.Right);
                return(handler.DataTypeTrait(binExp, PrimitiveType.Bool));
            }
            else if (binExp.Operator == Operator.Ge ||
                     binExp.Operator == Operator.Gt ||
                     binExp.Operator == Operator.Le ||
                     binExp.Operator == Operator.Lt)
            {
                handler.EqualTrait(binExp.Left, binExp.Right);
                var dt = handler.DataTypeTrait(binExp, PrimitiveType.Bool);
                handler.DataTypeTrait(binExp.Left, MakeSigned(binExp.Left.DataType));
                handler.DataTypeTrait(binExp.Right, MakeSigned(binExp.Right.DataType));
                return(dt);
            }
            else if (binExp.Operator is RealConditionalOperator)
            {
                handler.EqualTrait(binExp.Left, binExp.Right);
                var dt = handler.DataTypeTrait(binExp, PrimitiveType.Bool);
                handler.DataTypeTrait(binExp.Left, PrimitiveType.Create(Domain.Real, binExp.Left.DataType.Size));
                handler.DataTypeTrait(binExp.Right, PrimitiveType.Create(Domain.Real, binExp.Right.DataType.Size));
                return(dt);
            }
            else if (binExp.Operator == Operator.Uge ||
                     binExp.Operator == Operator.Ugt ||
                     binExp.Operator == Operator.Ule ||
                     binExp.Operator == Operator.Ult)
            {
                handler.EqualTrait(binExp.Left, binExp.Right);
                var dt = handler.DataTypeTrait(binExp, PrimitiveType.Bool);
                handler.DataTypeTrait(binExp.Left, MakeNotSigned(binExp.Left.DataType));
                handler.DataTypeTrait(binExp.Right, MakeNotSigned(binExp.Right.DataType));
                return(dt);
            }
            else if (binExp.Operator == Operator.FAdd ||
                     binExp.Operator == Operator.FSub ||
                     binExp.Operator == Operator.FMul ||
                     binExp.Operator == Operator.FDiv)
            {
                var dt = PrimitiveType.Create(Domain.Real, binExp.DataType.Size);
                handler.DataTypeTrait(binExp, dt);
                handler.DataTypeTrait(binExp.Left, dt);
                handler.DataTypeTrait(binExp.Right, dt);
                return(dt);
            }
            throw new NotImplementedException("NYI: " + binExp.Operator + " in " + binExp);
        }
コード例 #5
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];

            if (!(sidOrigHi.DefExpression is BinaryExpression shift &&
                  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,
                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);

            return(sidOrigLo.DefStatement.Instruction);
        }
コード例 #6
0
 private void RewriteMovsx()
 {
     m.Assign(
         SrcOp(instrCur.op1),
         m.Cast(PrimitiveType.Create(Domain.SignedInt, instrCur.op1.Width.Size), SrcOp(instrCur.op2)));
 }
コード例 #7
0
        protected virtual DataType MakeDataType(PrintfSize size, char cDomain)
        {
            Domain domain   = Domain.None;
            int    byteSize = this.wordSize;

            switch (cDomain)
            {
            case 'c':
            case 's':
                return(program.TypeFactory.CreatePointer(
                           size == PrintfSize.Long ? PrimitiveType.WChar : PrimitiveType.Char,
                           pointerSize));

            case 'o':
            case 'u':
            case 'x':
                switch (size)
                {
                case PrintfSize.HalfHalf: byteSize = 1; break;

                case PrintfSize.Half: byteSize = 2; break;

                case PrintfSize.Long: byteSize = this.longSize; break;

                case PrintfSize.LongLong: byteSize = 8; break;

                case PrintfSize.I32: byteSize = 4; break;

                case PrintfSize.I64: byteSize = 8; break;
                }
                domain = Domain.UnsignedInt;
                break;

            case 'd':
            case 'i':
                switch (size)
                {
                case PrintfSize.HalfHalf: byteSize = 1; break;

                case PrintfSize.Half: byteSize = 2; break;

                case PrintfSize.Long: byteSize = this.longSize; break;

                case PrintfSize.LongLong: byteSize = 8; break;

                case PrintfSize.I32: byteSize = 4; break;

                case PrintfSize.I64: byteSize = 8; break;
                }
                domain = Domain.SignedInt;
                break;

            case 'a':
            case 'e':
            case 'f':
            case 'g':
                byteSize = this.doubleSize;
                domain   = Domain.Real;
                break;

            case 'p':
                byteSize = this.pointerSize;
                domain   = Domain.Pointer;
                break;

            default:
                var el = this.services.RequireService <DecompilerEventListener>();
                el.Warn(
                    el.CreateAddressNavigator(program, addr),
                    "The format specifier '%{0}' passed to *scanf is not known.", cDomain);
                return(new UnknownType());
            }
            return(program.TypeFactory.CreatePointer(
                       PrimitiveType.Create(domain, byteSize),
                       pointerSize));
        }
コード例 #8
0
 private static PrimitiveType MakeInteger(Domain domain, DataType dt)
 {
     return(PrimitiveType.Create(domain, dt.BitSize));
 }
コード例 #9
0
ファイル: Constant.cs プロジェクト: Klanly/reko
        /// <summary>
        /// Creates a constant signed integer whose bit size is the same
        /// as <paramref name="dt"/>'s bit size.
        /// </summary>
        /// <param name="dt">Data type whose bit size is used to build
        /// the constant.</param>
        /// <param name="l">Constant value.</param>
        public static Constant Int(DataType dt, long l)
        {
            var dtInt = PrimitiveType.Create(Domain.SignedInt, dt.BitSize);

            return(Create(dtInt, l));
        }
コード例 #10
0
        private DataType MakeDataType(PrintfSize size, char cDomain)
        {
            Domain domain   = Domain.None;
            int    byteSize = this.wordSize;

            switch (cDomain)
            {
            case 'c':
                if (wideChars)
                {
                    return(PrimitiveType.WChar);
                }
                else
                {
                    return(PrimitiveType.Char);
                }

            case 'C':
                if (wideChars)
                {
                    return(PrimitiveType.Char);
                }
                else
                {
                    return(PrimitiveType.WChar);
                }

            case 'o':
            case 'u':
            case 'x':
            case 'X':
                switch (size)
                {
                case PrintfSize.HalfHalf: byteSize = 1; break;

                case PrintfSize.Half: byteSize = 2; break;

                case PrintfSize.Long: byteSize = this.longSize; break;

                case PrintfSize.LongLong: byteSize = 8; break;

                case PrintfSize.I32: byteSize = 4; break;

                case PrintfSize.I64: byteSize = 8; break;
                }
                domain = Domain.UnsignedInt;
                break;

            case 'd':
            case 'i':
                switch (size)
                {
                case PrintfSize.HalfHalf: byteSize = 1; break;

                case PrintfSize.Half: byteSize = 2; break;

                case PrintfSize.Long: byteSize = this.longSize; break;

                case PrintfSize.LongLong: byteSize = 8; break;

                case PrintfSize.I32: byteSize = 4; break;

                case PrintfSize.I64: byteSize = 8; break;
                }
                domain = Domain.SignedInt;
                break;

            case 'a':
            case 'A':
            case 'e':
            case 'E':
            case 'f':
            case 'F':
            case 'g':
            case 'G':
                domain = Domain.Real;
                break;

            case 'p':
                byteSize = this.pointerSize;
                domain   = Domain.Pointer;
                break;
            }
            return(PrimitiveType.Create(domain, byteSize));
        }
コード例 #11
0
 private static PrimitiveType MakeReal(DataType dt)
 {
     return(PrimitiveType.Create(Domain.Real, dt.BitSize));
 }
コード例 #12
0
 public static AddressOperand Create(Address addr)
 {
     return(new AddressOperand(
                addr,
                PrimitiveType.Create(Domain.Pointer, addr.DataType.BitSize)));
 }
コード例 #13
0
ファイル: MilStd1750Architecture.cs プロジェクト: qcyb/reko
 static MilStd1750Architecture()
 {
     Real48 = PrimitiveType.Create(Domain.Real, 48);
 }
コード例 #14
0
ファイル: SuperHRewriter.cs プロジェクト: xxtxiaofeng/reko
 private void RewriteFloat()
 {
     var src = SrcOp(instr.Operands[0]);
     var dst = DstOp(instr.Operands[1], src, (a, b) => m.Cast(PrimitiveType.Create(Domain.Real, a.DataType.BitSize), b));
 }
コード例 #15
0
 public void Hybrid32()
 {
     Assert.AreEqual("uip32", PrimitiveType.Create(Domain.SignedInt | Domain.UnsignedInt | Domain.Pointer, 32).ToString());
 }
コード例 #16
0
        public void CreateLongInstruction(AddSubCandidate loCandidate, AddSubCandidate hiCandidate)
        {
            var totalSize = PrimitiveType.Create(
                Domain.SignedInt | Domain.UnsignedInt,
                loCandidate.Dst !.DataType.BitSize + hiCandidate.Dst !.DataType.BitSize);
            var left  = CreateCandidate(loCandidate.Left, hiCandidate.Left, totalSize);
            var right = CreateCandidate(loCandidate.Right, hiCandidate.Right, totalSize);

            this.dst = CreateCandidate(loCandidate.Dst, hiCandidate.Dst, totalSize);
            var       stmts     = hiCandidate.Statement !.Block.Statements;
            var       linAddr   = hiCandidate.Statement.LinearAddress;
            var       iStm      = FindInsertPosition(loCandidate, hiCandidate, stmts);
            Statement?stmMkLeft = null;

            if (left is Identifier)
            {
                stmMkLeft = stmts.Insert(
                    iStm++,
                    linAddr,
                    CreateMkSeq(left, hiCandidate.Left, loCandidate.Left));
                left = ReplaceDstWithSsaIdentifier(left, null !, stmMkLeft);
            }

            Statement?stmMkRight = null;

            if (right is Identifier)
            {
                stmMkRight = stmts.Insert(
                    iStm++,
                    linAddr,
                    CreateMkSeq(right, hiCandidate.Right, loCandidate.Right));
                right = ReplaceDstWithSsaIdentifier(right, null !, stmMkRight);
            }

            var         expSum  = new BinaryExpression(loCandidate.Op, left.DataType, left, right);
            Instruction instr   = Assign(dst, expSum);
            var         stmLong = stmts.Insert(iStm++, linAddr, instr);

            this.dst = ReplaceDstWithSsaIdentifier(this.dst, expSum, stmLong);

            var sidDst   = GetSsaIdentifierOf(dst);
            var sidLeft  = GetSsaIdentifierOf(left);
            var sidRight = GetSsaIdentifierOf(right);

            if (stmMkLeft != null && sidLeft != null)
            {
                GetSsaIdentifierOf(loCandidate.Left)?.Uses.Add(stmMkLeft);
                GetSsaIdentifierOf(hiCandidate.Left)?.Uses.Add(stmMkLeft);
            }
            if (stmMkRight != null && sidRight != null)
            {
                GetSsaIdentifierOf(loCandidate.Right)?.Uses.Add(stmMkRight);
                GetSsaIdentifierOf(hiCandidate.Right)?.Uses.Add(stmMkRight);
            }
            if (sidDst != null)
            {
                if (sidLeft != null)
                {
                    sidLeft.Uses.Add(stmLong);
                }
                if (sidRight != null)
                {
                    sidRight.Uses.Add(stmLong);
                }
            }

            var sidDstLo = GetSsaIdentifierOf(loCandidate.Dst);

            if (sidDstLo != null)
            {
                var cast      = new Slice(loCandidate.Dst.DataType, dst, 0);
                var stmCastLo = stmts.Insert(iStm++, linAddr, new AliasAssignment(
                                                 sidDstLo.Identifier, cast));
                var stmDeadLo = sidDstLo.DefStatement;
                sidDstLo.DefExpression = cast;
                sidDstLo.DefStatement  = stmCastLo;

                var sidDstHi   = GetSsaIdentifierOf(hiCandidate.Dst);
                var slice      = new Slice(hiCandidate.Dst.DataType, dst, loCandidate.Dst.DataType.BitSize);
                var stmSliceHi = stmts.Insert(iStm++, linAddr, new AliasAssignment(
                                                  sidDstHi !.Identifier, slice));
                var stmDeadHi = sidDstHi.DefStatement;
                sidDstHi.DefExpression = slice;
                sidDstHi.DefStatement  = stmSliceHi;

                if (sidDstLo != null)
                {
                    sidDst !.Uses.Add(stmCastLo);
                }
                if (sidDstHi != null)
                {
                    sidDst !.Uses.Add(stmSliceHi);
                }
                ssa.DeleteStatement(stmDeadLo !);
                ssa.DeleteStatement(stmDeadHi !);
            }
        }
コード例 #17
0
        private void RewriteMultiply(BinaryOperator op, Domain resultDomain)
        {
            Expression product;

            switch (instrCur.Operands)
            {
            case 1:
                Identifier multiplicator;

                switch (instrCur.op1.Width.Size)
                {
                case 1:
                    multiplicator = orw.AluRegister(Registers.al);
                    product       = orw.AluRegister(Registers.ax);
                    break;

                case 2:
                    multiplicator = orw.AluRegister(Registers.ax);
                    product       = binder.EnsureSequence(
                        Registers.dx, multiplicator.Storage, PrimitiveType.Word32);
                    break;

                case 4:
                    multiplicator = orw.AluRegister(Registers.eax);
                    product       = binder.EnsureSequence(
                        Registers.edx, multiplicator.Storage, PrimitiveType.Word64);
                    break;

                case 8:
                    multiplicator = orw.AluRegister(Registers.rax);
                    product       = binder.EnsureSequence(
                        Registers.rdx, multiplicator.Storage, PrimitiveType.Word64);
                    break;

                default:
                    throw new ApplicationException(string.Format("Unexpected operand size: {0}", instrCur.op1.Width));
                }
                ;
                m.Assign(
                    product,
                    new BinaryExpression(
                        op,
                        PrimitiveType.Create(resultDomain, product.DataType.Size),
                        SrcOp(instrCur.op1),
                        multiplicator));
                EmitCcInstr(product, X86Instruction.DefCc(instrCur.code));
                return;

            case 2:
                EmitBinOp(op, instrCur.op1, instrCur.op1.Width.MaskDomain(resultDomain), SrcOp(instrCur.op1), SrcOp(instrCur.op2),
                          CopyFlags.EmitCc);
                return;

            case 3:
                EmitBinOp(op, instrCur.op1, instrCur.op1.Width.MaskDomain(resultDomain), SrcOp(instrCur.op2), SrcOp(instrCur.op3),
                          CopyFlags.EmitCc);
                return;

            default:
                throw new ArgumentException("Invalid number of operands");
            }
        }
コード例 #18
0
        public bool Match(Expression e)
        {
            elemSize     = null;
            Index        = null;
            ArrayPointer = null;

            BinaryExpression b = e as BinaryExpression;

            if (b == null)
            {
                return(false);
            }
            if (MatchMul(b))
            {
                ArrayPointer = Constant.Zero(b.DataType);
                return(true);
            }

            // (+ x y)
            if (b.Operator == Operator.IAdd)
            {
                BinaryExpression bInner = b.Left as BinaryExpression;
                if (bInner != null)
                {
                    if (MatchMul(bInner))
                    {
                        // (+ (* i c) ptr)
                        ArrayPointer = b.Right;
                        return(true);
                    }
                }
                bInner = b.Right as BinaryExpression;
                if (bInner != null)
                {
                    if (MatchMul(bInner))
                    {
                        // (+ ptr (* i c))
                        ArrayPointer = b.Left;
                        return(true);
                    }
                    if (bInner.Operator == Operator.IAdd)
                    {
                        // (+ x (+ a b))
                        var bbInner = bInner.Left as BinaryExpression;
                        if (bbInner != null && MatchMul(bbInner))
                        {
                            // (+ x (+ (* i c) y)) rearranges to become
                            // (+ (* i c) (+ x y))

                            this.ArrayPointer = new BinaryExpression(
                                Operator.IAdd,
                                PrimitiveType.Create(Domain.Pointer, b.Left.DataType.Size),
                                b.Left,
                                bInner.Right);
                            return(true);
                        }
                    }
                }
            }
            return(false);
        }
コード例 #19
0
 private DataType Integer(int size)
 {
     return(PrimitiveType.Create(Domain.SignedInt, size));
 }
コード例 #20
0
 public Expression SMul(Expression left, Expression right)
 {
     return(new BinaryExpression(Operator.SMul, PrimitiveType.Create(Domain.SignedInt, left.DataType.Size), left, right));
 }
コード例 #21
0
        public void TerArrayAssignment()
        {
            var sExp =
                #region Expected
                @"// Before ///////
// test
// Return size: 0
define test
test_entry:
	// succ:  l000000000040EC30
l000000000040EC30:
	word64 rbx_18 = rdx - 1<64>
	branch rdx == 0<64> l000000000040EC69
	// succ:  l000000000040EC40 l000000000040EC69
l000000000040EC40:
	word64 rax_22 = 0x10000040<64>
	// succ:  l000000000040EC50
l000000000040EC50:
	Mem0[rdi + rbx_18:byte] = CONVERT(Mem0[Mem0[rax_22:word64] + CONVERT(CONVERT(Mem0[rsi + rbx_18:byte], byte, word32), word32, uint64) * 4<64>:word32], word32, byte)
	rbx_18 = rbx_18 - 1<64>
	branch rbx_18 != 0xFFFFFFFFFFFFFFFF<64> l000000000040EC50
	// succ:  l000000000040EC69 l000000000040EC50
l000000000040EC69:
	return
	// succ:  test_exit
test_exit:

// After ///////
// test
// Return size: 0
define test
test_entry:
	// succ:  l000000000040EC30
l000000000040EC30:
	int64 rbx_18 = rdx - 1<64>
	branch rdx == 0<64> l000000000040EC69
	// succ:  l000000000040EC40 l000000000040EC69
l000000000040EC40:
	word32 (** rax_22)[] = (word32 (**)[]) 0x10000040<64>
	// succ:  l000000000040EC50
l000000000040EC50:
	rdi[rbx_18] = (byte) *((char *) *rax_22 + (uint64) ((word32) (rsi + rbx_18)) * 4<64>)
	rbx_18 = rbx_18 - 1<64>
	branch rbx_18 != 0xFFFFFFFFFFFFFFFF<64> l000000000040EC50
	// succ:  l000000000040EC69 l000000000040EC50
l000000000040EC69:
	return
	// succ:  test_exit
test_exit:

";

            #endregion

            // fn000000000040EC30 //////////
            RunStringTest(m =>
            {
                Identifier rbx_18 = m.Local(PrimitiveType.Word64, "rbx_18");
                Identifier rdx    = m.Local(PrimitiveType.Word64, "rdx");
                Identifier rax_22 = m.Local(PrimitiveType.Word64, "rax_22");
                Identifier rsi    = m.Local(PrimitiveType.Word64, "rsi");
                Identifier rdi    = m.Local(PrimitiveType.Word64, "rdi");

                m.Label("l000000000040EC30");
                m.Declare(rbx_18, m.ISub(rdx, Constant.Create(PrimitiveType.Create(Domain.Integer | Domain.Real | Domain.Pointer, 64), 0x1)));
                m.BranchIf(m.Eq(rdx, Constant.Create(PrimitiveType.Create(Domain.Integer | Domain.Real | Domain.Pointer, 64), 0x0)), "l000000000040EC69");

                m.Label("l000000000040EC40");
                m.Declare(rax_22, m.Word64(0x10000040));

                m.Label("l000000000040EC50");
                m.MStore(m.IAdd(rdi, rbx_18), m.Convert(
                             m.Mem32(m.IAdd(m.Mem64(rax_22), m.IMul(m.Convert(
                                                                        m.Convert(
                                                                            m.Mem8(m.IAdd(rsi, rbx_18)),
                                                                            PrimitiveType.Byte,
                                                                            PrimitiveType.Word32),
                                                                        PrimitiveType.Word32,
                                                                        PrimitiveType.UInt64),
                                                                    Constant.Create(PrimitiveType.Word64, 0x4)))),
                             PrimitiveType.Word32,
                             PrimitiveType.Byte));
                m.Assign(rbx_18, m.ISub(rbx_18, Constant.Create(PrimitiveType.Word64, 0x1)));
                m.BranchIf(m.Ne(rbx_18, Constant.Create(PrimitiveType.Word64, 0xFFFFFFFFFFFFFFFF)), "l000000000040EC50");

                m.Label("l000000000040EC69");
                m.Return();
            }, sExp);
        }
コード例 #22
0
 public Expression UMul(Expression left, int c)
 {
     return(new BinaryExpression(Operator.UMul, PrimitiveType.Create(Domain.UnsignedInt, left.DataType.Size), left, Constant.Create(left.DataType, c)));
 }
コード例 #23
0
ファイル: OperandRewriter.cs プロジェクト: mmyydd/reko
 public UnaryExpression AddrOf(Expression expr)
 {
     return(new UnaryExpression(Operator.AddrOf,
                                PrimitiveType.Create(Domain.Pointer, arch.WordWidth.Size), expr));
 }
コード例 #24
0
 public DataType VisitAddress(Address addr)
 {
     return(RecordDataType(
                PrimitiveType.Create(Domain.Pointer, addr.DataType.Size),
                addr));
 }
コード例 #25
0
        private DataType Parse(PrimitiveType charPrefix)
        {
            if (i >= str.Length)
            {
                return(new UnknownType());
            }
            int bitSize;

            switch (str[i++])
            {
            case 'a':
                return(ParseArray());

            case 'b':
                return(PrimitiveType.Byte);

            case 'p':
                if (i + 2 <= str.Length && str[i] == 'f' && str[i + 1] == 'n')
                {
                    i += 2;
                    return(new Pointer(new CodeType(), 4));
                }
                var pointee = Parse(PrimitiveType.Char);
                if (pointee is UnknownType)
                {
                    return(PrimitiveType.Pointer32);     //$ARch-dependent?
                }
                else
                {
                    return(new Pointer(pointee, 4));     //$ARCH-dependent!
                }

            case 'i':
                bitSize = ParseBitSize();
                if (bitSize == 0)
                {
                    return(PrimitiveType.Int32);         // Convenient for 2015... most ints are 32 in C code.
                }
                return(PrimitiveType.Create(Domain.SignedInt, bitSize / 8));

            case 'u':
                bitSize = ParseBitSize();
                if (bitSize == 0)
                {
                    return(PrimitiveType.UInt32);            //$REVIEW: arch word size?
                }
                return(PrimitiveType.Create(Domain.UnsignedInt, bitSize / 8));

            case 'r':
                bitSize = ParseBitSize();
                if (bitSize == 0)
                {
                    return(new UnknownType());
                }
                return(PrimitiveType.Create(Domain.Real, bitSize / 8));

            case 'f':
                return(PrimitiveType.Bool);

            case 'c':
                if (i < str.Length && str[i] == 'h')
                {
                    ++i;
                    return(charPrefix);
                }
                return(new UnknownType());

            case 's':
                if (i < str.Length)
                {
                    switch (str[i++])
                    {
                    case 'z':  return(StringType.NullTerminated(charPrefix));

                    case 'i': return(ParseLengthPrefixString(charPrefix));
                    }
                    --i;
                }
                return(new ArrayType(charPrefix, 0));

            case 'w':
                if (i < str.Length)
                {
                    var dt = Parse(PrimitiveType.WChar);
                    if (dt is UnknownType)
                    {
                        dt = PrimitiveType.Word32;
                    }
                    return(dt);
                }
                return(PrimitiveType.Word32);

            case 'x':
                return(new CodeType());
            }
            return(new UnknownType());
        }
コード例 #26
0
        public DataType VisitBinaryExpression(BinaryExpression binExp)
        {
            DataType dtLeft  = binExp.Left.Accept(this);
            DataType dtRight = binExp.Right.Accept(this);
            DataType dt;

            if (binExp.Operator == Operator.IAdd)
            {
                dt = GetPossibleFieldType(dtLeft, dtRight, binExp.Right);
                if (dt == null)
                {
                    dt = PullSumDataType(dtLeft, dtRight);
                }
            }
            else if (binExp.Operator == Operator.ISub)
            {
                dt = PullDiffDataType(dtLeft, dtRight);
            }
            else if (binExp.Operator == Operator.And ||
                     binExp.Operator == Operator.Or)
            {
                dt = PrimitiveType.CreateWord(dtLeft.Size).MaskDomain(Domain.Boolean | Domain.Integer | Domain.Character);
            }
            else if (
                binExp.Operator == Operator.IMul ||
                binExp.Operator == Operator.Shl ||
                binExp.Operator == Operator.IMod)
            {
                dt = PrimitiveType.CreateWord(binExp.DataType.Size).MaskDomain(Domain.Integer);
            }
            else if (
                binExp.Operator == Operator.SMul ||
                binExp.Operator == Operator.SDiv)
            {
                dt = PrimitiveType.CreateWord(binExp.DataType.Size).MaskDomain(Domain.SignedInt);
            }
            else if (
                binExp.Operator == Operator.UMul ||
                binExp.Operator == Operator.UDiv)
            {
                dt = PrimitiveType.CreateWord(binExp.DataType.Size).MaskDomain(Domain.UnsignedInt);
            }
            else if (binExp.Operator is ConditionalOperator)
            {
                dt = PrimitiveType.Bool;
            }
            else if (
                binExp.Operator == Operator.FAdd ||
                binExp.Operator == Operator.FSub ||
                binExp.Operator == Operator.FMul ||
                binExp.Operator == Operator.FDiv)
            {
                dt = PrimitiveType.Create(Domain.Real, dtLeft.Size);
            }
            else if (binExp.Operator == Operator.Shr)
            {
                dt = PrimitiveType.Create(Domain.UnsignedInt, dtLeft.Size);
            }
            else if (binExp.Operator == Operator.Sar)
            {
                dt = PrimitiveType.Create(Domain.SignedInt, dtLeft.Size);
            }
            else if (binExp.Operator == Operator.Xor ||
                     binExp.Operator == Operator.Shl)
            {
                dt = PrimitiveType.Create(Domain.Integer, dtLeft.Size);
            }
            else
            {
                throw NYI(binExp);
            }
            return(RecordDataType(dt, binExp));
        }
コード例 #27
0
        /// <summary>
        /// Creates an instance of PowerPcArchitecture.
        /// </summary>
        /// <param name="wordWidth">Supplies the word width of the PowerPC architecture.</param>
        public PowerPcArchitecture(string archId, PrimitiveType wordWidth, PrimitiveType signedWord) : base(archId)
        {
            WordWidth          = wordWidth;
            SignedWord         = signedWord;
            PointerType        = PrimitiveType.Create(Domain.Pointer, wordWidth.BitSize);
            FramePointerType   = PointerType;
            InstructionBitSize = 32;

            this.lr    = new RegisterStorage("lr", 0x48, 0, wordWidth);
            this.ctr   = new RegisterStorage("ctr", 0x49, 0, wordWidth);
            this.xer   = new RegisterStorage("xer", 0x4A, 0, wordWidth);
            this.fpscr = new RegisterStorage("fpscr", 0x4B, 0, wordWidth);

            this.cr  = new RegisterStorage("cr", 0x4C, 0, wordWidth);
            this.acc = new RegisterStorage("acc", 0x4D, 0, PrimitiveType.Word64);

            // gp regs  0..1F
            // fpu regs 20..3F
            // CR regs  40..47
            // vectors  80..FF
            fpregs = new ReadOnlyCollection <RegisterStorage>(
                Enumerable.Range(0, 0x20)
                .Select(n => new RegisterStorage("f" + n, n + 0x20, 0, PrimitiveType.Word64))
                .ToList());
            cregs = new ReadOnlyCollection <RegisterStorage>(
                Enumerable.Range(0, 8)
                .Select(n => new RegisterStorage("cr" + n, n + CcFieldMin, 0, PrimitiveType.Byte))
                .ToList());

            vregs = new ReadOnlyCollection <RegisterStorage>(
                Enumerable.Range(0, 128)        // VMX128 extension has 128 regs
                .Select(n => new RegisterStorage("v" + n, n + 0x80, 0, PrimitiveType.Word128))
                .ToList());

            ccFlagGroups = Enumerable.Range(0, 8)
                           .Select(n => new FlagGroupStorage(cr, 0xFu << (n * 4), $"cr{n}", PrimitiveType.Byte))
                           .ToDictionary(f => f.FlagGroupBits);
            ccFlagGroupsByName = ccFlagGroups.Values
                                 .ToDictionary(f => f.Name);


            regs = new ReadOnlyCollection <RegisterStorage>(
                Enumerable.Range(0, 0x20)
                .Select(n => new RegisterStorage("r" + n, n, 0, wordWidth))
                .Concat(fpregs)
                .Concat(cregs)
                .Concat(new[] { lr, ctr, xer })
                .Concat(vregs)
                .ToList());

            spregs = new Dictionary <int, RegisterStorage>
            {
                { 26, new RegisterStorage("srr0", 0x0100 + 26, 0, PrimitiveType.Word32) },
                { 27, new RegisterStorage("srr1", 0x0100 + 27, 0, PrimitiveType.Word32) },
            };

            //$REVIEW: using R1 as the stack register is a _convention_. It
            // should be platform-specific at the very least.
            StackRegister = regs[1];
            Options       = new Dictionary <string, object>();
        }
コード例 #28
0
 public DataType VisitPrimitive(PrimitiveType_v1 primitive)
 {
     return(PrimitiveType.Create(primitive.Domain, primitive.ByteSize));
 }
コード例 #29
0
 private DataType Real(int bitSize)
 {
     return(PrimitiveType.Create(Domain.Real, bitSize));
 }
コード例 #30
0
 private void RewriteFistp()
 {
     instrCur.op1.Width = PrimitiveType.Create(Domain.SignedInt, instrCur.op1.Width.Size);
     emitter.Assign(SrcOp(instrCur.op1), emitter.Cast(instrCur.op1.Width, orw.FpuRegister(0, state)));
     state.ShrinkFpuStack(1);
 }