Reader
This commit is contained in:
99
src/memory.h
Normal file
99
src/memory.h
Normal file
@ -0,0 +1,99 @@
|
||||
#ifndef INCLUDED_MEMORY_H
|
||||
#define INCLUDED_MEMORY_H
|
||||
|
||||
#include <float.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
// Geneal macros
|
||||
#ifndef __has_attribute
|
||||
# define __has_attribute(attr) 0
|
||||
#endif
|
||||
|
||||
#if __has_attribute(always_inline)
|
||||
# define ALWAYS_INLINE inline __attribute__((always_inline))
|
||||
#else
|
||||
# define ALWAYS_INLINE inline
|
||||
#endif
|
||||
|
||||
// Byte order stuff
|
||||
typedef enum {
|
||||
ENDIAN_LITTLE,
|
||||
ENDIAN_BIG,
|
||||
} Endianness;
|
||||
|
||||
static ALWAYS_INLINE Endianness ENDIANNESS(void) {
|
||||
uint16_t x = 1;
|
||||
return *(char *) &x == 1 ? ENDIAN_LITTLE : ENDIAN_BIG;
|
||||
}
|
||||
|
||||
static ALWAYS_INLINE bool LITTLE_ENDIAN_P(void) {
|
||||
return ENDIANNESS() == ENDIAN_LITTLE;
|
||||
}
|
||||
|
||||
// General float stuff
|
||||
#if SIZE_MAX == 0xffffffff
|
||||
# define LISP_WORD_BITS 32
|
||||
#elif SIZE_MAX == 0xffffffffffffffff
|
||||
# define LISP_WORD_BITS 64
|
||||
#else
|
||||
# error "Unablem to determine system word size!"
|
||||
#endif
|
||||
// Check if we support this system's floating point implementation
|
||||
#if FLT_RADIX != 2 || FLT_MANT_DIG != 24 || DBL_MANT_DIG != 53 \
|
||||
|| FLT_MAX_EXP != 128 || DBL_MAX_EXP != 1024
|
||||
# error "Floating point implementation not supported."
|
||||
#endif
|
||||
typedef float lisp_float32_t;
|
||||
typedef double lisp_float64_t;
|
||||
|
||||
static ALWAYS_INLINE uint32_t FLOAT32_TO_INT_BITS(lisp_float32_t flt) {
|
||||
union {
|
||||
uint32_t int_val;
|
||||
lisp_float32_t flt_val;
|
||||
} conv = {.flt_val = flt};
|
||||
return conv.int_val;
|
||||
}
|
||||
|
||||
static ALWAYS_INLINE uint64_t FLOAT64_TO_INT_BITS(lisp_float64_t flt) {
|
||||
union {
|
||||
uint64_t int_val;
|
||||
lisp_float64_t flt_val;
|
||||
} conv = {.flt_val = flt};
|
||||
return conv.int_val;
|
||||
}
|
||||
|
||||
#define FLOAT_TO_INT_BITS(flt) \
|
||||
_Generic((flt), \
|
||||
lisp_float32_t: FLOAT32_TO_INT_BITS(flt), \
|
||||
lisp_float64_t: FLOAT64_TO_INT_BITS(flt))
|
||||
|
||||
static ALWAYS_INLINE lisp_float32_t INT_TO_FLOAT32_BITS(uint32_t i) {
|
||||
union {
|
||||
uint32_t int_val;
|
||||
lisp_float32_t flt_val;
|
||||
} conv = {.int_val = i};
|
||||
return conv.flt_val;
|
||||
}
|
||||
|
||||
static ALWAYS_INLINE lisp_float64_t INT_TO_FLOAT64_BITS(uint64_t i) {
|
||||
union {
|
||||
uint64_t int_val;
|
||||
lisp_float64_t flt_val;
|
||||
} conv = {.int_val = i};
|
||||
return conv.flt_val;
|
||||
}
|
||||
|
||||
#define INT_TO_FLOAT_BITS(i) \
|
||||
_Generic((i), \
|
||||
uint32_t: INT_TO_FLOAT32_BITS(i), \
|
||||
uint64_t: INT_TO_FLOAT64_BITS(i))
|
||||
|
||||
// Allocator
|
||||
void *lisp_realloc(void *oldptr, size_t size);
|
||||
void *lisp_malloc(size_t size);
|
||||
void *lisp_malloc0(size_t size);
|
||||
void *lisp_aligned_alloc(size_t alignment, size_t size);
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user