git subrepo pull (merge) --force deps/libchdr
[pcsx_rearmed.git] / deps / libchdr / deps / zstd-1.5.5 / contrib / linux-kernel / test / include / asm / unaligned.h
diff --git a/deps/libchdr/deps/zstd-1.5.5/contrib/linux-kernel/test/include/asm/unaligned.h b/deps/libchdr/deps/zstd-1.5.5/contrib/linux-kernel/test/include/asm/unaligned.h
new file mode 100644 (file)
index 0000000..86ec4ca
--- /dev/null
@@ -0,0 +1,187 @@
+#ifndef ASM_UNALIGNED_H
+#define ASM_UNALIGNED_H
+
+#include <assert.h>
+#include <linux/types.h>
+
+#ifndef __LITTLE_ENDIAN
+# if (__BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__) || defined(__LITTLE_ENDIAN__)
+#  define __LITTLE_ENDIAN 1
+# endif
+#endif
+
+#ifdef __LITTLE_ENDIAN
+# define _IS_LITTLE_ENDIAN 1
+#else
+# define _IS_LITTLE_ENDIAN 0
+#endif
+
+static unsigned _isLittleEndian(void)
+{
+    const union { uint32_t u; uint8_t c[4]; } one = { 1 };
+    assert(_IS_LITTLE_ENDIAN == one.c[0]);
+    (void)one;
+    return _IS_LITTLE_ENDIAN;
+}
+
+static uint16_t _swap16(uint16_t in)
+{
+    return ((in & 0xF) << 8) + ((in & 0xF0) >> 8);
+}
+
+static uint32_t _swap32(uint32_t in)
+{
+    return __builtin_bswap32(in);
+}
+
+static uint64_t _swap64(uint64_t in)
+{
+    return __builtin_bswap64(in);
+}
+
+/* Little endian */
+static uint16_t get_unaligned_le16(const void* memPtr)
+{
+    uint16_t val;
+    __builtin_memcpy(&val, memPtr, sizeof(val));
+    if (!_isLittleEndian()) _swap16(val);
+    return val;
+}
+
+static uint32_t get_unaligned_le32(const void* memPtr)
+{
+    uint32_t val;
+    __builtin_memcpy(&val, memPtr, sizeof(val));
+    if (!_isLittleEndian()) _swap32(val);
+    return val;
+}
+
+static uint64_t get_unaligned_le64(const void* memPtr)
+{
+    uint64_t val;
+    __builtin_memcpy(&val, memPtr, sizeof(val));
+    if (!_isLittleEndian()) _swap64(val);
+    return val;
+}
+
+static void put_unaligned_le16(uint16_t value, void* memPtr)
+{
+    if (!_isLittleEndian()) value = _swap16(value);
+    __builtin_memcpy(memPtr, &value, sizeof(value));
+}
+
+static void put_unaligned_le32(uint32_t value, void* memPtr)
+{
+    if (!_isLittleEndian()) value = _swap32(value);
+    __builtin_memcpy(memPtr, &value, sizeof(value));
+}
+
+static void put_unaligned_le64(uint64_t value, void* memPtr)
+{
+    if (!_isLittleEndian()) value = _swap64(value);
+    __builtin_memcpy(memPtr, &value, sizeof(value));
+}
+
+/* big endian */
+static uint32_t get_unaligned_be32(const void* memPtr)
+{
+    uint32_t val;
+    __builtin_memcpy(&val, memPtr, sizeof(val));
+    if (_isLittleEndian()) _swap32(val);
+    return val;
+}
+
+static uint64_t get_unaligned_be64(const void* memPtr)
+{
+    uint64_t val;
+    __builtin_memcpy(&val, memPtr, sizeof(val));
+    if (_isLittleEndian()) _swap64(val);
+    return val;
+}
+
+static void put_unaligned_be32(uint32_t value, void* memPtr)
+{
+    if (_isLittleEndian()) value = _swap32(value);
+    __builtin_memcpy(memPtr, &value, sizeof(value));
+}
+
+static void put_unaligned_be64(uint64_t value, void* memPtr)
+{
+    if (_isLittleEndian()) value = _swap64(value);
+    __builtin_memcpy(memPtr, &value, sizeof(value));
+}
+
+/* generic */
+extern void __bad_unaligned_access_size(void);
+
+#define __get_unaligned_le(ptr) ((typeof(*(ptr)))({                            \
+    __builtin_choose_expr(sizeof(*(ptr)) == 1, *(ptr),                         \
+    __builtin_choose_expr(sizeof(*(ptr)) == 2, get_unaligned_le16((ptr)),      \
+    __builtin_choose_expr(sizeof(*(ptr)) == 4, get_unaligned_le32((ptr)),      \
+    __builtin_choose_expr(sizeof(*(ptr)) == 8, get_unaligned_le64((ptr)),      \
+    __bad_unaligned_access_size()))));                                         \
+    }))
+
+#define __get_unaligned_be(ptr) ((typeof(*(ptr)))({                            \
+    __builtin_choose_expr(sizeof(*(ptr)) == 1, *(ptr),                         \
+    __builtin_choose_expr(sizeof(*(ptr)) == 2, get_unaligned_be16((ptr)),      \
+    __builtin_choose_expr(sizeof(*(ptr)) == 4, get_unaligned_be32((ptr)),      \
+    __builtin_choose_expr(sizeof(*(ptr)) == 8, get_unaligned_be64((ptr)),      \
+    __bad_unaligned_access_size()))));                                         \
+    }))
+
+#define __put_unaligned_le(val, ptr)                                           \
+  ({                                                                           \
+    void *__gu_p = (ptr);                                                      \
+    switch (sizeof(*(ptr))) {                                                  \
+    case 1:                                                                    \
+      *(uint8_t *)__gu_p = (uint8_t)(val);                                     \
+      break;                                                                   \
+    case 2:                                                                    \
+      put_unaligned_le16((uint16_t)(val), __gu_p);                             \
+      break;                                                                   \
+    case 4:                                                                    \
+      put_unaligned_le32((uint32_t)(val), __gu_p);                             \
+      break;                                                                   \
+    case 8:                                                                    \
+      put_unaligned_le64((uint64_t)(val), __gu_p);                             \
+      break;                                                                   \
+    default:                                                                   \
+      __bad_unaligned_access_size();                                           \
+      break;                                                                   \
+    }                                                                          \
+    (void)0;                                                                   \
+  })
+
+#define __put_unaligned_be(val, ptr)                                           \
+  ({                                                                           \
+    void *__gu_p = (ptr);                                                      \
+    switch (sizeof(*(ptr))) {                                                  \
+    case 1:                                                                    \
+      *(uint8_t *)__gu_p = (uint8_t)(val);                                     \
+      break;                                                                   \
+    case 2:                                                                    \
+      put_unaligned_be16((uint16_t)(val), __gu_p);                             \
+      break;                                                                   \
+    case 4:                                                                    \
+      put_unaligned_be32((uint32_t)(val), __gu_p);                             \
+      break;                                                                   \
+    case 8:                                                                    \
+      put_unaligned_be64((uint64_t)(val), __gu_p);                             \
+      break;                                                                   \
+    default:                                                                   \
+      __bad_unaligned_access_size();                                           \
+      break;                                                                   \
+    }                                                                          \
+    (void)0;                                                                   \
+  })
+
+#if _IS_LITTLE_ENDIAN
+#  define get_unaligned __get_unaligned_le
+#  define put_unaligned __put_unaligned_le
+#else
+#  define get_unaligned __get_unaligned_be
+#  define put_unaligned __put_unaligned_be
+#endif
+
+#endif // ASM_UNALIGNED_H