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); } } }
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; } }
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); } } } }
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)); } } } } } }