Skip to content

Commit 5236a37

Browse files
committed
Make some improvements to DoubleWidth.&<<= and &>>=
1 parent cf179da commit 5236a37

File tree

1 file changed

+27
-33
lines changed

1 file changed

+27
-33
lines changed

stdlib/public/core/DoubleWidth.swift.gyb

Lines changed: 27 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -454,13 +454,7 @@ extension DoubleWidth : FixedWidthInteger {
454454
lhs = 0
455455
return
456456
}
457-
458-
// Shift is exactly the bit width of `Base`.
459-
if rhs._storage.low == Base.bitWidth {
460-
lhs = DoubleWidth((High(truncatingIfNeeded: lhs._storage.low), 0))
461-
return
462-
}
463-
457+
464458
lhs &<<= rhs
465459
}
466460

@@ -478,48 +472,48 @@ extension DoubleWidth : FixedWidthInteger {
478472
lhs = lhs < (0 as DoubleWidth) ? ~0 : 0
479473
return
480474
}
481-
482-
// Shift is exactly the bit width of `Base`.
483-
if rhs._storage.low == Base.bitWidth {
484-
lhs = DoubleWidth((
485-
lhs < (0 as DoubleWidth) ? ~0 : 0,
486-
Low(truncatingIfNeeded: lhs._storage.high)))
487-
return
488-
}
489475

490476
lhs &>>= rhs
491477
}
492478

493479
@_inlineable // FIXME(sil-serialize-all)
494480
public static func &<<=(lhs: inout DoubleWidth, rhs: DoubleWidth) {
495-
// We need to use smart shifts since rhs can be greater than Base.bitWidth.
496481
let rhs = rhs & DoubleWidth(DoubleWidth.bitWidth &- 1)
497482

498-
// If Base.bitWidth >= 4, then rhs == High(rhs._storage.low).
499-
lhs._storage.high <<= High(rhs._storage.low)
500-
501-
let lowInHigh = Base.bitWidth > rhs._storage.low
502-
? lhs._storage.low >> (Low(Base.bitWidth) &- rhs._storage.low)
503-
: lhs._storage.low << (rhs._storage.low &- Low(Base.bitWidth))
504-
lhs._storage.high |= High(truncatingIfNeeded: lowInHigh)
483+
guard rhs._storage.low < Base.bitWidth else {
484+
lhs._storage.high = High(
485+
truncatingIfNeeded: lhs._storage.low &<<
486+
(rhs._storage.low &- Low(Base.bitWidth)))
487+
lhs._storage.low = 0
488+
return
489+
}
505490

506-
lhs._storage.low <<= rhs._storage.low
491+
guard rhs._storage.low != (0 as Low) else { return }
492+
lhs._storage.high &<<= High(rhs._storage.low)
493+
lhs._storage.high |= High(
494+
truncatingIfNeeded: lhs._storage.low &>>
495+
(Low(Base.bitWidth) &- rhs._storage.low))
496+
lhs._storage.low &<<= rhs._storage.low
507497
}
508498

509499
@_inlineable // FIXME(sil-serialize-all)
510500
public static func &>>=(lhs: inout DoubleWidth, rhs: DoubleWidth) {
511-
// We need to use smart shifts since rhs can be greater than Base.bitWidth.
512501
let rhs = rhs & DoubleWidth(DoubleWidth.bitWidth &- 1)
513502

514-
lhs._storage.low >>= rhs._storage.low
515-
516-
// If Base.bitWidth >= 4, then rhs == High(rhs._storage.low).
517-
let highInLow = Base.bitWidth > rhs._storage.low
518-
? lhs._storage.high << (High(Base.bitWidth) &- High(rhs._storage.low))
519-
: lhs._storage.high >> (High(rhs._storage.low) &- High(Base.bitWidth))
520-
lhs._storage.low |= Low(truncatingIfNeeded: highInLow)
503+
guard rhs._storage.low < Base.bitWidth else {
504+
lhs._storage.low = Low(
505+
truncatingIfNeeded: lhs._storage.high &>>
506+
High(rhs._storage.low &- Low(Base.bitWidth)))
507+
lhs._storage.high = lhs._storage.high < (0 as High) ? ~0 : 0
508+
return
509+
}
521510

522-
lhs._storage.high >>= High(rhs._storage.low)
511+
guard rhs._storage.low != (0 as Low) else { return }
512+
lhs._storage.low &>>= rhs._storage.low
513+
lhs._storage.low |= Low(
514+
truncatingIfNeeded: lhs._storage.high &<<
515+
High(Low(Base.bitWidth) &- rhs._storage.low))
516+
lhs._storage.high &>>= High(rhs._storage.low)
523517
}
524518

525519
%{

0 commit comments

Comments
 (0)