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};

Reply via email to