3755 lines
99 KiB
C
3755 lines
99 KiB
C
/**
|
|
* Part of the Lccrt Project, under the Apache License v2.0
|
|
* See http://www.apache.org/licenses/LICENSE-2.0.txt for license information.
|
|
* SPDX-License-Identifier: Apache-2.0
|
|
*/
|
|
|
|
#include "lccrt_s.h"
|
|
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
#include <stdarg.h>
|
|
#include <assert.h>
|
|
|
|
#define __LCCRT_SHIFT_LR( v, a) (((v) << (a)) >> (a))
|
|
#define __LCCRT_SEXT( v, bits) __LCCRT_SHIFT_LR( ( int64_t)(v), 64LL - (bits))
|
|
#define __LCCRT_ZEXT( v, bits) __LCCRT_SHIFT_LR( (uint64_t)(v), 64ULL - (bits))
|
|
#define __LCCRT_CMP( a, b) (((a) < (b)) ? (-1) : (((a) == (b)) ? 0 : 1))
|
|
|
|
#define __LCCRT_NUM_DIGITS( a, b, c) (((__LCCRT_MAX( a, __LCCRT_MAX( b, c))) + 31) / 32)
|
|
#define __LCCRT_NUM_DIGITS4( a, b, c, d) (((__LCCRT_MAX( __LCCRT_MAX( a, b), __LCCRT_MAX( c, d))) + 31) / 32)
|
|
|
|
#define __LCCRT_ALIGN_BITS_N( b) \
|
|
( \
|
|
((b) <= 8) ? 8 : (((b) <= 16) ? 16 : (((b) <= 32) ? 32 : (((b) + 63) & ~63ULL))) \
|
|
)
|
|
|
|
#define __LCCRT_CONV( dst, dst_type, src) \
|
|
{ \
|
|
dst_type conv_value = (dst_type)src; \
|
|
memcpy( dst, &conv_value, sizeof( conv_value)); \
|
|
}
|
|
|
|
#define __LCCRT_BIT_INDEX( bsize, aind, k) \
|
|
( \
|
|
((bsize) == 8) \
|
|
? ((uint8_t *)aind)[k] \
|
|
: (((bsize) == 16) \
|
|
? ((uint16_t *)aind)[k] \
|
|
: (((bsize) == 32) \
|
|
? ((uint32_t *)aind)[k] \
|
|
: ((uint64_t *)aind)[k])) \
|
|
)
|
|
|
|
typedef __lccrt_f32_t (*__lccrt_ffunc32_t)( __lccrt_f32_t, __lccrt_f32_t);
|
|
typedef __lccrt_f64_t (*__lccrt_ffunc64_t)( __lccrt_f64_t, __lccrt_f64_t);
|
|
typedef __lccrt_f80_t (*__lccrt_ffunc80_t)( __lccrt_f80_t, __lccrt_f80_t);
|
|
|
|
typedef __lccrt_f32_t (*__lccrt_ffunc32_3_t)( __lccrt_f32_t, __lccrt_f32_t, __lccrt_f32_t);
|
|
typedef __lccrt_f64_t (*__lccrt_ffunc64_3_t)( __lccrt_f64_t, __lccrt_f64_t, __lccrt_f64_t);
|
|
typedef __lccrt_f80_t (*__lccrt_ffunc80_3_t)( __lccrt_f80_t, __lccrt_f80_t, __lccrt_f80_t);
|
|
|
|
typedef enum
|
|
{
|
|
A_LCCRT_CMP_EQ,
|
|
A_LCCRT_CMP_NE,
|
|
A_LCCRT_CMP_GT_I,
|
|
A_LCCRT_CMP_GE_I,
|
|
A_LCCRT_CMP_LT_I,
|
|
A_LCCRT_CMP_LE_I,
|
|
A_LCCRT_CMP_LT_U,
|
|
A_LCCRT_CMP_LE_U,
|
|
A_LCCRT_CMP_GT_U,
|
|
A_LCCRT_CMP_GE_U,
|
|
A_LCCRT_CMP_FO,
|
|
A_LCCRT_CMP_EQ_FO,
|
|
A_LCCRT_CMP_NE_FO,
|
|
A_LCCRT_CMP_LT_FO,
|
|
A_LCCRT_CMP_LE_FO,
|
|
A_LCCRT_CMP_GT_FO,
|
|
A_LCCRT_CMP_GE_FO,
|
|
A_LCCRT_CMP_FU,
|
|
A_LCCRT_CMP_EQ_FU,
|
|
A_LCCRT_CMP_NE_FU,
|
|
A_LCCRT_CMP_LT_FU,
|
|
A_LCCRT_CMP_LE_FU,
|
|
A_LCCRT_CMP_GT_FU,
|
|
A_LCCRT_CMP_GE_FU,
|
|
} __lccrt_cmp_type_t;
|
|
|
|
#if 0
|
|
static uint64_t
|
|
__lccrt_get_bits( uint64_t v, uint64_t lo, uint64_t hi)
|
|
{
|
|
uint64_t up = 63ULL - hi;
|
|
uint64_t r = (v << up) >> (lo + up);
|
|
|
|
return (r);
|
|
} /* __lccrt_get_bits */
|
|
|
|
static uint64_t
|
|
__lccrt_set_bits( uint64_t a, uint64_t lo, uint64_t hi, uint64_t v)
|
|
{
|
|
uint64_t ml = __lccrt_get_bits( ~0ULL, lo, hi);
|
|
uint64_t mh = ml << lo;
|
|
uint64_t r = (a & ~mh) | ((v << lo) & mh);
|
|
|
|
return (r);
|
|
} /* __lccrt_set_bits */
|
|
#endif
|
|
|
|
static void
|
|
__lccrt_zn_set_bits( uint32_t num_digits, int is_sign, uint32_t *za, uint32_t bb, uint8_t *b)
|
|
{
|
|
uint8_t *a = (uint8_t *)za;
|
|
|
|
if ( (bb == 0) )
|
|
{
|
|
memset( a, 0, 4*num_digits);
|
|
|
|
} else if ( (32*num_digits <= bb) )
|
|
{
|
|
memcpy( a, b, 4*num_digits);
|
|
} else
|
|
{
|
|
uint8_t sn = 0;
|
|
int bytes = (bb + 7) / 8;
|
|
int digits = (bb + 31) / 32;
|
|
|
|
memcpy( a, b, bytes);
|
|
if ( (bb % 32 != 0) )
|
|
{
|
|
if ( is_sign )
|
|
{
|
|
za[digits-1] = __LCCRT_SEXT( za[digits-1], bb % 32);
|
|
} else
|
|
{
|
|
za[digits-1] = __LCCRT_ZEXT( za[digits-1], bb % 32);
|
|
}
|
|
}
|
|
|
|
if ( (digits < num_digits) )
|
|
{
|
|
if ( is_sign )
|
|
{
|
|
sn = (int32_t)za[digits-1] >> 31;
|
|
}
|
|
|
|
memset( a + 4*digits, sn, 4*(num_digits - digits));
|
|
}
|
|
}
|
|
|
|
return;
|
|
} /* __lccrt_zn_set_bits */
|
|
|
|
static void
|
|
__lccrt_zn_get_bits( uint32_t num_digits, uint32_t *za, uint32_t bb, uint8_t *b)
|
|
{
|
|
uint8_t *a = (uint8_t *)za;
|
|
uint32_t ab = __LCCRT_MIN( 32*num_digits, bb);
|
|
uint32_t abytes_part = ab / 8;
|
|
uint32_t abytes = (ab + 7) / 8;
|
|
uint32_t bbytes = (bb + 7) / 8;
|
|
|
|
memcpy( b, a, abytes_part);
|
|
if ( (abytes_part < abytes) )
|
|
{
|
|
b[abytes_part] = __LCCRT_ZEXT( a[abytes_part], ab - 8*abytes_part);
|
|
}
|
|
|
|
if ( (abytes < bbytes) )
|
|
{
|
|
memset( b + abytes, 0, bbytes - abytes);
|
|
}
|
|
|
|
return;
|
|
} /* __lccrt_zn_get_bits */
|
|
|
|
static void
|
|
__lccrt_zn_abs( uint32_t num_digits, uint32_t *zr, uint32_t * __restrict za, int *is_overflow)
|
|
{
|
|
int i, j;
|
|
uint32_t zc[num_digits];
|
|
|
|
memset( zc, 0, num_digits*sizeof( zc[0]));
|
|
|
|
if ( (num_digits == 1) )
|
|
{
|
|
zc[0] = ((int32_t)za[0] >= (int32_t)0) ? (int32_t)za[0] : -(int32_t)za[0];
|
|
|
|
} else if ( (num_digits == 2) )
|
|
{
|
|
uint64_t bits = 32;
|
|
uint64_t va = ((uint64_t)za[1] << bits) | za[0];
|
|
uint64_t vc = ((int64_t)va >= (int64_t)0) ? (int64_t)va : -(int64_t)va;
|
|
|
|
zc[0] = (uint32_t)vc;
|
|
zc[1] = vc >> bits;
|
|
} else
|
|
{
|
|
assert( 0);
|
|
}
|
|
|
|
memcpy( zr, zc, num_digits*sizeof( zc[0]));
|
|
|
|
return;
|
|
} /* __lccrt_zn_abs */
|
|
|
|
static int
|
|
__lccrt_zn_cmp( uint32_t num_digits, uint32_t *za, uint32_t *zb)
|
|
{
|
|
int i;
|
|
int r = 0;
|
|
|
|
for ( i = num_digits - 1; (i >= 0) && (r == 0); --i )
|
|
{
|
|
if ( (za[i] < zb[i]) )
|
|
{
|
|
r = -1;
|
|
|
|
} else if ( (za[i] > zb[i]) )
|
|
{
|
|
r = 1;
|
|
}
|
|
}
|
|
|
|
return (r);
|
|
} /* __lccrt_zn_cmp */
|
|
|
|
static int
|
|
__lccrt_zn_cmp_signed( uint32_t num_digits, uint32_t *za, uint32_t *zb)
|
|
{
|
|
int i;
|
|
int r = 0;
|
|
|
|
if ( (num_digits > 0) )
|
|
{
|
|
int32_t va = za[num_digits - 1];
|
|
int32_t vb = zb[num_digits - 1];
|
|
|
|
if ( (va < 0) && (vb >= 0) )
|
|
{
|
|
r = -1;
|
|
|
|
} else if ( (va >= 0) && (vb < 0) )
|
|
{
|
|
r = 1;
|
|
} else
|
|
{
|
|
int q = __lccrt_zn_cmp( num_digits, za, zb);
|
|
|
|
if ( (va < 0) && (vb < 0) )
|
|
{
|
|
r = q;
|
|
|
|
} else if ( (va >= 0) && (vb >= 0) )
|
|
{
|
|
r = q;
|
|
} else
|
|
{
|
|
assert( 0);
|
|
}
|
|
}
|
|
}
|
|
|
|
return (r);
|
|
} /* __lccrt_zn_cmp_signed */
|
|
|
|
static void
|
|
__lccrt_zn_sar( uint32_t num_digits, uint32_t *zr, uint32_t * __restrict za, uint32_t * __restrict zb, int *is_overflow)
|
|
{
|
|
int i;
|
|
uint32_t zc[num_digits];
|
|
uint32_t w = zb[0];
|
|
int is_long = 0;
|
|
int digit_bits = 8*sizeof( zc[0]);
|
|
uint32_t sn = (int32_t)za[num_digits - 1] >> (digit_bits - 1);
|
|
|
|
for ( i = 1; i < num_digits; ++i )
|
|
{
|
|
if ( zb[i] )
|
|
{
|
|
is_long = 1;
|
|
break;
|
|
}
|
|
}
|
|
|
|
if ( (w >= num_digits*8*sizeof( zr[0])) )
|
|
{
|
|
is_long = 1;
|
|
}
|
|
|
|
if ( is_long )
|
|
{
|
|
/* Величина сдвига превышает или равна полному количеству битов, поэтому
|
|
просто заполняем все цифры знаком. */
|
|
for ( i = 0; i < num_digits; ++i )
|
|
{
|
|
zr[i] = sn;
|
|
}
|
|
} else
|
|
{
|
|
int digit_shift = w / digit_bits;
|
|
int lo_bits = w % digit_bits;
|
|
int hi_bits = digit_bits - lo_bits;
|
|
uint32_t lo = (lo_bits > 0) ? (sn << hi_bits) : 0;
|
|
|
|
/* Сначала сдвигаем на остаток по модулю количества бит в цифре. */
|
|
for ( i = num_digits-1; i >= 0; i-- )
|
|
{
|
|
zc[i] = lo | (za[i] >> lo_bits);
|
|
lo = (lo_bits > 0) ? (za[i] << hi_bits) : 0;
|
|
}
|
|
|
|
/* Теперь сдвигаем на оставшуюся часть, уже кратную количеству бит в цифре. */
|
|
for ( i = 0; i + digit_shift < num_digits ; ++i )
|
|
{
|
|
zr[i] = zc[i + digit_shift];
|
|
}
|
|
|
|
/* Заполняем старшие цифры знаком. */
|
|
for ( i = num_digits - digit_shift; i < num_digits; ++i )
|
|
{
|
|
zr[i] = sn;
|
|
}
|
|
}
|
|
|
|
return;
|
|
} /* __lccrt_zn_sar */
|
|
|
|
static void
|
|
__lccrt_zn_shl( uint32_t num_digits, uint32_t *zr, uint32_t * __restrict za, uint32_t * __restrict zb)
|
|
{
|
|
int i;
|
|
uint32_t x, y;
|
|
uint32_t zc[num_digits];
|
|
uint32_t num_bits = 32*num_digits;
|
|
uint32_t bit_shift = zb[0] % num_bits;
|
|
uint32_t shift0 = bit_shift % 32;
|
|
uint32_t dig_shift = bit_shift / 32;
|
|
|
|
memset( zc, 0, 4*dig_shift);
|
|
memcpy( zc + dig_shift, za, 4*(num_digits - dig_shift));
|
|
|
|
if ( (shift0 > 0) )
|
|
{
|
|
x = 0;
|
|
for ( i = dig_shift; i < num_digits; ++i )
|
|
{
|
|
y = zc[i];
|
|
zc[i] = (y << shift0) | x;
|
|
x = y >> (32 - shift0);
|
|
}
|
|
}
|
|
|
|
memcpy( zr, zc, num_digits*sizeof( zc[0]));
|
|
|
|
return;
|
|
} /* __lccrt_zn_shl */
|
|
|
|
static void
|
|
__lccrt_zn_shr( uint32_t num_digits, uint32_t *zr, uint32_t * __restrict za, uint32_t * __restrict zb)
|
|
{
|
|
int i;
|
|
uint32_t x, y;
|
|
uint32_t zc[num_digits];
|
|
uint32_t num_bits = 32*num_digits;
|
|
uint32_t bit_shift = zb[0] % num_bits;
|
|
uint32_t shift0 = bit_shift % 32;
|
|
uint32_t dig_shift = bit_shift / 32;
|
|
|
|
memset( zc + (num_digits - dig_shift), 0, 4*dig_shift);
|
|
memcpy( zc, za + dig_shift, 4*(num_digits - dig_shift));
|
|
|
|
if ( (shift0 > 0) )
|
|
{
|
|
x = 0;
|
|
for ( i = num_digits - 1; i >= (int)dig_shift; --i )
|
|
{
|
|
y = zc[i];
|
|
zc[i] = (y >> shift0) | x;
|
|
x = y << (32 - shift0);
|
|
}
|
|
}
|
|
|
|
memcpy( zr, zc, num_digits*sizeof( zc[0]));
|
|
|
|
return;
|
|
} /* __lccrt_zn_shr */
|
|
|
|
static void
|
|
__lccrt_zn_ior( uint32_t num_digits, uint32_t *zr, uint32_t * __restrict za, uint32_t * __restrict zb)
|
|
{
|
|
int i;
|
|
uint32_t zc[num_digits];
|
|
|
|
for ( i = 0; i < num_digits; ++i )
|
|
{
|
|
zc[i] = za[i] | zb[i];
|
|
}
|
|
|
|
memcpy( zr, zc, num_digits*sizeof( zc[0]));
|
|
|
|
return;
|
|
} /* __lccrt_zn_ior */
|
|
|
|
static void
|
|
__lccrt_zn_add( uint32_t num_digits, uint32_t *zr, uint32_t * __restrict za, uint32_t * __restrict zb, int *is_overflow)
|
|
{
|
|
int i;
|
|
uint32_t zc[num_digits];
|
|
uint64_t carry = 0;
|
|
|
|
for ( i = 0; i < num_digits; ++i )
|
|
{
|
|
carry = (uint64_t)za[i] + (uint64_t)zb[i] + carry;
|
|
zc[i] = (uint32_t)carry;
|
|
carry = carry >> 32ULL;
|
|
}
|
|
|
|
if ( is_overflow )
|
|
{
|
|
is_overflow[0] = (carry != 0);
|
|
}
|
|
|
|
memcpy( zr, zc, num_digits*sizeof( zc[0]));
|
|
|
|
return;
|
|
} /* __lccrt_zn_add */
|
|
|
|
static void
|
|
__lccrt_zn_sub( uint32_t num_digits, uint32_t *zr, uint32_t * __restrict za, uint32_t * __restrict zb, int *is_overflow)
|
|
{
|
|
int i;
|
|
uint32_t zc[num_digits];
|
|
int flag = 0;
|
|
uint64_t carry = 1;
|
|
|
|
for ( i = 0; i < num_digits; ++i )
|
|
{
|
|
carry = (uint64_t)za[i] + (uint64_t)(zb[i] ^ 0xffffffff) + carry;
|
|
zc[i] = (uint32_t)carry;
|
|
carry = carry >> 32ULL;
|
|
}
|
|
|
|
if ( is_overflow )
|
|
{
|
|
is_overflow[0] = (__lccrt_zn_cmp( num_digits, za, zb) < 0);
|
|
}
|
|
|
|
memcpy( zr, zc, num_digits*sizeof( zc[0]));
|
|
|
|
return;
|
|
} /* __lccrt_zn_sub */
|
|
|
|
static void
|
|
__lccrt_zn_mul( uint32_t num_digits, uint32_t *zr, uint32_t * __restrict za, uint32_t * __restrict zb, int *is_overflow)
|
|
{
|
|
int i, j;
|
|
uint32_t zc[num_digits];
|
|
int flag = 0;
|
|
|
|
memset( zc, 0, num_digits*sizeof( zc[0]));
|
|
|
|
for ( j = 0; j < num_digits; ++j )
|
|
{
|
|
uint64_t carry = 0;
|
|
|
|
for ( i = 0; i < num_digits - j; ++i )
|
|
{
|
|
carry = ((uint64_t)za[i] * (uint64_t)zb[j]) + (uint64_t)zc[j + i] + carry;
|
|
zc[j + i] = (uint32_t)carry;
|
|
carry = carry >> 32ULL;
|
|
}
|
|
|
|
if ( carry )
|
|
{
|
|
flag = 1;
|
|
}
|
|
}
|
|
|
|
if ( is_overflow )
|
|
{
|
|
for ( j = 1; (j < num_digits) && (flag == 0); ++j )
|
|
{
|
|
if ( zb[j] )
|
|
{
|
|
for ( i = num_digits - j; (i < num_digits) && (flag == 0); ++i )
|
|
{
|
|
if ( za[i] )
|
|
{
|
|
flag = 1;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
is_overflow[0] = flag;
|
|
}
|
|
|
|
memcpy( zr, zc, num_digits*sizeof( zc[0]));
|
|
|
|
return;
|
|
} /* __lccrt_zn_mul */
|
|
|
|
static void
|
|
__lccrt_zn_udiv( uint32_t num_digits, uint32_t *zr, uint32_t * __restrict za, uint32_t * __restrict zb,
|
|
int *is_overflow)
|
|
{
|
|
int i, j;
|
|
uint32_t zc[num_digits];
|
|
|
|
memset( zc, 0, num_digits*sizeof( zc[0]));
|
|
|
|
if ( (num_digits == 1) )
|
|
{
|
|
zc[0] = za[0] / zb[0];
|
|
|
|
} else if ( (num_digits == 2) )
|
|
{
|
|
uint64_t bits = 32;
|
|
uint64_t va = ((uint64_t)za[1] << bits) | za[0];
|
|
uint64_t vb = ((uint64_t)zb[1] << bits) | zb[0];
|
|
uint64_t vc = va / vb;
|
|
|
|
zc[0] = (uint32_t)vc;
|
|
zc[1] = vc >> bits;
|
|
} else
|
|
{
|
|
assert( 0);
|
|
}
|
|
|
|
memcpy( zr, zc, num_digits*sizeof( zc[0]));
|
|
|
|
return;
|
|
} /* __lccrt_zn_udiv */
|
|
|
|
static void
|
|
__lccrt_zn_sdiv( uint32_t num_digits, uint32_t *zr, uint32_t * __restrict za, uint32_t * __restrict zb,
|
|
int *is_overflow)
|
|
{
|
|
int i, j;
|
|
uint32_t zc[num_digits];
|
|
|
|
memset( zc, 0, num_digits*sizeof( zc[0]));
|
|
|
|
if ( (num_digits == 1) )
|
|
{
|
|
zc[0] = (int32_t)za[0] / (int32_t)zb[0];
|
|
|
|
} else if ( (num_digits == 2) )
|
|
{
|
|
uint64_t bits = 32;
|
|
uint64_t va = ((uint64_t)za[1] << bits) | za[0];
|
|
uint64_t vb = ((uint64_t)zb[1] << bits) | zb[0];
|
|
uint64_t vc = (int64_t)va / (int64_t)vb;
|
|
|
|
zc[0] = (uint32_t)vc;
|
|
zc[1] = vc >> bits;
|
|
} else
|
|
{
|
|
assert( 0);
|
|
}
|
|
|
|
memcpy( zr, zc, num_digits*sizeof( zc[0]));
|
|
|
|
return;
|
|
} /* __lccrt_zn_sdiv */
|
|
|
|
static void
|
|
__lccrt_zn_umod( uint32_t num_digits, uint32_t *zr, uint32_t * __restrict za, uint32_t * __restrict zb,
|
|
int *is_overflow)
|
|
{
|
|
int i, j;
|
|
uint32_t zc[num_digits];
|
|
|
|
memset( zc, 0, num_digits*sizeof( zc[0]));
|
|
|
|
if ( (num_digits == 1) )
|
|
{
|
|
zc[0] = za[0] / zb[0];
|
|
|
|
} else if ( (num_digits == 2) )
|
|
{
|
|
uint64_t bits = 32;
|
|
uint64_t va = ((uint64_t)za[1] << bits) | za[0];
|
|
uint64_t vb = ((uint64_t)zb[1] << bits) | zb[0];
|
|
uint64_t vc = va % vb;
|
|
|
|
zc[0] = (uint32_t)vc;
|
|
zc[1] = vc >> bits;
|
|
} else
|
|
{
|
|
assert( 0);
|
|
}
|
|
|
|
memcpy( zr, zc, num_digits*sizeof( zc[0]));
|
|
|
|
return;
|
|
} /* __lccrt_zn_umod */
|
|
|
|
static void
|
|
__lccrt_zn_smod( uint32_t num_digits, uint32_t *zr, uint32_t * __restrict za, uint32_t * __restrict zb,
|
|
int *is_overflow)
|
|
{
|
|
int i, j;
|
|
uint32_t zc[num_digits];
|
|
|
|
memset( zc, 0, num_digits*sizeof( zc[0]));
|
|
|
|
if ( (num_digits == 1) )
|
|
{
|
|
zc[0] = (int32_t)za[0] / (int32_t)zb[0];
|
|
|
|
} else if ( (num_digits == 2) )
|
|
{
|
|
uint64_t bits = 32;
|
|
uint64_t va = ((uint64_t)za[1] << bits) | za[0];
|
|
uint64_t vb = ((uint64_t)zb[1] << bits) | zb[0];
|
|
uint64_t vc = (int64_t)va % (int64_t)vb;
|
|
|
|
zc[0] = (uint32_t)vc;
|
|
zc[1] = vc >> bits;
|
|
} else
|
|
{
|
|
assert( 0);
|
|
}
|
|
|
|
memcpy( zr, zc, num_digits*sizeof( zc[0]));
|
|
|
|
return;
|
|
} /* __lccrt_zn_smod */
|
|
|
|
static void
|
|
__lccrt_arith1_v( void (*func)( uint32_t, uint32_t, uint8_t *, uint8_t *),
|
|
uint32_t rb, uint32_t ab, uint8_t *r, uint8_t *a,
|
|
uint32_t rn, uint32_t an, uint32_t reb, uint32_t aeb)
|
|
{
|
|
int i;
|
|
uint32_t reb_align = __LCCRT_ALIGN_BITS_N( reb);
|
|
uint32_t aeb_align = __LCCRT_ALIGN_BITS_N( aeb);
|
|
uint32_t rbytes_align = reb_align / 8;
|
|
uint32_t abytes_align = aeb_align / 8;
|
|
|
|
assert( (rn == an));
|
|
assert( rn*reb_align == rb);
|
|
assert( an*aeb_align == ab);
|
|
memset( r, 0, rn * rbytes_align);
|
|
for ( i = 0; i < rn; ++i )
|
|
{
|
|
(*func)( reb, aeb, r + i*rbytes_align, a + i*abytes_align);
|
|
}
|
|
|
|
return;
|
|
} /* __lccrt_arith1_v */
|
|
|
|
static void
|
|
__lccrt_arith2_v( void (*func)( uint32_t, uint32_t, uint32_t, uint8_t *, uint8_t *, uint8_t *),
|
|
uint32_t rb, uint32_t ab, uint32_t bb, uint8_t *r, uint8_t *a, uint8_t *b,
|
|
uint32_t rn, uint32_t an, uint32_t bn, uint32_t reb, uint32_t aeb, uint32_t beb)
|
|
{
|
|
int i;
|
|
uint32_t reb_align = __LCCRT_ALIGN_BITS_N( reb);
|
|
uint32_t aeb_align = __LCCRT_ALIGN_BITS_N( aeb);
|
|
uint32_t beb_align = __LCCRT_ALIGN_BITS_N( beb);
|
|
uint32_t rbytes_align = reb_align / 8;
|
|
|
|
assert( (rn == an) && (rn == bn) && (reb == aeb) && (reb == beb));
|
|
assert( (rb == ab) && (rb == bb));
|
|
assert( rn*reb_align == rb);
|
|
memset( r, 0, rn * rbytes_align);
|
|
for ( i = 0; i < rn; ++i )
|
|
{
|
|
(*func)( reb, aeb, beb, r + i*rbytes_align, a + i*rbytes_align, b + i*rbytes_align);
|
|
}
|
|
|
|
return;
|
|
} /* __lccrt_arith2_v */
|
|
|
|
static void
|
|
__lccrt_arith3_v( void (*func)( uint32_t, uint32_t, uint32_t, uint32_t, uint8_t *, uint8_t *, uint8_t *, uint8_t *),
|
|
uint32_t rb, uint32_t ab, uint32_t bb, uint32_t cb,
|
|
uint8_t *r, uint8_t *a, uint8_t *b, uint8_t *c,
|
|
uint32_t rn, uint32_t an, uint32_t bn, uint32_t cn,
|
|
uint32_t reb, uint32_t aeb, uint32_t beb, uint32_t ceb)
|
|
{
|
|
int i;
|
|
uint32_t reb_align = __LCCRT_ALIGN_BITS_N( reb);
|
|
uint32_t rbytes_align = reb_align / 8;
|
|
|
|
assert( (rb == ab) && (rb == bb) && (rb == cb));
|
|
assert( (rn == an) && (rn == bn) && (rn == cn));
|
|
assert( (reb == aeb) && (reb == beb) && (reb == ceb));
|
|
assert( rn*reb_align == rb);
|
|
memset( r, 0, rn * rbytes_align);
|
|
for ( i = 0; i < rn; ++i )
|
|
{
|
|
uint8_t *ri = r + i*rbytes_align;
|
|
uint8_t *ai = a + i*rbytes_align;
|
|
uint8_t *bi = b + i*rbytes_align;
|
|
uint8_t *ci = c + i*rbytes_align;
|
|
|
|
(*func)( reb, aeb, beb, ceb, ri, ai, bi, ci);
|
|
}
|
|
|
|
return;
|
|
} /* __lccrt_arith3_v */
|
|
|
|
static void
|
|
__lccrt_farith1_v( float (*f32)( float), double (*f64)( double), long double (*f80)( long double),
|
|
uint32_t rb, uint32_t ab, uint8_t *r, uint8_t *a,
|
|
uint32_t rn, uint32_t an, uint32_t reb, uint32_t aeb)
|
|
{
|
|
int i;
|
|
int byte_elen = reb / 8;
|
|
|
|
assert( (reb % 8 == 0));
|
|
assert( (rn == an) && (reb == aeb) && (rn*reb == rb));
|
|
for ( i = 0; i < rn; ++i )
|
|
{
|
|
uint8_t *q0 = r + i*byte_elen;
|
|
uint8_t *p0 = a + i*byte_elen;
|
|
|
|
if ( (reb == 32) )
|
|
{
|
|
float z, x;
|
|
|
|
memcpy( &x, p0, sizeof( x));
|
|
z = (*f32)( x);
|
|
memcpy( q0, &z, sizeof( z));
|
|
|
|
} else if ( (reb == 64) )
|
|
{
|
|
double z, x;
|
|
|
|
memcpy( &x, p0, sizeof( x));
|
|
z = (*f64)( x);
|
|
memcpy( q0, &z, sizeof( z));
|
|
|
|
} else if ( (reb == 80) )
|
|
{
|
|
long double z, x;
|
|
|
|
memcpy( &x, p0, sizeof( x));
|
|
z = (*f80)( x);
|
|
memcpy( q0, &z, sizeof( z));
|
|
} else
|
|
{
|
|
assert( 0);
|
|
}
|
|
}
|
|
|
|
return;
|
|
} /* __lccrt_farith1_v */
|
|
|
|
static void
|
|
__lccrt_farith2_v( float (*f32)( float, float), double (*f64)( double, double),
|
|
long double (*f80)( long double, long double),
|
|
uint32_t rb, uint32_t ab, uint32_t bb, uint8_t *r, uint8_t *a, uint8_t *b,
|
|
uint32_t rn, uint32_t an, uint32_t bn, uint32_t reb, uint32_t aeb, uint32_t beb)
|
|
{
|
|
int i;
|
|
int byte_elen = reb / 8;
|
|
|
|
assert( (reb % 8 == 0));
|
|
assert( (rn == an) && (rn == bn) && (reb == aeb) && (reb == beb) && (rn*reb == rb));
|
|
for ( i = 0; i < rn; ++i )
|
|
{
|
|
uint8_t *q0 = r + i*byte_elen;
|
|
uint8_t *p0 = a + i*byte_elen;
|
|
uint8_t *p1 = b + i*byte_elen;
|
|
|
|
if ( (reb == 32) )
|
|
{
|
|
float z, x, y;
|
|
|
|
memcpy( &x, p0, sizeof( x));
|
|
memcpy( &y, p1, sizeof( y));
|
|
z = (*f32)( x, y);
|
|
memcpy( q0, &z, sizeof( z));
|
|
|
|
} else if ( (reb == 64) )
|
|
{
|
|
double z, x, y;
|
|
|
|
memcpy( &x, p0, sizeof( x));
|
|
memcpy( &y, p1, sizeof( y));
|
|
z = (*f64)( x, y);
|
|
memcpy( q0, &z, sizeof( z));
|
|
|
|
} else if ( (reb == 80) )
|
|
{
|
|
long double z, x, y;
|
|
|
|
memcpy( &x, p0, sizeof( x));
|
|
memcpy( &y, p1, sizeof( y));
|
|
z = (*f80)( x, y);
|
|
memcpy( q0, &z, sizeof( z));
|
|
} else
|
|
{
|
|
assert( 0);
|
|
}
|
|
}
|
|
|
|
return;
|
|
} /* __lccrt_farith2_v */
|
|
|
|
void
|
|
__lccrt_bitcast_n( uint32_t rb, uint32_t ab, uint8_t *r, uint8_t *a)
|
|
{
|
|
int rlen = rb / 8;
|
|
int alen = ab / 8;
|
|
int rlen1 = (rb + 7) / 8;
|
|
int len = __LCCRT_MIN( alen, rlen1);
|
|
|
|
memcpy( r, a, len);
|
|
memset( r + len, 0, rlen1 - len);
|
|
|
|
if ( (8*alen < ab)
|
|
&& (8*alen < rb) )
|
|
{
|
|
int bits = __LCCRT_MIN( ab, rb);
|
|
|
|
r[alen] = __LCCRT_ZEXT( a[alen], bits - 8*alen);
|
|
}
|
|
|
|
if ( (rlen < rlen1) )
|
|
{
|
|
r[rlen] = __LCCRT_ZEXT( r[rlen], rb - 8*rlen);
|
|
}
|
|
|
|
return;
|
|
} /* __lccrt_bitcast_n */
|
|
|
|
void
|
|
__lccrt_select( uint32_t rb, uint32_t ab, uint32_t bb, uint32_t cb,
|
|
uint8_t *r, uint8_t *a, uint8_t *b, uint8_t *c)
|
|
{
|
|
assert( ab == 8);
|
|
assert( rb == bb);
|
|
assert( rb == cb);
|
|
if ( a[0] )
|
|
{
|
|
__lccrt_bitcast_n( rb, bb, r, b);
|
|
} else
|
|
{
|
|
__lccrt_bitcast_n( rb, cb, r, c);
|
|
}
|
|
|
|
return;
|
|
} /* __lccrt_select */
|
|
|
|
void
|
|
__lccrt_select_v( uint32_t rb, uint32_t ab, uint32_t bb, uint32_t cb,
|
|
uint8_t *r, uint8_t *a, uint8_t *b, uint8_t *c,
|
|
uint32_t rn, uint32_t an, uint32_t bn, uint32_t cn)
|
|
{
|
|
if ( (rn == an)
|
|
&& (rn == bn)
|
|
&& (rn == cn)
|
|
&& (ab > 0)
|
|
&& (rb == bb)
|
|
&& (rb == cb)
|
|
&& (rn > 0)
|
|
&& (rb > 0) )
|
|
{
|
|
int k;
|
|
uint32_t re = rb / rn;
|
|
uint32_t ae = ab / an;
|
|
uint32_t be = bb / bn;
|
|
uint32_t ce = bb / bn;
|
|
|
|
if ( (ae == 8)
|
|
&& (re > 0)
|
|
&& (re == be)
|
|
&& (re == ce)
|
|
&& (rb % rn == 0)
|
|
&& (ab % an == 0)
|
|
&& (re % 8 == 0) )
|
|
{
|
|
for ( k = 0; k < rn; ++k )
|
|
{
|
|
__lccrt_select( re, ae, be, ce, r + k*(re/8), a + k*(ae/8), b + k*(be/8), c + k*(ce/8));
|
|
}
|
|
} else
|
|
{
|
|
__LCCRT_PRINT_BITS3( rb, ab, bb);
|
|
assert( 0);
|
|
}
|
|
} else
|
|
{
|
|
__LCCRT_PRINT_BITS3( rb, ab, bb);
|
|
assert( 0);
|
|
}
|
|
|
|
return;
|
|
} /* __lccrt_select_v */
|
|
|
|
void
|
|
__lccrt_zext_n( uint32_t rb, uint32_t ab, uint8_t *r, uint8_t *a)
|
|
{
|
|
assert( rb >= ab);
|
|
__lccrt_bitcast_n( rb, ab, r, a);
|
|
|
|
return;
|
|
} /* __lccrt_zext_n */
|
|
|
|
void
|
|
__lccrt_trunc_n( uint32_t rb, uint32_t ab, uint8_t *r, uint8_t *a)
|
|
{
|
|
assert( rb <= ab);
|
|
__lccrt_bitcast_n( rb, ab, r, a);
|
|
|
|
return;
|
|
} /* __lccrt_trunc_n */
|
|
|
|
void
|
|
__lccrt_sext_n( uint32_t rb, uint32_t ab, uint8_t *r, uint8_t *a)
|
|
{
|
|
int rlen = rb / 8;
|
|
int alen = ab / 8;
|
|
int rlen1 = (rb + 7) / 8;
|
|
int len = __LCCRT_MIN( alen, rlen);
|
|
|
|
assert( rb >= ab);
|
|
if ( (ab == 0) )
|
|
{
|
|
memset( r, 0, rlen1);
|
|
} else
|
|
{
|
|
int8_t va;
|
|
|
|
memcpy( r, a, len);
|
|
|
|
if ( (8*alen < ab) )
|
|
{
|
|
len = alen + 1;
|
|
va = __LCCRT_SEXT( a[len - 1], ab - 8*alen);
|
|
r[alen] = va;
|
|
} else
|
|
{
|
|
len = alen;
|
|
va = a[len - 1];
|
|
}
|
|
|
|
va = va >> 7;
|
|
memset( r + len, va, rlen1 - len);
|
|
if ( (rlen < rlen1) )
|
|
{
|
|
r[rlen] = __LCCRT_ZEXT( r[rlen], rb - 8*rlen);
|
|
}
|
|
}
|
|
|
|
return;
|
|
} /* __lccrt_sext_n */
|
|
|
|
void
|
|
__lccrt_trunc_v( uint32_t rb, uint32_t ab, uint8_t *r, uint8_t *a, uint32_t rn, uint32_t an,
|
|
uint32_t reb, uint32_t aeb)
|
|
{
|
|
__lccrt_arith1_v( &__lccrt_trunc_n, rb, ab, r, a, rn, an, reb, aeb);
|
|
|
|
return;
|
|
} /* __lccrt_trunc_v */
|
|
|
|
void
|
|
__lccrt_zext_v( uint32_t rb, uint32_t ab, uint8_t *r, uint8_t *a, uint32_t rn, uint32_t an,
|
|
uint32_t reb, uint32_t aeb)
|
|
{
|
|
__lccrt_arith1_v( &__lccrt_zext_n, rb, ab, r, a, rn, an, reb, aeb);
|
|
|
|
return;
|
|
} /* __lccrt_zext_v */
|
|
|
|
void
|
|
__lccrt_sext_v( uint32_t rb, uint32_t ab, uint8_t *r, uint8_t *a, uint32_t rn, uint32_t an,
|
|
uint32_t reb, uint32_t aeb)
|
|
{
|
|
__lccrt_arith1_v( &__lccrt_sext_n, rb, ab, r, a, rn, an, reb, aeb);
|
|
|
|
return;
|
|
} /* __lccrt_sext_v */
|
|
|
|
static int
|
|
__lccrt_cmp_lexic( int bits, uint8_t *a, uint8_t *b)
|
|
{
|
|
int i;
|
|
int u = 0;
|
|
int n = bits / 8;
|
|
int n1 = (bits + 7) / 8;
|
|
|
|
if ( (n < n1) )
|
|
{
|
|
uint8_t ah = __LCCRT_ZEXT( a[n], bits - 8*n);
|
|
uint8_t bh = __LCCRT_ZEXT( b[n], bits - 8*n);
|
|
|
|
u = (ah < bh) ? (-1) : ((ah == bh) ? 0 : 1);
|
|
}
|
|
|
|
for ( i = n - 1; (i >= 0) && (u == 0); --i )
|
|
{
|
|
if ( (a[i] != b[i]) )
|
|
{
|
|
u = (a[i] < b[i]) ? (-1) : 1;
|
|
}
|
|
}
|
|
|
|
return (u);
|
|
} /* __lccrt_cmp_lexic */
|
|
|
|
static int
|
|
__lccrt_cmp_lexic_sign( int bits, uint8_t *a, uint8_t *b)
|
|
{
|
|
int u = 0;
|
|
int n = bits / 8;
|
|
int n1 = (bits + 7) / 8;
|
|
|
|
if ( (n1 > 0) )
|
|
{
|
|
int hl = bits % 8;
|
|
int8_t hs = (8 - hl) % 8;
|
|
int ha = ((int8_t)(((int8_t)a[n1-1]) << hs)) >> hs;
|
|
int hb = ((int8_t)(((int8_t)b[n1-1]) << hs)) >> hs;
|
|
|
|
if ( (ha < hb) )
|
|
{
|
|
u = -1;
|
|
|
|
} else if ( (ha > hb) )
|
|
{
|
|
u = 1;
|
|
|
|
} else if ( (bits > 8) )
|
|
{
|
|
u = __lccrt_cmp_lexic( 8*(n1 - 1), a, b);
|
|
}
|
|
}
|
|
|
|
return (u);
|
|
} /* __lccrt_cmp_lexic_sign */
|
|
|
|
static int
|
|
__lccrt_fcmp( uint32_t rb, uint32_t ab, uint32_t bb, uint8_t *r, uint8_t *a, uint8_t *b,
|
|
uint32_t type)
|
|
{
|
|
int v = 0;
|
|
|
|
if ( (rb == 8)
|
|
&& (ab == bb) )
|
|
{
|
|
int u = 0;
|
|
|
|
if ( (ab == 32) )
|
|
{
|
|
float fa, fb;
|
|
|
|
memcpy( &fa, a, sizeof( fa));
|
|
memcpy( &fb, b, sizeof( fb));
|
|
u = (fa <= fb) || (fa > fb);
|
|
|
|
switch ( type )
|
|
{
|
|
case A_LCCRT_CMP_FU: v = !u; break;
|
|
case A_LCCRT_CMP_FO: v = u; break;
|
|
case A_LCCRT_CMP_EQ_FU: v = (fa == fb) || !u; break;
|
|
case A_LCCRT_CMP_EQ_FO: v = (fa == fb) && u; break;
|
|
case A_LCCRT_CMP_NE_FU: v = (fa != fb) || !u; break;
|
|
case A_LCCRT_CMP_NE_FO: v = (fa != fb) && u; break;
|
|
case A_LCCRT_CMP_LT_FU: v = (fa < fb) || !u; break;
|
|
case A_LCCRT_CMP_LT_FO: v = (fa < fb) && u; break;
|
|
case A_LCCRT_CMP_LE_FU: v = (fa <= fb) || !u; break;
|
|
case A_LCCRT_CMP_LE_FO: v = (fa <= fb) && u; break;
|
|
case A_LCCRT_CMP_GT_FU: v = (fa > fb) || !u; break;
|
|
case A_LCCRT_CMP_GT_FO: v = (fa > fb) && u; break;
|
|
case A_LCCRT_CMP_GE_FU: v = (fa >= fb) || !u; break;
|
|
case A_LCCRT_CMP_GE_FO: v = (fa >= fb) && u; break;
|
|
default: assert( 0); break;
|
|
}
|
|
} else if ( (ab == 64) )
|
|
{
|
|
double da, db;
|
|
|
|
memcpy( &da, a, sizeof( da));
|
|
memcpy( &db, b, sizeof( db));
|
|
u = (da <= db) || (da > db);
|
|
|
|
switch ( type )
|
|
{
|
|
case A_LCCRT_CMP_FU: v = !u; break;
|
|
case A_LCCRT_CMP_FO: v = u; break;
|
|
case A_LCCRT_CMP_EQ_FU: v = (da == db) || !u; break;
|
|
case A_LCCRT_CMP_EQ_FO: v = (da == db) && u; break;
|
|
case A_LCCRT_CMP_NE_FU: v = (da != db) || !u; break;
|
|
case A_LCCRT_CMP_NE_FO: v = (da != db) && u; break;
|
|
case A_LCCRT_CMP_LT_FU: v = (da < db) || !u; break;
|
|
case A_LCCRT_CMP_LT_FO: v = (da < db) && u; break;
|
|
case A_LCCRT_CMP_LE_FU: v = (da <= db) || !u; break;
|
|
case A_LCCRT_CMP_LE_FO: v = (da <= db) && u; break;
|
|
case A_LCCRT_CMP_GT_FU: v = (da > db) || !u; break;
|
|
case A_LCCRT_CMP_GT_FO: v = (da > db) && u; break;
|
|
case A_LCCRT_CMP_GE_FU: v = (da >= db) || !u; break;
|
|
case A_LCCRT_CMP_GE_FO: v = (da >= db) && u; break;
|
|
default: assert( 0); break;
|
|
}
|
|
} else if ( (ab == 80) )
|
|
{
|
|
long double la, lb;
|
|
|
|
memcpy( &la, a, sizeof( la));
|
|
memcpy( &lb, b, sizeof( lb));
|
|
u = (la <= lb) || (la > lb);
|
|
|
|
switch ( type )
|
|
{
|
|
case A_LCCRT_CMP_FU: v = !u; break;
|
|
case A_LCCRT_CMP_FO: v = u; break;
|
|
case A_LCCRT_CMP_EQ_FU: v = (la == lb) || !u; break;
|
|
case A_LCCRT_CMP_EQ_FO: v = (la == lb) && u; break;
|
|
case A_LCCRT_CMP_NE_FU: v = (la != lb) || !u; break;
|
|
case A_LCCRT_CMP_NE_FO: v = (la != lb) && u; break;
|
|
case A_LCCRT_CMP_LT_FU: v = (la < lb) || !u; break;
|
|
case A_LCCRT_CMP_LT_FO: v = (la < lb) && u; break;
|
|
case A_LCCRT_CMP_LE_FU: v = (la <= lb) || !u; break;
|
|
case A_LCCRT_CMP_LE_FO: v = (la <= lb) && u; break;
|
|
case A_LCCRT_CMP_GT_FU: v = (la > lb) || !u; break;
|
|
case A_LCCRT_CMP_GT_FO: v = (la > lb) && u; break;
|
|
case A_LCCRT_CMP_GE_FU: v = (la >= lb) || !u; break;
|
|
case A_LCCRT_CMP_GE_FO: v = (la >= lb) && u; break;
|
|
default: assert( 0); break;
|
|
}
|
|
} else
|
|
{
|
|
__LCCRT_PRINT_BITS3( rb, ab, bb);
|
|
assert( 0);
|
|
}
|
|
|
|
if ( r )
|
|
{
|
|
r[0] = v;
|
|
}
|
|
} else
|
|
{
|
|
__LCCRT_PRINT_BITS3( rb, ab, bb);
|
|
assert( 0);
|
|
}
|
|
|
|
return (v);
|
|
} /* __lccrt_fcmp */
|
|
|
|
static void
|
|
__lccrt_cmp_n( uint32_t type, uint32_t rb, uint32_t ab, uint32_t bb,
|
|
uint8_t *r, uint8_t *a, uint8_t *b)
|
|
{
|
|
int i;
|
|
int alen = ab / 8;
|
|
int alen1 = (ab + 7) / 8;
|
|
|
|
if ( (0 < rb)
|
|
&& (rb <= 8)
|
|
&& (ab == bb)
|
|
&& (ab > 0) )
|
|
{
|
|
int v = 0;
|
|
|
|
switch ( type )
|
|
{
|
|
case A_LCCRT_CMP_EQ: v = (__lccrt_cmp_lexic( ab, a, b) == 0); break;
|
|
case A_LCCRT_CMP_NE: v = (__lccrt_cmp_lexic( ab, a, b) != 0); break;
|
|
case A_LCCRT_CMP_LT_I: v = (__lccrt_cmp_lexic_sign( ab, a, b) == -1); break;
|
|
case A_LCCRT_CMP_LT_U: v = (__lccrt_cmp_lexic( ab, a, b) == -1); break;
|
|
case A_LCCRT_CMP_LE_I: v = (__lccrt_cmp_lexic_sign( ab, a, b) <= 0); break;
|
|
case A_LCCRT_CMP_LE_U: v = (__lccrt_cmp_lexic( ab, a, b) <= 0); break;
|
|
case A_LCCRT_CMP_GT_I: v = (__lccrt_cmp_lexic_sign( ab, a, b) == 1); break;
|
|
case A_LCCRT_CMP_GT_U: v = (__lccrt_cmp_lexic( ab, a, b) == 1); break;
|
|
case A_LCCRT_CMP_GE_I: v = (__lccrt_cmp_lexic_sign( ab, a, b) >= 0); break;
|
|
case A_LCCRT_CMP_GE_U: v = (__lccrt_cmp_lexic( ab, a, b) >= 0); break;
|
|
case A_LCCRT_CMP_FU: v = (__lccrt_fcmp( rb, ab, bb, 0, a, b, type)); break;
|
|
case A_LCCRT_CMP_FO: v = (__lccrt_fcmp( rb, ab, bb, 0, a, b, type)); break;
|
|
case A_LCCRT_CMP_EQ_FU: v = (__lccrt_fcmp( rb, ab, bb, 0, a, b, type)); break;
|
|
case A_LCCRT_CMP_EQ_FO: v = (__lccrt_fcmp( rb, ab, bb, 0, a, b, type)); break;
|
|
case A_LCCRT_CMP_NE_FU: v = (__lccrt_fcmp( rb, ab, bb, 0, a, b, type)); break;
|
|
case A_LCCRT_CMP_NE_FO: v = (__lccrt_fcmp( rb, ab, bb, 0, a, b, type)); break;
|
|
case A_LCCRT_CMP_LT_FU: v = (__lccrt_fcmp( rb, ab, bb, 0, a, b, type)); break;
|
|
case A_LCCRT_CMP_LT_FO: v = (__lccrt_fcmp( rb, ab, bb, 0, a, b, type)); break;
|
|
case A_LCCRT_CMP_LE_FU: v = (__lccrt_fcmp( rb, ab, bb, 0, a, b, type)); break;
|
|
case A_LCCRT_CMP_LE_FO: v = (__lccrt_fcmp( rb, ab, bb, 0, a, b, type)); break;
|
|
case A_LCCRT_CMP_GT_FU: v = (__lccrt_fcmp( rb, ab, bb, 0, a, b, type)); break;
|
|
case A_LCCRT_CMP_GT_FO: v = (__lccrt_fcmp( rb, ab, bb, 0, a, b, type)); break;
|
|
case A_LCCRT_CMP_GE_FU: v = (__lccrt_fcmp( rb, ab, bb, 0, a, b, type)); break;
|
|
case A_LCCRT_CMP_GE_FO: v = (__lccrt_fcmp( rb, ab, bb, 0, a, b, type)); break;
|
|
default: assert( 0); break;
|
|
}
|
|
|
|
r[0] = v;
|
|
} else
|
|
{
|
|
__LCCRT_PRINT_BITS3( rb, ab, bb);
|
|
assert( 0);
|
|
}
|
|
|
|
return;
|
|
} /* __lccrt_cmp_n */
|
|
|
|
void
|
|
__lccrt_cmp_n_eq_i( uint32_t rb, uint32_t ab, uint32_t bb, uint8_t *r, uint8_t *a, uint8_t *b)
|
|
{
|
|
__lccrt_cmp_n( A_LCCRT_CMP_EQ, rb, ab, bb, r, a, b);
|
|
|
|
return;
|
|
} /* __lccrt_cmp_n_eq_i */
|
|
|
|
void
|
|
__lccrt_cmp_n_ne_i( uint32_t rb, uint32_t ab, uint32_t bb, uint8_t *r, uint8_t *a, uint8_t *b)
|
|
{
|
|
__lccrt_cmp_n( A_LCCRT_CMP_NE, rb, ab, bb, r, a, b);
|
|
|
|
return;
|
|
} /* __lccrt_cmp_n_ne_i */
|
|
|
|
void
|
|
__lccrt_cmp_n_lt_i( uint32_t rb, uint32_t ab, uint32_t bb, uint8_t *r, uint8_t *a, uint8_t *b)
|
|
{
|
|
__lccrt_cmp_n( A_LCCRT_CMP_LT_I, rb, ab, bb, r, a, b);
|
|
|
|
return;
|
|
} /* __lccrt_cmp_n_lt_i */
|
|
|
|
void
|
|
__lccrt_cmp_n_lt_u( uint32_t rb, uint32_t ab, uint32_t bb, uint8_t *r, uint8_t *a, uint8_t *b)
|
|
{
|
|
__lccrt_cmp_n( A_LCCRT_CMP_LT_U, rb, ab, bb, r, a, b);
|
|
|
|
return;
|
|
} /* __lccrt_cmp_n_lt_u */
|
|
|
|
void
|
|
__lccrt_cmp_n_le_i( uint32_t rb, uint32_t ab, uint32_t bb, uint8_t *r, uint8_t *a, uint8_t *b)
|
|
{
|
|
__lccrt_cmp_n( A_LCCRT_CMP_LE_I, rb, ab, bb, r, a, b);
|
|
|
|
return;
|
|
} /* __lccrt_cmp_n_le_i */
|
|
|
|
void
|
|
__lccrt_cmp_n_le_u( uint32_t rb, uint32_t ab, uint32_t bb, uint8_t *r, uint8_t *a, uint8_t *b)
|
|
{
|
|
__lccrt_cmp_n( A_LCCRT_CMP_LE_U, rb, ab, bb, r, a, b);
|
|
|
|
return;
|
|
} /* __lccrt_cmp_n_le_u */
|
|
|
|
void
|
|
__lccrt_cmp_n_gt_i( uint32_t rb, uint32_t ab, uint32_t bb, uint8_t *r, uint8_t *a, uint8_t *b)
|
|
{
|
|
__lccrt_cmp_n( A_LCCRT_CMP_GT_I, rb, ab, bb, r, a, b);
|
|
|
|
return;
|
|
} /* __lccrt_cmp_n_gt_i */
|
|
|
|
void
|
|
__lccrt_cmp_n_gt_u( uint32_t rb, uint32_t ab, uint32_t bb, uint8_t *r, uint8_t *a, uint8_t *b)
|
|
{
|
|
__lccrt_cmp_n( A_LCCRT_CMP_GT_U, rb, ab, bb, r, a, b);
|
|
|
|
return;
|
|
} /* __lccrt_cmp_n_gt_u */
|
|
|
|
void
|
|
__lccrt_cmp_n_ge_i( uint32_t rb, uint32_t ab, uint32_t bb, uint8_t *r, uint8_t *a, uint8_t *b)
|
|
{
|
|
__lccrt_cmp_n( A_LCCRT_CMP_GE_I, rb, ab, bb, r, a, b);
|
|
|
|
return;
|
|
} /* __lccrt_cmp_n_ge_i */
|
|
|
|
void
|
|
__lccrt_cmp_n_ge_u( uint32_t rb, uint32_t ab, uint32_t bb, uint8_t *r, uint8_t *a, uint8_t *b)
|
|
{
|
|
__lccrt_cmp_n( A_LCCRT_CMP_GE_U, rb, ab, bb, r, a, b);
|
|
|
|
return;
|
|
} /* __lccrt_cmp_n_ge_u */
|
|
|
|
void
|
|
__lccrt_cmp_fo( uint32_t rb, uint32_t ab, uint32_t bb, uint8_t *r, uint8_t *a, uint8_t *b)
|
|
{
|
|
__lccrt_fcmp( rb, ab, bb, r, a, b, A_LCCRT_CMP_FO);
|
|
|
|
return;
|
|
} /* __lccrt_cmp_fo */
|
|
|
|
void
|
|
__lccrt_cmp_eq_fo( uint32_t rb, uint32_t ab, uint32_t bb, uint8_t *r, uint8_t *a, uint8_t *b)
|
|
{
|
|
__lccrt_fcmp( rb, ab, bb, r, a, b, A_LCCRT_CMP_EQ_FO);
|
|
|
|
return;
|
|
} /* __lccrt_cmp_eq_fo */
|
|
|
|
void
|
|
__lccrt_cmp_ne_fo( uint32_t rb, uint32_t ab, uint32_t bb, uint8_t *r, uint8_t *a, uint8_t *b)
|
|
{
|
|
__lccrt_fcmp( rb, ab, bb, r, a, b, A_LCCRT_CMP_NE_FO);
|
|
|
|
return;
|
|
} /* __lccrt_cmp_ne_fo */
|
|
|
|
void
|
|
__lccrt_cmp_lt_fo( uint32_t rb, uint32_t ab, uint32_t bb, uint8_t *r, uint8_t *a, uint8_t *b)
|
|
{
|
|
__lccrt_fcmp( rb, ab, bb, r, a, b, A_LCCRT_CMP_LT_FO);
|
|
|
|
return;
|
|
} /* __lccrt_cmp_lt_fo */
|
|
|
|
void
|
|
__lccrt_cmp_le_fo( uint32_t rb, uint32_t ab, uint32_t bb, uint8_t *r, uint8_t *a, uint8_t *b)
|
|
{
|
|
__lccrt_fcmp( rb, ab, bb, r, a, b, A_LCCRT_CMP_LE_FO);
|
|
|
|
return;
|
|
} /* __lccrt_cmp_le_fo */
|
|
|
|
void
|
|
__lccrt_cmp_gt_fo( uint32_t rb, uint32_t ab, uint32_t bb, uint8_t *r, uint8_t *a, uint8_t *b)
|
|
{
|
|
__lccrt_fcmp( rb, ab, bb, r, a, b, A_LCCRT_CMP_GT_FO);
|
|
|
|
return;
|
|
} /* __lccrt_cmp_gt_fo */
|
|
|
|
void
|
|
__lccrt_cmp_ge_fo( uint32_t rb, uint32_t ab, uint32_t bb, uint8_t *r, uint8_t *a, uint8_t *b)
|
|
{
|
|
__lccrt_fcmp( rb, ab, bb, r, a, b, A_LCCRT_CMP_GE_FO);
|
|
|
|
return;
|
|
} /* __lccrt_cmp_ge_fo */
|
|
|
|
void
|
|
__lccrt_cmp_fu( uint32_t rb, uint32_t ab, uint32_t bb, uint8_t *r, uint8_t *a, uint8_t *b)
|
|
{
|
|
__lccrt_fcmp( rb, ab, bb, r, a, b, A_LCCRT_CMP_FU);
|
|
|
|
return;
|
|
} /* __lccrt_cmp_fu */
|
|
|
|
void
|
|
__lccrt_cmp_eq_fu( uint32_t rb, uint32_t ab, uint32_t bb, uint8_t *r, uint8_t *a, uint8_t *b)
|
|
{
|
|
__lccrt_fcmp( rb, ab, bb, r, a, b, A_LCCRT_CMP_EQ_FU);
|
|
|
|
return;
|
|
} /* __lccrt_cmp_eq_fu */
|
|
|
|
void
|
|
__lccrt_cmp_ne_fu( uint32_t rb, uint32_t ab, uint32_t bb, uint8_t *r, uint8_t *a, uint8_t *b)
|
|
{
|
|
__lccrt_fcmp( rb, ab, bb, r, a, b, A_LCCRT_CMP_NE_FU);
|
|
|
|
return;
|
|
} /* __lccrt_cmp_ne_fu */
|
|
|
|
void
|
|
__lccrt_cmp_lt_fu( uint32_t rb, uint32_t ab, uint32_t bb, uint8_t *r, uint8_t *a, uint8_t *b)
|
|
{
|
|
__lccrt_fcmp( rb, ab, bb, r, a, b, A_LCCRT_CMP_LT_FU);
|
|
|
|
return;
|
|
} /* __lccrt_cmp_lt_fu */
|
|
|
|
void
|
|
__lccrt_cmp_le_fu( uint32_t rb, uint32_t ab, uint32_t bb, uint8_t *r, uint8_t *a, uint8_t *b)
|
|
{
|
|
__lccrt_fcmp( rb, ab, bb, r, a, b, A_LCCRT_CMP_LE_FU);
|
|
|
|
return;
|
|
} /* __lccrt_cmp_le_fu */
|
|
|
|
void
|
|
__lccrt_cmp_gt_fu( uint32_t rb, uint32_t ab, uint32_t bb, uint8_t *r, uint8_t *a, uint8_t *b)
|
|
{
|
|
__lccrt_fcmp( rb, ab, bb, r, a, b, A_LCCRT_CMP_GT_FU);
|
|
|
|
return;
|
|
} /* __lccrt_cmp_gt_fu */
|
|
|
|
void
|
|
__lccrt_cmp_ge_fu( uint32_t rb, uint32_t ab, uint32_t bb, uint8_t *r, uint8_t *a, uint8_t *b)
|
|
{
|
|
__lccrt_fcmp( rb, ab, bb, r, a, b, A_LCCRT_CMP_GE_FU);
|
|
|
|
return;
|
|
} /* __lccrt_cmp_ge_fu */
|
|
|
|
static void
|
|
__lccrt_cmp_v( uint32_t type, uint32_t rb, uint32_t ab, uint32_t bb, uint8_t *r, uint8_t *a, uint8_t *b,
|
|
uint32_t rn, uint32_t an, uint32_t bn)
|
|
{
|
|
if ( (rn == an)
|
|
&& (an == bn)
|
|
&& (ab == bb)
|
|
&& (rn > 0)
|
|
&& (rb > 0)
|
|
&& (ab > 0)
|
|
&& (bb > 0) )
|
|
{
|
|
int k;
|
|
uint32_t re = rb / rn;
|
|
uint32_t ae = ab / an;
|
|
uint32_t be = bb / bn;
|
|
|
|
if ( (re == 8)
|
|
&& (ae == be)
|
|
&& (rb % rn == 0)
|
|
&& (ab % an == 0)
|
|
&& (ae % 8 == 0)
|
|
&& (be % 8 == 0) )
|
|
{
|
|
for ( k = 0; k < rn; ++k )
|
|
{
|
|
__lccrt_cmp_n( type, re, ae, be, r + k*(re/8), a + k*(ae/8), b + k*(be/8));
|
|
}
|
|
} else
|
|
{
|
|
__LCCRT_PRINT_BITS3( rb, ab, bb);
|
|
assert( 0);
|
|
}
|
|
} else
|
|
{
|
|
__LCCRT_PRINT_BITS3( rb, ab, bb);
|
|
assert( 0);
|
|
}
|
|
|
|
return;
|
|
} /* __lccrt_cmp_v */
|
|
|
|
void
|
|
__lccrt_cmp_v_eq_i( uint32_t rb, uint32_t ab, uint32_t bb, uint8_t *r, uint8_t *a, uint8_t *b,
|
|
uint32_t rn, uint32_t an, uint32_t bn)
|
|
{
|
|
__lccrt_cmp_v( A_LCCRT_CMP_EQ, rb, ab, bb, r, a, b, rn, an, bn);
|
|
|
|
return;
|
|
} /* __lccrt_cmp_v_eq_i */
|
|
|
|
void
|
|
__lccrt_cmp_v_ne_i( uint32_t rb, uint32_t ab, uint32_t bb, uint8_t *r, uint8_t *a, uint8_t *b,
|
|
uint32_t rn, uint32_t an, uint32_t bn)
|
|
{
|
|
__lccrt_cmp_v( A_LCCRT_CMP_NE, rb, ab, bb, r, a, b, rn, an, bn);
|
|
|
|
return;
|
|
} /* __lccrt_cmp_v_ne_i */
|
|
|
|
void
|
|
__lccrt_cmp_v_lt_i( uint32_t rb, uint32_t ab, uint32_t bb, uint8_t *r, uint8_t *a, uint8_t *b,
|
|
uint32_t rn, uint32_t an, uint32_t bn)
|
|
{
|
|
__lccrt_cmp_v( A_LCCRT_CMP_LT_I, rb, ab, bb, r, a, b, rn, an, bn);
|
|
|
|
return;
|
|
} /* __lccrt_cmp_v_lt_i */
|
|
|
|
void
|
|
__lccrt_cmp_v_lt_u( uint32_t rb, uint32_t ab, uint32_t bb, uint8_t *r, uint8_t *a, uint8_t *b,
|
|
uint32_t rn, uint32_t an, uint32_t bn)
|
|
{
|
|
__lccrt_cmp_v( A_LCCRT_CMP_LT_U, rb, ab, bb, r, a, b, rn, an, bn);
|
|
|
|
return;
|
|
} /* __lccrt_cmp_v_lt_u */
|
|
|
|
void
|
|
__lccrt_cmp_v_le_i( uint32_t rb, uint32_t ab, uint32_t bb, uint8_t *r, uint8_t *a, uint8_t *b,
|
|
uint32_t rn, uint32_t an, uint32_t bn)
|
|
{
|
|
__lccrt_cmp_v( A_LCCRT_CMP_LE_I, rb, ab, bb, r, a, b, rn, an, bn);
|
|
|
|
return;
|
|
} /* __lccrt_cmp_v_le_i */
|
|
|
|
void
|
|
__lccrt_cmp_v_le_u( uint32_t rb, uint32_t ab, uint32_t bb, uint8_t *r, uint8_t *a, uint8_t *b,
|
|
uint32_t rn, uint32_t an, uint32_t bn)
|
|
{
|
|
__lccrt_cmp_v( A_LCCRT_CMP_LE_U, rb, ab, bb, r, a, b, rn, an, bn);
|
|
|
|
return;
|
|
} /* __lccrt_cmp_v_le_u */
|
|
|
|
void
|
|
__lccrt_cmp_v_gt_i( uint32_t rb, uint32_t ab, uint32_t bb, uint8_t *r, uint8_t *a, uint8_t *b,
|
|
uint32_t rn, uint32_t an, uint32_t bn)
|
|
{
|
|
__lccrt_cmp_v( A_LCCRT_CMP_GT_I, rb, ab, bb, r, a, b, rn, an, bn);
|
|
|
|
return;
|
|
} /* __lccrt_cmp_v_gt_i */
|
|
|
|
void
|
|
__lccrt_cmp_v_gt_u( uint32_t rb, uint32_t ab, uint32_t bb, uint8_t *r, uint8_t *a, uint8_t *b,
|
|
uint32_t rn, uint32_t an, uint32_t bn)
|
|
{
|
|
__lccrt_cmp_v( A_LCCRT_CMP_GT_U, rb, ab, bb, r, a, b, rn, an, bn);
|
|
|
|
return;
|
|
} /* __lccrt_cmp_v_gt_u */
|
|
|
|
void
|
|
__lccrt_cmp_v_ge_i( uint32_t rb, uint32_t ab, uint32_t bb, uint8_t *r, uint8_t *a, uint8_t *b,
|
|
uint32_t rn, uint32_t an, uint32_t bn)
|
|
{
|
|
__lccrt_cmp_v( A_LCCRT_CMP_GE_I, rb, ab, bb, r, a, b, rn, an, bn);
|
|
|
|
return;
|
|
} /* __lccrt_cmp_v_ge_i */
|
|
|
|
void
|
|
__lccrt_cmp_v_ge_u( uint32_t rb, uint32_t ab, uint32_t bb, uint8_t *r, uint8_t *a, uint8_t *b,
|
|
uint32_t rn, uint32_t an, uint32_t bn)
|
|
{
|
|
__lccrt_cmp_v( A_LCCRT_CMP_GE_U, rb, ab, bb, r, a, b, rn, an, bn);
|
|
|
|
return;
|
|
} /* __lccrt_cmp_v_ge_u */
|
|
|
|
void
|
|
__lccrt_cmp_v_fo( uint32_t rb, uint32_t ab, uint32_t bb, uint8_t *r, uint8_t *a, uint8_t *b,
|
|
uint32_t rn, uint32_t an, uint32_t bn)
|
|
{
|
|
__lccrt_cmp_v( A_LCCRT_CMP_FO, rb, ab, bb, r, a, b, rn, an, bn);
|
|
|
|
return;
|
|
} /* __lccrt_cmp_v_fo */
|
|
|
|
void
|
|
__lccrt_cmp_v_eq_fo( uint32_t rb, uint32_t ab, uint32_t bb, uint8_t *r, uint8_t *a, uint8_t *b,
|
|
uint32_t rn, uint32_t an, uint32_t bn)
|
|
{
|
|
__lccrt_cmp_v( A_LCCRT_CMP_EQ_FO, rb, ab, bb, r, a, b, rn, an, bn);
|
|
|
|
return;
|
|
} /* __lccrt_cmp_v_eq_fo */
|
|
|
|
void
|
|
__lccrt_cmp_v_ne_fo( uint32_t rb, uint32_t ab, uint32_t bb, uint8_t *r, uint8_t *a, uint8_t *b,
|
|
uint32_t rn, uint32_t an, uint32_t bn)
|
|
{
|
|
__lccrt_cmp_v( A_LCCRT_CMP_NE_FO, rb, ab, bb, r, a, b, rn, an, bn);
|
|
|
|
return;
|
|
} /* __lccrt_cmp_v_ne_fo */
|
|
|
|
void
|
|
__lccrt_cmp_v_lt_fo( uint32_t rb, uint32_t ab, uint32_t bb, uint8_t *r, uint8_t *a, uint8_t *b,
|
|
uint32_t rn, uint32_t an, uint32_t bn)
|
|
{
|
|
__lccrt_cmp_v( A_LCCRT_CMP_LT_FO, rb, ab, bb, r, a, b, rn, an, bn);
|
|
|
|
return;
|
|
} /* __lccrt_cmp_v_lt_fo */
|
|
|
|
void
|
|
__lccrt_cmp_v_le_fo( uint32_t rb, uint32_t ab, uint32_t bb, uint8_t *r, uint8_t *a, uint8_t *b,
|
|
uint32_t rn, uint32_t an, uint32_t bn)
|
|
{
|
|
__lccrt_cmp_v( A_LCCRT_CMP_LE_FO, rb, ab, bb, r, a, b, rn, an, bn);
|
|
|
|
return;
|
|
} /* __lccrt_cmp_v_le_fo */
|
|
|
|
void
|
|
__lccrt_cmp_v_gt_fo( uint32_t rb, uint32_t ab, uint32_t bb, uint8_t *r, uint8_t *a, uint8_t *b,
|
|
uint32_t rn, uint32_t an, uint32_t bn)
|
|
{
|
|
__lccrt_cmp_v( A_LCCRT_CMP_GT_FO, rb, ab, bb, r, a, b, rn, an, bn);
|
|
|
|
return;
|
|
} /* __lccrt_cmp_v_gt_fo */
|
|
|
|
void
|
|
__lccrt_cmp_v_ge_fo( uint32_t rb, uint32_t ab, uint32_t bb, uint8_t *r, uint8_t *a, uint8_t *b,
|
|
uint32_t rn, uint32_t an, uint32_t bn)
|
|
{
|
|
__lccrt_cmp_v( A_LCCRT_CMP_GE_FO, rb, ab, bb, r, a, b, rn, an, bn);
|
|
|
|
return;
|
|
} /* __lccrt_cmp_v_ge_fo */
|
|
|
|
void
|
|
__lccrt_cmp_v_fu( uint32_t rb, uint32_t ab, uint32_t bb, uint8_t *r, uint8_t *a, uint8_t *b,
|
|
uint32_t rn, uint32_t an, uint32_t bn)
|
|
{
|
|
__lccrt_cmp_v( A_LCCRT_CMP_FU, rb, ab, bb, r, a, b, rn, an, bn);
|
|
|
|
return;
|
|
} /* __lccrt_cmp_v_fu */
|
|
|
|
void
|
|
__lccrt_cmp_v_eq_fu( uint32_t rb, uint32_t ab, uint32_t bb, uint8_t *r, uint8_t *a, uint8_t *b,
|
|
uint32_t rn, uint32_t an, uint32_t bn)
|
|
{
|
|
__lccrt_cmp_v( A_LCCRT_CMP_EQ_FU, rb, ab, bb, r, a, b, rn, an, bn);
|
|
|
|
return;
|
|
} /* __lccrt_cmp_v_eq_fu */
|
|
|
|
void
|
|
__lccrt_cmp_v_ne_fu( uint32_t rb, uint32_t ab, uint32_t bb, uint8_t *r, uint8_t *a, uint8_t *b,
|
|
uint32_t rn, uint32_t an, uint32_t bn)
|
|
{
|
|
__lccrt_cmp_v( A_LCCRT_CMP_NE_FU, rb, ab, bb, r, a, b, rn, an, bn);
|
|
|
|
return;
|
|
} /* __lccrt_cmp_v_ne_fu */
|
|
|
|
void
|
|
__lccrt_cmp_v_lt_fu( uint32_t rb, uint32_t ab, uint32_t bb, uint8_t *r, uint8_t *a, uint8_t *b,
|
|
uint32_t rn, uint32_t an, uint32_t bn)
|
|
{
|
|
__lccrt_cmp_v( A_LCCRT_CMP_LT_FU, rb, ab, bb, r, a, b, rn, an, bn);
|
|
|
|
return;
|
|
} /* __lccrt_cmp_v_lt_fu */
|
|
|
|
void
|
|
__lccrt_cmp_v_le_fu( uint32_t rb, uint32_t ab, uint32_t bb, uint8_t *r, uint8_t *a, uint8_t *b,
|
|
uint32_t rn, uint32_t an, uint32_t bn)
|
|
{
|
|
__lccrt_cmp_v( A_LCCRT_CMP_LE_FU, rb, ab, bb, r, a, b, rn, an, bn);
|
|
|
|
return;
|
|
} /* __lccrt_cmp_v_le_fu */
|
|
|
|
void
|
|
__lccrt_cmp_v_gt_fu( uint32_t rb, uint32_t ab, uint32_t bb, uint8_t *r, uint8_t *a, uint8_t *b,
|
|
uint32_t rn, uint32_t an, uint32_t bn)
|
|
{
|
|
__lccrt_cmp_v( A_LCCRT_CMP_GT_FU, rb, ab, bb, r, a, b, rn, an, bn);
|
|
|
|
return;
|
|
} /* __lccrt_cmp_v_gt_fu */
|
|
|
|
void
|
|
__lccrt_cmp_v_ge_fu( uint32_t rb, uint32_t ab, uint32_t bb, uint8_t *r, uint8_t *a, uint8_t *b,
|
|
uint32_t rn, uint32_t an, uint32_t bn)
|
|
{
|
|
__lccrt_cmp_v( A_LCCRT_CMP_GE_FU, rb, ab, bb, r, a, b, rn, an, bn);
|
|
|
|
return;
|
|
} /* __lccrt_cmp_v_ge_fu */
|
|
|
|
void
|
|
__lccrt_abs_n( uint32_t rb, uint32_t ab, uint8_t *r, uint8_t *a)
|
|
{
|
|
uint32_t num_digits = __LCCRT_NUM_DIGITS( rb, ab, ab);
|
|
uint32_t zr[num_digits];
|
|
uint32_t za[num_digits];
|
|
|
|
__lccrt_zn_set_bits( num_digits, 1, za, ab, a);
|
|
|
|
if ( (ab > 0)
|
|
&& (rb == ab) )
|
|
{
|
|
__lccrt_zn_abs( num_digits, zr, za, 0);
|
|
} else
|
|
{
|
|
__LCCRT_PRINT_BITS3( rb, ab, ab);
|
|
assert( 0);
|
|
}
|
|
|
|
__lccrt_zn_get_bits( num_digits, zr, ab, r);
|
|
|
|
return;
|
|
} /* __lccrt_abs_n */
|
|
|
|
void
|
|
__lccrt_shl_n( uint32_t rb, uint32_t ab, uint32_t bb, uint8_t *r, uint8_t *a, uint8_t *b)
|
|
{
|
|
int rlen = rb / 8;
|
|
int rlen1 = (rb + 7) / 8;
|
|
uint64_t vb = 0;
|
|
|
|
assert( rb == ab);
|
|
assert( rb == bb);
|
|
if ( (rb > 0) )
|
|
{
|
|
int64_t k;
|
|
|
|
if ( (rlen < rlen1) )
|
|
{
|
|
vb = __LCCRT_ZEXT( b[rlen], rb - 8*rlen);
|
|
}
|
|
|
|
for ( k = rlen - 1; k >= 0; k-- )
|
|
{
|
|
vb = 256*vb + b[k];
|
|
if ( (vb > rb) )
|
|
{
|
|
break;
|
|
}
|
|
}
|
|
|
|
if ( (vb >= rb) )
|
|
{
|
|
memset( r, 0, rlen1);
|
|
} else
|
|
{
|
|
int vbr = vb % 8;
|
|
int vbd = vb / 8;
|
|
|
|
memset( r, 0, vbd);
|
|
if ( (vbr == 0) )
|
|
{
|
|
memcpy( r + vbd, a, rlen1 - vbd);
|
|
} else
|
|
{
|
|
int k;
|
|
uint8_t lo = 0;
|
|
|
|
for ( k = vbd; k < rlen1; ++k )
|
|
{
|
|
uint8_t va = a[k - vbd];
|
|
|
|
r[k] = (va << vbr) | lo;
|
|
lo = va >> (8 - vbr);
|
|
}
|
|
}
|
|
|
|
if ( (rlen < rlen1) )
|
|
{
|
|
r[rlen] = __LCCRT_ZEXT( r[rlen], rb - 8*rlen);
|
|
}
|
|
}
|
|
}
|
|
|
|
return;
|
|
} /* __lccrt_shl_n */
|
|
|
|
void
|
|
__lccrt_shr_n( uint32_t rb, uint32_t ab, uint32_t bb, uint8_t *r, uint8_t *a, uint8_t *b)
|
|
{
|
|
int rlen = rb / 8;
|
|
int rlen1 = (rb + 7) / 8;
|
|
uint64_t vb = 0;
|
|
|
|
assert( rb == ab);
|
|
assert( rb == bb);
|
|
if ( (rb > 0) )
|
|
{
|
|
int64_t k;
|
|
|
|
if ( (rlen < rlen1) )
|
|
{
|
|
vb = __LCCRT_ZEXT( b[rlen], rb - 8*rlen);
|
|
}
|
|
|
|
for ( k = rlen - 1; k >= 0; k-- )
|
|
{
|
|
vb = 256*vb + b[k];
|
|
if ( (vb > rb) )
|
|
{
|
|
break;
|
|
}
|
|
}
|
|
|
|
if ( (vb >= rb) )
|
|
{
|
|
memset( r, 0, rlen1);
|
|
} else
|
|
{
|
|
int vbr = vb % 8;
|
|
int vbd = vb / 8;
|
|
|
|
memset( r + rlen1 - vbd, 0, vbd);
|
|
if ( (vbr == 0) )
|
|
{
|
|
memcpy( r, a + vbd, rlen1 - vbd);
|
|
} else
|
|
{
|
|
int k;
|
|
uint8_t hi = 0;
|
|
|
|
for ( k = rlen1 - vbd - 1; k >= 0; --k )
|
|
{
|
|
uint8_t va = a[k + vbd];
|
|
|
|
va = ((k == rlen1 - vbd - 1) && (rlen < rlen1)) ? __LCCRT_ZEXT( va, rb - 8*rlen) : va;
|
|
r[k] = hi | (va >> vbr);
|
|
hi = va << (8 - vbr);
|
|
}
|
|
}
|
|
|
|
if ( (rlen < rlen1) )
|
|
{
|
|
r[rlen1 - vbd - 1] = __LCCRT_ZEXT( r[rlen1 - vbd - 1], rb - 8*rlen);
|
|
}
|
|
}
|
|
}
|
|
|
|
return;
|
|
} /* __lccrt_shr_n */
|
|
|
|
void
|
|
__lccrt_sar_n( uint32_t rb, uint32_t ab, uint32_t bb, uint8_t *r, uint8_t *a, uint8_t *b)
|
|
{
|
|
uint32_t num_digits = __LCCRT_NUM_DIGITS( rb, ab, bb);
|
|
uint32_t zr[num_digits];
|
|
uint32_t za[num_digits];
|
|
uint32_t zb[num_digits];
|
|
|
|
__lccrt_zn_set_bits( num_digits, 1, za, ab, a);
|
|
__lccrt_zn_set_bits( num_digits, 0, zb, bb, b);
|
|
|
|
if ( (ab > 0)
|
|
&& (ab == bb)
|
|
&& (rb == ab) )
|
|
{
|
|
__lccrt_zn_sar( num_digits, zr, za, zb, 0);
|
|
} else
|
|
{
|
|
__LCCRT_PRINT_BITS3( rb, ab, bb);
|
|
assert( 0);
|
|
}
|
|
|
|
__lccrt_zn_get_bits( num_digits, zr, rb, r);
|
|
|
|
return;
|
|
} /* __lccrt_sar_n */
|
|
|
|
void
|
|
__lccrt_fshl_n( uint32_t rb, uint32_t ab, uint32_t bb, uint32_t cb, uint8_t *r, uint8_t *a, uint8_t *b, uint8_t *c)
|
|
{
|
|
uint32_t num_digits = __LCCRT_NUM_DIGITS4( rb, ab, bb, cb);
|
|
uint32_t zr[num_digits];
|
|
uint32_t za[num_digits];
|
|
uint32_t zb[num_digits];
|
|
uint32_t zc[num_digits];
|
|
uint32_t zd[num_digits];
|
|
uint32_t ze[num_digits];
|
|
uint32_t zf[num_digits];
|
|
|
|
__lccrt_zn_set_bits( num_digits, 0, za, ab, a);
|
|
__lccrt_zn_set_bits( num_digits, 0, zb, bb, b);
|
|
__lccrt_zn_set_bits( num_digits, 0, zc, cb, c);
|
|
|
|
if ( (ab > 0)
|
|
&& (ab == bb)
|
|
&& (ab == cb)
|
|
&& (rb == ab) )
|
|
{
|
|
memset( zf, 0, 4*num_digits);
|
|
zc[0] = zc[0] % ab;
|
|
zf[0] = (ab - zc[0]) % ab;
|
|
if ( (zc[0] == 0) )
|
|
{
|
|
memcpy( zr, za, 4*num_digits);
|
|
} else
|
|
{
|
|
__lccrt_zn_shl( num_digits, zd, za, zc);
|
|
__lccrt_zn_shr( num_digits, ze, zb, zf);
|
|
__lccrt_zn_ior( num_digits, zr, zd, ze);
|
|
}
|
|
} else
|
|
{
|
|
__LCCRT_PRINT_BITS4( rb, ab, bb, cb);
|
|
assert( 0);
|
|
}
|
|
|
|
__lccrt_zn_get_bits( num_digits, zr, rb, r);
|
|
|
|
return;
|
|
} /* __lccrt_fshl_n */
|
|
|
|
void
|
|
__lccrt_and_n( uint32_t rb, uint32_t ab, uint32_t bb, uint8_t *r, uint8_t *a, uint8_t *b)
|
|
{
|
|
int rlen = rb / 8;
|
|
int rlen1 = (rb + 7) / 8;
|
|
|
|
assert( rb == ab);
|
|
assert( rb == bb);
|
|
if ( (rb > 0) )
|
|
{
|
|
int64_t k;
|
|
|
|
for ( k = 0; k < rlen; k++ )
|
|
{
|
|
r[k] = a[k] & b[k];
|
|
}
|
|
|
|
if ( (rlen < rlen1) )
|
|
{
|
|
uint8_t v = a[rlen] & b[rlen];
|
|
|
|
r[rlen] = __LCCRT_ZEXT( v, rb - 8*rlen);
|
|
}
|
|
}
|
|
|
|
return;
|
|
} /* __lccrt_and_n */
|
|
|
|
void
|
|
__lccrt_or_n( uint32_t rb, uint32_t ab, uint32_t bb, uint8_t *r, uint8_t *a, uint8_t *b)
|
|
{
|
|
int rlen = rb / 8;
|
|
int rlen1 = (rb + 7) / 8;
|
|
|
|
assert( rb == ab);
|
|
assert( rb == bb);
|
|
if ( (rb > 0) )
|
|
{
|
|
int64_t k;
|
|
|
|
for ( k = 0; k < rlen; k++ )
|
|
{
|
|
r[k] = a[k] | b[k];
|
|
}
|
|
|
|
if ( (rlen < rlen1) )
|
|
{
|
|
uint8_t v = a[rlen] | b[rlen];
|
|
|
|
r[rlen] = __LCCRT_ZEXT( v, rb - 8*rlen);
|
|
}
|
|
}
|
|
|
|
return;
|
|
} /* __lccrt_or_n */
|
|
|
|
void
|
|
__lccrt_xor_n( uint32_t rb, uint32_t ab, uint32_t bb, uint8_t *r, uint8_t *a, uint8_t *b)
|
|
{
|
|
int rlen = rb / 8;
|
|
int rlen1 = (rb + 7) / 8;
|
|
|
|
assert( rb == ab);
|
|
assert( rb == bb);
|
|
if ( (rb > 0) )
|
|
{
|
|
int64_t k;
|
|
|
|
for ( k = 0; k < rlen; k++ )
|
|
{
|
|
r[k] = a[k] ^ b[k];
|
|
}
|
|
|
|
if ( (rlen < rlen1) )
|
|
{
|
|
uint8_t v = a[rlen] ^ b[rlen];
|
|
|
|
r[rlen] = __LCCRT_ZEXT( v, rb - 8*rlen);
|
|
}
|
|
}
|
|
|
|
return;
|
|
} /* __lccrt_xor_n */
|
|
|
|
void
|
|
__lccrt_add_n( uint32_t rb, uint32_t ab, uint32_t bb, uint8_t *r, uint8_t *a, uint8_t *b)
|
|
{
|
|
uint32_t num_digits = __LCCRT_NUM_DIGITS( rb, ab, bb);
|
|
uint32_t zr[num_digits];
|
|
uint32_t za[num_digits];
|
|
uint32_t zb[num_digits];
|
|
|
|
__lccrt_zn_set_bits( num_digits, 0, za, ab, a);
|
|
__lccrt_zn_set_bits( num_digits, 0, zb, bb, b);
|
|
|
|
if ( (ab > 0)
|
|
&& (ab == bb)
|
|
&& (rb == ab) )
|
|
{
|
|
__lccrt_zn_add( num_digits, zr, za, zb, 0);
|
|
} else
|
|
{
|
|
__LCCRT_PRINT_BITS3( rb, ab, bb);
|
|
assert( 0);
|
|
}
|
|
|
|
__lccrt_zn_get_bits( num_digits, zr, rb, r);
|
|
|
|
return;
|
|
} /* __lccrt_add_n */
|
|
|
|
void
|
|
__lccrt_sub_n( uint32_t rb, uint32_t ab, uint32_t bb, uint8_t *r, uint8_t *a, uint8_t *b)
|
|
{
|
|
uint32_t num_digits = __LCCRT_NUM_DIGITS( rb, ab, bb);
|
|
uint32_t zr[num_digits];
|
|
uint32_t za[num_digits];
|
|
uint32_t zb[num_digits];
|
|
|
|
__lccrt_zn_set_bits( num_digits, 0, za, ab, a);
|
|
__lccrt_zn_set_bits( num_digits, 0, zb, bb, b);
|
|
|
|
if ( (ab > 0)
|
|
&& (ab == bb)
|
|
&& (rb == ab) )
|
|
{
|
|
__lccrt_zn_sub( num_digits, zr, za, zb, 0);
|
|
} else
|
|
{
|
|
__LCCRT_PRINT_BITS3( rb, ab, bb);
|
|
assert( 0);
|
|
}
|
|
|
|
__lccrt_zn_get_bits( num_digits, zr, rb, r);
|
|
|
|
return;
|
|
} /* __lccrt_sub_n */
|
|
|
|
void
|
|
__lccrt_mul_n( uint32_t rb, uint32_t ab, uint32_t bb, uint8_t *r, uint8_t *a, uint8_t *b)
|
|
{
|
|
uint32_t num_digits = __LCCRT_NUM_DIGITS( rb, ab, bb);
|
|
uint32_t zr[num_digits];
|
|
uint32_t za[num_digits];
|
|
uint32_t zb[num_digits];
|
|
|
|
__lccrt_zn_set_bits( num_digits, 0, za, ab, a);
|
|
__lccrt_zn_set_bits( num_digits, 0, zb, bb, b);
|
|
|
|
if ( (ab > 0)
|
|
&& (ab == bb)
|
|
&& (rb == ab) )
|
|
{
|
|
__lccrt_zn_mul( num_digits, zr, za, zb, 0);
|
|
} else
|
|
{
|
|
__LCCRT_PRINT_BITS3( rb, ab, bb);
|
|
assert( 0);
|
|
}
|
|
|
|
__lccrt_zn_get_bits( num_digits, zr, rb, r);
|
|
|
|
return;
|
|
} /* __lccrt_mul_n */
|
|
|
|
void
|
|
__lccrt_udiv_n( uint32_t rb, uint32_t ab, uint32_t bb, uint8_t *r, uint8_t *a, uint8_t *b)
|
|
{
|
|
uint32_t num_digits = __LCCRT_NUM_DIGITS( rb, ab, bb);
|
|
uint32_t zr[num_digits];
|
|
uint32_t za[num_digits];
|
|
uint32_t zb[num_digits];
|
|
|
|
__lccrt_zn_set_bits( num_digits, 0, za, ab, a);
|
|
__lccrt_zn_set_bits( num_digits, 0, zb, bb, b);
|
|
|
|
if ( (ab > 0)
|
|
&& (ab == bb)
|
|
&& (rb == ab) )
|
|
{
|
|
__lccrt_zn_udiv( num_digits, zr, za, zb, 0);
|
|
} else
|
|
{
|
|
__LCCRT_PRINT_BITS3( rb, ab, bb);
|
|
assert( 0);
|
|
}
|
|
|
|
__lccrt_zn_get_bits( num_digits, zr, rb, r);
|
|
|
|
return;
|
|
} /* __lccrt_udiv_n */
|
|
|
|
void
|
|
__lccrt_sdiv_n( uint32_t rb, uint32_t ab, uint32_t bb, uint8_t *r, uint8_t *a, uint8_t *b)
|
|
{
|
|
uint32_t num_digits = __LCCRT_NUM_DIGITS( rb, ab, bb);
|
|
uint32_t zr[num_digits];
|
|
uint32_t za[num_digits];
|
|
uint32_t zb[num_digits];
|
|
|
|
__lccrt_zn_set_bits( num_digits, 1, za, ab, a);
|
|
__lccrt_zn_set_bits( num_digits, 1, zb, bb, b);
|
|
|
|
if ( (ab > 0)
|
|
&& (ab == bb)
|
|
&& (rb == ab) )
|
|
{
|
|
__lccrt_zn_sdiv( num_digits, zr, za, zb, 0);
|
|
} else
|
|
{
|
|
__LCCRT_PRINT_BITS3( rb, ab, bb);
|
|
assert( 0);
|
|
}
|
|
|
|
__lccrt_zn_get_bits( num_digits, zr, rb, r);
|
|
|
|
return;
|
|
} /* __lccrt_sdiv_n */
|
|
|
|
void
|
|
__lccrt_umod_n( uint32_t rb, uint32_t ab, uint32_t bb, uint8_t *r, uint8_t *a, uint8_t *b)
|
|
{
|
|
uint32_t num_digits = __LCCRT_NUM_DIGITS( rb, ab, bb);
|
|
uint32_t zr[num_digits];
|
|
uint32_t za[num_digits];
|
|
uint32_t zb[num_digits];
|
|
|
|
__lccrt_zn_set_bits( num_digits, 0, za, ab, a);
|
|
__lccrt_zn_set_bits( num_digits, 0, zb, bb, b);
|
|
|
|
if ( (ab > 0)
|
|
&& (ab == bb)
|
|
&& (rb == ab) )
|
|
{
|
|
__lccrt_zn_umod( num_digits, zr, za, zb, 0);
|
|
} else
|
|
{
|
|
__LCCRT_PRINT_BITS3( rb, ab, bb);
|
|
assert( 0);
|
|
}
|
|
|
|
__lccrt_zn_get_bits( num_digits, zr, rb, r);
|
|
|
|
return;
|
|
} /* __lccrt_umod_n */
|
|
|
|
void
|
|
__lccrt_smod_n( uint32_t rb, uint32_t ab, uint32_t bb, uint8_t *r, uint8_t *a, uint8_t *b)
|
|
{
|
|
uint32_t num_digits = __LCCRT_NUM_DIGITS( rb, ab, bb);
|
|
uint32_t zr[num_digits];
|
|
uint32_t za[num_digits];
|
|
uint32_t zb[num_digits];
|
|
|
|
__lccrt_zn_set_bits( num_digits, 1, za, ab, a);
|
|
__lccrt_zn_set_bits( num_digits, 1, zb, bb, b);
|
|
|
|
if ( (ab > 0)
|
|
&& (ab == bb)
|
|
&& (rb == ab) )
|
|
{
|
|
__lccrt_zn_smod( num_digits, zr, za, zb, 0);
|
|
} else
|
|
{
|
|
__LCCRT_PRINT_BITS3( rb, ab, bb);
|
|
assert( 0);
|
|
}
|
|
|
|
__lccrt_zn_get_bits( num_digits, zr, rb, r);
|
|
|
|
return;
|
|
} /* __lccrt_smod_n */
|
|
|
|
static void
|
|
__lccrt_ffunc_n( __lccrt_ffunc32_t f32, __lccrt_ffunc64_t f64, __lccrt_ffunc80_t f80,
|
|
uint32_t rb, uint32_t ab, uint32_t bb, uint8_t *r, uint8_t *a, uint8_t *b)
|
|
{
|
|
if ( (rb == ab)
|
|
&& (ab == bb)
|
|
&& (ab > 0) )
|
|
{
|
|
if ( (rb == 32) )
|
|
{
|
|
float v, u0, u1;
|
|
|
|
memcpy( &u0, a, sizeof( u0));
|
|
memcpy( &u1, b, sizeof( u1));
|
|
v = (*f32)( u0, u1);
|
|
memcpy( r, &v, sizeof( v));
|
|
|
|
} else if ( (rb == 64) )
|
|
{
|
|
double v, u0, u1;
|
|
|
|
memcpy( &u0, a, sizeof( u0));
|
|
memcpy( &u1, b, sizeof( u1));
|
|
v = (*f64)( u0, u1);
|
|
memcpy( r, &v, sizeof( v));
|
|
|
|
} else if ( (rb == 80) )
|
|
{
|
|
long double v, u0, u1;
|
|
|
|
memcpy( &u0, a, sizeof( u0));
|
|
memcpy( &u1, b, sizeof( u1));
|
|
v = (*f80)( u0, u1);
|
|
memcpy( r, &v, sizeof( v));
|
|
} else
|
|
{
|
|
__LCCRT_PRINT_BITS3( rb, ab, bb);
|
|
assert( 0);
|
|
}
|
|
} else
|
|
{
|
|
__LCCRT_PRINT_BITS3( rb, ab, bb);
|
|
assert( 0);
|
|
}
|
|
|
|
return;
|
|
} /* __lccrt_ffunc_n */
|
|
|
|
static void
|
|
__lccrt_ffunc3_n( __lccrt_ffunc32_3_t f32, __lccrt_ffunc64_3_t f64, __lccrt_ffunc80_3_t f80,
|
|
uint32_t rb, uint32_t ab, uint32_t bb, uint32_t cb,
|
|
uint8_t *r, uint8_t *a, uint8_t *b, uint8_t *c)
|
|
{
|
|
if ( (rb == ab)
|
|
&& (rb == bb)
|
|
&& (rb == cb)
|
|
&& (rb > 0) )
|
|
{
|
|
if ( (rb == 32) )
|
|
{
|
|
float v, u0, u1, u2;
|
|
|
|
memcpy( &u0, a, sizeof( u0));
|
|
memcpy( &u1, b, sizeof( u1));
|
|
memcpy( &u2, c, sizeof( u2));
|
|
v = (*f32)( u0, u1, u2);
|
|
memcpy( r, &v, sizeof( v));
|
|
|
|
} else if ( (rb == 64) )
|
|
{
|
|
double v, u0, u1, u2;
|
|
|
|
memcpy( &u0, a, sizeof( u0));
|
|
memcpy( &u1, b, sizeof( u1));
|
|
memcpy( &u2, c, sizeof( u2));
|
|
v = (*f64)( u0, u1, u2);
|
|
memcpy( r, &v, sizeof( v));
|
|
|
|
} else if ( (rb == 80) )
|
|
{
|
|
long double v, u0, u1, u2;
|
|
|
|
memcpy( &u0, a, sizeof( u0));
|
|
memcpy( &u1, b, sizeof( u1));
|
|
memcpy( &u2, c, sizeof( u2));
|
|
v = (*f80)( u0, u1, u2);
|
|
memcpy( r, &v, sizeof( v));
|
|
} else
|
|
{
|
|
__LCCRT_PRINT_BITS4( rb, ab, bb, cb);
|
|
assert( 0);
|
|
}
|
|
} else
|
|
{
|
|
__LCCRT_PRINT_BITS4( rb, ab, bb, cb);
|
|
assert( 0);
|
|
}
|
|
|
|
return;
|
|
} /* __lccrt_ffunc3_n */
|
|
|
|
static __lccrt_f32_t __lccrt_fadd32( __lccrt_f32_t x, __lccrt_f32_t y) { return (x + y); }
|
|
static __lccrt_f64_t __lccrt_fadd64( __lccrt_f64_t x, __lccrt_f64_t y) { return (x + y); }
|
|
static __lccrt_f80_t __lccrt_fadd80( __lccrt_f80_t x, __lccrt_f80_t y) { return (x + y); }
|
|
|
|
void
|
|
__lccrt_fadd_n( uint32_t rb, uint32_t ab, uint32_t bb, uint8_t *r, uint8_t *a, uint8_t *b)
|
|
{
|
|
__lccrt_ffunc_n( &__lccrt_fadd32, &__lccrt_fadd64, &__lccrt_fadd80, rb, ab, bb, r, a, b);
|
|
|
|
return;
|
|
} /* __lccrt_fadd_n */
|
|
|
|
static __lccrt_f32_t __lccrt_fsub32( __lccrt_f32_t x, __lccrt_f32_t y) { return (x - y); }
|
|
static __lccrt_f64_t __lccrt_fsub64( __lccrt_f64_t x, __lccrt_f64_t y) { return (x - y); }
|
|
static __lccrt_f80_t __lccrt_fsub80( __lccrt_f80_t x, __lccrt_f80_t y) { return (x - y); }
|
|
|
|
void
|
|
__lccrt_fsub_n( uint32_t rb, uint32_t ab, uint32_t bb, uint8_t *r, uint8_t *a, uint8_t *b)
|
|
{
|
|
__lccrt_ffunc_n( &__lccrt_fsub32, &__lccrt_fsub64, &__lccrt_fsub80, rb, ab, bb, r, a, b);
|
|
|
|
return;
|
|
} /* __lccrt_fsub_n */
|
|
|
|
static __lccrt_f32_t __lccrt_fmul32( __lccrt_f32_t x, __lccrt_f32_t y) { return (x * y); }
|
|
static __lccrt_f64_t __lccrt_fmul64( __lccrt_f64_t x, __lccrt_f64_t y) { return (x * y); }
|
|
static __lccrt_f80_t __lccrt_fmul80( __lccrt_f80_t x, __lccrt_f80_t y) { return (x * y); }
|
|
|
|
void
|
|
__lccrt_fmul_n( uint32_t rb, uint32_t ab, uint32_t bb, uint8_t *r, uint8_t *a, uint8_t *b)
|
|
{
|
|
__lccrt_ffunc_n( &__lccrt_fmul32, &__lccrt_fmul64, &__lccrt_fmul80, rb, ab, bb, r, a, b);
|
|
|
|
return;
|
|
} /* __lccrt_fmul_n */
|
|
|
|
static __lccrt_f32_t __lccrt_fmuladd32( __lccrt_f32_t x, __lccrt_f32_t y, __lccrt_f32_t z) { return (x*y + z); }
|
|
static __lccrt_f64_t __lccrt_fmuladd64( __lccrt_f64_t x, __lccrt_f64_t y, __lccrt_f64_t z) { return (x*y + z); }
|
|
static __lccrt_f80_t __lccrt_fmuladd80( __lccrt_f80_t x, __lccrt_f80_t y, __lccrt_f80_t z) { return (x*y + z); }
|
|
|
|
void
|
|
__lccrt_fmuladd_n( uint32_t rb, uint32_t ab, uint32_t bb, uint32_t cb, uint8_t *r, uint8_t *a, uint8_t *b, uint8_t *c)
|
|
{
|
|
__lccrt_ffunc3_n( &__lccrt_fmuladd32, &__lccrt_fmuladd64, &__lccrt_fmuladd80, rb, ab, bb, cb, r, a, b, c);
|
|
|
|
return;
|
|
} /* __lccrt_fmuladd_n */
|
|
|
|
static __lccrt_f32_t __lccrt_fdiv32( __lccrt_f32_t x, __lccrt_f32_t y) { return (x / y); }
|
|
static __lccrt_f64_t __lccrt_fdiv64( __lccrt_f64_t x, __lccrt_f64_t y) { return (x / y); }
|
|
static __lccrt_f80_t __lccrt_fdiv80( __lccrt_f80_t x, __lccrt_f80_t y) { return (x / y); }
|
|
|
|
void
|
|
__lccrt_fdiv_n( uint32_t rb, uint32_t ab, uint32_t bb, uint8_t *r, uint8_t *a, uint8_t *b)
|
|
{
|
|
__lccrt_ffunc_n( &__lccrt_fdiv32, &__lccrt_fdiv64, &__lccrt_fdiv80, rb, ab, bb, r, a, b);
|
|
|
|
return;
|
|
} /* __lccrt_fdiv_n */
|
|
|
|
void
|
|
__lccrt_fmod_n( uint32_t rb, uint32_t ab, uint32_t bb, uint8_t *r, uint8_t *a, uint8_t *b)
|
|
{
|
|
if ( (rb == ab)
|
|
&& (ab == bb)
|
|
&& (ab > 0) )
|
|
{
|
|
if ( (rb == 32) )
|
|
{
|
|
float v, u0, u1;
|
|
|
|
memcpy( &u0, a, sizeof( u0));
|
|
memcpy( &u1, b, sizeof( u1));
|
|
v = fmodf( u0, u1);
|
|
memcpy( r, &v, sizeof( v));
|
|
|
|
} else if ( (rb == 64) )
|
|
{
|
|
double v, u0, u1;
|
|
|
|
memcpy( &u0, a, sizeof( u0));
|
|
memcpy( &u1, b, sizeof( u1));
|
|
v = fmod( u0, u1);
|
|
memcpy( r, &v, sizeof( v));
|
|
|
|
} else if ( (rb == 80) )
|
|
{
|
|
long double v, u0, u1;
|
|
|
|
memcpy( &u0, a, sizeof( u0));
|
|
memcpy( &u1, b, sizeof( u1));
|
|
v = fmodl( u0, u1);
|
|
memcpy( r, &v, sizeof( v));
|
|
} else
|
|
{
|
|
__LCCRT_PRINT_BITS3( rb, ab, bb);
|
|
assert( 0);
|
|
}
|
|
} else
|
|
{
|
|
__LCCRT_PRINT_BITS3( rb, ab, bb);
|
|
assert( 0);
|
|
}
|
|
|
|
return;
|
|
} /* __lccrt_fmod_n */
|
|
|
|
void
|
|
__lccrt_minnum_n( uint32_t rb, uint32_t ab, uint32_t bb, uint8_t *r, uint8_t *a, uint8_t *b)
|
|
{
|
|
if ( (rb == ab)
|
|
&& (ab == bb)
|
|
&& (ab > 0) )
|
|
{
|
|
if ( (rb == 32) )
|
|
{
|
|
float v, u0, u1;
|
|
|
|
memcpy( &u0, a, sizeof( u0));
|
|
memcpy( &u1, b, sizeof( u1));
|
|
v = __builtin_fminf( u0, u1);
|
|
memcpy( r, &v, sizeof( v));
|
|
|
|
} else if ( (rb == 64) )
|
|
{
|
|
double v, u0, u1;
|
|
|
|
memcpy( &u0, a, sizeof( u0));
|
|
memcpy( &u1, b, sizeof( u1));
|
|
v = __builtin_fmin( u0, u1);
|
|
memcpy( r, &v, sizeof( v));
|
|
|
|
} else if ( (rb == 80) )
|
|
{
|
|
long double v, u0, u1;
|
|
|
|
memcpy( &u0, a, sizeof( u0));
|
|
memcpy( &u1, b, sizeof( u1));
|
|
v = __builtin_fminl( u0, u1);
|
|
memcpy( r, &v, sizeof( v));
|
|
} else
|
|
{
|
|
__LCCRT_PRINT_BITS3( rb, ab, bb);
|
|
assert( 0);
|
|
}
|
|
} else
|
|
{
|
|
__LCCRT_PRINT_BITS3( rb, ab, bb);
|
|
assert( 0);
|
|
}
|
|
|
|
return;
|
|
} /* __lccrt_minnum_n */
|
|
|
|
void
|
|
__lccrt_maxnum_n( uint32_t rb, uint32_t ab, uint32_t bb, uint8_t *r, uint8_t *a, uint8_t *b)
|
|
{
|
|
if ( (rb == ab)
|
|
&& (ab == bb)
|
|
&& (ab > 0) )
|
|
{
|
|
if ( (rb == 32) )
|
|
{
|
|
float v, u0, u1;
|
|
|
|
memcpy( &u0, a, sizeof( u0));
|
|
memcpy( &u1, b, sizeof( u1));
|
|
v = __builtin_fmaxf( u0, u1);
|
|
memcpy( r, &v, sizeof( v));
|
|
|
|
} else if ( (rb == 64) )
|
|
{
|
|
double v, u0, u1;
|
|
|
|
memcpy( &u0, a, sizeof( u0));
|
|
memcpy( &u1, b, sizeof( u1));
|
|
v = __builtin_fmax( u0, u1);
|
|
memcpy( r, &v, sizeof( v));
|
|
|
|
} else if ( (rb == 80) )
|
|
{
|
|
long double v, u0, u1;
|
|
|
|
memcpy( &u0, a, sizeof( u0));
|
|
memcpy( &u1, b, sizeof( u1));
|
|
v = __builtin_fmaxl( u0, u1);
|
|
memcpy( r, &v, sizeof( v));
|
|
} else
|
|
{
|
|
__LCCRT_PRINT_BITS3( rb, ab, bb);
|
|
assert( 0);
|
|
}
|
|
} else
|
|
{
|
|
__LCCRT_PRINT_BITS3( rb, ab, bb);
|
|
assert( 0);
|
|
}
|
|
|
|
return;
|
|
} /* __lccrt_maxnum_n */
|
|
|
|
void
|
|
__lccrt_fneg_n( uint32_t rb, uint32_t ab, uint8_t *r, uint8_t *a)
|
|
{
|
|
if ( (rb == ab)
|
|
&& (ab > 0) )
|
|
{
|
|
if ( (rb == 32) )
|
|
{
|
|
float v, u0;
|
|
|
|
memcpy( &u0, a, sizeof( u0));
|
|
v = -u0;
|
|
memcpy( r, &v, sizeof( v));
|
|
|
|
} else if ( (rb == 64) )
|
|
{
|
|
double v, u0;
|
|
|
|
memcpy( &u0, a, sizeof( u0));
|
|
v = -u0;
|
|
memcpy( r, &v, sizeof( v));
|
|
|
|
} else if ( (rb == 80) )
|
|
{
|
|
long double v, u0;
|
|
|
|
memcpy( &u0, a, sizeof( u0));
|
|
v = -u0;
|
|
memcpy( r, &v, sizeof( v));
|
|
} else
|
|
{
|
|
__LCCRT_PRINT_BITS2( rb, ab);
|
|
assert( 0);
|
|
}
|
|
} else
|
|
{
|
|
__LCCRT_PRINT_BITS2( rb, ab);
|
|
assert( 0);
|
|
}
|
|
|
|
return;
|
|
} /* __lccrt_fneg_n */
|
|
|
|
void
|
|
__lccrt_fptofp_n( uint32_t rb, uint32_t ab, uint8_t *r, uint8_t *a)
|
|
{
|
|
int is_conv = 0;
|
|
|
|
if ( (ab == 32) )
|
|
{
|
|
float u0;
|
|
|
|
memcpy( &u0, a, sizeof( u0));
|
|
if ( (rb == 32) ) { is_conv = 1; __LCCRT_CONV( r, float, u0); }
|
|
else if ( (rb == 64) ) { is_conv = 1; __LCCRT_CONV( r, double, u0); }
|
|
else if ( (rb == 80) ) { is_conv = 1; __LCCRT_CONV( r, long double, u0); }
|
|
|
|
} else if ( (ab == 64) )
|
|
{
|
|
double u0;
|
|
|
|
memcpy( &u0, a, sizeof( u0));
|
|
if ( (rb == 32) ) { is_conv = 1; __LCCRT_CONV( r, float, u0); }
|
|
else if ( (rb == 64) ) { is_conv = 1; __LCCRT_CONV( r, double, u0); }
|
|
else if ( (rb == 80) ) { is_conv = 1; __LCCRT_CONV( r, long double, u0); }
|
|
|
|
} else if ( (ab == 80) )
|
|
{
|
|
long double u0;
|
|
|
|
memcpy( &u0, a, sizeof( u0));
|
|
if ( (rb == 32) ) { is_conv = 1; __LCCRT_CONV( r, float, u0); }
|
|
else if ( (rb == 64) ) { is_conv = 1; __LCCRT_CONV( r, double, u0); }
|
|
else if ( (rb == 80) ) { is_conv = 1; __LCCRT_CONV( r, long double, u0); }
|
|
}
|
|
|
|
if ( !is_conv )
|
|
{
|
|
__LCCRT_PRINT_BITS2( rb, ab);
|
|
assert( 0);
|
|
}
|
|
|
|
return;
|
|
} /* __lccrt_fptofp_n */
|
|
|
|
void
|
|
__lccrt_fptosi_n( uint32_t rb, uint32_t ab, uint8_t *r, uint8_t *a)
|
|
{
|
|
int is_conv = 0;
|
|
|
|
if ( (ab == 32) )
|
|
{
|
|
float u0;
|
|
|
|
memcpy( &u0, a, sizeof( u0));
|
|
if ( (rb == 8) ) { is_conv = 1; __LCCRT_CONV( r, int8_t, u0); }
|
|
else if ( (rb == 16) ) { is_conv = 1; __LCCRT_CONV( r, int16_t, u0); }
|
|
else if ( (rb == 32) ) { is_conv = 1; __LCCRT_CONV( r, int32_t, u0); }
|
|
else if ( (rb == 64) ) { is_conv = 1; __LCCRT_CONV( r, int64_t, u0); }
|
|
|
|
} else if ( (ab == 64) )
|
|
{
|
|
double u0;
|
|
|
|
memcpy( &u0, a, sizeof( u0));
|
|
if ( (rb == 8) ) { is_conv = 1; __LCCRT_CONV( r, int8_t, u0); }
|
|
else if ( (rb == 16) ) { is_conv = 1; __LCCRT_CONV( r, int16_t, u0); }
|
|
else if ( (rb == 32) ) { is_conv = 1; __LCCRT_CONV( r, int32_t, u0); }
|
|
else if ( (rb == 64) ) { is_conv = 1; __LCCRT_CONV( r, int64_t, u0); }
|
|
|
|
} else if ( (ab == 80) )
|
|
{
|
|
long double u0;
|
|
|
|
memcpy( &u0, a, sizeof( u0));
|
|
if ( (rb == 8) ) { is_conv = 1; __LCCRT_CONV( r, int8_t, u0); }
|
|
else if ( (rb == 16) ) { is_conv = 1; __LCCRT_CONV( r, int16_t, u0); }
|
|
else if ( (rb == 32) ) { is_conv = 1; __LCCRT_CONV( r, int32_t, u0); }
|
|
else if ( (rb == 64) ) { is_conv = 1; __LCCRT_CONV( r, int64_t, u0); }
|
|
}
|
|
|
|
if ( !is_conv )
|
|
{
|
|
__LCCRT_PRINT_BITS2( rb, ab);
|
|
assert( 0);
|
|
}
|
|
|
|
return;
|
|
} /* __lccrt_fptosi_n */
|
|
|
|
void
|
|
__lccrt_fptoui_n( uint32_t rb, uint32_t ab, uint8_t *r, uint8_t *a)
|
|
{
|
|
int is_conv = 0;
|
|
|
|
if ( (ab == 32) )
|
|
{
|
|
float u0;
|
|
|
|
memcpy( &u0, a, sizeof( u0));
|
|
if ( (rb == 8) ) { is_conv = 1; __LCCRT_CONV( r, uint8_t, u0); }
|
|
else if ( (rb == 16) ) { is_conv = 1; __LCCRT_CONV( r, uint16_t, u0); }
|
|
else if ( (rb == 32) ) { is_conv = 1; __LCCRT_CONV( r, uint32_t, u0); }
|
|
else if ( (rb == 64) ) { is_conv = 1; __LCCRT_CONV( r, uint64_t, u0); }
|
|
|
|
} else if ( (ab == 64) )
|
|
{
|
|
double u0;
|
|
|
|
memcpy( &u0, a, sizeof( u0));
|
|
if ( (rb == 8) ) { is_conv = 1; __LCCRT_CONV( r, uint8_t, u0); }
|
|
else if ( (rb == 16) ) { is_conv = 1; __LCCRT_CONV( r, uint16_t, u0); }
|
|
else if ( (rb == 32) ) { is_conv = 1; __LCCRT_CONV( r, uint32_t, u0); }
|
|
else if ( (rb == 64) ) { is_conv = 1; __LCCRT_CONV( r, uint64_t, u0); }
|
|
|
|
} else if ( (ab == 80) )
|
|
{
|
|
long double u0;
|
|
|
|
memcpy( &u0, a, sizeof( u0));
|
|
if ( (rb == 8) ) { is_conv = 1; __LCCRT_CONV( r, uint8_t, u0); }
|
|
else if ( (rb == 16) ) { is_conv = 1; __LCCRT_CONV( r, uint16_t, u0); }
|
|
else if ( (rb == 32) ) { is_conv = 1; __LCCRT_CONV( r, uint32_t, u0); }
|
|
else if ( (rb == 64) ) { is_conv = 1; __LCCRT_CONV( r, uint64_t, u0); }
|
|
}
|
|
|
|
if ( !is_conv )
|
|
{
|
|
__LCCRT_PRINT_BITS2( rb, ab);
|
|
assert( 0);
|
|
}
|
|
|
|
return;
|
|
} /* __lccrt_fptoui_n */
|
|
|
|
void
|
|
__lccrt_sitofp_n( uint32_t rb, uint32_t ab, uint8_t *r, uint8_t *a)
|
|
{
|
|
int is_conv = 0;
|
|
|
|
if ( (ab == 8) )
|
|
{
|
|
int8_t u0;
|
|
|
|
memcpy( &u0, a, sizeof( u0));
|
|
if ( (rb == 32) ) { is_conv = 1; __LCCRT_CONV( r, float, u0); }
|
|
else if ( (rb == 64) ) { is_conv = 1; __LCCRT_CONV( r, double, u0); }
|
|
else if ( (rb == 80) ) { is_conv = 1; __LCCRT_CONV( r, long double, u0); }
|
|
|
|
} else if ( (ab == 16) )
|
|
{
|
|
int16_t u0;
|
|
|
|
memcpy( &u0, a, sizeof( u0));
|
|
if ( (rb == 32) ) { is_conv = 1; __LCCRT_CONV( r, float, u0); }
|
|
else if ( (rb == 64) ) { is_conv = 1; __LCCRT_CONV( r, double, u0); }
|
|
else if ( (rb == 80) ) { is_conv = 1; __LCCRT_CONV( r, long double, u0); }
|
|
|
|
} else if ( (ab == 32) )
|
|
{
|
|
int32_t u0;
|
|
|
|
memcpy( &u0, a, sizeof( u0));
|
|
if ( (rb == 32) ) { is_conv = 1; __LCCRT_CONV( r, float, u0); }
|
|
else if ( (rb == 64) ) { is_conv = 1; __LCCRT_CONV( r, double, u0); }
|
|
else if ( (rb == 80) ) { is_conv = 1; __LCCRT_CONV( r, long double, u0); }
|
|
|
|
} else if ( (ab == 64) )
|
|
{
|
|
int64_t u0;
|
|
|
|
memcpy( &u0, a, sizeof( u0));
|
|
if ( (rb == 32) ) { is_conv = 1; __LCCRT_CONV( r, float, u0); }
|
|
else if ( (rb == 64) ) { is_conv = 1; __LCCRT_CONV( r, double, u0); }
|
|
else if ( (rb == 80) ) { is_conv = 1; __LCCRT_CONV( r, long double, u0); }
|
|
}
|
|
|
|
if ( !is_conv )
|
|
{
|
|
__LCCRT_PRINT_BITS2( rb, ab);
|
|
assert( 0);
|
|
}
|
|
|
|
return;
|
|
} /* __lccrt_sitofp_n */
|
|
|
|
void
|
|
__lccrt_uitofp_n( uint32_t rb, uint32_t ab, uint8_t *r, uint8_t *a)
|
|
{
|
|
int is_conv = 0;
|
|
|
|
if ( (ab == 8) )
|
|
{
|
|
uint8_t u0;
|
|
|
|
memcpy( &u0, a, sizeof( u0));
|
|
if ( (rb == 32) ) { is_conv = 1; __LCCRT_CONV( r, float, u0); }
|
|
else if ( (rb == 64) ) { is_conv = 1; __LCCRT_CONV( r, double, u0); }
|
|
else if ( (rb == 80) ) { is_conv = 1; __LCCRT_CONV( r, long double, u0); }
|
|
|
|
} else if ( (ab == 16) )
|
|
{
|
|
uint16_t u0;
|
|
|
|
memcpy( &u0, a, sizeof( u0));
|
|
if ( (rb == 32) ) { is_conv = 1; __LCCRT_CONV( r, float, u0); }
|
|
else if ( (rb == 64) ) { is_conv = 1; __LCCRT_CONV( r, double, u0); }
|
|
else if ( (rb == 80) ) { is_conv = 1; __LCCRT_CONV( r, long double, u0); }
|
|
|
|
} else if ( (ab == 32) )
|
|
{
|
|
uint32_t u0;
|
|
|
|
memcpy( &u0, a, sizeof( u0));
|
|
if ( (rb == 32) ) { is_conv = 1; __LCCRT_CONV( r, float, u0); }
|
|
else if ( (rb == 64) ) { is_conv = 1; __LCCRT_CONV( r, double, u0); }
|
|
else if ( (rb == 80) ) { is_conv = 1; __LCCRT_CONV( r, long double, u0); }
|
|
|
|
} else if ( (ab == 64) )
|
|
{
|
|
uint64_t u0;
|
|
|
|
memcpy( &u0, a, sizeof( u0));
|
|
if ( (rb == 32) ) { is_conv = 1; __LCCRT_CONV( r, float, u0); }
|
|
else if ( (rb == 64) ) { is_conv = 1; __LCCRT_CONV( r, double, u0); }
|
|
else if ( (rb == 80) ) { is_conv = 1; __LCCRT_CONV( r, long double, u0); }
|
|
}
|
|
|
|
if ( !is_conv )
|
|
{
|
|
__LCCRT_PRINT_BITS2( rb, ab);
|
|
assert( 0);
|
|
}
|
|
|
|
return;
|
|
} /* __lccrt_uitofp_n */
|
|
|
|
void
|
|
__lccrt_func2_stdint_n( __LCCRT_N_ARG2( rb, ab, bb, r, a, b),
|
|
uint8_t (*f8)( uint8_t, uint8_t),
|
|
uint16_t (*f16)( uint16_t, uint16_t),
|
|
uint32_t (*f32)( uint32_t, uint32_t),
|
|
uint64_t (*f64)( uint64_t, uint64_t))
|
|
{
|
|
assert( (rb == ab) && (rb == bb));
|
|
if ( (rb == 8) )
|
|
{
|
|
uint8_t *x = (uint8_t *)a;
|
|
uint8_t *y = (uint8_t *)b;
|
|
uint8_t *z = (uint8_t *)r;
|
|
|
|
z[0] = f8( x[0], y[0]);
|
|
|
|
} else if ( (rb == 16) )
|
|
{
|
|
uint16_t *x = (uint16_t *)a;
|
|
uint16_t *y = (uint16_t *)b;
|
|
uint16_t *z = (uint16_t *)r;
|
|
|
|
z[0] = f16( x[0], y[0]);
|
|
|
|
} else if ( (ab == 32) )
|
|
{
|
|
uint32_t *x = (uint32_t *)a;
|
|
uint32_t *y = (uint32_t *)b;
|
|
uint32_t *z = (uint32_t *)r;
|
|
|
|
z[0] = f32( x[0], y[0]);
|
|
|
|
} else if ( (ab == 64) )
|
|
{
|
|
uint64_t *x = (uint64_t *)a;
|
|
uint64_t *y = (uint64_t *)b;
|
|
uint64_t *z = (uint64_t *)r;
|
|
|
|
z[0] = f64( x[0], y[0]);
|
|
} else
|
|
{
|
|
__LCCRT_PRINT_BITS3( rb, ab, rb);
|
|
assert( 0);
|
|
}
|
|
|
|
return;
|
|
} /* __lccrt_func2_stdint_n */
|
|
|
|
void
|
|
__lccrt_uadd_sat_n( __LCCRT_N_ARG2( rb, ab, bb, r, a, b))
|
|
{
|
|
__lccrt_func2_stdint_n( rb, ab, bb, r, a, b,
|
|
&__lccrt_uadd_sat_8, &__lccrt_uadd_sat_16,
|
|
&__lccrt_uadd_sat_32, &__lccrt_uadd_sat_64);
|
|
|
|
return;
|
|
} /* __lccrt_uadd_sat_n */
|
|
|
|
void
|
|
__lccrt_sadd_sat_n( __LCCRT_N_ARG2( rb, ab, bb, r, a, b))
|
|
{
|
|
__lccrt_func2_stdint_n( rb, ab, bb, r, a, b,
|
|
&__lccrt_sadd_sat_8, &__lccrt_sadd_sat_16,
|
|
&__lccrt_sadd_sat_32, &__lccrt_sadd_sat_64);
|
|
|
|
return;
|
|
} /* __lccrt_sadd_sat_n */
|
|
|
|
void
|
|
__lccrt_usub_sat_n( __LCCRT_N_ARG2( rb, ab, bb, r, a, b))
|
|
{
|
|
__lccrt_func2_stdint_n( rb, ab, bb, r, a, b,
|
|
&__lccrt_usub_sat_8, &__lccrt_usub_sat_16,
|
|
&__lccrt_usub_sat_32, &__lccrt_usub_sat_64);
|
|
|
|
return;
|
|
} /* __lccrt_usub_sat_n */
|
|
|
|
void
|
|
__lccrt_ssub_sat_n( __LCCRT_N_ARG2( rb, ab, bb, r, a, b))
|
|
{
|
|
__lccrt_func2_stdint_n( rb, ab, bb, r, a, b,
|
|
&__lccrt_ssub_sat_8, &__lccrt_ssub_sat_16,
|
|
&__lccrt_ssub_sat_32, &__lccrt_ssub_sat_64);
|
|
|
|
return;
|
|
} /* __lccrt_ssub_sat_n */
|
|
|
|
void
|
|
__lccrt_bswap_n( __LCCRT_N_ARG1( rb, ab, r, a))
|
|
{
|
|
int i;
|
|
int rlen = rb / 8;
|
|
|
|
assert( (rb > 0) && (rb == ab) && (rb % 16 == 0));
|
|
for ( i = 0; i < rlen; ++i )
|
|
{
|
|
r[rlen - 1 - i] = a[i];
|
|
}
|
|
|
|
return;
|
|
} /* __lccrt_bswap_n */
|
|
|
|
void
|
|
__lccrt_bitreverse_n( __LCCRT_N_ARG1( rb, ab, r, a))
|
|
{
|
|
uint32_t num_digits = __LCCRT_NUM_DIGITS( rb, ab, ab);
|
|
uint32_t zr[num_digits];
|
|
uint32_t za[num_digits];
|
|
uint32_t zb[num_digits];
|
|
|
|
__lccrt_zn_set_bits( num_digits, 0, za, ab, a);
|
|
|
|
if ( (ab > 0)
|
|
&& (rb == ab) )
|
|
{
|
|
int i;
|
|
|
|
for ( i = 0; i < num_digits; ++i )
|
|
{
|
|
za[i] = __builtin_e2k_bitrevs( za[i]);
|
|
zb[i] = 0;
|
|
}
|
|
|
|
for ( i = 0; i < num_digits/2; ++i )
|
|
{
|
|
uint32_t v = za[i];
|
|
int i0 = i;
|
|
int i1 = num_digits/2 - i;
|
|
|
|
za[i0] = za[i1];
|
|
za[i1] = v;
|
|
}
|
|
|
|
zb[0] = 32*num_digits - ab;
|
|
__lccrt_zn_shr( num_digits, zr, za, zb);
|
|
} else
|
|
{
|
|
__LCCRT_PRINT_BITS3( rb, ab, ab);
|
|
assert( 0);
|
|
}
|
|
|
|
__lccrt_zn_get_bits( num_digits, zr, rb, r);
|
|
|
|
return;
|
|
} /* __lccrt_bitreverse_n */
|
|
|
|
void
|
|
__lccrt_ctpop_n( __LCCRT_N_ARG1( rb, ab, r, a))
|
|
{
|
|
uint32_t num_digits = __LCCRT_NUM_DIGITS( rb, ab, ab);
|
|
uint32_t zr[num_digits];
|
|
uint32_t za[num_digits];
|
|
|
|
__lccrt_zn_set_bits( num_digits, 0, za, ab, a);
|
|
|
|
if ( (ab > 0)
|
|
&& (rb == ab) )
|
|
{
|
|
int i;
|
|
int v = 0;
|
|
|
|
for ( i = 0; i < num_digits; ++i )
|
|
{
|
|
zr[i] = 0;
|
|
v += __builtin_popcount( za[i]);
|
|
}
|
|
|
|
zr[0] = v;
|
|
} else
|
|
{
|
|
__LCCRT_PRINT_BITS3( rb, ab, ab);
|
|
assert( 0);
|
|
}
|
|
|
|
__lccrt_zn_get_bits( num_digits, zr, rb, r);
|
|
|
|
return;
|
|
} /* __lccrt_ctpop_n */
|
|
|
|
void
|
|
__lccrt_abs_v( uint32_t rb, uint32_t ab, uint8_t *r, uint8_t *a, uint32_t rn, uint32_t an,
|
|
uint32_t reb, uint32_t aeb)
|
|
{
|
|
__lccrt_arith1_v( &__lccrt_abs_n, rb, ab, r, a, rn, an, reb, aeb);
|
|
|
|
return;
|
|
} /* __lccrt_abs_v */
|
|
|
|
void
|
|
__lccrt_shl_v( uint32_t rb, uint32_t ab, uint32_t bb, uint8_t *r, uint8_t *a, uint8_t *b,
|
|
uint32_t rn, uint32_t an, uint32_t bn, uint32_t reb, uint32_t aeb, uint32_t beb)
|
|
{
|
|
__lccrt_arith2_v( &__lccrt_shl_n, rb, ab, bb, r, a, b, rn, an, bn, reb, aeb, beb);
|
|
|
|
return;
|
|
} /* __lccrt_shl_v */
|
|
|
|
void
|
|
__lccrt_shr_v( uint32_t rb, uint32_t ab, uint32_t bb, uint8_t *r, uint8_t *a, uint8_t *b,
|
|
uint32_t rn, uint32_t an, uint32_t bn, uint32_t reb, uint32_t aeb, uint32_t beb)
|
|
{
|
|
__lccrt_arith2_v( &__lccrt_shr_n, rb, ab, bb, r, a, b, rn, an, bn, reb, aeb, beb);
|
|
|
|
return;
|
|
} /* __lccrt_shr_v */
|
|
|
|
void
|
|
__lccrt_sar_v( uint32_t rb, uint32_t ab, uint32_t bb, uint8_t *r, uint8_t *a, uint8_t *b,
|
|
uint32_t rn, uint32_t an, uint32_t bn, uint32_t reb, uint32_t aeb, uint32_t beb)
|
|
{
|
|
__lccrt_arith2_v( &__lccrt_sar_n, rb, ab, bb, r, a, b, rn, an, bn, reb, aeb, beb);
|
|
|
|
return;
|
|
} /* __lccrt_sar_v */
|
|
|
|
void
|
|
__lccrt_fshl_v( uint32_t rb, uint32_t ab, uint32_t bb, uint32_t cb,
|
|
uint8_t *r, uint8_t *a, uint8_t *b, uint8_t *c,
|
|
uint32_t rn, uint32_t an, uint32_t bn, uint32_t cn,
|
|
uint32_t reb, uint32_t aeb, uint32_t beb, uint32_t ceb)
|
|
{
|
|
__lccrt_arith3_v( &__lccrt_fshl_n, rb, ab, bb, cb, r, a, b, c, rn, an, bn, cn, reb, aeb, beb, ceb);
|
|
|
|
return;
|
|
} /* __lccrt_fshl_v */
|
|
|
|
void
|
|
__lccrt_and_v( uint32_t rb, uint32_t ab, uint32_t bb, uint8_t *r, uint8_t *a, uint8_t *b,
|
|
uint32_t rn, uint32_t an, uint32_t bn, uint32_t reb, uint32_t aeb, uint32_t beb)
|
|
{
|
|
__lccrt_arith2_v( &__lccrt_and_n, rb, ab, bb, r, a, b, rn, an, bn, reb, aeb, beb);
|
|
|
|
return;
|
|
} /* __lccrt_and_v */
|
|
|
|
void
|
|
__lccrt_or_v( uint32_t rb, uint32_t ab, uint32_t bb, uint8_t *r, uint8_t *a, uint8_t *b,
|
|
uint32_t rn, uint32_t an, uint32_t bn, uint32_t reb, uint32_t aeb, uint32_t beb)
|
|
{
|
|
__lccrt_arith2_v( &__lccrt_or_n, rb, ab, bb, r, a, b, rn, an, bn, reb, aeb, beb);
|
|
|
|
return;
|
|
} /* __lccrt_or_v */
|
|
|
|
void
|
|
__lccrt_xor_v( uint32_t rb, uint32_t ab, uint32_t bb, uint8_t *r, uint8_t *a, uint8_t *b,
|
|
uint32_t rn, uint32_t an, uint32_t bn, uint32_t reb, uint32_t aeb, uint32_t beb)
|
|
{
|
|
__lccrt_arith2_v( &__lccrt_xor_n, rb, ab, bb, r, a, b, rn, an, bn, reb, aeb, beb);
|
|
|
|
return;
|
|
} /* __lccrt_xor_v */
|
|
|
|
void
|
|
__lccrt_add_v( uint32_t rb, uint32_t ab, uint32_t bb, uint8_t *r, uint8_t *a, uint8_t *b,
|
|
uint32_t rn, uint32_t an, uint32_t bn, uint32_t reb, uint32_t aeb, uint32_t beb)
|
|
{
|
|
__lccrt_arith2_v( &__lccrt_add_n, rb, ab, bb, r, a, b, rn, an, bn, reb, aeb, beb);
|
|
|
|
return;
|
|
} /* __lccrt_add_v */
|
|
|
|
void
|
|
__lccrt_sub_v( uint32_t rb, uint32_t ab, uint32_t bb, uint8_t *r, uint8_t *a, uint8_t *b,
|
|
uint32_t rn, uint32_t an, uint32_t bn, uint32_t reb, uint32_t aeb, uint32_t beb)
|
|
{
|
|
__lccrt_arith2_v( &__lccrt_sub_n, rb, ab, bb, r, a, b, rn, an, bn, reb, aeb, beb);
|
|
|
|
return;
|
|
} /* __lccrt_sub_v */
|
|
|
|
void
|
|
__lccrt_mul_v( uint32_t rb, uint32_t ab, uint32_t bb, uint8_t *r, uint8_t *a, uint8_t *b,
|
|
uint32_t rn, uint32_t an, uint32_t bn, uint32_t reb, uint32_t aeb, uint32_t beb)
|
|
{
|
|
__lccrt_arith2_v( &__lccrt_mul_n, rb, ab, bb, r, a, b, rn, an, bn, reb, aeb, beb);
|
|
|
|
return;
|
|
} /* __lccrt_mul_v */
|
|
|
|
void
|
|
__lccrt_udiv_v( uint32_t rb, uint32_t ab, uint32_t bb, uint8_t *r, uint8_t *a, uint8_t *b,
|
|
uint32_t rn, uint32_t an, uint32_t bn, uint32_t reb, uint32_t aeb, uint32_t beb)
|
|
{
|
|
__lccrt_arith2_v( &__lccrt_udiv_n, rb, ab, bb, r, a, b, rn, an, bn, reb, aeb, beb);
|
|
|
|
return;
|
|
} /* __lccrt_udiv_v */
|
|
|
|
void
|
|
__lccrt_sdiv_v( uint32_t rb, uint32_t ab, uint32_t bb, uint8_t *r, uint8_t *a, uint8_t *b,
|
|
uint32_t rn, uint32_t an, uint32_t bn, uint32_t reb, uint32_t aeb, uint32_t beb)
|
|
{
|
|
__lccrt_arith2_v( &__lccrt_sdiv_n, rb, ab, bb, r, a, b, rn, an, bn, reb, aeb, beb);
|
|
|
|
return;
|
|
} /* __lccrt_sdiv_v */
|
|
|
|
void
|
|
__lccrt_umod_v( uint32_t rb, uint32_t ab, uint32_t bb, uint8_t *r, uint8_t *a, uint8_t *b,
|
|
uint32_t rn, uint32_t an, uint32_t bn, uint32_t reb, uint32_t aeb, uint32_t beb)
|
|
{
|
|
__lccrt_arith2_v( &__lccrt_umod_n, rb, ab, bb, r, a, b, rn, an, bn, reb, aeb, beb);
|
|
|
|
return;
|
|
} /* __lccrt_umod_v */
|
|
|
|
void
|
|
__lccrt_smod_v( uint32_t rb, uint32_t ab, uint32_t bb, uint8_t *r, uint8_t *a, uint8_t *b,
|
|
uint32_t rn, uint32_t an, uint32_t bn, uint32_t reb, uint32_t aeb, uint32_t beb)
|
|
{
|
|
__lccrt_arith2_v( &__lccrt_smod_n, rb, ab, bb, r, a, b, rn, an, bn, reb, aeb, beb);
|
|
|
|
return;
|
|
} /* __lccrt_smod_v */
|
|
|
|
void
|
|
__lccrt_fadd_v( uint32_t rb, uint32_t ab, uint32_t bb, uint8_t *r, uint8_t *a, uint8_t *b,
|
|
uint32_t rn, uint32_t an, uint32_t bn, uint32_t reb, uint32_t aeb, uint32_t beb)
|
|
{
|
|
__lccrt_arith2_v( &__lccrt_fadd_n, rb, ab, bb, r, a, b, rn, an, bn, reb, aeb, beb);
|
|
|
|
return;
|
|
} /* __lccrt_fadd_v */
|
|
|
|
void
|
|
__lccrt_fsub_v( uint32_t rb, uint32_t ab, uint32_t bb, uint8_t *r, uint8_t *a, uint8_t *b,
|
|
uint32_t rn, uint32_t an, uint32_t bn, uint32_t reb, uint32_t aeb, uint32_t beb)
|
|
{
|
|
__lccrt_arith2_v( &__lccrt_fsub_n, rb, ab, bb, r, a, b, rn, an, bn, reb, aeb, beb);
|
|
|
|
return;
|
|
} /* __lccrt_fsub_v */
|
|
|
|
void
|
|
__lccrt_fmul_v( uint32_t rb, uint32_t ab, uint32_t bb, uint8_t *r, uint8_t *a, uint8_t *b,
|
|
uint32_t rn, uint32_t an, uint32_t bn, uint32_t reb, uint32_t aeb, uint32_t beb)
|
|
{
|
|
__lccrt_arith2_v( &__lccrt_fmul_n, rb, ab, bb, r, a, b, rn, an, bn, reb, aeb, beb);
|
|
|
|
return;
|
|
} /* __lccrt_fmul_v */
|
|
|
|
void
|
|
__lccrt_fmuladd_v( uint32_t rb, uint32_t ab, uint32_t bb, uint32_t cb,
|
|
uint8_t *r, uint8_t *a, uint8_t *b, uint8_t *c,
|
|
uint32_t rn, uint32_t an, uint32_t bn, uint32_t cn,
|
|
uint32_t reb, uint32_t aeb, uint32_t beb, uint32_t ceb)
|
|
{
|
|
__lccrt_arith3_v( &__lccrt_fmuladd_n, rb, ab, bb, cb, r, a, b, c, rn, an, bn, cn, reb, aeb, beb, ceb);
|
|
|
|
return;
|
|
} /* __lccrt_fmuladd_v */
|
|
|
|
void
|
|
__lccrt_fdiv_v( uint32_t rb, uint32_t ab, uint32_t bb, uint8_t *r, uint8_t *a, uint8_t *b,
|
|
uint32_t rn, uint32_t an, uint32_t bn, uint32_t reb, uint32_t aeb, uint32_t beb)
|
|
{
|
|
__lccrt_arith2_v( &__lccrt_fdiv_n, rb, ab, bb, r, a, b, rn, an, bn, reb, aeb, beb);
|
|
|
|
return;
|
|
} /* __lccrt_fdiv_v */
|
|
|
|
void
|
|
__lccrt_fmod_v( uint32_t rb, uint32_t ab, uint32_t bb, uint8_t *r, uint8_t *a, uint8_t *b,
|
|
uint32_t rn, uint32_t an, uint32_t bn, uint32_t reb, uint32_t aeb, uint32_t beb)
|
|
{
|
|
__lccrt_arith2_v( &__lccrt_fmod_n, rb, ab, bb, r, a, b, rn, an, bn, reb, aeb, beb);
|
|
|
|
return;
|
|
} /* __lccrt_fmod_v */
|
|
|
|
void
|
|
__lccrt_minnum_v( uint32_t rb, uint32_t ab, uint32_t bb, uint8_t *r, uint8_t *a, uint8_t *b,
|
|
uint32_t rn, uint32_t an, uint32_t bn, uint32_t reb, uint32_t aeb, uint32_t beb)
|
|
{
|
|
__lccrt_arith2_v( &__lccrt_minnum_n, rb, ab, bb, r, a, b, rn, an, bn, reb, aeb, beb);
|
|
|
|
return;
|
|
} /* __lccrt_minnum_v */
|
|
|
|
void
|
|
__lccrt_maxnum_v( uint32_t rb, uint32_t ab, uint32_t bb, uint8_t *r, uint8_t *a, uint8_t *b,
|
|
uint32_t rn, uint32_t an, uint32_t bn, uint32_t reb, uint32_t aeb, uint32_t beb)
|
|
{
|
|
__lccrt_arith2_v( &__lccrt_maxnum_n, rb, ab, bb, r, a, b, rn, an, bn, reb, aeb, beb);
|
|
|
|
return;
|
|
} /* __lccrt_maxnum_v */
|
|
|
|
void
|
|
__lccrt_fneg_v( uint32_t rb, uint32_t ab, uint8_t *r, uint8_t *a,
|
|
uint32_t rn, uint32_t an, uint32_t reb, uint32_t aeb)
|
|
{
|
|
__lccrt_arith1_v( &__lccrt_fneg_n, rb, ab, r, a, rn, an, reb, aeb);
|
|
|
|
return;
|
|
} /* __lccrt_fneg_v */
|
|
|
|
void
|
|
__lccrt_ptoi_v( uint32_t rb, uint32_t ab, uint8_t *r, uint8_t *a,
|
|
uint32_t rn, uint32_t an, uint32_t reb, uint32_t aeb)
|
|
{
|
|
__lccrt_arith1_v( &__lccrt_bitcast_n, rb, ab, r, a, rn, an, reb, aeb);
|
|
|
|
return;
|
|
} /* __lccrt_ptoi_v */
|
|
|
|
void
|
|
__lccrt_itop_v( uint32_t rb, uint32_t ab, uint8_t *r, uint8_t *a,
|
|
uint32_t rn, uint32_t an, uint32_t reb, uint32_t aeb)
|
|
{
|
|
__lccrt_arith1_v( &__lccrt_bitcast_n, rb, ab, r, a, rn, an, reb, aeb);
|
|
|
|
return;
|
|
} /* __lccrt_itop_v */
|
|
|
|
void
|
|
__lccrt_fptofp_v( uint32_t rb, uint32_t ab, uint8_t *r, uint8_t *a,
|
|
uint32_t rn, uint32_t an, uint32_t reb, uint32_t aeb)
|
|
{
|
|
__lccrt_arith1_v( &__lccrt_fptofp_n, rb, ab, r, a, rn, an, reb, aeb);
|
|
|
|
return;
|
|
} /* __lccrt_fptofp_v */
|
|
|
|
void
|
|
__lccrt_fptosi_v( uint32_t rb, uint32_t ab, uint8_t *r, uint8_t *a,
|
|
uint32_t rn, uint32_t an, uint32_t reb, uint32_t aeb)
|
|
{
|
|
__lccrt_arith1_v( &__lccrt_fptosi_n, rb, ab, r, a, rn, an, reb, aeb);
|
|
|
|
return;
|
|
} /* __lccrt_fptosi_v */
|
|
|
|
void
|
|
__lccrt_fptoui_v( uint32_t rb, uint32_t ab, uint8_t *r, uint8_t *a,
|
|
uint32_t rn, uint32_t an, uint32_t reb, uint32_t aeb)
|
|
{
|
|
__lccrt_arith1_v( &__lccrt_fptoui_n, rb, ab, r, a, rn, an, reb, aeb);
|
|
|
|
return;
|
|
} /* __lccrt_fptoui_v */
|
|
|
|
void
|
|
__lccrt_sitofp_v( uint32_t rb, uint32_t ab, uint8_t *r, uint8_t *a,
|
|
uint32_t rn, uint32_t an, uint32_t reb, uint32_t aeb)
|
|
{
|
|
__lccrt_arith1_v( &__lccrt_sitofp_n, rb, ab, r, a, rn, an, reb, aeb);
|
|
|
|
return;
|
|
} /* __lccrt_sitofp_v */
|
|
|
|
void
|
|
__lccrt_uitofp_v( uint32_t rb, uint32_t ab, uint8_t *r, uint8_t *a,
|
|
uint32_t rn, uint32_t an, uint32_t reb, uint32_t aeb)
|
|
{
|
|
__lccrt_arith1_v( &__lccrt_uitofp_n, rb, ab, r, a, rn, an, reb, aeb);
|
|
|
|
return;
|
|
} /* __lccrt_uitofp_v */
|
|
|
|
void
|
|
__lccrt_uadd_sat_v( __LCCRT_VEC_ARGS2( rb, ab, bb, r, a, b, rn, an, bn, reb, aeb, beb))
|
|
{
|
|
__lccrt_arith2_v( &__lccrt_uadd_sat_n, rb, ab, bb, r, a, b, rn, an, bn, reb, aeb, beb);
|
|
|
|
return;
|
|
} /* __lccrt_uadd_sat_v */
|
|
|
|
void
|
|
__lccrt_sadd_sat_v( __LCCRT_VEC_ARGS2( rb, ab, bb, r, a, b, rn, an, bn, reb, aeb, beb))
|
|
{
|
|
__lccrt_arith2_v( &__lccrt_sadd_sat_n, rb, ab, bb, r, a, b, rn, an, bn, reb, aeb, beb);
|
|
|
|
return;
|
|
} /* __lccrt_sadd_sat_v */
|
|
|
|
void
|
|
__lccrt_usub_sat_v( __LCCRT_VEC_ARGS2( rb, ab, bb, r, a, b, rn, an, bn, reb, aeb, beb))
|
|
{
|
|
__lccrt_arith2_v( &__lccrt_usub_sat_n, rb, ab, bb, r, a, b, rn, an, bn, reb, aeb, beb);
|
|
|
|
return;
|
|
} /* __lccrt_usub_sat_v */
|
|
|
|
void
|
|
__lccrt_ssub_sat_v( __LCCRT_VEC_ARGS2( rb, ab, bb, r, a, b, rn, an, bn, reb, aeb, beb))
|
|
{
|
|
__lccrt_arith2_v( &__lccrt_ssub_sat_n, rb, ab, bb, r, a, b, rn, an, bn, reb, aeb, beb);
|
|
|
|
return;
|
|
} /* __lccrt_ssub_sat_v */
|
|
|
|
void
|
|
__lccrt_fabs_v( __LCCRT_VEC_ARGS1( rb, ab, r, a, rn, an, reb, aeb))
|
|
{
|
|
__lccrt_farith1_v( &fabsf, &fabs, &fabsl, rb, ab, r, a, rn, an, reb, aeb);
|
|
|
|
return;
|
|
} /* __lccrt_fabs_v */
|
|
|
|
void
|
|
__lccrt_exp2_v( __LCCRT_VEC_ARGS1( rb, ab, r, a, rn, an, reb, aeb))
|
|
{
|
|
__lccrt_farith1_v( &exp2f, &exp2, &exp2l, rb, ab, r, a, rn, an, reb, aeb);
|
|
|
|
return;
|
|
} /* __lccrt_exp2_v */
|
|
|
|
void
|
|
__lccrt_exp10_v( __LCCRT_VEC_ARGS1( rb, ab, r, a, rn, an, reb, aeb))
|
|
{
|
|
__lccrt_farith1_v( &exp10f, &exp10, &exp10l, rb, ab, r, a, rn, an, reb, aeb);
|
|
|
|
return;
|
|
} /* __lccrt_exp10_v */
|
|
|
|
void
|
|
__lccrt_exp_v( __LCCRT_VEC_ARGS1( rb, ab, r, a, rn, an, reb, aeb))
|
|
{
|
|
__lccrt_farith1_v( &expf, &exp, &expl, rb, ab, r, a, rn, an, reb, aeb);
|
|
|
|
return;
|
|
} /* __lccrt_exp_v */
|
|
|
|
void
|
|
__lccrt_pow_v( __LCCRT_VEC_ARGS2( rb, ab, bb, r, a, b, rn, an, bn, reb, aeb, beb))
|
|
{
|
|
__lccrt_farith2_v( &powf, &pow, &powl, rb, ab, bb, r, a, b, rn, an, bn, reb, aeb, beb);
|
|
|
|
return;
|
|
} /* __lccrt_pow_v */
|
|
|
|
void
|
|
__lccrt_powi_v( __LCCRT_VEC_ARGS2( rb, ab, bb, r, a, b, rn, an, bn, reb, aeb, beb))
|
|
{
|
|
int i;
|
|
int byte_elen = reb / 8;
|
|
|
|
assert( (reb % 8 == 0) && (bn == 1) && (reb == 32));
|
|
assert( (rn == an) && (reb == aeb) && (reb == beb) && (rn*reb == rb));
|
|
for ( i = 0; i < rn; ++i )
|
|
{
|
|
int y;
|
|
uint8_t *q0 = r + i*byte_elen;
|
|
uint8_t *p0 = a + i*byte_elen;
|
|
|
|
memcpy( &y, b, sizeof( y));
|
|
if ( (reb == 32) )
|
|
{
|
|
float z, x;
|
|
|
|
memcpy( &x, p0, sizeof( x));
|
|
z = __builtin_powif( x, y);
|
|
memcpy( q0, &z, sizeof( z));
|
|
|
|
} else if ( (reb == 64) )
|
|
{
|
|
double z, x;
|
|
|
|
memcpy( &x, p0, sizeof( x));
|
|
z = __builtin_powi( x, y);
|
|
memcpy( q0, &z, sizeof( z));
|
|
|
|
} else if ( (reb == 80) )
|
|
{
|
|
long double z, x;
|
|
|
|
memcpy( &x, p0, sizeof( x));
|
|
z = __builtin_powil( x, y);
|
|
memcpy( q0, &z, sizeof( z));
|
|
} else
|
|
{
|
|
assert( 0);
|
|
}
|
|
}
|
|
|
|
return;
|
|
} /* __lccrt_powi_v */
|
|
|
|
void
|
|
__lccrt_fma_v( __LCCRT_VEC_ARGS3( rb, ab, bb, cb, r, a, b, c, rn, an, bn, cn, reb, aeb, beb, ceb))
|
|
{
|
|
int i;
|
|
int byte_elen = reb / 8;
|
|
|
|
assert( (reb % 8 == 0));
|
|
assert( (rn == an) && (rn == bn) && (rn == cn) && (rn*reb == rb));
|
|
assert( (reb == aeb) && (reb == beb) && (reb == ceb));
|
|
for ( i = 0; i < rn; ++i )
|
|
{
|
|
uint8_t *q0 = r + i*byte_elen;
|
|
uint8_t *p0 = a + i*byte_elen;
|
|
uint8_t *p1 = b + i*byte_elen;
|
|
uint8_t *p2 = c + i*byte_elen;
|
|
|
|
if ( (reb == 32) )
|
|
{
|
|
float z, x, y, u;
|
|
|
|
memcpy( &x, p0, sizeof( x));
|
|
memcpy( &y, p1, sizeof( y));
|
|
memcpy( &u, p2, sizeof( u));
|
|
z = fmaf( x, y, u);
|
|
memcpy( q0, &z, sizeof( z));
|
|
|
|
} else if ( (reb == 64) )
|
|
{
|
|
double z, x, y, u;
|
|
|
|
memcpy( &x, p0, sizeof( x));
|
|
memcpy( &y, p1, sizeof( y));
|
|
memcpy( &u, p2, sizeof( u));
|
|
z = fma( x, y, u);
|
|
memcpy( q0, &z, sizeof( z));
|
|
|
|
} else if ( (reb == 80) )
|
|
{
|
|
long double z, x, y, u;
|
|
|
|
memcpy( &x, p0, sizeof( x));
|
|
memcpy( &y, p1, sizeof( y));
|
|
memcpy( &u, p2, sizeof( u));
|
|
z = fmal( x, y, u);
|
|
memcpy( q0, &z, sizeof( z));
|
|
} else
|
|
{
|
|
assert( 0);
|
|
}
|
|
}
|
|
|
|
return;
|
|
} /* __lccrt_fma_v */
|
|
|
|
void
|
|
__lccrt_minn_v( __LCCRT_VEC_ARGS2( rb, ab, bb, r, a, b, rn, an, bn, reb, aeb, beb))
|
|
{
|
|
__lccrt_farith2_v( &fminf, &fmin, &fminl, rb, ab, bb, r, a, b, rn, an, bn, reb, aeb, beb);
|
|
|
|
return;
|
|
} /* __lccrt_minn_v */
|
|
|
|
void
|
|
__lccrt_maxn_v( __LCCRT_VEC_ARGS2( rb, ab, bb, r, a, b, rn, an, bn, reb, aeb, beb))
|
|
{
|
|
__lccrt_farith2_v( &fmaxf, &fmax, &fmaxl, rb, ab, bb, r, a, b, rn, an, bn, reb, aeb, beb);
|
|
|
|
return;
|
|
} /* __lccrt_maxn_v */
|
|
|
|
void
|
|
__lccrt_sqrt_v( __LCCRT_VEC_ARGS1( rb, ab, r, a, rn, an, reb, aeb))
|
|
{
|
|
__lccrt_farith1_v( &sqrtf, &sqrt, &sqrtl, rb, ab, r, a, rn, an, reb, aeb);
|
|
|
|
return;
|
|
} /* __lccrt_sqrt_v */
|
|
|
|
void
|
|
__lccrt_log2_v( __LCCRT_VEC_ARGS1( rb, ab, r, a, rn, an, reb, aeb))
|
|
{
|
|
__lccrt_farith1_v( &log2f, &log2, &log2l, rb, ab, r, a, rn, an, reb, aeb);
|
|
|
|
return;
|
|
} /* __lccrt_log2_v */
|
|
|
|
void
|
|
__lccrt_log10_v( __LCCRT_VEC_ARGS1( rb, ab, r, a, rn, an, reb, aeb))
|
|
{
|
|
__lccrt_farith1_v( &log10f, &log10, &log10l, rb, ab, r, a, rn, an, reb, aeb);
|
|
|
|
return;
|
|
} /* __lccrt_log10_v */
|
|
|
|
void
|
|
__lccrt_log_v( __LCCRT_VEC_ARGS1( rb, ab, r, a, rn, an, reb, aeb))
|
|
{
|
|
__lccrt_farith1_v( &logf, &log, &logl, rb, ab, r, a, rn, an, reb, aeb);
|
|
|
|
return;
|
|
} /* __lccrt_log_v */
|
|
|
|
void
|
|
__lccrt_cos_v( __LCCRT_VEC_ARGS1( rb, ab, r, a, rn, an, reb, aeb))
|
|
{
|
|
__lccrt_farith1_v( &cosf, &cos, &cosl, rb, ab, r, a, rn, an, reb, aeb);
|
|
|
|
return;
|
|
} /* __lccrt_cos_v */
|
|
|
|
void
|
|
__lccrt_sin_v( __LCCRT_VEC_ARGS1( rb, ab, r, a, rn, an, reb, aeb))
|
|
{
|
|
__lccrt_farith1_v( &sinf, &sin, &sinl, rb, ab, r, a, rn, an, reb, aeb);
|
|
|
|
return;
|
|
} /* __lccrt_sin_v */
|
|
|
|
void
|
|
__lccrt_tan_v( __LCCRT_VEC_ARGS1( rb, ab, r, a, rn, an, reb, aeb))
|
|
{
|
|
__lccrt_farith1_v( &tanf, &tan, &tanl, rb, ab, r, a, rn, an, reb, aeb);
|
|
|
|
return;
|
|
} /* __lccrt_tan_v */
|
|
|
|
void
|
|
__lccrt_acos_v( __LCCRT_VEC_ARGS1( rb, ab, r, a, rn, an, reb, aeb))
|
|
{
|
|
__lccrt_farith1_v( &acosf, &acos, &acosl, rb, ab, r, a, rn, an, reb, aeb);
|
|
|
|
return;
|
|
} /* __lccrt_acos_v */
|
|
|
|
void
|
|
__lccrt_asin_v( __LCCRT_VEC_ARGS1( rb, ab, r, a, rn, an, reb, aeb))
|
|
{
|
|
__lccrt_farith1_v( &asinf, &asin, &asinl, rb, ab, r, a, rn, an, reb, aeb);
|
|
|
|
return;
|
|
} /* __lccrt_asin_v */
|
|
|
|
void
|
|
__lccrt_floor_v( __LCCRT_VEC_ARGS1( rb, ab, r, a, rn, an, reb, aeb))
|
|
{
|
|
__lccrt_farith1_v( &floorf, &floor, &floorl, rb, ab, r, a, rn, an, reb, aeb);
|
|
|
|
return;
|
|
} /* __lccrt_floor_v */
|
|
|
|
void
|
|
__lccrt_ceil_v( __LCCRT_VEC_ARGS1( rb, ab, r, a, rn, an, reb, aeb))
|
|
{
|
|
__lccrt_farith1_v( &ceilf, &ceil, &ceill, rb, ab, r, a, rn, an, reb, aeb);
|
|
|
|
return;
|
|
} /* __lccrt_ceil_v */
|
|
|
|
void
|
|
__lccrt_round_v( __LCCRT_VEC_ARGS1( rb, ab, r, a, rn, an, reb, aeb))
|
|
{
|
|
__lccrt_farith1_v( &roundf, &round, &roundl, rb, ab, r, a, rn, an, reb, aeb);
|
|
|
|
return;
|
|
} /* __lccrt_round_v */
|
|
|
|
void
|
|
__lccrt_ftrunc_v( __LCCRT_VEC_ARGS1( rb, ab, r, a, rn, an, reb, aeb))
|
|
{
|
|
__lccrt_farith1_v( &truncf, &trunc, &truncl, rb, ab, r, a, rn, an, reb, aeb);
|
|
|
|
return;
|
|
} /* __lccrt_ftrunc_v */
|
|
|
|
void
|
|
__lccrt_rint_v( __LCCRT_VEC_ARGS1( rb, ab, r, a, rn, an, reb, aeb))
|
|
{
|
|
__lccrt_farith1_v( &rintf, &rint, &rintl, rb, ab, r, a, rn, an, reb, aeb);
|
|
|
|
return;
|
|
} /* __lccrt_rint_v */
|
|
|
|
void
|
|
__lccrt_bswap_v( __LCCRT_VEC_ARGS1( rb, ab, r, a, rn, an, reb, aeb))
|
|
{
|
|
__lccrt_arith1_v( &__lccrt_bswap_n, rb, ab, r, a, rn, an, reb, aeb);
|
|
|
|
return;
|
|
} /* __lccrt_bswap_v */
|
|
|
|
void
|
|
__lccrt_bitreverse_v( __LCCRT_VEC_ARGS1( rb, ab, r, a, rn, an, reb, aeb))
|
|
{
|
|
__lccrt_arith1_v( &__lccrt_bitreverse_n, rb, ab, r, a, rn, an, reb, aeb);
|
|
|
|
return;
|
|
} /* __lccrt_bitreverse_v */
|
|
|
|
void
|
|
__lccrt_ctpop_v( __LCCRT_VEC_ARGS1( rb, ab, r, a, rn, an, reb, aeb))
|
|
{
|
|
__lccrt_arith1_v( &__lccrt_ctpop_n, rb, ab, r, a, rn, an, reb, aeb);
|
|
|
|
return;
|
|
} /* __lccrt_ctpop_v */
|
|
|
|
void
|
|
__lccrt_shuffle_n( uint32_t rb, uint32_t ab, uint32_t bb, uint32_t cb,
|
|
uint8_t *r, uint8_t *a, uint8_t *b, uint8_t *c,
|
|
uint32_t rn, uint32_t an, uint32_t bn, uint32_t cn)
|
|
{
|
|
int i;
|
|
|
|
if ( (rn == cn)
|
|
&& (rn > 0)
|
|
&& (an > 0)
|
|
&& (bn > 0)
|
|
&& (rb > 0)
|
|
&& (ab > 0)
|
|
&& (bb > 0) )
|
|
{
|
|
int k;
|
|
uint32_t re = rb / rn;
|
|
uint32_t ae = ab / an;
|
|
uint32_t be = bb / bn;
|
|
uint32_t ce = cb / cn;
|
|
|
|
if ( (re == ae)
|
|
&& (re == be)
|
|
&& (rb % rn == 0)
|
|
&& (ab % an == 0)
|
|
&& (bb % bn == 0)
|
|
&& (cb % cn == 0)
|
|
&& ((ce == 8)
|
|
|| (ce == 16)
|
|
|| (ce == 32)
|
|
|| (ce == 64)) )
|
|
{
|
|
if ( (re % 8 == 0) )
|
|
{
|
|
for ( k = 0; k < rn; ++k )
|
|
{
|
|
uint8_t *ps = 0;
|
|
uint64_t j = __LCCRT_BIT_INDEX( ce, c, k);
|
|
|
|
assert( (0 <= j) && (j < an + bn));
|
|
ps = (j < an) ? (a + j*(ae/8)) : (b + (j - an)*(be/8));
|
|
memcpy( r + k*(re/8), ps, re/8);
|
|
}
|
|
#if 0
|
|
} else if ( (re == 1)
|
|
|| (re == 2)
|
|
|| (re == 4) )
|
|
{
|
|
memset( r, 0, rb/8);
|
|
for ( k = 0; k < rn; ++k )
|
|
{
|
|
uint64_t j = __LCCRT_BIT_INDEX( ce, c, k);
|
|
uint64_t l0 = (j*re) / 8;
|
|
uint64_t l1 = (j*re) % 8;
|
|
uint64_t n0 = (k*re) / 8;
|
|
uint64_t n1 = (k*re) % 8;
|
|
uint8_t *p = (j < an) ? a : b;
|
|
uint8_t u = __lccrt_get_bits( p[l0], l1, l1 + re - 1);
|
|
|
|
assert( (0 <= j) && (j < an + bn));
|
|
r[n0] = __lccrt_set_bits( r[n0], n1, n1 + re - 1, u);
|
|
}
|
|
#endif
|
|
} else
|
|
{
|
|
__LCCRT_PRINT_BITS4( rb, ab, bb, cb);
|
|
__LCCRT_PRINT_BITS4( rn, an, bn, cn);
|
|
assert( 0);
|
|
}
|
|
} else
|
|
{
|
|
__LCCRT_PRINT_BITS4( rb, ab, bb, cb);
|
|
__LCCRT_PRINT_BITS4( rn, an, bn, cn);
|
|
assert( 0);
|
|
}
|
|
} else
|
|
{
|
|
__LCCRT_PRINT_BITS4( rb, ab, bb, cb);
|
|
__LCCRT_PRINT_BITS4( rn, an, bn, cn);
|
|
assert( 0);
|
|
}
|
|
|
|
return;
|
|
} /* __lccrt_shuffle_n */
|
|
|
|
void
|
|
__lccrt_elemptr_v( int32_t res_len, uint8_t **res, int32_t num_inds, int32_t ptr_len, uint8_t **ptr, ...)
|
|
{
|
|
va_list ap;
|
|
int i, j;
|
|
|
|
//va_start( ap, ptr_len);
|
|
va_start( ap, ptr);
|
|
|
|
assert( (res_len > 0) && (num_inds > 0));
|
|
assert( (ptr_len == 1) || (ptr_len == res_len));
|
|
for ( i = 0; i < res_len; ++i )
|
|
{
|
|
res[i] = (ptr_len == 1) ? ptr[0] : ptr[i];
|
|
}
|
|
|
|
for ( i = 0; i < num_inds; ++i )
|
|
{
|
|
int64_t ind_offset = va_arg( ap, int64_t);
|
|
int32_t ind_len = va_arg( ap, int32_t);
|
|
int32_t ind_bitsize = va_arg( ap, int32_t);
|
|
|
|
assert( (ind_len > 0) && (ind_offset >= 0));
|
|
assert( (ind_bitsize == 32) || (ind_bitsize == 64));
|
|
if ( (ind_bitsize == 32) )
|
|
{
|
|
int32_t *ind = va_arg( ap, int32_t *);
|
|
|
|
for ( j = 0; j < res_len; ++j )
|
|
{
|
|
res[j] += ind_offset * ((ind_len == 1) ? ind[0] : ind[j]);
|
|
}
|
|
} else
|
|
{
|
|
int64_t *ind = va_arg( ap, int64_t *);
|
|
|
|
for ( j = 0; j < res_len; ++j )
|
|
{
|
|
res[j] += ind_offset * ((ind_len == 1) ? ind[0] : ind[j]);
|
|
}
|
|
}
|
|
}
|
|
|
|
va_end( ap);
|
|
|
|
return;
|
|
} /* __lccrt_elemptr_v */
|
|
|
|
void
|
|
__lccrt_reduce_fmin_v( uint32_t rb, uint32_t ab, uint8_t *r, uint8_t *a,
|
|
uint32_t rn, uint32_t an, uint32_t reb, uint32_t aeb)
|
|
{
|
|
int i;
|
|
int byte_elen = reb / 8;
|
|
|
|
assert( (reb % 8 == 0) && (rn == 1) && (reb == rb) && (an >= 1));
|
|
assert( (reb == aeb) && (an*aeb == ab));
|
|
if ( (reb == 32) )
|
|
{
|
|
float x, y;
|
|
|
|
memcpy( &x, a + 0*byte_elen, sizeof( x));
|
|
for ( i = 1; i < an; ++i )
|
|
{
|
|
memcpy( &y, a + i*byte_elen, sizeof( y));
|
|
x = __builtin_fminf( x, y);
|
|
}
|
|
|
|
memcpy( r, &x, sizeof( x));
|
|
|
|
} else if ( (reb == 64) )
|
|
{
|
|
double x, y;
|
|
|
|
memcpy( &x, a + 0*byte_elen, sizeof( x));
|
|
for ( i = 1; i < an; ++i )
|
|
{
|
|
memcpy( &y, a + i*byte_elen, sizeof( y));
|
|
x = __builtin_fmin( x, y);
|
|
}
|
|
|
|
memcpy( r, &x, sizeof( x));
|
|
|
|
} else if ( (reb == 80) )
|
|
{
|
|
long double x, y;
|
|
|
|
memcpy( &x, a + 0*byte_elen, sizeof( x));
|
|
for ( i = 1; i < an; ++i )
|
|
{
|
|
memcpy( &y, a + i*byte_elen, sizeof( y));
|
|
x = __builtin_fminl( x, y);
|
|
}
|
|
|
|
memcpy( r, &x, sizeof( x));
|
|
} else
|
|
{
|
|
assert( 0);
|
|
}
|
|
|
|
return;
|
|
} /* __lccrt_reduce_fmin_v */
|
|
|
|
void
|
|
__lccrt_reduce_fmax_v( uint32_t rb, uint32_t ab, uint8_t *r, uint8_t *a,
|
|
uint32_t rn, uint32_t an, uint32_t reb, uint32_t aeb)
|
|
{
|
|
int i;
|
|
int byte_elen = reb / 8;
|
|
|
|
assert( (reb % 8 == 0) && (rn == 1) && (reb == rb) && (an >= 1));
|
|
assert( (reb == aeb) && (an*aeb == ab));
|
|
if ( (reb == 32) )
|
|
{
|
|
float x, y;
|
|
|
|
memcpy( &x, a + 0*byte_elen, sizeof( x));
|
|
for ( i = 1; i < an; ++i )
|
|
{
|
|
memcpy( &y, a + i*byte_elen, sizeof( y));
|
|
x = __builtin_fmaxf( x, y);
|
|
}
|
|
|
|
memcpy( r, &x, sizeof( x));
|
|
|
|
} else if ( (reb == 64) )
|
|
{
|
|
double x, y;
|
|
|
|
memcpy( &x, a + 0*byte_elen, sizeof( x));
|
|
for ( i = 1; i < an; ++i )
|
|
{
|
|
memcpy( &y, a + i*byte_elen, sizeof( y));
|
|
x = __builtin_fmax( x, y);
|
|
}
|
|
|
|
memcpy( r, &x, sizeof( x));
|
|
|
|
} else if ( (reb == 80) )
|
|
{
|
|
long double x, y;
|
|
|
|
memcpy( &x, a + 0*byte_elen, sizeof( x));
|
|
for ( i = 1; i < an; ++i )
|
|
{
|
|
memcpy( &y, a + i*byte_elen, sizeof( y));
|
|
x = __builtin_fmaxl( x, y);
|
|
}
|
|
|
|
memcpy( r, &x, sizeof( x));
|
|
} else
|
|
{
|
|
assert( 0);
|
|
}
|
|
|
|
return;
|
|
} /* __lccrt_reduce_fmax_v */
|
|
|
|
__lccrt_uint128_t
|
|
__lccrt_bswap_128( __lccrt_uint128_t v)
|
|
{
|
|
__lccrt_uint128_t r = {__builtin_bswap64( v.hi), __builtin_bswap64( v.lo)};
|
|
|
|
return (r);
|
|
} /* __lccrt_bswap_128 */
|