@# -*- 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(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 } }