about summary refs log tree commit diff
path: root/iconv/gconv_int.h
diff options
context:
space:
mode:
authorAdhemerval Zanella <adhemerval.zanella@linaro.org>2023-02-10 14:09:10 -0300
committerAdhemerval Zanella <adhemerval.zanella@linaro.org>2023-02-17 15:56:54 -0300
commit5729e0e9af590807df66a3db688008f9547bce9f (patch)
treeb4f50ff2f122c75e0833ec18c7256afa2c4c1ab7 /iconv/gconv_int.h
parent62d4c768a4df59e4381464385b3a7246e6df6661 (diff)
downloadglibc-5729e0e9af590807df66a3db688008f9547bce9f.tar.gz
glibc-5729e0e9af590807df66a3db688008f9547bce9f.tar.xz
glibc-5729e0e9af590807df66a3db688008f9547bce9f.zip
iconv: Remove _STRING_ARCH_unaligned usage for get/set macros
And use a packed structure instead.  The compiler generates optimized
unaligned code if the architecture supports it.

Checked on x86_64-linux-gnu and i686-linux-gnu.

Reviewed-by: Wilco Dijkstra  <Wilco.Dijkstra@arm.com>
Diffstat (limited to 'iconv/gconv_int.h')
-rw-r--r--iconv/gconv_int.h28
1 files changed, 28 insertions, 0 deletions
diff --git a/iconv/gconv_int.h b/iconv/gconv_int.h
index da792a95f5..4b247a815f 100644
--- a/iconv/gconv_int.h
+++ b/iconv/gconv_int.h
@@ -26,6 +26,34 @@
 
 __BEGIN_DECLS
 
+/* We have to provide support for machines which are not able to handled
+   unaligned memory accesses.  Some of the character encodings have
+   representations with a fixed width of 2 or 4 bytes.  */
+#define get16(addr)							\
+({									\
+  const struct { uint16_t r; } __attribute__ ((__packed__)) *__ptr	\
+    = (__typeof(__ptr))(addr);						\
+  __ptr->r;								\
+})
+#define get32(addr)							\
+({									\
+  const struct { uint32_t r; } __attribute__ ((__packed__)) *__ptr	\
+    = (__typeof(__ptr))(addr);						\
+  __ptr->r;								\
+})
+
+#define put16(addr, val)						\
+do {									\
+   struct { uint16_t r; } __attribute__ ((__packed__)) *__ptr		\
+    = (__typeof(__ptr))(addr);						\
+   __ptr->r = val;							\
+} while (0)
+#define put32(addr, val)						\
+do {									\
+   struct { uint32_t r; } __attribute__ ((__packed__)) *__ptr		\
+    = (__typeof(__ptr))(addr);						\
+   __ptr->r = val;							\
+} while (0)
 
 /* Structure for alias definition.  Simply two strings.  */
 struct gconv_alias