@# -*- mode: swift -*- @# Ignore the following admonition; it applies to the resulting .swift file only //// Automatically Generated From FixedPoint.gyb. Do Not Edit Directly! //===----------------------------------------------------------------------===// // // This source file is part of the Swift.org open source project // // Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information // See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors // //===----------------------------------------------------------------------===// @{ # # 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 allNames = [8, 16, 32, 64, 'Int'] # Number of bits in the biggest int type maxBits = 64 # Number of bits in the Builtin.Word type wordBits = int(CMAKE_SIZEOF_VOID_P) * 8 # Number of bits in integer literals. builtinIntLiteralBits = 2048 # FIXME: checked and unchecked conversions of Word types CastFromWord = 'zextOrBitCast_Word_Int64' if wordBits==64 else 'truncOrBitCast_Word_Int32' CastToWord = 'truncOrBitCast_Int64_Word' if wordBits==64 else 'zextOrBitCast_Int32_Word' def maskBits(n): """Return an n-bit mask in hex""" return hexify((1 << n) - 1) def allInts(): for name in allNames: for signed in False, True: yield str(name), int(wordBits if name=='Int' else name), signed def baseIntName(name): return 'Int' if name == 'Int' else 'Int' + str(name) def builtinIntName(name): return 'Word' if name == 'Int' else 'Int' + str(name) def intName(name, signed): return ('' if signed else 'U') + baseIntName(name) def otherIntName(name, signed): return ('U' if signed else '') + baseIntName(name) }@ typealias IntMax = Int${maxBits} typealias UIntMax = UInt${maxBits} @ for (name, bits, signed) in allInts(): @ (sign, ext) = ('s', 'sext') if signed else ('u', 'zext') @ BuiltinName = builtinIntName(name) @ Self = intName(name, signed) @ OtherSelf = otherIntName(name, signed) @ ConstructIntType = 'Int' if Self != 'Int' else '' @ ArrayBound = 'ArrayBound, ' if bits <= 64 else '' struct ${Self} : BuiltinIntegerLiteralConvertible, IntegerLiteralConvertible, ${ArrayBound}ReplPrintable { var value: Builtin.${BuiltinName} @@transparent init() { var maxWidthZero: IntMax = 0 value = Builtin.truncOrBitCast_Int${maxBits}_${BuiltinName}(maxWidthZero.value) } @@transparent init(v: Builtin.${BuiltinName}) { value = v } @@transparent static func _convertFromBuiltinIntegerLiteral(value: Builtin.Int${builtinIntLiteralBits}) -> ${Self} { return ${Self}(Builtin.s_to_${sign}_checked_trunc_Int${builtinIntLiteralBits}_${BuiltinName}(value).0) } @@transparent static func convertFromIntegerLiteral(value: ${Self}) -> ${Self} { return value } @ if ArrayBound: @@transparent func _getBuiltinArrayBoundValue() -> Builtin.Word { @ if bits < wordBits: return Builtin.${ext}OrBitCast_${BuiltinName}_Word(self.value) @ elif bits > wordBits: return Builtin.truncOrBitCast_${BuiltinName}_Word(self.value) @ elif BuiltinName == 'Word': return self.value @ else: return Builtin.${CastToWord}(self.value) @ end } typealias ArrayBoundType = ${Self} func getArrayBoundValue() -> ${Self} { return self } @ end func replPrint() { print(${ 'self' if BuiltinName == 'Int64' else (('String' if bits > 64 else 'Int64' if signed else 'UInt64') + '(self)')}) } @ max = maskBits((bits - 1) if signed else bits) @@transparent static var max: ${Self} { return ${max} } @@transparent static var min: ${Self} { return ${'-%s-1' % max if signed else '0'} } } extension ${Self} : Hashable { func hashValue() -> Int { @ if bits < wordBits: return Int(Builtin.sextOrBitCast_${BuiltinName}_Word(self.value)) @ elif bits > wordBits: var result: Int = 0 for var i = 0; i < (sizeof(self) * 8); i += sizeof(Int.self) * 8 { result ^= Int(self >> ${Self}(i)) & ~0 } return result @ elif BuiltinName == 'Word': return Int(self.value) @ else: return Int(Builtin.${CastToWord}(self.value)) @ end } } @@transparent extension ${Self} : RandomAccessIndex { @@transparent func succ() -> ${Self} { return self + 1 } @@transparent func pred() -> ${Self} { return self - 1 } @@transparent func distanceTo(other: ${Self}) -> Int { return ${ConstructIntType}(other - self) } typealias DistanceType = ${Self} @@transparent static func sub(lhs: ${Self}, rhs: ${Self}, reportOverflow: Bool) -> (DistanceType, Bool) { var tmp = Builtin.${sign}sub_with_overflow_${BuiltinName}(lhs.value, rhs.value, reportOverflow.value) return (${Self}(tmp.0), Bool(tmp.1)) } @@transparent static func add(lhs: ${Self}, rhs: DistanceType, reportOverflow: Bool) -> (${Self}, Bool) { var tmp = Builtin.${sign}add_with_overflow_${BuiltinName}(lhs.value, rhs.value, reportOverflow.value) return (${Self}(tmp.0), Bool(tmp.1)) } @@transparent static func mul(lhs: ${Self}, rhs: ${Self}, reportOverflow: Bool) -> (${Self}, Bool) { var tmp = Builtin.${sign}mul_with_overflow_${BuiltinName}(lhs.value, rhs.value, reportOverflow.value) return (${Self}(tmp.0), Bool(tmp.1)) } @@transparent static func div(lhs: ${Self}, rhs: ${Self}, reportOverflow: Bool) -> (${Self}, Bool) { if rhs == 0 { return (0, true) } @ if signed: if lhs == ${Self}.min && rhs == -1 { return (lhs, true) } @ end var tmp = Builtin.${sign}div_${BuiltinName}(lhs.value, rhs.value) return (${Self}(tmp), false) } @@transparent static func rem(lhs: ${Self}, rhs: ${Self}, reportOverflow: Bool) -> (${Self}, Bool) { if rhs == 0 { return (0, true) } @ if signed: if lhs == ${Self}.min && rhs == -1 { return (0, true) } @ end var tmp = Builtin.${sign}rem_${BuiltinName}(lhs.value, rhs.value) return (${Self}(tmp), false) } @@transparent static func sub(lhs: ${Self}, rhs: ${Self}) -> (DistanceType, Bool) { return sub(lhs, rhs, true) } @@transparent static func add(lhs: ${Self}, rhs: DistanceType) -> (${Self}, Bool) { return add(lhs, rhs, true) } @@transparent static func mul(lhs: ${Self}, rhs: ${Self}) -> (${Self}, Bool) { return mul(lhs, rhs, true) } @@transparent static func div(lhs: ${Self}, rhs: ${Self}) -> (${Self}, Bool) { return div(lhs, rhs, true) } @@transparent static func rem(lhs: ${Self}, rhs: ${Self}) -> (${Self}, Bool) { return rem(lhs, rhs, true) } @@transparent func toIntMax() -> IntMax { return ${'self' if Self == 'Int%s' % maxBits else 'IntMax(self)'} } } @ if signed: @@transparent extension ${Self} : SignedNumber { @@transparent static func negate(rhs: ${Self}) -> (${Self}, Bool) { return ${Self}.sub(0, rhs) } @@transparent static func abs(rhs: ${Self}) -> (${Self}, Bool) { return rhs.isNegative() ? ${Self}.negate(rhs) : (rhs, false) } @@transparent func isNegative() -> Bool { return self < 0 } } @ end @# FIXME: checked conversions of Word types // construction from other integer types @@transparent extension ${Self} { @ for (srcName, srcBits, srcSigned) in allInts(): @ Src = intName(srcName, srcSigned) @ srcBuiltinName = builtinIntName(srcName) @ (srcSign, srcExt) = ('s', 'sext') if srcSigned else ('u', 'zext') @ if Self != Src: init(v: ${Src}) { @ @ if srcBuiltinName == 'Word': var srcNotWord = Builtin.${CastFromWord}(v.value) @ else: var srcNotWord = v.value @ end @ @ if srcBits == bits and srcSign == sign: var dstNotWord = srcNotWord @ @ elif srcBits == bits: var tmp = Builtin.${srcSign}_to_${sign}_checked_conversion_Int${srcBits}(srcNotWord) Builtin.condfail(tmp.1) var dstNotWord = tmp.0 @ @ elif srcBits > bits: var tmp = Builtin.${srcSign}_to_${sign}_checked_trunc_Int${srcBits}_Int${bits}(srcNotWord) Builtin.condfail(tmp.1) var dstNotWord = tmp.0 @ @ elif srcSigned and not signed: var tmp = Builtin.s_to_u_checked_conversion_Int${srcBits}(srcNotWord) Builtin.condfail(tmp.1) var dstNotWord = Builtin.${srcExt}_Int${srcBits}_Int${bits}(tmp.0) @ @ else: var dstNotWord = Builtin.${srcExt}_Int${srcBits}_Int${bits}(srcNotWord) @ end @ @ if BuiltinName == 'Word': value = Builtin.${CastToWord}(dstNotWord) @ else: value = dstNotWord @ end } @ end @ end func as${'Unsigned' if signed else 'Signed'}() -> ${OtherSelf} { return ${OtherSelf}(value) } } // Operations with masking and non-masking versions @ for op,method in ('+','add'), ('*','mul'), ('-','sub'): @@transparent func &${op} (lhs: ${Self}, rhs: ${Self}) -> ${Self} { return ${Self}.${method}(lhs, rhs, false).0 } @@transparent func ${op} (lhs: ${Self}, rhs: ${Self}) -> ${Self} { var tmp = ${Self}.${method}(lhs, rhs) Builtin.condfail(tmp.1.value) return tmp.0 } @ end // Bitwise negate @@transparent @@prefix func ~(rhs: ${Self}) -> ${Self} { let mask = ${Self}.sub(0, 1).0 return ${Self}(Builtin.xor_${BuiltinName}(rhs.value, mask.value)) } @ for op, name in ( @ ('==','eq'), ('!=','ne'), @ ('<',sign+'lt'), ('<=',sign+'le'), @ ('>',sign+'gt'), ('>=',sign+'ge')): @@transparent func ${op} (lhs: ${Self}, rhs: ${Self}) -> Bool { return Bool(Builtin.cmp_${name}_${BuiltinName}(lhs.value, rhs.value)) } @ end @ for op, name in (('<<','shl'), ('>>','ashr' if signed else 'lshr')): @@transparent func ${op} (lhs: ${Self}, rhs: ${Self}) -> ${Self} { @ if signed: assert(U${Self}(rhs) < U${Self}(sizeof(rhs) * 8)) @ else: assert(rhs < ${Self}(sizeof(rhs) * 8)) @ end return ${Self}(Builtin.${name}_${BuiltinName}(lhs.value, rhs.value)) } @ end @ for op, name in (('&','and'), ('^','xor'), ('|','or')): @@transparent func ${op} (lhs: ${Self}, rhs: ${Self}) -> ${Self} { return ${Self}(Builtin.${name}_${BuiltinName}(lhs.value, rhs.value)) } @ end // bitwise operations @@transparent extension ${Self} : BitwiseOperations { static func allZeros() -> ${Self} { return 0 } } // Compound assignments @ for op in '+', '-', '*', '<<', '>>', '&', '|', '^': @@transparent @@assignment func ${op}=(inout lhs: ${Self}, rhs: ${Self}) { lhs = lhs ${op} rhs } @ end @ end # for bits in allInts typealias Word = Int typealias UWord = UInt