summaryrefslogtreecommitdiff
path: root/cesar/lib/src/bitstream.c
diff options
context:
space:
mode:
authorschodet2008-09-04 13:38:11 +0000
committerschodet2008-09-04 13:38:11 +0000
commit1db04da7757e933a210e99c02c0ae40de3701ea9 (patch)
tree25a4ab086b57e1b173d0593ab787840b08cad507 /cesar/lib/src/bitstream.c
parentdd09e7d6ac2df137afe6f107e5bd7d1552fe9dc7 (diff)
* lib/bitstream:
- added slow memcpy and memcmp versions, however, 15 times faster than original. git-svn-id: svn+ssh://pessac/svn/cesar/trunk@2854 017c9cb6-072f-447c-8318-d5b54f68fe89
Diffstat (limited to 'cesar/lib/src/bitstream.c')
-rw-r--r--cesar/lib/src/bitstream.c128
1 files changed, 128 insertions, 0 deletions
diff --git a/cesar/lib/src/bitstream.c b/cesar/lib/src/bitstream.c
index 3b14d4047c..9901219b1b 100644
--- a/cesar/lib/src/bitstream.c
+++ b/cesar/lib/src/bitstream.c
@@ -525,3 +525,131 @@ bitstream_access_str (bitstream_t *ctx, char *str, uint size)
return bitstream_write_str (ctx, str, size);
}
+void
+bitstream_memcpy (void *dest, const void *src, uint size)
+{
+ const u32 *s;
+ u32 *d;
+ u32 sw, dw;
+ uint sb, db;
+ uint duna, suna;
+ dbg_assert_ptr (dest);
+ dbg_assert_ptr (src);
+ /* Setup destination. */
+ duna = (u32) dest & 0x3;
+ if (duna)
+ {
+ d = (u32 *) ((u32) dest & ~0x3);
+ dw = *d;
+ dw &= bit_mask (duna * 8);
+ db = duna;
+ }
+ else
+ {
+ d = dest;
+ dw = 0;
+ db = 0;
+ }
+ /* Setup source. */
+ suna = (u32) src & 0x3;
+ if (suna)
+ {
+ s = (u32 *) ((u32) src & ~0x3);
+ sw = *s++;
+ sw >>= suna * 8;
+ sb = 4 - suna;
+ }
+ else
+ {
+ s = src;
+ sb = 0;
+ }
+ /* Copy bytes. */
+ while (size)
+ {
+ if (sb == 0)
+ {
+ sw = *s++;
+ sb = 4;
+ }
+ dw |= (sw & 0xff) << (db * 8);
+ db++;
+ sw >>= 8;
+ sb--;
+ if (db == 4)
+ {
+ *d++ = dw;
+ db = 0;
+ dw = 0;
+ }
+ size--;
+ }
+ /* Last destination word. */
+ if (db)
+ {
+ dw |= *d & ~bit_mask (db * 8);
+ *d = dw;
+ }
+}
+
+bool
+bitstream_memcmp (const void *s1, const void *s2, uint size)
+{
+ const u32 *p1, *p2;
+ u32 w1, w2;
+ uint b1, b2;
+ uint una1, una2;
+ dbg_assert_ptr (s1);
+ dbg_assert_ptr (s2);
+ /* Setup s1. */
+ una1 = (u32) s1 & 0x3;
+ if (una1)
+ {
+ p1 = (u32 *) ((u32) s1 & ~0x3);
+ w1 = *p1++;
+ w1 >>= una1 * 8;
+ b1 = 4 - una1;
+ }
+ else
+ {
+ p1 = s1;
+ b1 = 0;
+ }
+ /* Setup s2. */
+ una2 = (u32) s2 & 0x3;
+ if (una2)
+ {
+ p2 = (u32 *) ((u32) s2 & ~0x3);
+ w2 = *p2++;
+ w2 >>= una2 * 8;
+ b2 = 4 - una2;
+ }
+ else
+ {
+ p2 = s2;
+ b2 = 0;
+ }
+ /* Compare bytes. */
+ while (size)
+ {
+ if (b1 == 0)
+ {
+ w1 = *p1++;
+ b1 = 4;
+ }
+ if (b2 == 0)
+ {
+ w2 = *p2++;
+ b2 = 4;
+ }
+ if ((w1 & 0xff) != (w2 & 0xff))
+ return false;
+ w1 >>= 8;
+ b1--;
+ w2 >>= 8;
+ b2--;
+ size--;
+ }
+ return true;
+}
+