On 03/24/2011 10:29 AM, Peter Maydell wrote:
> On 24 March 2011 15:58, Alexander Graf <ag...@suse.de> wrote:
> 
> This is more random comments in passing than a thorough review; sorry.
> 
>> +#if HOST_LONG_BITS == 64 && defined(__GNUC__)
>> +        /* assuming 64-bit hosts have __uint128_t */
>> +        __uint128_t dividend = (((__uint128_t)env->regs[r1]) << 64) |
>> +                               (env->regs[r1+1]);
>> +        __uint128_t quotient = dividend / divisor;
>> +        env->regs[r1+1] = quotient;
>> +        __uint128_t remainder = dividend % divisor;
>> +        env->regs[r1] = remainder;
>> +#else
>> +        /* 32-bit hosts would need special wrapper functionality - just 
>> abort if
>> +           we encounter such a case; it's very unlikely anyways. */
>> +        cpu_abort(env, "128 -> 64/64 division not implemented\n");
>> +#endif
> 
> ...I'm still using a 32 bit system :-)

A couple of options:

(1) Steal code from gcc's __[u]divdi3 for implementing double-word division via
    single-word division.  In this case, your "single-word" will be long long.

(2) Implement a simple bit reduction loop.  This is probably easiest.

(3) Reuse some of the softfloat code that manipulates 128bit quantities.  This
    is probably the best option, particularly if the availability of __uint128
    is taught to softfloat so that it doesn't always open-code stuff that the
    compiler could take care of.


r~

Reply via email to