Пример #1
0
        NumberState CheckForOpOverflow(NumberKind opKind, LLVMValueRef result)
        {
            if (opKind.IsSigned())
            {
                var lessThan = LLVM.ConstICmp(LLVMIntPredicate.LLVMIntSLT, result, MinLongLLVMValue).ConstIntGetZExtValue() == 1;
                if (lessThan)
                {
                    return(NumberState.Underflow);
                }
                var greatherThan = LLVM.ConstICmp(LLVMIntPredicate.LLVMIntSGT, result, MaxLongLLVMValue).ConstIntGetZExtValue() == 1;
                if (greatherThan)
                {
                    return(NumberState.Overflow);
                }

                var overflows = CheckForOverflow(result.ConstIntGetSExtValue(), opKind);
                if (overflows == 1)
                {
                    return(NumberState.Overflow);
                }
                else if (overflows == -1)
                {
                    return(NumberState.Underflow);
                }
                else
                {
                    return(NumberState.Ok);
                }
            }
            else
            {
                var greatherThan = LLVM.ConstICmp(LLVMIntPredicate.LLVMIntUGT, result, MaxULongLLVMValue).ConstIntGetZExtValue() == 1;
                if (greatherThan)
                {
                    return(NumberState.Overflow);
                }

                var overflows = CheckForOverflow(result.ConstIntGetZExtValue(), opKind);
                if (overflows == 1)
                {
                    return(NumberState.Overflow);
                }
                else if (overflows == -1)
                {
                    return(NumberState.Underflow);
                }
                else
                {
                    return(NumberState.Ok);
                }
            }
        }
Пример #2
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;
            }
        }
Пример #3
0
        static NumberKind OperationKind(NumberKind k1, NumberKind k2, bool unsignedWins = false)
        {
            if (k1.IsInteger())
            {
                if (k2.IsInteger())
                {
                    var sameSignedness = (k1.IsSigned() && k2.IsSigned()) || (k1.IsUnsigned() && k2.IsUnsigned());
                    if (sameSignedness)
                    {
                        var minKSize = Semantics.DefaultKind.BitSize(Semantics);
                        var k1Size   = k1.BitSize(Semantics);
                        var k2Size   = k2.BitSize(Semantics);

                        if (k1Size < minKSize && k2Size < minKSize)
                        {
                            if (k1.IsSigned())
                            {
                                return(Semantics.DefaultKind.Signed());
                            }
                            else
                            {
                                return(Semantics.DefaultKind.Unsigned());
                            }
                        }
                        else
                        {
                            var kSize = Math.Max(k1Size, k2Size);
                            if (kSize == k1Size)
                            {
                                return(k1);
                            }
                            else
                            {
                                return(k2);
                            }
                        }
                    }
                    else
                    {
                        if (unsignedWins)
                        {
                            k1 = k1.Unsigned();
                            k2 = k2.Unsigned();
                        }
                        else
                        {
                            k1 = k1.Signed();
                            k2 = k2.Signed();
                        }

                        var minKSize = Semantics.DefaultKind.BitSize(Semantics);
                        var k1Size   = k1.BitSize(Semantics);
                        var k2Size   = k2.BitSize(Semantics);

                        if (k1Size < minKSize && k2Size < minKSize)
                        {
                            if (k1.IsSigned())
                            {
                                return(Semantics.DefaultKind.Signed());
                            }
                            else
                            {
                                return(Semantics.DefaultKind.Unsigned());
                            }
                        }
                        else
                        {
                            var kSize = Math.Max(k1Size, k2Size);
                            if (kSize == k1Size)
                            {
                                return(k1);
                            }
                            else
                            {
                                return(k2);
                            }
                        }
                    }
                }
                else
                {
                    return(k2);
                }
            }
            else
            {
                if (k2.IsInteger())
                {
                    return(k1);
                }
                else
                {
                    var k1Size = k1.BitSize(Semantics);
                    var k2Size = k2.BitSize(Semantics);

                    if (k1Size == k2Size)
                    {
                        if (k1 == k2)
                        {
                            return(k1);
                        }
                        else
                        {
                            return(GetBestFloatKind(k1, k2));
                        }
                    }
                    else
                    {
                        var biggest = Math.Max(k1Size, k2Size);
                        return(biggest == k1Size ? k1 : k2);
                    }
                }
            }
        }
Пример #4
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));
                            }
                        }
                    }
                }
            }
        }