#define _BITSOURCE_H 1
#include <assert.h>
+#include <stdbool.h>
#include <stddef.h>
#include <stdint.h>
#include <sys/types.h>
typedef uint64_t bitreservoir_t;
typedef uint32_t bitreservoir_fill_t;
-static inline bitreservoir_fill_t read_bitreservoir_fill(uint8_t* source)
+// Note: We return bitreservoir_t here, so we can get implicit zero extension on amd64.
+static inline bitreservoir_t read_bitreservoir_fill(uint8_t* source)
{
+#if defined(__GNUC__) && defined(__x86_64__)
+ bitreservoir_t ret;
+ asm("bswapl %1" : "=r" (ret) : "0" (*(bitreservoir_fill_t*)(source)));
+ return ret;
+#elif defined(__GNUC__) && defined(__i386__)
+ bitreservoir_fill_t ret;
+ asm("bswapl %1" : "=r" (ret) : "0" (*(bitreservoir_fill_t*)(source)));
+ return ret;
+#else
return ntohl(*(bitreservoir_fill_t*)(source));
+#endif
}
static const unsigned BITRESERVOIR_SIZE = 8 * sizeof(bitreservoir_t);
// Data source.
input_func_t* input_func;
void* userdata;
+ bool source_eof;
};
void init_bit_source(struct bit_source* source, input_func_t* input_func,
// Slower path (~99% of remaining invocations?)
assert(source->bits_available + BITRESERVOIR_FILL_SIZE < BITRESERVOIR_SIZE);
if (source->bytes_available >= sizeof(bitreservoir_fill_t)) {
- bitreservoir_fill_t fill = read_bitreservoir_fill(source->byte_read_ptr);
+ bitreservoir_t fill = read_bitreservoir_fill(source->byte_read_ptr);
source->byte_read_ptr += sizeof(bitreservoir_fill_t);
source->bytes_available -= sizeof(bitreservoir_fill_t);
source->bits |= (bitreservoir_t)fill << (BITRESERVOIR_SIZE - BITRESERVOIR_FILL_SIZE - source->bits_available);