https://gcc.gnu.org/bugzilla/show_bug.cgi?id=111209
--- Comment #5 from cqwrteur <unlvsur at live dot com> ---
(In reply to Jakub Jelinek from comment #4)
> (In reply to cqwrteur from comment #3)
> > (In reply to Jakub Jelinek from comment #1)
> > > Just use __int128 addition if all you want is double-word addition (or
> > > long
> > > long for 32-bit arches)?
> >
> > Well, I've presented this merely as an illustrative example. The length can
> > actually be arbitrary.
>
> No, it was working with all the other lengths.
This might come across as unusual. I frequently engage in manipulations
involving the carry flag.
like this implementation for 128 bit division (for 32 bit machine and Microsoft
compiler)
auto shift = static_cast<unsigned>(::std::countl_zero(divisorhigh) -
::std::countl_zero(dividendhigh));
divisorhigh =
::fast_io::intrinsics::shiftleft(divisorlow,divisorhigh,shift);
divisorlow <<= shift;
quotientlow = 0;
bool carry;
do
{
carry=0;
dividendlow=intrinsics::subc(dividendlow,divisorlow,carry,carry);
dividendhigh=intrinsics::subc(dividendhigh,divisorhigh,carry,carry);
constexpr T zero{};
T mask{zero-carry};
T templow{divisorlow&mask},temphigh{divisorhigh&mask};
carry=!carry;
quotientlow=intrinsics::addc(quotientlow,quotientlow,carry,carry);
carry=0;
dividendlow=intrinsics::addc(dividendlow,templow,carry,carry);
dividendhigh=intrinsics::addc(dividendhigh,temphigh,carry,carry);
divisorlow = intrinsics::shiftright(divisorlow,divisorhigh,1u);
divisorhigh >>= 1u;
}
while(shift--);
return {quotientlow,0,dividendlow,dividendhigh};