mirror of
https://gitflic.ru/project/e2khome/lccrt.git
synced 2024-11-21 09:25:22 +01:00
ecomp.r29.143691
: liblccopt: ecomp.r29.143691 - ecomp.r28.143691
This commit is contained in:
parent
1ba9bd4379
commit
535fb613ad
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user