[WIP] [PATCH v0.0-20200229 02/11] ez: add helpers for unaligned accesses

Gao Xiang hsiangkao at aol.com
Sat Feb 29 15:50:08 AEDT 2020


Signed-off-by: Gao Xiang <hsiangkao at aol.com>
---
 include/ez/unaligned.h | 55 ++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 55 insertions(+)
 create mode 100644 include/ez/unaligned.h

diff --git a/include/ez/unaligned.h b/include/ez/unaligned.h
new file mode 100644
index 0000000..f7c7f4f
--- /dev/null
+++ b/include/ez/unaligned.h
@@ -0,0 +1,55 @@
+/* SPDX-License-Identifier: Apache-2.0 */
+/*
+ * ez/include/ez/unaligned.h
+ *
+ * Copyright (C) 2019 Gao Xiang <hsiangkao at aol.com>
+ */
+#ifndef __EZ_UNALIGNED_H
+#define __EZ_UNALIGNED_H
+
+#include <stdint.h>
+
+/*
+ * __pack instructions are safer, but compiler specific, hence potentially
+ * problematic for some compilers (workable on gcc, clang).
+ */
+static inline uint16_t get_unaligned16(const void *ptr)
+{
+	const struct { uint16_t v; } __attribute__((packed)) *unalign = ptr;
+
+	return unalign->v;
+}
+
+static inline uint32_t get_unaligned32(const void *ptr)
+{
+	const struct { uint32_t v; } __attribute__((packed)) *unalign = ptr;
+
+	return unalign->v;
+}
+
+static inline unsigned int __is_little_endian(void)
+{
+#ifdef __LITTLE_ENDIAN
+	return 1;
+#elif defined(__BIG_ENDIAN)
+	return 0;
+#else
+	/* don't use static : performance detrimental */
+	const union { uint32_t u; uint8_t c[4]; } one = { 1 };
+
+	return one.c[0];
+#endif
+}
+
+static inline uint32_t get_unaligned_le32(const void *ptr)
+{
+	if (!__is_little_endian()) {
+		const uint8_t *p = (const uint8_t *)ptr;
+
+		return p[0] | (p[1] << 8) | (p[2] << 16) | (p[3] << 24);
+	}
+	return get_unaligned32(ptr);
+}
+
+#endif
+
-- 
2.20.1



More information about the Linux-erofs mailing list