clang-format
This commit is contained in:
@@ -96,67 +96,64 @@
|
||||
*/
|
||||
static long long __lmulq(unsigned int, unsigned int);
|
||||
|
||||
long long
|
||||
__muldi3(long long a, long long b)
|
||||
{
|
||||
union uu u, v, low, prod;
|
||||
unsigned int high, mid, udiff, vdiff;
|
||||
int negall, negmid;
|
||||
#define u1 u.ui[H]
|
||||
#define u0 u.ui[L]
|
||||
#define v1 v.ui[H]
|
||||
#define v0 v.ui[L]
|
||||
long long __muldi3(long long a, long long b) {
|
||||
union uu u, v, low, prod;
|
||||
unsigned int high, mid, udiff, vdiff;
|
||||
int negall, negmid;
|
||||
#define u1 u.ui[H]
|
||||
#define u0 u.ui[L]
|
||||
#define v1 v.ui[H]
|
||||
#define v0 v.ui[L]
|
||||
|
||||
/*
|
||||
* Get u and v such that u, v >= 0. When this is finished,
|
||||
* u1, u0, v1, and v0 will be directly accessible through the
|
||||
* int fields.
|
||||
*/
|
||||
if (a >= 0)
|
||||
u.ll = a, negall = 0;
|
||||
else
|
||||
u.ll = -a, negall = 1;
|
||||
if (b >= 0)
|
||||
v.ll = b;
|
||||
else
|
||||
v.ll = -b, negall ^= 1;
|
||||
/*
|
||||
* Get u and v such that u, v >= 0. When this is finished,
|
||||
* u1, u0, v1, and v0 will be directly accessible through the
|
||||
* int fields.
|
||||
*/
|
||||
if (a >= 0)
|
||||
u.ll = a, negall = 0;
|
||||
else
|
||||
u.ll = -a, negall = 1;
|
||||
if (b >= 0)
|
||||
v.ll = b;
|
||||
else
|
||||
v.ll = -b, negall ^= 1;
|
||||
|
||||
if (u1 == 0 && v1 == 0) {
|
||||
/*
|
||||
* An (I hope) important optimization occurs when u1 and v1
|
||||
* are both 0. This should be common since most numbers
|
||||
* are small. Here the product is just u0*v0.
|
||||
*/
|
||||
prod.ll = __lmulq(u0, v0);
|
||||
} else {
|
||||
/*
|
||||
* Compute the three intermediate products, remembering
|
||||
* whether the middle term is negative. We can discard
|
||||
* any upper bits in high and mid, so we can use native
|
||||
* unsigned int * unsigned int => unsigned int arithmetic.
|
||||
*/
|
||||
low.ll = __lmulq(u0, v0);
|
||||
if (u1 == 0 && v1 == 0) {
|
||||
/*
|
||||
* An (I hope) important optimization occurs when u1 and v1
|
||||
* are both 0. This should be common since most numbers
|
||||
* are small. Here the product is just u0*v0.
|
||||
*/
|
||||
prod.ll = __lmulq(u0, v0);
|
||||
} else {
|
||||
/*
|
||||
* Compute the three intermediate products, remembering
|
||||
* whether the middle term is negative. We can discard
|
||||
* any upper bits in high and mid, so we can use native
|
||||
* unsigned int * unsigned int => unsigned int arithmetic.
|
||||
*/
|
||||
low.ll = __lmulq(u0, v0);
|
||||
|
||||
if (u1 >= u0)
|
||||
negmid = 0, udiff = u1 - u0;
|
||||
else
|
||||
negmid = 1, udiff = u0 - u1;
|
||||
if (v0 >= v1)
|
||||
vdiff = v0 - v1;
|
||||
else
|
||||
vdiff = v1 - v0, negmid ^= 1;
|
||||
mid = udiff * vdiff;
|
||||
if (u1 >= u0)
|
||||
negmid = 0, udiff = u1 - u0;
|
||||
else
|
||||
negmid = 1, udiff = u0 - u1;
|
||||
if (v0 >= v1)
|
||||
vdiff = v0 - v1;
|
||||
else
|
||||
vdiff = v1 - v0, negmid ^= 1;
|
||||
mid = udiff * vdiff;
|
||||
|
||||
high = u1 * v1;
|
||||
high = u1 * v1;
|
||||
|
||||
/*
|
||||
* Assemble the final product.
|
||||
*/
|
||||
prod.ui[H] = high + (negmid ? -mid : mid) + low.ui[L] +
|
||||
low.ui[H];
|
||||
prod.ui[L] = low.ui[L];
|
||||
}
|
||||
return (negall ? -prod.ll : prod.ll);
|
||||
/*
|
||||
* Assemble the final product.
|
||||
*/
|
||||
prod.ui[H] = high + (negmid ? -mid : mid) + low.ui[L] + low.ui[H];
|
||||
prod.ui[L] = low.ui[L];
|
||||
}
|
||||
return (negall ? -prod.ll : prod.ll);
|
||||
#undef u1
|
||||
#undef u0
|
||||
#undef v1
|
||||
@@ -180,62 +177,60 @@ __muldi3(long long a, long long b)
|
||||
*
|
||||
* splits into high and low ints as HHALF(l) and LHUP(l) respectively.
|
||||
*/
|
||||
static long long
|
||||
__lmulq(unsigned int u, unsigned int v)
|
||||
{
|
||||
unsigned int u1, u0, v1, v0, udiff, vdiff, high, mid, low;
|
||||
unsigned int prodh, prodl, was;
|
||||
union uu prod;
|
||||
int neg;
|
||||
static long long __lmulq(unsigned int u, unsigned int v) {
|
||||
unsigned int u1, u0, v1, v0, udiff, vdiff, high, mid, low;
|
||||
unsigned int prodh, prodl, was;
|
||||
union uu prod;
|
||||
int neg;
|
||||
|
||||
u1 = HHALF(u);
|
||||
u0 = LHALF(u);
|
||||
v1 = HHALF(v);
|
||||
v0 = LHALF(v);
|
||||
u1 = HHALF(u);
|
||||
u0 = LHALF(u);
|
||||
v1 = HHALF(v);
|
||||
v0 = LHALF(v);
|
||||
|
||||
low = u0 * v0;
|
||||
low = u0 * v0;
|
||||
|
||||
/* This is the same small-number optimization as before. */
|
||||
if (u1 == 0 && v1 == 0)
|
||||
return (low);
|
||||
/* This is the same small-number optimization as before. */
|
||||
if (u1 == 0 && v1 == 0)
|
||||
return (low);
|
||||
|
||||
if (u1 >= u0)
|
||||
udiff = u1 - u0, neg = 0;
|
||||
else
|
||||
udiff = u0 - u1, neg = 1;
|
||||
if (v0 >= v1)
|
||||
vdiff = v0 - v1;
|
||||
else
|
||||
vdiff = v1 - v0, neg ^= 1;
|
||||
mid = udiff * vdiff;
|
||||
if (u1 >= u0)
|
||||
udiff = u1 - u0, neg = 0;
|
||||
else
|
||||
udiff = u0 - u1, neg = 1;
|
||||
if (v0 >= v1)
|
||||
vdiff = v0 - v1;
|
||||
else
|
||||
vdiff = v1 - v0, neg ^= 1;
|
||||
mid = udiff * vdiff;
|
||||
|
||||
high = u1 * v1;
|
||||
high = u1 * v1;
|
||||
|
||||
/* prod = (high << 2N) + (high << N); */
|
||||
prodh = high + HHALF(high);
|
||||
prodl = LHUP(high);
|
||||
/* prod = (high << 2N) + (high << N); */
|
||||
prodh = high + HHALF(high);
|
||||
prodl = LHUP(high);
|
||||
|
||||
/* if (neg) prod -= mid << N; else prod += mid << N; */
|
||||
if (neg) {
|
||||
was = prodl;
|
||||
prodl -= LHUP(mid);
|
||||
prodh -= HHALF(mid) + (prodl > was);
|
||||
} else {
|
||||
was = prodl;
|
||||
prodl += LHUP(mid);
|
||||
prodh += HHALF(mid) + (prodl < was);
|
||||
}
|
||||
/* if (neg) prod -= mid << N; else prod += mid << N; */
|
||||
if (neg) {
|
||||
was = prodl;
|
||||
prodl -= LHUP(mid);
|
||||
prodh -= HHALF(mid) + (prodl > was);
|
||||
} else {
|
||||
was = prodl;
|
||||
prodl += LHUP(mid);
|
||||
prodh += HHALF(mid) + (prodl < was);
|
||||
}
|
||||
|
||||
/* prod += low << N */
|
||||
was = prodl;
|
||||
prodl += LHUP(low);
|
||||
prodh += HHALF(low) + (prodl < was);
|
||||
/* ... + low; */
|
||||
if ((prodl += low) < low)
|
||||
prodh++;
|
||||
/* prod += low << N */
|
||||
was = prodl;
|
||||
prodl += LHUP(low);
|
||||
prodh += HHALF(low) + (prodl < was);
|
||||
/* ... + low; */
|
||||
if ((prodl += low) < low)
|
||||
prodh++;
|
||||
|
||||
/* return 4N-bit product */
|
||||
prod.ui[H] = prodh;
|
||||
prod.ui[L] = prodl;
|
||||
return (prod.ll);
|
||||
/* return 4N-bit product */
|
||||
prod.ui[H] = prodh;
|
||||
prod.ui[L] = prodl;
|
||||
return (prod.ll);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user