@@ -186,13 +186,28 @@ public protocol IntegerType
186
186
var mostSignificantBit: Word { get }
187
187
188
188
@warn_unused_result
189
- func word (n: Word) -> Word
189
+ func uword (n: Word) -> UWord
190
190
191
+ mutating func replaceUWord(n: Word, with newBits: UWord)
192
+
191
193
init<T : IntegerType>(_ source: T)
192
194
193
195
init<T : IntegerType>(extendingOrTruncating source: T)
194
196
}
195
197
198
+ extension IntegerType {
199
+ /// The number of words required to represent our value. If `self`
200
+ /// is negative, returns the index of the least significant words of
201
+ /// our representation such that all more-significant words are -1.
202
+ /// Has the value -1 if `self` is 0.
203
+ @_transparent
204
+ public // transparent
205
+ var _mostSignificantWord: Word {
206
+ let msb = mostSignificantBit
207
+ return msb < 0 ? msb : msb / ${word_bits}
208
+ }
209
+ }
210
+
196
211
//===--- Homogeneous comparison -------------------------------------------===//
197
212
@_transparent
198
213
@warn_unused_result
@@ -329,9 +344,9 @@ ${comment}
329
344
@warn_unused_result
330
345
func countLeadingZeros() -> Word
331
346
332
- init(_truncatingBits bits: Word )
347
+ init(_truncatingBits bits: UWord )
333
348
334
- var _lowWord: Word { get }
349
+ var _lowUWord: UWord { get }
335
350
}
336
351
337
352
% for x in binaryBitwise:
@@ -477,7 +492,7 @@ extension FixedWidthIntegerType {
477
492
@_transparent
478
493
public init<T : IntegerType>(extendingOrTruncating source: T) {
479
494
if Self.bitWidth <= ${word_bits} {
480
- self = Self.init(_truncatingBits: source.word (0))
495
+ self = Self.init(_truncatingBits: source.uword (0))
481
496
}
482
497
else {
483
498
var result: Self = source < 0 ? ~0 : 0
@@ -488,7 +503,7 @@ extension FixedWidthIntegerType {
488
503
// that Self.bitWidth > ${word_bits}. Not masking results in
489
504
// infinite recursion.
490
505
result &<<= ${word_bits}
491
- result |= Self(_truncatingBits: source.word (n))
506
+ result |= Self(_truncatingBits: source.uword (n))
492
507
n -= 1
493
508
}
494
509
@@ -497,25 +512,33 @@ extension FixedWidthIntegerType {
497
512
}
498
513
499
514
@_transparent
500
- public func word (n: Word) -> Word {
515
+ public func uword (n: Word) -> UWord {
501
516
var n = n
502
517
_precondition(n >= 0, "Negative word index")
503
518
var x = self
504
519
while n > 0 {
505
- // Using a masking shift here allows us to make more things
506
- // transparent, but this would have the wrong semantics if the
507
- // masking ever had an effect.
508
- _sanityCheck(Self.bitWidth > ${word_bits})
509
- x &>>= ${word_bits}
520
+ x &>>= Swift.min(Self(_truncatingBits: Self._bitWidth) &- 1, ${word_bits})
510
521
n -= 1
511
522
}
512
- return x._lowWord
523
+ return x._lowUWord
513
524
}
514
525
526
+ @_transparent
527
+ public mutating func replaceUWord(n: Word, with newBits: UWord) {
528
+ // Make sure the masking shift is going to be OK.
529
+ _sanityCheck(Self.bitWidth > ${word_bits} * n)
530
+ self ^= Self(_truncatingBits: newBits ^ uword(n)) &<< (${word_bits} * n)
531
+ }
532
+
515
533
@_transparent
516
534
public // transparent
517
535
static var _highBitIndex: Self {
518
- return Self.init(_truncatingBits: Self.bitWidth - 1)
536
+ return Self.init(_truncatingBits: Self._bitWidth &- 1)
537
+ }
538
+
539
+ @_transparent
540
+ public static var _bitWidth : UWord {
541
+ return UWord(bitWidth._storage)
519
542
}
520
543
}
521
544
@@ -650,6 +673,11 @@ public struct ${Self}
650
673
_storage), x))
651
674
}
652
675
676
+ @_transparent
677
+ public init(bitPattern x: ${'U' if signed else ''}Int${bits}) {
678
+ _storage = x._storage
679
+ }
680
+
653
681
@warn_unused_result
654
682
public func isEqualTo(rhs: ${Self}) -> Bool {
655
683
return Bool(Builtin.cmp_eq_Int${bits}(_storage, rhs._storage))
@@ -727,31 +755,24 @@ public struct ${Self}
727
755
@_transparent
728
756
@warn_unused_result
729
757
public func countLeadingZeros() -> Word {
730
- return ${Self}(
731
- Builtin.int_ctlz_Int${bits}(self._storage, false.__value))._lowWord
732
- }
733
-
734
- @_transparent
735
- public // transparent
736
- var _lowWord: Word {
737
- % truncOrExt = z + 'ext' if bits <= word_bits else 'trunc'
738
758
return Word(
739
- Builtin.${truncOrExt}OrBitCast_Int${bits}_Int${word_bits}(_storage)
740
- )
759
+ ${Self}(
760
+ Builtin.int_ctlz_Int${bits}(self._storage, false.__value)
761
+ )._lowUWord._storage)
741
762
}
742
763
743
764
@_transparent
744
765
public // transparent
745
- var _lowUnsignedWord: Word {
766
+ var _lowUWord: UWord {
746
767
% truncOrExt = z + 'ext' if bits <= word_bits else 'trunc'
747
- return Word (
768
+ return UWord (
748
769
Builtin.${truncOrExt}OrBitCast_Int${bits}_Int${word_bits}(_storage)
749
770
)
750
771
}
751
772
752
773
@_transparent
753
774
public // transparent
754
- init(_truncatingBits bits: Word ) {
775
+ init(_truncatingBits bits: UWord ) {
755
776
% truncOrExt = 'zext' if bits > word_bits else 'trunc'
756
777
self.init(
757
778
Builtin.${truncOrExt}OrBitCast_Int${word_bits}_Int${bits}(bits._storage))
@@ -875,6 +896,7 @@ tests.test("mostSignificantBit") {
875
896
expectEqual(7, UInt8.max.mostSignificantBit)
876
897
expectEqual(-1, UInt8.min.mostSignificantBit)
877
898
expectEqual(6, Int8.max.mostSignificantBit)
899
+ expectEqual(-1, (0 as Int8).mostSignificantBit)
878
900
expectEqual(6, Int8.min.mostSignificantBit)
879
901
}
880
902
0 commit comments