mirror of
https://github.com/apple/swift.git
synced 2025-12-21 12:14:44 +01:00
Following Jordan suggestion to r8446, replace the current version of Int's init() to make it 128 bit-proof. Swift SVN r8531
222 lines
6.1 KiB
Swift
222 lines
6.1 KiB
Swift
@# -*- mode: swift -*-
|
|
|
|
@# Ignore the following admonition; it applies to the resulting .swift file only
|
|
//// Automatically Generated From FixedPoint.gyb. Do Not Edit Directly ////
|
|
//// To regenerate: ////
|
|
//// ../../tools/gyb FixedPoint.gyb -o FixedPoint.swift ////
|
|
func overflowCheck<T: RandomAccessIndex>(arg: T, overflow: Bool) -> T {
|
|
alwaysTrap(overflow == false)
|
|
return arg
|
|
}
|
|
@{
|
|
#
|
|
# Utility code for later in this template
|
|
#
|
|
def hexify(n):
|
|
"""Return a legible hex representation of n, using '_' separators """
|
|
z = '%X' % n
|
|
l = len(z)
|
|
r = []
|
|
while z:
|
|
r.insert(0, z[-4:])
|
|
z = z[:-4]
|
|
return '0x' + '_'.join(r)
|
|
|
|
|
|
# Bit counts for all int types
|
|
allBits = [8, 16, 32, 64]
|
|
|
|
# Number of bits in the biggest int type
|
|
maxBits = max(allBits)
|
|
|
|
# Number of bits in an Int
|
|
intBits = 64
|
|
|
|
assert(intBits in allBits)
|
|
|
|
def maskBits(n):
|
|
"""Return an n-bit mask in hex"""
|
|
return hexify((1 << n) - 1)
|
|
|
|
def all_ints():
|
|
for bits in allBits:
|
|
for signed in False, True:
|
|
yield bits,signed
|
|
|
|
def int_name(bits, signed):
|
|
return ('' if signed else 'U') + 'Int' + str(bits)
|
|
}@
|
|
|
|
@for (bits, signed) in all_ints():
|
|
@ sign = 's' if signed else 'u'
|
|
@ Self = int_name(bits, signed)
|
|
@ ArrayBound = 'ArrayBound, ' if bits > 8 and bits < 128 else ''
|
|
|
|
struct ${Self} : BuiltinIntegerLiteralConvertible, IntegerLiteralConvertible,
|
|
${ArrayBound}ReplPrintable {
|
|
var value : Builtin.Int${bits}
|
|
|
|
init() {
|
|
var maxWidthZero : Int${str(maxBits)} = 0
|
|
value = ${'maxWidthZero.value' if bits == maxBits else ('Builtin.trunc_Int%d_Int%d(maxWidthZero.value)' % (maxBits, bits) )}
|
|
}
|
|
|
|
init [transparent] (v : Builtin.Int${bits}) {
|
|
value = v
|
|
}
|
|
|
|
static func [transparent] _convertFromBuiltinIntegerLiteral(val : Builtin.Int${maxBits}) -> ${Self} {
|
|
return ${Self}(${'val' if bits == maxBits else ('Builtin.trunc_Int%d_Int%d(val)' % (maxBits, bits) )})
|
|
}
|
|
|
|
typealias IntegerLiteralType = ${Self}
|
|
static func [transparent] convertFromIntegerLiteral(value : ${Self}) -> ${Self} {
|
|
return value
|
|
}
|
|
@if ArrayBound:
|
|
func _getBuiltinArrayBoundValue() -> Builtin.Int${bits} {
|
|
return value
|
|
}
|
|
|
|
typealias ArrayBoundType = ${Self}
|
|
func getArrayBoundValue() -> ${Self} {
|
|
return self
|
|
}
|
|
@else:
|
|
|
|
@end
|
|
func replPrint() {
|
|
print(${
|
|
'self' if bits == 64
|
|
else (('String' if bits > 64 else 'Int64' if signed else 'UInt64') + '(self)')})
|
|
}
|
|
|
|
@max = maskBits((bits - 1) if signed else bits)
|
|
// FIXME: these should be static vars when supported
|
|
static func max() -> ${Self} { return ${max} }
|
|
static func min() -> ${Self} { return ${'-%s-1' % max if signed else '0'} }
|
|
}
|
|
|
|
extension ${Self} : RandomAccessIndex, Hashable {
|
|
func __equal__(rhs: ${Self}) -> Bool {
|
|
return _getBool(Builtin.cmp_eq_Int${bits}(value, rhs.value))
|
|
}
|
|
func __less__(rhs: ${Self}) -> Bool {
|
|
return _getBool(Builtin.cmp_${sign}lt_Int${bits}(value, rhs.value))
|
|
}
|
|
func succ() -> ${Self} {
|
|
return self + 1
|
|
}
|
|
func pred() -> ${Self} {
|
|
return self - 1
|
|
}
|
|
func hashValue() -> Int {
|
|
@{
|
|
if bits <= intBits:
|
|
hashValue = 'Int(self)'
|
|
else:
|
|
# count of ints needed to represent this type
|
|
ints = (bits + intBits - 1) / intBits
|
|
|
|
# accumulate the high word
|
|
i = ints - 1
|
|
hashValue = 'Int(self >> %s)' % (i * intBits)
|
|
|
|
# accumulate middle words; these require shift + mask
|
|
while i > 1:
|
|
i = i-1
|
|
hashValue += ' ^ Int((self >> %d) & %s)' % (
|
|
intBits * i, maskBits(intBits))
|
|
|
|
# accumulate the low word; requires only a mask
|
|
hashValue += ' ^ Int(self & %s)' % maskBits(intBits)
|
|
}@
|
|
return ${hashValue}
|
|
}
|
|
|
|
typealias DistanceType = ${Self}
|
|
static func sub(lhs: ${Self}, rhs: ${Self}) -> (DistanceType, Bool) {
|
|
var tmp = Builtin.int_${sign}sub_with_overflow_Int${bits}(lhs.value, rhs.value)
|
|
return (${Self}(tmp.0), _getBool(tmp.1))
|
|
}
|
|
static func add(lhs: ${Self}, rhs: DistanceType) -> (${Self}, Bool) {
|
|
var tmp = Builtin.int_${sign}add_with_overflow_Int${bits}(lhs.value, rhs.value)
|
|
return (${Self}(tmp.0), _getBool(tmp.1))
|
|
}
|
|
static func mul(lhs: ${Self}, rhs: ${Self}) -> (${Self}, Bool) {
|
|
var tmp = Builtin.int_${sign}mul_with_overflow_Int${bits}(lhs.value, rhs.value)
|
|
return (${Self}(tmp.0), _getBool(tmp.1))
|
|
}
|
|
}
|
|
|
|
@if signed:
|
|
extension ${Self} : SignedNumber {
|
|
static func negate(rhs: ${Self}) -> (${Self}, Bool) { return ${Self}.sub(0, rhs) }
|
|
func isNegative() -> Bool { return self < 0 }
|
|
}
|
|
@end
|
|
|
|
// construction from other integer types
|
|
extension ${Self} {
|
|
@for (src_bits, src_signed) in all_ints():
|
|
@ That = int_name(src_bits, src_signed)
|
|
@ if Self != That:
|
|
init(v: ${That}) {
|
|
@if bits == src_bits:
|
|
value = v.value
|
|
@else:
|
|
value = Builtin.${
|
|
('trunc' if src_bits > bits
|
|
else 'sext' if src_signed
|
|
else 'zext')
|
|
}_Int${src_bits}_Int${bits}(v.value)
|
|
@end
|
|
}
|
|
@ end
|
|
@end
|
|
}
|
|
|
|
// Unary plus
|
|
func [prefix, transparent] +(rhs: ${Self}) -> ${Self} { return rhs }
|
|
|
|
// Operations with masking and non-masking versions
|
|
@for op,method in ('+','add'), ('*','mul'), ('-','sub'):
|
|
func [transparent] &${op} (lhs: ${Self}, rhs: ${Self}) -> ${Self} {
|
|
return ${Self}.${method}(lhs, rhs).0
|
|
}
|
|
func [transparent] ${op} (lhs: ${Self}, rhs: ${Self}) -> ${Self} {
|
|
return overflowCheck(${Self}.${method}(lhs, rhs))
|
|
}
|
|
@end
|
|
|
|
// Bitwise negate
|
|
func [prefix, transparent] ~(rhs: ${Self}) -> ${Self} {
|
|
return rhs ^ ${maskBits(bits)}
|
|
}
|
|
|
|
@for op, name in (
|
|
@ ('/',sign+'div'), ('%',sign+'rem'),
|
|
@ ('<<','shl'), ('>>','ashr' if signed else 'lshr'),
|
|
@ ('&','and'), ('^','xor'), ('|','or')):
|
|
func [transparent] ${op} (lhs: ${Self}, rhs: ${Self}) -> ${Self} {
|
|
return ${Self}(Builtin.${name}_Int${bits}(lhs.value, rhs.value))
|
|
}
|
|
@end
|
|
|
|
// Compound assignments
|
|
@for op in '+', '-', '*', '/', '%', '<<', '>>', '&', '|', '^':
|
|
func [assignment, transparent] ${op}=(lhs: [byref] ${Self}, rhs: ${Self}) {
|
|
lhs = lhs ${op} rhs
|
|
}
|
|
@end
|
|
@end # for bits in all_ints
|
|
|
|
// FIXME: rdar://14897572
|
|
// hack to make non-x86 architectures build at a reasonable speed
|
|
struct Hack14897572 { }
|
|
extension UInt32 {
|
|
init(_: Hack14897572) {
|
|
value = UInt32(0).value
|
|
}
|
|
}
|