ecomp.r29.143691

 :
   liblccopt: ecomp.r29.143691 - ecomp.r28.143691
This commit is contained in:
stepanov 2024-02-28 14:27:26 +03:00
parent 1ba9bd4379
commit 535fb613ad
2 changed files with 111 additions and 22 deletions

View File

@ -1 +1 @@
ecomp.version : ecomp.r29.143635
ecomp.version : ecomp.r29.143691

View File

@ -10,6 +10,82 @@
#include <string.h>
#include <assert.h>
static uint64_t
__lccrt_get_bits( uint64_t u, int off, int bits) {
int lshift = 64 - off - bits;
int rshift = 64 - bits;
uint64_t r = (bits > 0) ? ((u << lshift) >> rshift) : 0;
return (r);
} /* __lccrt_get_bits */
static uint64_t
__lccrt_set_bits( uint64_t u, int off, int bits, uint64_t v) {
uint64_t r = u;
if ( bits > 0 ) {
int lshift = 64 - bits;
int rshift = 64 - bits - off;
uint64_t bitmask = ((~0ULL) << lshift) >> rshift;
r = (u & ~bitmask) | ((v << off) & bitmask);
}
return (r);
} /* __lccrt_set_bits */
/**
* ÷ ËÁÖÄÏÍ ÉÚ ÐÁÒÁÍÅÔÒÏ× u0/u1 ÈÒÁÎÉÔÓÑ ÐÏ ubytes ÂÁÊÔ ÄÁÎÎÙÈ. îÕÖÎÏ ÓËÌÅÉÔØ
* ÄÁÎÎÙÅ É ÐÏ ÂÉÔÏ×ÏÍÕ ÓÍÅÝÅÎÉÀ eoff ÐÒÏÞÉÔÁÔØ ÚÎÁÞÅÎÉÅ ÒÁÚÍÅÒÏÍ ebits ÂÉÔ.
*/
static uint64_t
__lccrt_get_pair_bits( uint64_t u0, uint64_t u1, int ubytes, int eoff, int ebits) {
uint64_t r = 0;
int ubits = 8*ubytes;
assert( (0 <= eoff) && (0 <= ebits));
assert( (eoff + ebits <= 2*ubits) && (ebits <= 64));
if ( eoff + ebits <= ubits ) {
r = __lccrt_get_bits( u0, eoff, ebits);
} else if ( eoff >= ubits ) {
r = __lccrt_get_bits( u1, eoff - ubits, ebits);
} else {
int lo_len = ubits - eoff;
uint64_t lo = __lccrt_get_bits( u0, eoff, lo_len);
uint64_t hi = __lccrt_get_bits( u1, 0, ebits - lo_len);
r = (hi << lo_len) | lo;
}
return (r);
} /* __lccrt_get_pair_bits */
/**
* ÷ ËÁÖÄÏÍ ÉÚ ÐÁÒÁÍÅÔÒÏ× u0/u1 ÈÒÁÎÉÔÓÑ ÐÏ ubytes ÂÁÊÔ ÄÁÎÎÙÈ. îÕÖÎÏ
* ÌÏÇÉÞÅÓËÉ ÓËÌÅÉÔØ ÄÁÎÎÙÅ É ÐÏ ÂÉÔÏ×ÏÍÕ ÓÍÅÝÅÎÉÀ eoff ÚÁÐÉÓÁÔØ ÚÎÁÞÅÎÉÅ v
* ÒÁÚÍÅÒÏÍ ebits ÂÉÔ.
*/
static void
__lccrt_set_pair_bits( uint64_t *u0, uint64_t *u1, int ubytes, int eoff, int ebits, uint64_t v) {
uint64_t r = 0;
int ubits = 8*ubytes;
assert( (0 <= eoff) && (0 <= ebits));
assert( (eoff + ebits <= 2*ubits) && (ebits <= 64));
if ( eoff + ebits <= ubits ) {
u0[0] = __lccrt_set_bits( u0[0], eoff, ebits, v);
} else if ( eoff >= ubits ) {
u1[0] = __lccrt_set_bits( u1[0], eoff - ubits, ebits, v);
} else {
int lo_len = ubits - eoff;
u0[0] = __lccrt_set_bits( u0[0], eoff, lo_len, v);
u1[0] = __lccrt_set_bits( u1[0], 0, ebits - lo_len, v >> lo_len);
}
return;
} /* __lccrt_set_pair_bits */
static int
__lccrt_bitwidth_bytesize( int bitsize) {
int r = 0;
@ -75,50 +151,63 @@ __lccrt_load_bytes( void *src, int64_t bytesize) {
/**
* õÐÁËÏ×ËÁ ÂÉÔÏ× ×ÅËÔÏÒÁ ÎÅÓÔÁÎÄÁÒÔÎÙÈ ÃÅÌÙÈ × (ÎÅÓÔÁÎÄÁÒÔÎÏÅ) ÃÅÌÏÅ ÚÎÁÞÅÎÉÅ.
* óÕÍÍÁÒÎÏÅ ËÏÌÉÞÅÓÔ×Ï ÚÎÁÞÉÍÙÈ ÂÉÔ ÎÅ ÄÏÌÖÎÏ ÐÒÅ×ÙÛÁÔØ 64.
* ðÒÉÍÅÒ: <3 x i6> -> i18.
*/
void
__lccrt_vecbitpack( void *dst, void *src, int64_t veclen, int64_t elembitsize) {
uint64_t r = 0;
int ebytes = __lccrt_bitwidth_bytesize( elembitsize);
int maskshift = 64 - elembitsize;
int totalbitsize = veclen*elembitsize;
int lcnt = 0;
int uoff = 0;
uint64_t u0 = 0;
uint64_t u1 = 0;
assert( (0 <= veclen) && (0 < elembitsize) && (totalbitsize <= 64));
for ( int i = veclen - 1; i >= 0; --i ) {
uint64_t si = 0;
assert( (0 <= veclen) && (0 < elembitsize) && (elembitsize <= 64));
for ( int i = 0; i < veclen; ++i ) {
uint64_t v = __lccrt_load_bytes( (char *)src + i*ebytes, ebytes);
si = __lccrt_load_bytes( (char *)src + i*ebytes, ebytes);
si = (si << maskshift) >> maskshift;
r = (r << elembitsize) | si;
__lccrt_set_pair_bits( &u0, &u1, ebytes, uoff, elembitsize, v);
uoff = uoff + elembitsize;
if ( uoff >= 8*ebytes ) {
__lccrt_store_bytes( (char *)dst + lcnt, u0, ebytes);
u0 = u1;
u1 = 0;
lcnt += ebytes;
uoff = uoff - 8*ebytes;
}
}
__lccrt_store_bytes( dst, r, __lccrt_bitwidth_bytesize( totalbitsize));
if ( uoff > 0 ) {
__lccrt_store_bytes( (char *)dst + lcnt, u0, ebytes);
}
return;
}
/**
* òÁÓÐÁËÏ×ËÁ ÂÉÔÏ× (ÎÅÓÔÁÎÄÁÒÔÎÏÇÏ) ÃÅÌÏÇÏ × ×ÅËÔÏÒ ÎÅÓÔÁÎÄÁÒÔÎÙÈ ÃÅÌÙÈ.
* óÕÍÍÁÒÎÏÅ ËÏÌÉÞÅÓÔ×Ï ÚÎÁÞÉÍÙÈ ÂÉÔ ÎÅ ÄÏÌÖÎÏ ÐÒÅ×ÙÛÁÔØ 64.
* ðÒÉÍÅÒ: i18 -> <3 x i6>.
*/
void
__lccrt_vecbitunpack( void *dst, void *src, int64_t veclen, int64_t elembitsize) {
int ebytes = __lccrt_bitwidth_bytesize( elembitsize);
int maskshift = 64 - elembitsize;
int totalbitsize = veclen*elembitsize;
uint64_t v0 = __lccrt_load_bytes( src, __lccrt_bitwidth_bytesize( totalbitsize));
uint64_t v = v0;
int lcnt = ebytes;
int uoff = 8*ebytes;
uint64_t u0 = 0;
uint64_t u1 = __lccrt_load_bytes( src, ebytes);
assert( (0 <= veclen) && (0 < elembitsize) && (totalbitsize <= 64));
assert( (0 <= veclen) && (0 < elembitsize) && (elembitsize <= 64));
for ( int i = 0; i < veclen; ++i ) {
uint64_t si = 0;
uint64_t v = __lccrt_get_pair_bits( u0, u1, ebytes, uoff, elembitsize);
si = (v << maskshift) >> maskshift;
v = v >> elembitsize;
__lccrt_store_bytes( (char *)dst + i*ebytes, si, ebytes);
__lccrt_store_bytes( (char *)dst + i*ebytes, v, ebytes);
uoff = uoff + elembitsize;
if ( uoff + elembitsize > 2*8*ebytes ) {
u0 = u1;
u1 = __lccrt_load_bytes( (char *)src + lcnt, ebytes);
lcnt += ebytes;
uoff = uoff - 8*ebytes;
}
}
return;