Don't take short cuts trying to avoid conditionals. This leads to

negative shift amounts and/or shifts wider than the type. VAX traps on
the former, X86 and other platforms produce incorrect results on the
latter.

llvm-svn: 204193
This commit is contained in:
Joerg Sonnenberger 2014-03-18 22:10:36 +00:00
parent 319026d148
commit 4e08a634e1
2 changed files with 73 additions and 111 deletions

View File

@ -143,43 +143,29 @@ __udivmoddi4(du_int a, du_int b, du_int* rem)
/* 2 <= sr <= n_udword_bits - 1 /* 2 <= sr <= n_udword_bits - 1
* q.all = n.all << (n_udword_bits - sr); * q.all = n.all << (n_udword_bits - sr);
* r.all = n.all >> sr; * r.all = n.all >> sr;
* if (sr == n_uword_bits)
* {
* q.s.low = 0;
* q.s.high = n.s.low;
* r.s.high = 0;
* r.s.low = n.s.high;
* }
* else if (sr < n_uword_bits) // 2 <= sr <= n_uword_bits - 1
* {
* q.s.low = 0;
* q.s.high = n.s.low << (n_uword_bits - sr);
* r.s.high = n.s.high >> sr;
* r.s.low = (n.s.high << (n_uword_bits - sr)) | (n.s.low >> sr);
* }
* else // n_uword_bits + 1 <= sr <= n_udword_bits - 1
* {
* q.s.low = n.s.low << (n_udword_bits - sr);
* q.s.high = (n.s.high << (n_udword_bits - sr)) |
* (n.s.low >> (sr - n_uword_bits));
* r.s.high = 0;
* r.s.low = n.s.high >> (sr - n_uword_bits);
* }
*/ */
q.s.low = (n.s.low << (n_udword_bits - sr)) & if (sr == n_uword_bits)
((si_int)(n_uword_bits - sr) >> (n_uword_bits-1)); {
q.s.high = ((n.s.low << ( n_uword_bits - sr)) & q.s.low = 0;
((si_int)(sr - n_uword_bits - 1) >> (n_uword_bits-1))) | q.s.high = n.s.low;
(((n.s.high << (n_udword_bits - sr)) | r.s.high = 0;
(n.s.low >> (sr - n_uword_bits))) & r.s.low = n.s.high;
((si_int)(n_uword_bits - sr) >> (n_uword_bits-1))); }
r.s.high = (n.s.high >> sr) & else if (sr < n_uword_bits) // 2 <= sr <= n_uword_bits - 1
((si_int)(sr - n_uword_bits) >> (n_uword_bits-1)); {
r.s.low = ((n.s.high >> (sr - n_uword_bits)) & q.s.low = 0;
((si_int)(n_uword_bits - sr - 1) >> (n_uword_bits-1))) | q.s.high = n.s.low << (n_uword_bits - sr);
(((n.s.high << (n_uword_bits - sr)) | r.s.high = n.s.high >> sr;
(n.s.low >> sr)) & r.s.low = (n.s.high << (n_uword_bits - sr)) | (n.s.low >> sr);
((si_int)(sr - n_uword_bits) >> (n_uword_bits-1))); }
else // n_uword_bits + 1 <= sr <= n_udword_bits - 1
{
q.s.low = n.s.low << (n_udword_bits - sr);
q.s.high = (n.s.high << (n_udword_bits - sr)) |
(n.s.low >> (sr - n_uword_bits));
r.s.high = 0;
r.s.low = n.s.high >> (sr - n_uword_bits);
}
} }
else else
{ {
@ -191,7 +177,7 @@ __udivmoddi4(du_int a, du_int b, du_int* rem)
/* 0 <= sr <= n_uword_bits - 1 or sr large */ /* 0 <= sr <= n_uword_bits - 1 or sr large */
if (sr > n_uword_bits - 1) if (sr > n_uword_bits - 1)
{ {
if (rem) if (rem)
*rem = n.all; *rem = n.all;
return 0; return 0;
} }
@ -199,24 +185,18 @@ __udivmoddi4(du_int a, du_int b, du_int* rem)
/* 1 <= sr <= n_uword_bits */ /* 1 <= sr <= n_uword_bits */
/* q.all = n.all << (n_udword_bits - sr); */ /* q.all = n.all << (n_udword_bits - sr); */
q.s.low = 0; q.s.low = 0;
q.s.high = n.s.low << (n_uword_bits - sr); if (sr == n_uword_bits)
/* r.all = n.all >> sr; {
* if (sr < n_uword_bits) q.s.high = n.s.low;
* { r.s.high = 0;
* r.s.high = n.s.high >> sr; r.s.low = n.s.high;
* r.s.low = (n.s.high << (n_uword_bits - sr)) | (n.s.low >> sr); }
* } else
* else {
* { q.s.high = n.s.low << (n_uword_bits - sr);
* r.s.high = 0; r.s.high = n.s.high >> sr;
* r.s.low = n.s.high; r.s.low = (n.s.high << (n_uword_bits - sr)) | (n.s.low >> sr);
* } }
*/
r.s.high = (n.s.high >> sr) &
((si_int)(sr - n_uword_bits) >> (n_uword_bits-1));
r.s.low = (n.s.high << (n_uword_bits - sr)) |
((n.s.low >> sr) &
((si_int)(sr - n_uword_bits) >> (n_uword_bits-1)));
} }
} }
/* Not a special case /* Not a special case

View File

@ -146,43 +146,29 @@ __udivmodti4(tu_int a, tu_int b, tu_int* rem)
/* 2 <= sr <= n_utword_bits - 1 /* 2 <= sr <= n_utword_bits - 1
* q.all = n.all << (n_utword_bits - sr); * q.all = n.all << (n_utword_bits - sr);
* r.all = n.all >> sr; * r.all = n.all >> sr;
* if (sr == n_udword_bits)
* {
* q.s.low = 0;
* q.s.high = n.s.low;
* r.s.high = 0;
* r.s.low = n.s.high;
* }
* else if (sr < n_udword_bits) // 2 <= sr <= n_udword_bits - 1
* {
* q.s.low = 0;
* q.s.high = n.s.low << (n_udword_bits - sr);
* r.s.high = n.s.high >> sr;
* r.s.low = (n.s.high << (n_udword_bits - sr)) | (n.s.low >> sr);
* }
* else // n_udword_bits + 1 <= sr <= n_utword_bits - 1
* {
* q.s.low = n.s.low << (n_utword_bits - sr);
* q.s.high = (n.s.high << (n_utword_bits - sr)) |
* (n.s.low >> (sr - n_udword_bits));
* r.s.high = 0;
* r.s.low = n.s.high >> (sr - n_udword_bits);
* }
*/ */
q.s.low = (n.s.low << (n_utword_bits - sr)) & if (sr == n_udword_bits)
((di_int)(int)(n_udword_bits - sr) >> (n_udword_bits-1)); {
q.s.high = ((n.s.low << ( n_udword_bits - sr)) & q.s.low = 0;
((di_int)(int)(sr - n_udword_bits - 1) >> (n_udword_bits-1))) | q.s.high = n.s.low;
(((n.s.high << (n_utword_bits - sr)) | r.s.high = 0;
(n.s.low >> (sr - n_udword_bits))) & r.s.low = n.s.high;
((di_int)(int)(n_udword_bits - sr) >> (n_udword_bits-1))); }
r.s.high = (n.s.high >> sr) & else if (sr < n_udword_bits) // 2 <= sr <= n_udword_bits - 1
((di_int)(int)(sr - n_udword_bits) >> (n_udword_bits-1)); {
r.s.low = ((n.s.high >> (sr - n_udword_bits)) & q.s.low = 0;
((di_int)(int)(n_udword_bits - sr - 1) >> (n_udword_bits-1))) | q.s.high = n.s.low << (n_udword_bits - sr);
(((n.s.high << (n_udword_bits - sr)) | r.s.high = n.s.high >> sr;
(n.s.low >> sr)) & r.s.low = (n.s.high << (n_udword_bits - sr)) | (n.s.low >> sr);
((di_int)(int)(sr - n_udword_bits) >> (n_udword_bits-1))); }
else // n_udword_bits + 1 <= sr <= n_utword_bits - 1
{
q.s.low = n.s.low << (n_utword_bits - sr);
q.s.high = (n.s.high << (n_utword_bits - sr)) |
(n.s.low >> (sr - n_udword_bits));
r.s.high = 0;
r.s.low = n.s.high >> (sr - n_udword_bits);
}
} }
else else
{ {
@ -199,27 +185,23 @@ __udivmodti4(tu_int a, tu_int b, tu_int* rem)
return 0; return 0;
} }
++sr; ++sr;
/* 1 <= sr <= n_udword_bits */ /* 1 <= sr <= n_udword_bits
/* q.all = n.all << (n_utword_bits - sr); */ * q.all = n.all << (n_utword_bits - sr);
q.s.low = 0; * r.all = n.all >> sr;
q.s.high = n.s.low << (n_udword_bits - sr);
/* r.all = n.all >> sr;
* if (sr < n_udword_bits)
* {
* r.s.high = n.s.high >> sr;
* r.s.low = (n.s.high << (n_udword_bits - sr)) | (n.s.low >> sr);
* }
* else
* {
* r.s.high = 0;
* r.s.low = n.s.high;
* }
*/ */
r.s.high = (n.s.high >> sr) & q.s.low = 0;
((di_int)(int)(sr - n_udword_bits) >> (n_udword_bits-1)); if (sr == n_udword_bits)
r.s.low = (n.s.high << (n_udword_bits - sr)) | {
((n.s.low >> sr) & q.s.high = n.s.low;
((di_int)(int)(sr - n_udword_bits) >> (n_udword_bits-1))); r.s.high = 0;
r.s.low = n.s.high;
}
else
{
r.s.high = n.s.high >> sr;
r.s.low = (n.s.high << (n_udword_bits - sr)) | (n.s.low >> sr);
q.s.high = n.s.low << (n_udword_bits - sr);
}
} }
} }
/* Not a special case /* Not a special case