예제 #1
0
        public void VpCastRealConstant()
        {
            var m  = new ProcedureBuilder();
            var r1 = m.Reg32("r1", 1);

            m.Assign(r1, m.Cast(PrimitiveType.Real32, ConstantReal.Real64(1)));

            var ssa  = RunTest(m);
            var sExp =
                #region Expected
                @"r1_1: orig: r1
    def:  r1_1 = 1.0F
// ProcedureBuilder
// Return size: 0
define ProcedureBuilder
ProcedureBuilder_entry:
	// succ:  l1
l1:
	r1_1 = 1.0F
ProcedureBuilder_exit:
";

            #endregion

            AssertStringsEqual(sExp, ssa);
        }
예제 #2
0
        public virtual Expression VisitCast(Cast cast)
        {
            var exp = cast.Expression.Accept(this);

            if (exp != Constant.Invalid)
            {
                var      ptCast = cast.DataType.ResolveAs <PrimitiveType>();
                Constant c      = exp as Constant;
                if (c != null && ptCast != null)
                {
                    PrimitiveType ptSrc = c.DataType as PrimitiveType;
                    if (ptSrc != null)
                    {
                        if (ptCast.Domain == Domain.Real)
                        {
                            if (ptSrc.Domain == Domain.Real &&
                                ptCast.Size < ptSrc.Size)
                            {
                                Changed = true;
                                return(ConstantReal.Create(ptCast, c.ToReal64()));
                            }
                        }
                        else if ((ptSrc.Domain & Domain.Integer) != 0)
                        {
                            Changed = true;
                            return(Constant.Create(ptCast, c.ToUInt64()));
                        }
                    }
                }
                Identifier  id;
                DepositBits dpb;
                if (exp.As(out id) && ctx.GetDefiningExpression(id).As(out dpb) && dpb.BitPosition == 0)
                {
                    // If we are casting the result of a DPB, and the deposited part is >=
                    // the size of the cast, then use deposited part directly.
                    int sizeDiff = dpb.InsertedBits.DataType.Size - cast.DataType.Size;
                    if (sizeDiff >= 0)
                    {
                        ctx.RemoveIdentifierUse(id);
                        ctx.UseExpression(dpb.InsertedBits);
                        Changed = true;
                        if (sizeDiff > 0)
                        {
                            return(new Cast(cast.DataType, dpb.InsertedBits));
                        }
                        else
                        {
                            return(dpb.InsertedBits);
                        }
                    }
                }
                cast = new Cast(cast.DataType, exp);
            }
            if (castCastRule.Match(cast))
            {
                Changed = true;
                return(castCastRule.Transform());
            }
            return(cast);
        }
예제 #3
0
        protected Constant BuildConstant(DataType t1, DataType t2, double val)
        {
            PrimitiveType p1   = (PrimitiveType)t1;
            PrimitiveType p2   = (PrimitiveType)t2;
            int           size = Math.Max(p1.Size, p2.Size);

            return(ConstantReal.Create(PrimitiveType.Create(p1.Domain & p2.Domain, size), val));
        }
예제 #4
0
        protected Constant BuildConstant(DataType t1, DataType t2, double val)
        {
            PrimitiveType p1      = t1.ResolveAs <PrimitiveType>() !;
            PrimitiveType p2      = t2.ResolveAs <PrimitiveType>() !;
            int           bitSize = Math.Max(p1.BitSize, p2.BitSize);

            return(ConstantReal.Create(PrimitiveType.Create(p1.Domain & p2.Domain, bitSize), val));
        }
예제 #5
0
 public override Constant ReinterpretAsFloat(Constant rawBits)
 {
     if (rawBits.DataType.BitSize == 32)
     {
         var n = ConstantReal.Create(rawBits.DataType, Real32ToIEEE(rawBits.ToUInt32()));
         return(n);
     }
     else if (rawBits.DataType.BitSize == 48)
     {
         var n = ConstantReal.Create(rawBits.DataType, Real48ToIEEE(rawBits.ToUInt64()));
         return(n);
     }
     throw new NotSupportedException($"Floating point bit size {rawBits.DataType.BitSize} is not supported.");
 }
예제 #6
0
        /// <summary>
        /// Take a bitvector of type wordXXX and reinterpret it as a floating-point
        /// constant.
        /// </summary>
        /// <param name="ptCast">Floating-point type to which the raw bits are being cast.</param>
        /// <param name="rawBits">The raw bits being cast.</param>
        /// <returns>A floating-point constant, possibly with a <see cref="Cast"/> wrapped around it
        /// if the constant is not 32- or 64-bit.
        /// </returns>
        private Expression CastRawBitsToReal(PrimitiveType ptCast, Constant rawBits)
        {
            var bitSize = Math.Min(rawBits.DataType.BitSize, 64);
            var dtImm   = PrimitiveType.Create(Domain.Real, bitSize);
            var cImm    = Constant.RealFromBitpattern(dtImm, rawBits.ToInt64());

            cImm = ConstantReal.Create(dtImm, cImm.ToReal64());
            if (cImm.DataType.BitSize == ptCast.BitSize)
            {
                return(cImm);
            }
            else
            {
                return(new Conversion(cImm, cImm.DataType, ptCast));
            }
        }
예제 #7
0
        public virtual Expression VisitCast(Cast cast)
        {
            var exp = cast.Expression.Accept(this);

            if (exp != Constant.Invalid)
            {
                var ptCast = cast.DataType.ResolveAs <PrimitiveType>();
                if (exp is Constant c && ptCast != null)
                {
                    if (c.DataType is PrimitiveType ptSrc)
                    {
                        if (ptCast.Domain == Domain.Real)
                        {
                            if (ptSrc.Domain == Domain.Real &&
                                ptCast.Size < ptSrc.Size)
                            {
                                Changed = true;
                                return(ConstantReal.Create(ptCast, c.ToReal64()));
                            }
                        }
                        else if ((ptSrc.Domain & Domain.Integer) != 0)
                        {
                            Changed = true;
                            return(Constant.Create(ptCast, c.ToUInt64()));
                        }
                    }
                }
                if (exp is Identifier id &&
                    ctx.GetDefiningExpression(id) is DepositBits dpb &&
                    dpb.BitPosition == 0)
                {
                    // If we are casting the result of a DPB, and the deposited part is >=
                    // the size of the cast, then use deposited part directly.
                    int sizeDiff = dpb.InsertedBits.DataType.Size - cast.DataType.Size;
                    if (sizeDiff >= 0)
                    {
                        ctx.RemoveIdentifierUse(id);
                        ctx.UseExpression(dpb.InsertedBits);
                        Changed = true;
                        if (sizeDiff > 0)
                        {
                            return(new Cast(cast.DataType, dpb.InsertedBits));
                        }
                        else
                        {
                            return(dpb.InsertedBits);
                        }
                    }
                }
                if (exp is ProcedureConstant pc && cast.DataType.BitSize == pc.DataType.BitSize)
                {
                    // (wordnn) procedure_const => procedure_const
                    return(pc);
                }
                if (exp.DataType.BitSize == cast.DataType.BitSize)
                {
                    // Redundant word-casts can be stripped.
                    var wordType = PrimitiveType.CreateWord(exp.DataType.BitSize);
                    if (wordType == cast.DataType)
                    {
                        return(exp);
                    }
                }
                cast = new Cast(cast.DataType, exp);
            }
            if (castCastRule.Match(cast))
            {
                Changed = true;
                return(castCastRule.Transform());
            }
            return(cast);
        }
예제 #8
0
        public virtual Expression VisitConversion(Conversion conversion)
        {
            var exp = conversion.Expression.Accept(this);

            if (!(exp is InvalidConstant))
            {
                var ptCvt = conversion.DataType.ResolveAs <PrimitiveType>();
                var ptSrc = conversion.SourceDataType.ResolveAs <PrimitiveType>();
                if (exp is Constant c && ptCvt != null)
                {
                    if (ptSrc != null)
                    {
                        if (ptCvt.Domain == Domain.Real)
                        {
                            if (ptSrc.Domain == Domain.Real)
                            {
                                if (ptCvt.Size < ptSrc.Size)
                                {
                                    // Real-to-real conversion.
                                    Changed = true;
                                    return(ConstantReal.Create(ptCvt, c.ToReal64()));
                                }
                            }
                            else if (ptSrc.IsWord)
                            {
                                // Raw bit pattern reinterpretation.
                                Changed = true;
                                return(CastRawBitsToReal(ptCvt, c));
                            }
                            else
                            {
                                // integer to real conversion
                                Changed = true;
                                return(ConstantReal.Create(ptCvt, c.ToInt64()));
                            }
                        }
                        else if ((ptSrc.Domain & Domain.Integer) != 0)
                        {
                            if (ptSrc != null)
                            {
                                if (ptSrc.Domain == Domain.SignedInt)
                                {
                                    Changed = true;
                                    return(Constant.Create(ptCvt, c.ToInt64()));
                                }
                                else if (ptSrc.Domain.HasFlag(Domain.SignedInt))
                                {
                                    Changed = true;
                                    return(Constant.Create(ptCvt, c.ToUInt64()));
                                }
                            }
                        }
                    }
                }
                if (exp is Identifier id &&
                    ctx.GetDefiningExpression(id) is MkSequence seq)
                {
                    // If we are casting a SEQ, and the corresponding element is >=
                    // the size of the cast, then use deposited part directly.
                    var lsbElem  = seq.Expressions[seq.Expressions.Length - 1];
                    int sizeDiff = lsbElem.DataType.Size - conversion.DataType.Size;
                    if (sizeDiff >= 0)
                    {
                        foreach (var elem in seq.Expressions)
                        {
                            ctx.RemoveExpressionUse(elem);
                        }
                        ctx.UseExpression(lsbElem);
                        Changed = true;
                        if (sizeDiff > 0)
                        {
                            return(new Conversion(lsbElem, lsbElem.DataType, conversion.DataType));
                        }
                        else
                        {
                            return(lsbElem);
                        }
                    }
                }
                if (exp is ProcedureConstant pc && conversion.DataType.BitSize == pc.DataType.BitSize)
                {
                    // (wordnn) procedure_const => procedure_const
                    return(pc);
                }
                if (exp.DataType.BitSize == conversion.DataType.BitSize)
                {
                    // Redundant word-casts can be stripped.
                    if (conversion.DataType.IsWord)
                    {
                        return(exp);
                    }
                }
                conversion = new Conversion(exp, exp.DataType, conversion.DataType);
            }
            if (convertConvertRule.Match(conversion))
            {
                Changed = true;
                return(convertConvertRule.Transform());
            }
            return(conversion);
        }
예제 #9
0
 private Expression FCmp0(Expression val)
 {
     return(m.FSub(val, ConstantReal.Create(val.DataType, 0.0)));
 }
예제 #10
0
        public virtual Expression VisitCast(Cast cast)
        {
            var exp = cast.Expression.Accept(this);

            if (exp != Constant.Invalid)
            {
                var ptCast = cast.DataType.ResolveAs <PrimitiveType>();
                if (exp is Constant c && ptCast != null)
                {
                    if (c.DataType is PrimitiveType ptSrc)
                    {
                        if (ptCast.Domain == Domain.Real)
                        {
                            if (ptSrc.Domain == Domain.Real &&
                                ptCast.Size < ptSrc.Size)
                            {
                                Changed = true;
                                return(ConstantReal.Create(ptCast, c.ToReal64()));
                            }
                        }
                        else if ((ptSrc.Domain & Domain.Integer) != 0)
                        {
                            Changed = true;
                            return(Constant.Create(ptCast, c.ToUInt64()));
                        }
                    }
                }
                if (exp is Identifier id &&
                    ctx.GetDefiningExpression(id) is MkSequence seq)
                {
                    // If we are casting a SEQ, and the corresponding element is >=
                    // the size of the cast, then use deposited part directly.
                    var lsbElem  = seq.Expressions[seq.Expressions.Length - 1];
                    int sizeDiff = lsbElem.DataType.Size - cast.DataType.Size;
                    if (sizeDiff >= 0)
                    {
                        foreach (var elem in seq.Expressions)
                        {
                            ctx.RemoveExpressionUse(elem);
                        }
                        ctx.UseExpression(lsbElem);
                        Changed = true;
                        if (sizeDiff > 0)
                        {
                            return(new Cast(cast.DataType, lsbElem));
                        }
                        else
                        {
                            return(lsbElem);
                        }
                    }
                }
                if (exp is ProcedureConstant pc && cast.DataType.BitSize == pc.DataType.BitSize)
                {
                    // (wordnn) procedure_const => procedure_const
                    return(pc);
                }
                if (exp.DataType.BitSize == cast.DataType.BitSize)
                {
                    // Redundant word-casts can be stripped.
                    if (cast.DataType.IsWord())
                    {
                        return(exp);
                    }
                }
                cast = new Cast(cast.DataType, exp);
            }
            if (castCastRule.Match(cast))
            {
                Changed = true;
                return(castCastRule.Transform());
            }
            return(cast);
        }