summaryrefslogtreecommitdiff
path: root/vere/ext/nasm/include/bytesex.h
diff options
context:
space:
mode:
Diffstat (limited to 'vere/ext/nasm/include/bytesex.h')
-rw-r--r--vere/ext/nasm/include/bytesex.h261
1 files changed, 261 insertions, 0 deletions
diff --git a/vere/ext/nasm/include/bytesex.h b/vere/ext/nasm/include/bytesex.h
new file mode 100644
index 0000000..186d561
--- /dev/null
+++ b/vere/ext/nasm/include/bytesex.h
@@ -0,0 +1,261 @@
+/* ----------------------------------------------------------------------- *
+ *
+ * Copyright 1996-2017 The NASM Authors - All Rights Reserved
+ * See the file AUTHORS included with the NASM distribution for
+ * the specific copyright holders.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following
+ * conditions are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided
+ * with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
+ * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * ----------------------------------------------------------------------- */
+
+/*
+ * bytesex.h - byte order helper functions
+ *
+ * In this function, be careful about getting X86_MEMORY versus
+ * LITTLE_ENDIAN correct: X86_MEMORY also means we are allowed to
+ * do unaligned memory references, and is probabilistic.
+ */
+
+#ifndef NASM_BYTEORD_H
+#define NASM_BYTEORD_H
+
+#include "compiler.h"
+
+/*
+ * Some handy macros that will probably be of use in more than one
+ * output format: convert integers into little-endian byte packed
+ * format in memory.
+ */
+
+#define WRITECHAR(p,v) \
+ do { \
+ uint8_t *_wc_p = (uint8_t *)(p); \
+ *_wc_p++ = (v); \
+ (p) = (void *)_wc_p; \
+ } while (0)
+
+#if X86_MEMORY
+
+#define WRITESHORT(p,v) \
+ do { \
+ uint16_t *_ws_p = (uint16_t *)(p); \
+ *_ws_p++ = (v); \
+ (p) = (void *)_ws_p; \
+ } while (0)
+
+#define WRITELONG(p,v) \
+ do { \
+ uint32_t *_wl_p = (uint32_t *)(p); \
+ *_wl_p++ = (v); \
+ (p) = (void *)_wl_p; \
+ } while (0)
+
+#define WRITEDLONG(p,v) \
+ do { \
+ uint64_t *_wq_p = (uint64_t *)(p); \
+ *_wq_p++ = (v); \
+ (p) = (void *)_wq_p; \
+ } while (0)
+
+#else /* !X86_MEMORY */
+
+#define WRITESHORT(p,v) \
+ do { \
+ uint8_t *_ws_p = (uint8_t *)(p); \
+ const uint16_t _ws_v = (v); \
+ WRITECHAR(_ws_p, _ws_v); \
+ WRITECHAR(_ws_p, _ws_v >> 8); \
+ (p) = (void *)_ws_p; \
+ } while (0)
+
+#define WRITELONG(p,v) \
+ do { \
+ uint8_t *_wl_p = (uint8_t *)(p); \
+ const uint32_t _wl_v = (v); \
+ WRITESHORT(_wl_p, _wl_v); \
+ WRITESHORT(_wl_p, _wl_v >> 16); \
+ (p) = (void *)_wl_p; \
+ } while (0)
+
+#define WRITEDLONG(p,v) \
+ do { \
+ uint8_t *_wq_p = (uint8_t *)(p); \
+ const uint64_t _wq_v = (v); \
+ WRITELONG(_wq_p, _wq_v); \
+ WRITELONG(_wq_p, _wq_v >> 32); \
+ (p) = (void *)_wq_p; \
+ } while (0)
+
+#endif /* X86_MEMORY */
+
+/*
+ * Endian control functions which work on a single integer
+ */
+#ifdef WORDS_LITTLEENDIAN
+
+#ifndef HAVE_CPU_TO_LE16
+# define cpu_to_le16(v) ((uint16_t)(v))
+#endif
+#ifndef HAVE_CPU_TO_LE32
+# define cpu_to_le32(v) ((uint32_t)(v))
+#endif
+#ifndef HAVE_CPU_TO_LE64
+# define cpu_to_le64(v) ((uint64_t)(v))
+#endif
+
+#elif defined(WORDS_BIGENDIAN)
+
+#ifndef HAVE_CPU_TO_LE16
+static inline uint16_t cpu_to_le16(uint16_t v)
+{
+# ifdef HAVE___CPU_TO_LE16
+ return __cpu_to_le16(v);
+# elif defined(HAVE_HTOLE16)
+ return htole16(v);
+# elif defined(HAVE___BSWAP_16)
+ return __bswap_16(v);
+# elif defined(HAVE___BUILTIN_BSWAP16)
+ return __builtin_bswap16(v);
+# elif defined(HAVE__BYTESWAP_USHORT) && (USHRT_MAX == 0xffffU)
+ return _byteswap_ushort(v);
+# else
+ return (v << 8) | (v >> 8);
+# endif
+}
+#endif
+
+#ifndef HAVE_CPU_TO_LE32
+static inline uint32_t cpu_to_le32(uint32_t v)
+{
+# ifdef HAVE___CPU_TO_LE32
+ return __cpu_to_le32(v);
+# elif defined(HAVE_HTOLE32)
+ return htole32(v);
+# elif defined(HAVE___BSWAP_32)
+ return __bswap_32(v);
+# elif defined(HAVE___BUILTIN_BSWAP32)
+ return __builtin_bswap32(v);
+# elif defined(HAVE__BYTESWAP_ULONG) && (ULONG_MAX == 0xffffffffUL)
+ return _byteswap_ulong(v);
+# else
+ v = ((v << 8) & 0xff00ff00 ) |
+ ((v >> 8) & 0x00ff00ff);
+ return (v << 16) | (v >> 16);
+# endif
+}
+#endif
+
+#ifndef HAVE_CPU_TO_LE64
+static inline uint64_t cpu_to_le64(uint64_t v)
+{
+# ifdef HAVE___CPU_TO_LE64
+ return __cpu_to_le64(v);
+# elif defined(HAVE_HTOLE64)
+ return htole64(v);
+# elif defined(HAVE___BSWAP_64)
+ return __bswap_64(v);
+# elif defined(HAVE___BUILTIN_BSWAP64)
+ return __builtin_bswap64(v);
+# elif defined(HAVE__BYTESWAP_UINT64)
+ return _byteswap_uint64(v);
+# else
+ v = ((v << 8) & 0xff00ff00ff00ff00ull) |
+ ((v >> 8) & 0x00ff00ff00ff00ffull);
+ v = ((v << 16) & 0xffff0000ffff0000ull) |
+ ((v >> 16) & 0x0000ffff0000ffffull);
+ return (v << 32) | (v >> 32);
+# endif
+}
+#endif
+
+#else /* not WORDS_LITTLEENDIAN or WORDS_BIGENDIAN */
+
+static inline uint16_t cpu_to_le16(uint16_t v)
+{
+ union u16 {
+ uint16_t v;
+ uint8_t c[2];
+ } x;
+ uint8_t *cp = &x.c;
+
+ WRITESHORT(cp, v);
+ return x.v;
+}
+
+static inline uint32_t cpu_to_le32(uint32_t v)
+{
+ union u32 {
+ uint32_t v;
+ uint8_t c[4];
+ } x;
+ uint8_t *cp = &x.c;
+
+ WRITELONG(cp, v);
+ return x.v;
+}
+
+static inline uint64_t cpu_to_le64(uint64_t v)
+{
+ union u64 {
+ uint64_t v;
+ uint8_t c[8];
+ } x;
+ uint8_t *cp = &x.c;
+
+ WRITEDLONG(cp, v);
+ return x.v;
+}
+
+#endif
+
+#define WRITEADDR(p,v,s) \
+ do { \
+ switch (is_constant(s) ? (s) : 0) { \
+ case 1: \
+ WRITECHAR(p,v); \
+ break; \
+ case 2: \
+ WRITESHORT(p,v); \
+ break; \
+ case 4: \
+ WRITELONG(p,v); \
+ break; \
+ case 8: \
+ WRITEDLONG(p,v); \
+ break; \
+ default: \
+ { \
+ const uint64_t _wa_v = cpu_to_le64(v); \
+ const size_t _wa_s = (s); \
+ uint8_t * const _wa_p = (uint8_t *)(p); \
+ memcpy(_wa_p, &_wa_v, _wa_s); \
+ (p) = (void *)(_wa_p + _wa_s); \
+ } \
+ break; \
+ } \
+ } while (0)
+
+#endif /* NASM_BYTESEX_H */