@@ -41,6 +41,7 @@ public struct APInt: IRConstant {
4141 self . value = . single( val & mask)
4242 case var . many( vals) :
4343 vals [ vals. endIndex - 1 ] &= mask
44+ self . value = . many( vals)
4445 }
4546 }
4647
@@ -537,7 +538,7 @@ extension APInt {
537538 public var signExtendedValue : Int64 ? {
538539 switch self . value {
539540 case let . single( val) :
540- return Int64 ( bitPattern: val << ( 64 - self . bitWidth) ) >> ( 64 - self . bitWidth) ;
541+ return Int64 ( bitPattern: val << ( 64 - self . bitWidth) ) >> ( 64 - self . bitWidth)
541542 case let . many( vals) :
542543 guard ( self . bitWidth - self . leadingZeroBitCount) <= 64 else {
543544 return nil
@@ -600,7 +601,6 @@ extension APInt {
600601 count += v. leadingZeroBitCount
601602 break
602603 }
603-
604604 count += bitsPerWord
605605 }
606606 // Adjust for unused bits in the most significant word (they are zero).
@@ -610,6 +610,37 @@ extension APInt {
610610 }
611611 }
612612
613+
614+ /// The number of leading ones in this value’s binary representation.
615+ public var leadingNonZeroBitCount : Int {
616+ switch self . value {
617+ case let . single( val) :
618+ return ( ~ ( val << ( bitsPerWord - self . bitWidth) ) ) . leadingZeroBitCount
619+ case let . many( vals) :
620+ var highWordBits = self . bitWidth % bitsPerWord
621+ var shift : Int
622+ if highWordBits == 0 {
623+ highWordBits = bitsPerWord
624+ shift = 0
625+ } else {
626+ shift = bitsPerWord - highWordBits
627+ }
628+ let tail = requiredWords ( for: self . bitWidth) - 1
629+ var count = ( ~ ( vals [ tail] << shift) ) . leadingZeroBitCount
630+ if count == highWordBits {
631+ for j in ( 0 ..< tail) . reversed ( ) {
632+ if vals [ j] == . max {
633+ count += bitsPerWord
634+ } else {
635+ count += ( ~ vals[ j] ) . leadingZeroBitCount
636+ break
637+ }
638+ }
639+ }
640+ return count
641+ }
642+ }
643+
613644 /// The number of trailing zeros in this value’s binary representation.
614645 public var trailingZeroBitCount : Int {
615646 switch self . value {
@@ -629,6 +660,25 @@ extension APInt {
629660 }
630661 }
631662
663+ /// The number of trailing ones in this value’s binary representation.
664+ public var trailingNonZeroBitCount : Int {
665+ switch self . value {
666+ case let . single( val) :
667+ return ( ~ val) . trailingZeroBitCount
668+ case let . many( vals) :
669+ var count = 0
670+ var i = 0
671+ while i < vals. count && vals [ i] == . max {
672+ defer { i += 1 }
673+ count += bitsPerWord
674+ }
675+ if i < vals. count {
676+ count += ( ~ vals[ i] ) . trailingZeroBitCount
677+ }
678+ return count
679+ }
680+ }
681+
632682 /// The number of bits equal to 1 in this value’s binary representation.
633683 public var nonzeroBitCount : Int {
634684 switch self . value {
@@ -644,6 +694,159 @@ extension APInt {
644694 }
645695}
646696
697+ // MARK: Bit Twiddling Operations
698+
699+ extension APInt {
700+ /// Sets all bits to one in this value's binary representation.
701+ public mutating func setAllBits( ) {
702+ switch self . value {
703+ case . single( _) :
704+ self . value = . single( . max)
705+ case . many( _) :
706+ self . value = . many( [ APInt . Word] ( repeating: . max, count: requiredWords ( for: self . bitWidth) ) )
707+ }
708+ self . clearUnusedBits ( )
709+ }
710+
711+ /// Sets the bit at the given position to one.
712+ ///
713+ /// - Parameters:
714+ /// - position: The position of the bit to set.
715+ public mutating func setBit( at position: Int ) {
716+ precondition ( 0 <= position)
717+ precondition ( position < self . bitWidth)
718+ let mask : Word = ( 1 as Word ) << UInt64 ( position % bitsPerWord)
719+ switch self . value {
720+ case let . single( val) :
721+ self . value = . single( val | mask)
722+ case var . many( vals) :
723+ vals [ position % bitsPerWord] |= mask
724+ self . value = . many( vals)
725+ }
726+ }
727+
728+ /// Sets the sign bit to one in this value's binary representation.
729+ public mutating func setSignBit( ) {
730+ self . setBit ( at: self . bitWidth - 1 )
731+ }
732+
733+ /// Sets all bits in the given range to one in this value's binary
734+ /// representation.
735+ ///
736+ /// - Parameters:
737+ /// - range: The range of bits to flip.
738+ public mutating func setBits( _ range: ClosedRange < Int > ) {
739+ precondition ( range. upperBound <= self . bitWidth)
740+ precondition ( range. lowerBound <= self . bitWidth)
741+ precondition ( range. lowerBound <= range. upperBound)
742+ guard range. lowerBound != range. upperBound else {
743+ return
744+ }
745+
746+ var mask : Word = Word . max >> ( bitsPerWord - ( range. upperBound - range. lowerBound) )
747+ mask <<= range. lowerBound
748+ switch self . value {
749+ case let . single( val) :
750+ self . value = . single( val | mask)
751+ case var . many( vals) where range. lowerBound < bitsPerWord && range. upperBound <= bitsPerWord:
752+ vals [ 0 ] |= mask
753+ self . value = . many( vals)
754+ case var . many( vals) :
755+ let ( loWord, loShift) = range. lowerBound. quotientAndRemainder ( dividingBy: bitsPerWord)
756+ let ( hiWord, hiShift) = range. upperBound. quotientAndRemainder ( dividingBy: bitsPerWord)
757+
758+ // If hiBit is not aligned, we need a high mask.
759+ var loMask = Word . max << loShift
760+ if hiShift != 0 {
761+ let hiMask = Word . max >> ( bitsPerWord - hiShift)
762+ if hiWord == loWord {
763+ loMask &= hiMask
764+ } else {
765+ vals [ hiWord] |= hiMask
766+ }
767+ }
768+ vals [ loWord] |= loMask
769+
770+ // Fill any words between loWord and hiWord with all ones.
771+ if loWord < hiWord {
772+ for word in ( loWord + 1 ) ..< hiWord {
773+ vals [ word] = . max
774+ }
775+ }
776+
777+ self . value = . many( vals)
778+ }
779+ }
780+
781+ /// Sets all bits in the given range to one in this value's binary
782+ /// representation.
783+ ///
784+ /// - Parameters:
785+ /// - range: The range of bits to flip.
786+ public mutating func setBits( _ range: Range < Int > ) {
787+ self . setBits ( range. lowerBound... range. upperBound - 1 )
788+ }
789+
790+ /// Sets all bits in the given range to one in this value's binary
791+ /// representation.
792+ ///
793+ /// - Parameters:
794+ /// - range: The range of bits to flip.
795+ public mutating func setBits( _ range: PartialRangeUpTo < Int > ) {
796+ self . setBits ( 0 ... range. upperBound - 1 )
797+ }
798+
799+ /// Sets all bits in the given range to one in this value's binary
800+ /// representation.
801+ ///
802+ /// - Parameters:
803+ /// - range: The range of bits to flip.
804+ public mutating func setBits( _ range: PartialRangeThrough < Int > ) {
805+ self . setBits ( 0 ... range. upperBound)
806+ }
807+
808+ /// Sets all bits in the given range to one in this value's binary
809+ /// representation.
810+ ///
811+ /// - Parameters:
812+ /// - range: The range of bits to flip.
813+ public mutating func setBits( _ range: PartialRangeFrom < Int > ) {
814+ self . setBits ( range. lowerBound... self . bitWidth)
815+ }
816+
817+ /// Clears all bits to one in this value's binary representation.
818+ public mutating func clearAllBits( ) {
819+ switch self . value {
820+ case . single( _) :
821+ self . value = . single( 0 )
822+ case . many( _) :
823+ self . value = . many( [ Word] ( repeating: 0 , count: requiredWords ( for: self . bitWidth) ) )
824+ }
825+ }
826+
827+ /// Sets the bit at the given position to zero.
828+ ///
829+ /// - Parameters:
830+ /// - position: The position of the bit to zero.
831+ public mutating func clearBit( _ position: Int ) {
832+ precondition ( 0 <= position)
833+ precondition ( position < self . bitWidth)
834+ let mask : Word = ~ ( ( 1 as Word ) << UInt64 ( position % bitsPerWord) )
835+ switch self . value {
836+ case let . single( val) :
837+ self . value = . single( val | mask)
838+ case var . many( vals) :
839+ vals [ position % bitsPerWord] |= mask
840+ self . value = . many( vals)
841+ }
842+ }
843+
844+ /// Clears the sign bit in this value's binary representation.
845+ public mutating func clearSignBit( ) {
846+ self . clearBit ( self . bitWidth - 1 )
847+ }
848+ }
849+
647850/// MARK: Resizing Operations
648851
649852extension APInt {
0 commit comments