mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
Remove all gyb-generated files and generate them automatically from .gyb files. Rename the proof-of-concept UnsafeArray.swift.gyb back to UnsafeArray.swift. Never forget to update the .gyb file or regenerate again! Swift SVN r14445
375 lines
10 KiB
Swift
375 lines
10 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!
|
|
//===----------------------------------------------------------------------===//
|
|
//
|
|
// 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
|