[PATCH 11/11] math: Use tanf from CORE-MATH

Adhemerval Zanella Netto adhemerval.zanella@linaro.org
Tue Nov 12 18:41:43 GMT 2024



On 12/11/24 10:17, Paul Zimmermann wrote:
>        Hi Adhemerval,
> 
> some typos and possible improvements (this is not a review since I am in
> the "Signed-off-by" fields):
> 
>> +  (src/binary32/tan/tanf.cc in CORE-MATH)
> 
> should be src/binary32/tan/tanf.c

Ack.

> 
>> +  - The code was adapted to use glibc code style and internal
>> +    functions to handle errno, overflow, and underflow.  It was changed
>> +    to use an internal wrapper for 128 bit unsigned integer operation
> 
> maybe "operations"?
>

Ack.

 
>> +/* Limited support for internal 128 bit integer, used on some math
>> +   implementations.  It uses compiler builtin type if supported, otherwise
>> +   it is emulate.  Only unsigned and some operations are currently supported:
> 
> emulate -> emulated
> 

Ack.

>> +
>> +   - u128_t:         the 128 bit unsigned type.
>> +   - u128_high:      return the high part of the number.
>> +   - u128_low:       return the low part of the number.
>> +   - u128_from_u64:  createa 128 bit number from a 64 bit one.
> 
> create a

Ack.

> 
>> +   - u128_mul:       multiple two 128 bit numbers.
> 
> multiply
> 

Ack.

>> +   - u128_add:       add two 128 bit numbers.
>> +   - u128_lshift:    left shift a number.
>> +   - u128_rshift:    right shift a number.
>> + */
>> +
>> +#ifdef __SIZEOF_INT128__
>> +typedef unsigned __int128 u128;
>> +# define u128_high(__x)         (uint64_t)((__x) >> 64)
>> +# define u128_low(__x)          (uint64_t)(__x)
>> +# define u128_from_u64(__x)     (u128)(__x)
>> +# define u128_mul(__x, __y)     (__x) * (__y)
>> +# define u128_add(__x, __y)     (__x) + (__y)
>> +# define u128_lshift(__x, __y)  (__x) << (__y)
>> +# define u128_rshift(__x, __y)  (__x) >> (__y)
>> +#else
>> +typedef struct
>> +{
>> +  uint64_t low;
>> +  uint64_t high;
>> +} u128;
>> +
>> +# define u128_high(__x)         (__x).high
>> +# define u128_low(__x)          (__x).low
>> +
>> +# define u128_from_u64(__x)     (u128){.low = (__x), .high = 0}
>> +
>> +# define TOPBIT                 (UINT64_C(1) << 63)
>> +# define MASK32                 (UINT64_C(0xffffffff))
>> +
>> +static u128 u128_add (u128 x, u128 y)
>> +{
>> +  uint64_t lower = (x.low & ~TOPBIT) + (y.low & ~TOPBIT);
>> +  bool carry = (lower >> 63) + (x.low >> 63) + (y.low >> 63) > 1;
>> +  return (u128) { .high = x.high + y.high + carry, .low = x.low + y.low };
> 
> why not simply the following?
> 
>     bool carry = x.low + y.low < x.low;
>     return (u128) { ... };

Because I forgot these are unsigned valued. Ack.

> 
>> +}
>> +
>> +static u128 u128_lshift (u128 x, unsigned int n)
>> +{
>> +  switch (n)
>> +    {
>> +    case 0:         return x;
>> +    case 1 ... 63:  return (u128) { .high = (x.high << n) | (x.low >> (64 - n)),
>> +				    .low = x.low << n };
>> +    case 64 ...127: return (u128) { .high = x.low << (n - 64), .low = 0};
>> +    default:        return (u128) { .high = 0, .low = 0 };
>> +    }
>> +}
>> +
>> +static u128 u128_rshift (u128 x, unsigned int n)
>> +{
>> +  switch (n)
>> +    {
>> +    case 0:         return x;
>> +    case 1 ... 63:  return (u128) { .high = x.high >> n,
>> +				    .low = (x.high << (64 - n)) | (x.low >> n) };
>> +    case 64 ...127: return (u128) { .high = 0, .low = x.high >> (n - 64) };
>> +    default:        return (u128) { .high = 0, .low = 0 };
>> +    }
>> +}
>> +
>> +static u128 u128_mul (u128 x, u128 y)
>> +{
>> +  if (x.high == 0 && y.high == 0)
>> +    {
>> +      uint64_t x0 = x.low & MASK32;
>> +      uint64_t x1 = x.low >> 32;
>> +      uint64_t y0 = y.low & MASK32;
>> +      uint64_t y1 = y.low >> 32;
>> +      u128 x0y0 = { .high = 0, .low = x0 * y0 };
>> +      u128 x0y1 = { .high = 0, .low = x0 * y1 };
>> +      u128 x1y0 = { .high = 0, .low = x1 * y0 };
>> +      u128 x1y1 = { .high = 0, .low = x1 * y1 };
>> +      /* x0y0 + ((x0y1 + x1y0) << 32) + (x1y1 << 64)  */
>> +      return u128_add (u128_add (x0y0, u128_lshift (u128_add (x0y1,
>> +							      x1y0),
>> +						    32)),
>> +		       u128_lshift (x1y1, 64));
> 
> maybe you can form x1y1 = { .high = x1 * y1, .low = 0 } to avoid the left
> shift of x1y1

Indeed, I will change it.

> 
> Paul



More information about the Libc-alpha mailing list