mirror of
https://github.com/apple/swift.git
synced 2025-12-21 12:14:44 +01:00
Allow large integer literals for DoubleWidth
This commit is contained in:
@@ -83,7 +83,10 @@ public struct DoubleWidth<Base : FixedWidthInteger> :
|
||||
|
||||
@_inlineable // FIXME(sil-serialize-all)
|
||||
public init<T : BinaryInteger>(_ source: T) {
|
||||
self.init(exactly: source)!
|
||||
guard let result = DoubleWidth<Base>(exactly: source) else {
|
||||
_preconditionFailure("Value is outside the representable range")
|
||||
}
|
||||
self = result
|
||||
}
|
||||
|
||||
@_inlineable // FIXME(sil-serialize-all)
|
||||
@@ -596,9 +599,42 @@ binaryOperators = [
|
||||
// other
|
||||
//
|
||||
@_inlineable // FIXME(sil-serialize-all)
|
||||
public init(_builtinIntegerLiteral x: _MaxBuiltinIntegerType) {
|
||||
// FIXME: This won't work if `x` is out of range for `Int64`
|
||||
self.init(Int64(_builtinIntegerLiteral: x))
|
||||
public init(_builtinIntegerLiteral _x: _MaxBuiltinIntegerType) {
|
||||
var _x = _x
|
||||
self = DoubleWidth()
|
||||
|
||||
// If we can capture the entire literal in a single Int64, stop there.
|
||||
// This avoids some potential deep recursion due to literal expressions in
|
||||
// other DoubleWidth methods.
|
||||
let (_value, _overflow) = Builtin.s_to_s_checked_trunc_Int2048_Int64(_x)
|
||||
if !Bool(_overflow) {
|
||||
self = DoubleWidth(Int64(_value))
|
||||
return
|
||||
}
|
||||
|
||||
// Convert all but the most significant 64 bits as unsigned integers.
|
||||
let _shift = Builtin.sext_Int64_Int2048((64 as Int64)._value)
|
||||
let lowWordCount = (bitWidth - 1) / 64
|
||||
for i in 0..<lowWordCount {
|
||||
let value =
|
||||
DoubleWidth(UInt64(Builtin.s_to_u_checked_trunc_Int2048_Int64(_x).0))
|
||||
&<< DoubleWidth(i * 64)
|
||||
self |= value
|
||||
_x = Builtin.ashr_Int2048(_x, _shift)
|
||||
}
|
||||
|
||||
// Finally, convert the most significant 64 bits and check for overflow.
|
||||
let overflow: Bool
|
||||
if Base.isSigned {
|
||||
let (_value, _overflow) = Builtin.s_to_s_checked_trunc_Int2048_Int64(_x)
|
||||
self |= DoubleWidth(Int64(_value)) &<< DoubleWidth(lowWordCount * 64)
|
||||
overflow = Bool(_overflow)
|
||||
} else {
|
||||
let (_value, _overflow) = Builtin.s_to_u_checked_trunc_Int2048_Int64(_x)
|
||||
self |= DoubleWidth(UInt64(_value)) &<< DoubleWidth(lowWordCount * 64)
|
||||
overflow = Bool(_overflow)
|
||||
}
|
||||
_precondition(!overflow, "Literal integer out of range for this type")
|
||||
}
|
||||
|
||||
@_inlineable // FIXME(sil-serialize-all)
|
||||
|
||||
Reference in New Issue
Block a user