MCPcopy Create free account
hub / github.com/ablab/spades / magic

Method magic

ext/src/llvm/APInt.cpp:1224–1260  ·  view source on GitHub ↗

Calculate the magic numbers required to implement a signed integer division by a constant as a sequence of multiplies, adds and shifts. Requires that the divisor not be 0, 1, or -1. Taken from "Hacker's Delight", Henry S. Warren, Jr., chapter 10.

Source from the content-addressed store, hash-verified

1222/// the divisor not be 0, 1, or -1. Taken from "Hacker's Delight", Henry S.
1223/// Warren, Jr., chapter 10.
1224APInt::ms APInt::magic() const {
1225 const APInt& d = *this;
1226 unsigned p;
1227 APInt ad, anc, delta, q1, r1, q2, r2, t;
1228 APInt signedMin = APInt::getSignedMinValue(d.getBitWidth());
1229 struct ms mag;
1230
1231 ad = d.abs();
1232 t = signedMin + (d.lshr(d.getBitWidth() - 1));
1233 anc = t - 1 - t.urem(ad); // absolute value of nc
1234 p = d.getBitWidth() - 1; // initialize p
1235 q1 = signedMin.udiv(anc); // initialize q1 = 2p/abs(nc)
1236 r1 = signedMin - q1*anc; // initialize r1 = rem(2p,abs(nc))
1237 q2 = signedMin.udiv(ad); // initialize q2 = 2p/abs(d)
1238 r2 = signedMin - q2*ad; // initialize r2 = rem(2p,abs(d))
1239 do {
1240 p = p + 1;
1241 q1 = q1<<1; // update q1 = 2p/abs(nc)
1242 r1 = r1<<1; // update r1 = rem(2p/abs(nc))
1243 if (r1.uge(anc)) { // must be unsigned comparison
1244 q1 = q1 + 1;
1245 r1 = r1 - anc;
1246 }
1247 q2 = q2<<1; // update q2 = 2p/abs(d)
1248 r2 = r2<<1; // update r2 = rem(2p/abs(d))
1249 if (r2.uge(ad)) { // must be unsigned comparison
1250 q2 = q2 + 1;
1251 r2 = r2 - ad;
1252 }
1253 delta = ad - r2;
1254 } while (q1.ult(delta) || (q1 == delta && r1 == 0));
1255
1256 mag.m = q2 + 1;
1257 if (d.isNegative()) mag.m = -mag.m; // resulting magic number
1258 mag.s = p - d.getBitWidth(); // resulting shift
1259 return mag;
1260}
1261
1262/// Calculate the magic numbers required to implement an unsigned integer
1263/// division by a constant as a sequence of multiplies, adds and shifts.

Callers

nothing calls this directly

Calls 4

getSignedMinValueFunction · 0.85
uremMethod · 0.80
udivMethod · 0.80
isNegativeMethod · 0.45

Tested by

no test coverage detected