Exemplo n.º 1
0
        int CheckForULongOverflow()
        {
            switch (this.Kind)
            {
            case NumberKind.Real:
            case NumberKind.Quad:
                int            status;
                LLVMAPFloatRef apFloat       = LLVMExt.APFloatFromAPFloat(APFloat, APFloatSemantics.IEEEquad, out status);
                var            comparisonMax = LLVMExt.APFloatCompare(apFloat, MaxULongValue);
                var            comparisonMin = LLVMExt.APFloatCompare(apFloat, MinULongValue);
                LLVMExt.APFloatDispose(apFloat);

                if (comparisonMax == 2)
                {
                    return(1);
                }
                if (comparisonMin == 0)
                {
                    return(-1);
                }
                return(0);

            default:
                throw new NotSupportedException();
            }
        }
Exemplo n.º 2
0
        public Number(ulong number, NumberKind numberKind)
        {
            this.Kind = numberKind;

            if (numberKind.IsInteger())
            {
                var overflows = CheckForOverflow(number, numberKind);
                if (overflows == 1)
                {
                    this.State = NumberState.Overflow;
                }
                else if (overflows == -1)
                {
                    this.State = NumberState.Underflow;
                }

                if (!HasErrors)
                {
                    this.Value = LLVM.ConstInt(GetLLVMType(), number, new LLVMBool(0));
                }
            }
            else
            {
                this.APFloat = LLVMExt.APFloatZero(GetAPFloatSemantics(this.Kind));
                this.State  |= (NumberState)LLVMExt.APFloatFromString(this.APFloat, number.ToString(CultureInfo.InvariantCulture), RoundingMode);
            }
        }
Exemplo n.º 3
0
        public Number(string number, NumberKind numberKind)
        {
            if (number == null)
            {
                throw new ArgumentNullException(nameof(number));
            }

            this.Kind = numberKind;

            if (numberKind.IsInteger())
            {
                this.State = CheckIntegerString(number, numberKind);
                if (!this.HasErrors)
                {
                    this.Value = LLVM.ConstIntOfString(LLVM.Int128Type(), number, 10);
                }
            }
            else
            {
                this.State = CheckFloatString(number);
                if (!this.HasErrors)
                {
                    this.APFloat = LLVMExt.APFloatZero(GetAPFloatSemantics(this.Kind));
                    this.State  |= (NumberState)LLVMExt.APFloatFromString(this.APFloat, number, RoundingMode);
                }
            }
        }
Exemplo n.º 4
0
        static Number()
        {
            MaxLongValue  = LLVMExt.APFloatZero(APFloatSemantics.IEEEquad);
            MinLongValue  = LLVMExt.APFloatZero(APFloatSemantics.IEEEquad);
            MaxULongValue = LLVMExt.APFloatZero(APFloatSemantics.IEEEquad);
            MinULongValue = LLVMExt.APFloatZero(APFloatSemantics.IEEEquad);

            LLVMExt.APFloatFromString(MaxLongValue, long.MaxValue.ToString(CultureInfo.InvariantCulture), RoundingMode);
            LLVMExt.APFloatFromString(MinLongValue, long.MinValue.ToString(CultureInfo.InvariantCulture), RoundingMode);
            LLVMExt.APFloatFromString(MaxULongValue, ulong.MaxValue.ToString(CultureInfo.InvariantCulture), RoundingMode);
            LLVMExt.APFloatFromString(MinULongValue, ulong.MinValue.ToString(CultureInfo.InvariantCulture), RoundingMode);

            MaxLongLLVMValue  = LLVM.ConstInt(LLVM.Int128Type(), long.MaxValue, new LLVMBool(1));
            MinLongLLVMValue  = LLVM.ConstInt(LLVM.Int128Type(), unchecked ((ulong)long.MinValue), new LLVMBool(1));
            MaxULongLLVMValue = LLVM.ConstInt(LLVM.Int128Type(), ulong.MaxValue, new LLVMBool(0));
        }
Exemplo n.º 5
0
        public Number Duplicate()
        {
            var dup = new Number(dummy: string.Empty);

            dup.State = this.State;
            dup.Kind  = this.Kind;
            if (this.Value.Pointer.ToInt64() != 0)
            {
                dup.Value = Value;
            }
            if (this.APFloat.Pointer.ToInt64() != 0)
            {
                int status;
                dup.APFloat = LLVMExt.APFloatFromAPFloat(this.APFloat, GetAPFloatSemantics(this.Kind), out status);
            }
            return(dup);
        }
Exemplo n.º 6
0
        public NumberComparison CompareTo(Number n)
        {
            if (this.HasErrors || n.HasErrors)
            {
                return(NumberComparison.Invalid);
            }

            var opKind = OperationKind(this.Kind, n.Kind);
            var op1    = this.Convert(opKind);
            var op2    = n.Convert(opKind);

            if (opKind.IsInteger())
            {
                var result = LLVM.ConstICmp(LLVMIntPredicate.LLVMIntEQ, op1.LLVMValue, op2.LLVMValue).ConstIntGetZExtValue();
                if (result == 1)
                {
                    return(NumberComparison.Eq);
                }
                else
                {
                    result = LLVM.ConstICmp(opKind.IsSigned() ? LLVMIntPredicate.LLVMIntSGT : LLVMIntPredicate.LLVMIntUGT,
                                            op1.LLVMValue,
                                            op2.LLVMValue).ConstIntGetZExtValue();

                    return(result == 1 ? NumberComparison.Gt : NumberComparison.Ls);
                }
            }
            else
            {
                var result = LLVMExt.APFloatCompare(op1.APFloat, op2.APFloat);
                switch (result)
                {
                case 0:
                    return(NumberComparison.Ls);

                case 1:
                    return(NumberComparison.Eq);

                case 2:
                    return(NumberComparison.Gt);

                default:
                    return(NumberComparison.Undef);
                }
            }
        }
Exemplo n.º 7
0
        public Number Rem(Number n)
        {
            var opKind = OperationKind(this.Kind, n.Kind);

            if (this.HasErrors || n.HasErrors)
            {
                return(new Number(this.State | n.State, opKind));
            }

            if (opKind.IsInteger())
            {
                var result = opKind.IsSigned() ? LLVM.ConstSRem(this.Value, n.Value) : LLVM.ConstURem(this.Value, n.Value);
                var state  = CheckForOpOverflow(opKind, result);

                if (state != NumberState.Ok)
                {
                    return(new Number(state | this.State | n.State, opKind));
                }
                else
                {
                    return new Number(dummy: string.Empty)
                           {
                               Value = result,
                               State = this.State | n.State,
                               Kind  = opKind
                           }
                };
            }
            else
            {
                var op1 = this.Convert(opKind);
                var op2 = n.Convert(opKind);

                if (op1 == this)
                {
                    op1 = op1.Duplicate();
                }
                op1.State |= (NumberState)LLVMExt.APFloatMod(op1.APFloat, op2.APFloat);
                return(op1);
            }
        }
Exemplo n.º 8
0
        public Number Neg()
        {
            var opKind = OperationKind(this.Kind, NumberKind.UInt8);

            if (this.HasErrors)
            {
                return(new Number(this.State, opKind));
            }

            if (opKind.IsInteger())
            {
                var result = LLVM.ConstNeg(this.Value);
                var undef  = result.IsUndef();

                return(new Number(dummy: string.Empty)
                {
                    Value = result,
                    State = this.State | (undef ? NumberState.Invalid : NumberState.Ok),
                    Kind = opKind
                });
            }
            else
            {
                var dup      = this.Duplicate();
                var minusOne = new Number(-1.0, this.Kind);
                var state    = (NumberState)LLVMExt.APFloatMult(dup.APFloat, minusOne.APFloat, RoundingMode);
                var result   = dup.APFloat;
                dup.APFloat = new LLVMAPFloatRef(IntPtr.Zero);

                return(new Number(dummy: string.Empty)
                {
                    APFloat = result,
                    State = this.State | state,
                    Kind = opKind
                });
            }
        }
Exemplo n.º 9
0
        public Number(double number, NumberKind numberKind)
        {
            this.Kind = numberKind;

            if (numberKind.IsInteger())
            {
                var overflows = CheckForOverflow(number, numberKind);
                if (overflows == 1)
                {
                    this.State = NumberState.Overflow;
                }
                else if (overflows == -1)
                {
                    this.State = NumberState.Underflow;
                }

                if (!HasErrors)
                {
                    this.Value = LLVM.ConstReal(LLVM.DoubleType(), number);
                    if (numberKind.IsSigned())
                    {
                        this.Value = LLVM.ConstFPToSI(this.Value, GetLLVMType());
                    }
                    else
                    {
                        this.Value = LLVM.ConstFPToUI(this.Value, GetLLVMType());
                    }
                }
            }
            else
            {
                int state;
                this.APFloat = LLVMExt.APFloatFromDouble(number, GetAPFloatSemantics(this.Kind), out state);
                this.State  |= (NumberState)state;
            }
        }
Exemplo n.º 10
0
        public Number Convert(NumberKind kind)
        {
            if (kind == this.Kind)
            {
                return(this);
            }
            if (this.HasErrors)
            {
                return(new Number(this.State, this.Kind));
            }

            if (this.Kind.IsInteger())
            {
                if (this.Kind.IsSigned())
                {
                    var n = new Number(this.Int64Value, kind);
                    n.State |= this.State;
                    return(n);
                }
                else
                {
                    var n = new Number(this.UInt64Value, kind);
                    n.State |= this.State;
                    return(n);
                }
            }
            else
            {
                if (kind.IsFloat())
                {
                    int status;
                    var apFloat = LLVMExt.APFloatFromAPFloat(this.APFloat, GetAPFloatSemantics(kind), out status);
                    return(new Number(dummy: string.Empty)
                    {
                        APFloat = apFloat,
                        State = this.State | (NumberState)status,
                        Kind = kind
                    });
                }
                else
                {
                    if (this.Kind == NumberKind.Double)
                    {
                        var n = new Number(this.DoubleValue, kind);
                        n.State |= this.State;
                        return(n);
                    }
                    else if (this.Kind == NumberKind.Float)
                    {
                        var n = new Number(this.FloatValue, kind);
                        n.State |= this.State;
                        return(n);
                    }
                    else
                    {
                        if (kind.IsSigned())
                        {
                            var overflows = CheckForLongOverflow();
                            if (overflows == 1)
                            {
                                return(new Number(NumberState.Overflow, kind));
                            }
                            else if (overflows == -1)
                            {
                                return(new Number(NumberState.Underflow, kind));
                            }
                            else
                            {
                                var longValue  = LLVM.ConstFPToSI(LLVMExt.APFloatToValue(APFloat), LLVM.Int64Type());
                                var longValue2 = LLVM.ConstIntGetSExtValue(longValue);

                                return(new Number(longValue2, kind));
                            }
                        }
                        else
                        {
                            var overflows = CheckForULongOverflow();
                            if (overflows == 1)
                            {
                                return(new Number(NumberState.Overflow, kind));
                            }
                            else if (overflows == -1)
                            {
                                return(new Number(NumberState.Underflow, kind));
                            }
                            else
                            {
                                var ulongValue  = LLVM.ConstFPToUI(LLVMExt.APFloatToValue(APFloat), LLVM.Int64Type());
                                var ulongValue2 = LLVM.ConstIntGetZExtValue(ulongValue);

                                return(new Number(ulongValue2, kind));
                            }
                        }
                    }
                }
            }
        }