| ... | @@ -542,6 +542,36 @@ pub const Mutable = struct { | ... | @@ -542,6 +542,36 @@ pub const Mutable = struct { |
| 542 | rma.positive = (a.positive == b.positive); | 542 | rma.positive = (a.positive == b.positive); |
| 543 | } | 543 | } |
| 544 | | 544 | |
| | 545 | pub fn mulNoAliasWrap( |
| | 546 | rma: *Mutable, |
| | 547 | a: Const, |
| | 548 | b: Const, |
| | 549 | signedness: std.builtin.Signedness, |
| | 550 | bit_count: usize, |
| | 551 | ) void { |
| | 552 | assert(rma.limbs.ptr != a.limbs.ptr); // illegal aliasing |
| | 553 | assert(rma.limbs.ptr != b.limbs.ptr); // illegal aliasing |
| | 554 | |
| | 555 | const req_limbs = calcTwosCompLimbCount(bit_count); |
| | 556 | |
| | 557 | // We can ignore the upper bits here, those results will be discarded anyway. |
| | 558 | const a_limbs = a.limbs[0..math.min(req_limbs, a.limbs.len)]; |
| | 559 | const b_limbs = b.limbs[0..math.min(req_limbs, b.limbs.len)]; |
| | 560 | |
| | 561 | mem.set(Limb, rma.limbs[0..req_limbs], 0); |
| | 562 | |
| | 563 | if (a_limbs.len >= b_limbs.len) { |
| | 564 | llmulacc_lo(rma.limbs, a_limbs, b_limbs); |
| | 565 | } else { |
| | 566 | llmulacc_lo(rma.limbs, b_limbs, a_limbs); |
| | 567 | } |
| | 568 | |
| | 569 | rma.normalize(math.min(req_limbs, a.limbs.len + b.limbs.len)); |
| | 570 | rma.positive = (a.positive == b.positive); |
| | 571 | |
| | 572 | rma.truncate(rma.toConst(), signedness, bit_count); |
| | 573 | } |
| | 574 | |
| 545 | /// rma = a * a | 575 | /// rma = a * a |
| 546 | /// | 576 | /// |
| 547 | /// `rma` may not alias with `a`. | 577 | /// `rma` may not alias with `a`. |
| ... | @@ -2156,6 +2186,19 @@ pub const Managed = struct { | ... | @@ -2156,6 +2186,19 @@ pub const Managed = struct { |
| 2156 | } | 2186 | } |
| 2157 | }; | 2187 | }; |
| 2158 | | 2188 | |
| | 2189 | /// r = a * b, ignoring overflow |
| | 2190 | fn llmulacc_lo(r: []Limb, a: []const Limb, b: []const Limb) void { |
| | 2191 | assert(r.len >= a.len); |
| | 2192 | assert(a.len >= b.len); |
| | 2193 | |
| | 2194 | // TODO: Improve performance. |
| | 2195 | |
| | 2196 | var i: usize = 0; |
| | 2197 | while (i < b.len) : (i += 1) { |
| | 2198 | llmulDigit(r[i..], a, b[i]); |
| | 2199 | } |
| | 2200 | } |
| | 2201 | |
| 2159 | /// Knuth 4.3.1, Algorithm M. | 2202 | /// Knuth 4.3.1, Algorithm M. |
| 2160 | /// | 2203 | /// |
| 2161 | /// r MUST NOT alias any of a or b. | 2204 | /// r MUST NOT alias any of a or b. |