diff options
| author | kr.angelov <kr.angelov@gmail.com> | 2012-01-20 13:41:10 +0000 |
|---|---|---|
| committer | kr.angelov <kr.angelov@gmail.com> | 2012-01-20 13:41:10 +0000 |
| commit | 2eee382a62a909d5a3f2f5eda94f30fe68fd5335 (patch) | |
| tree | b0b0d513535895f244214aebf6358e172b8dce6d /src/runtime/c/gu/bits.h | |
| parent | b9728357126f8b9a6311cca17d9f0dcc2a7bfb9b (diff) | |
initial import of the C runtime
Diffstat (limited to 'src/runtime/c/gu/bits.h')
| -rw-r--r-- | src/runtime/c/gu/bits.h | 151 |
1 files changed, 151 insertions, 0 deletions
diff --git a/src/runtime/c/gu/bits.h b/src/runtime/c/gu/bits.h new file mode 100644 index 000000000..9ba1b0c8e --- /dev/null +++ b/src/runtime/c/gu/bits.h @@ -0,0 +1,151 @@ +#ifndef GU_BITS_H_ +#define GU_BITS_H_ + +#include <gu/defs.h> +#include <gu/assert.h> + + +#define GU_WORD_BITS (sizeof(GuWord) * CHAR_BIT) + + +/* + * Based on the Bit Twiddling Hacks collection by Sean Eron Anderson + * <http://graphics.stanford.edu/~seander/bithacks.html> + */ + +unsigned gu_ceil2e(unsigned i); + +static inline int +gu_sign(int i) { + return (i > 0) - (i < 0); +} + +static inline size_t +gu_ceildiv(size_t size, size_t div) +{ + return (size + div - 1) / div; +} + +static inline bool +gu_aligned(uintptr_t addr, size_t alignment) +{ + gu_require(alignment == gu_ceil2e(alignment)); + return (addr & (alignment - 1)) == 0; +} + +static inline uintptr_t +gu_align_forward(uintptr_t addr, size_t alignment) { + gu_require(alignment == gu_ceil2e(alignment)); + uintptr_t mask = alignment - 1; + return (addr + mask) & ~mask; +} + +static inline uintptr_t +gu_align_backward(uintptr_t addr, size_t alignment) { + gu_require(alignment == gu_ceil2e(alignment)); + return addr & ~(alignment - 1); +} + +static inline bool +gu_bits_test(const GuWord* bitmap, int idx) { + return !!(bitmap[idx / GU_WORD_BITS] & 1 << (idx % GU_WORD_BITS)); +} + +static inline void +gu_bits_set(GuWord* bitmap, int idx) { + bitmap[idx / GU_WORD_BITS] |= ((GuWord) 1) << (idx % GU_WORD_BITS); +} + +static inline void +gu_bits_clear(GuWord* bitmap, int idx) { + bitmap[idx / GU_WORD_BITS] &= ~(((GuWord) 1) << (idx % GU_WORD_BITS)); +} + +static inline size_t +gu_bits_size(size_t n_bits) { + return gu_ceildiv(n_bits, GU_WORD_BITS) * sizeof(GuWord); +} + +static inline void* +gu_word_ptr(GuWord w) +{ + return (void*) w; +} + +static inline GuWord +gu_ptr_word(void* p) +{ + return (GuWord) p; +} + +#define GuOpaque() struct { GuWord w_; } + +typedef GuWord GuTagged; + +#define GU_TAG_MAX (sizeof(GuWord) - 1) + +static inline size_t +gu_tagged_tag(GuTagged t) { + return (int) (t & (sizeof(GuWord) - 1)); +} + +static inline void* +gu_tagged_ptr(GuTagged w) { + return (void*) gu_align_backward(w, sizeof(GuWord)); +} + +static inline GuTagged +gu_tagged(void* ptr, size_t tag) { + gu_require(tag < sizeof(GuWord)); + uintptr_t u = (uintptr_t) ptr; + gu_require(gu_align_backward(u, sizeof(GuWord)) == u); + return (GuWord) { u | tag }; +} + +#include <gu/exn.h> +#include <gu/type.h> + +extern GU_DECLARE_TYPE(GuIntDecodeExn, abstract); + +#define GU_DECODE_2C_(u_, t_, umax_, posmax_, tmin_, err_) \ + (((u_) <= (posmax_)) \ + ? (t_) (u_) \ + : (tmin_) + ((t_) ((umax_) - (u_))) < 0 \ + ? -1 - ((t_) ((umax_) - (u_))) \ + : (gu_raise(err_, GuIntDecodeExn), -1)) + + +static inline int8_t +gu_decode_2c8(uint8_t u, GuExn* err) +{ + return GU_DECODE_2C_(u, int8_t, UINT8_C(0xff), + INT8_C(0x7f), INT8_MIN, err); +} + +static inline int16_t +gu_decode_2c16(uint16_t u, GuExn* err) +{ + return GU_DECODE_2C_(u, int16_t, UINT16_C(0xffff), + INT16_C(0x7fff), INT16_MIN, err); +} + +static inline int32_t +gu_decode_2c32(uint32_t u, GuExn* err) +{ + return GU_DECODE_2C_(u, int32_t, UINT32_C(0xffffffff), + INT32_C(0x7fffffff), INT32_MIN, err); +} + +static inline int64_t +gu_decode_2c64(uint64_t u, GuExn* err) +{ + return GU_DECODE_2C_(u, int64_t, UINT64_C(0xffffffffffffffff), + INT64_C(0x7fffffffffffffff), INT64_MIN, err); +} + +double +gu_decode_double(uint64_t u); + + + +#endif // GU_BITS_H_ |
