__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
#include <stddef.h>
#include <libc-diag.h>
-/* 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. But if we cannot
- access unaligned memory we still have to read byte-wise. */
#undef FCTNAME2
#if _STRING_ARCH_unaligned || !defined DEFINE_UNALIGNED
-/* We can handle unaligned memory access. */
-# define get16(addr) *((const uint16_t *) (addr))
-# define get32(addr) *((const uint32_t *) (addr))
-
-/* We need no special support for writing values either. */
-# define put16(addr, val) *((uint16_t *) (addr)) = (val)
-# define put32(addr, val) *((uint32_t *) (addr)) = (val)
-
# define FCTNAME2(name) name
#else
-/* Distinguish between big endian and little endian. */
-# if __BYTE_ORDER == __LITTLE_ENDIAN
-# define get16(addr) \
- (((const unsigned char *) (addr))[1] << 8 \
- | ((const unsigned char *) (addr))[0])
-# define get32(addr) \
- (((((const unsigned char *) (addr))[3] << 8 \
- | ((const unsigned char *) (addr))[2]) << 8 \
- | ((const unsigned char *) (addr))[1]) << 8 \
- | ((const unsigned char *) (addr))[0])
-
-# define put16(addr, val) \
- ({ uint16_t __val = (val); \
- ((unsigned char *) (addr))[0] = __val; \
- ((unsigned char *) (addr))[1] = __val >> 8; \
- (void) 0; })
-# define put32(addr, val) \
- ({ uint32_t __val = (val); \
- ((unsigned char *) (addr))[0] = __val; \
- __val >>= 8; \
- ((unsigned char *) (addr))[1] = __val; \
- __val >>= 8; \
- ((unsigned char *) (addr))[2] = __val; \
- __val >>= 8; \
- ((unsigned char *) (addr))[3] = __val; \
- (void) 0; })
-# else
-# define get16(addr) \
- (((const unsigned char *) (addr))[0] << 8 \
- | ((const unsigned char *) (addr))[1])
-# define get32(addr) \
- (((((const unsigned char *) (addr))[0] << 8 \
- | ((const unsigned char *) (addr))[1]) << 8 \
- | ((const unsigned char *) (addr))[2]) << 8 \
- | ((const unsigned char *) (addr))[3])
-
-# define put16(addr, val) \
- ({ uint16_t __val = (val); \
- ((unsigned char *) (addr))[1] = __val; \
- ((unsigned char *) (addr))[0] = __val >> 8; \
- (void) 0; })
-# define put32(addr, val) \
- ({ uint32_t __val = (val); \
- ((unsigned char *) (addr))[3] = __val; \
- __val >>= 8; \
- ((unsigned char *) (addr))[2] = __val; \
- __val >>= 8; \
- ((unsigned char *) (addr))[1] = __val; \
- __val >>= 8; \
- ((unsigned char *) (addr))[0] = __val; \
- (void) 0; })
-# endif
-
# define FCTNAME2(name) name##_unaligned
#endif
#define FCTNAME(name) FCTNAME2(name)
#if !defined DEFINE_UNALIGNED && !_STRING_ARCH_unaligned \
&& MIN_NEEDED_INPUT != 1 && MAX_NEEDED_INPUT % MIN_NEEDED_INPUT == 0 \
&& MIN_NEEDED_OUTPUT != 1 && MAX_NEEDED_OUTPUT % MIN_NEEDED_OUTPUT == 0
-# undef get16
-# undef get32
-# undef put16
-# undef put32
# undef unaligned
# define DEFINE_UNALIGNED
#undef LOOP_NEED_STATE
#undef LOOP_NEED_FLAGS
#undef LOOP_NEED_DATA
-#undef get16
-#undef get32
-#undef put16
-#undef put32
#undef unaligned
#endif
-/* Define macros which can access unaligned buffers. These macros are
- supposed to be used only in code outside the inner loops. For the inner
- loops we have other definitions which allow optimized access. */
-#if _STRING_ARCH_unaligned
-/* We can handle unaligned memory access. */
-# define get16u(addr) *((const uint16_t *) (addr))
-# define get32u(addr) *((const uint32_t *) (addr))
-
-/* We need no special support for writing values either. */
-# define put16u(addr, val) *((uint16_t *) (addr)) = (val)
-# define put32u(addr, val) *((uint32_t *) (addr)) = (val)
-#else
-/* Distinguish between big endian and little endian. */
-# if __BYTE_ORDER == __LITTLE_ENDIAN
-# define get16u(addr) \
- (((const unsigned char *) (addr))[1] << 8 \
- | ((const unsigned char *) (addr))[0])
-# define get32u(addr) \
- (((((const unsigned char *) (addr))[3] << 8 \
- | ((const unsigned char *) (addr))[2]) << 8 \
- | ((const unsigned char *) (addr))[1]) << 8 \
- | ((const unsigned char *) (addr))[0])
-
-# define put16u(addr, val) \
- ({ uint16_t __val = (val); \
- ((unsigned char *) (addr))[0] = __val; \
- ((unsigned char *) (addr))[1] = __val >> 8; \
- (void) 0; })
-# define put32u(addr, val) \
- ({ uint32_t __val = (val); \
- ((unsigned char *) (addr))[0] = __val; \
- __val >>= 8; \
- ((unsigned char *) (addr))[1] = __val; \
- __val >>= 8; \
- ((unsigned char *) (addr))[2] = __val; \
- __val >>= 8; \
- ((unsigned char *) (addr))[3] = __val; \
- (void) 0; })
-# else
-# define get16u(addr) \
- (((const unsigned char *) (addr))[0] << 8 \
- | ((const unsigned char *) (addr))[1])
-# define get32u(addr) \
- (((((const unsigned char *) (addr))[0] << 8 \
- | ((const unsigned char *) (addr))[1]) << 8 \
- | ((const unsigned char *) (addr))[2]) << 8 \
- | ((const unsigned char *) (addr))[3])
-
-# define put16u(addr, val) \
- ({ uint16_t __val = (val); \
- ((unsigned char *) (addr))[1] = __val; \
- ((unsigned char *) (addr))[0] = __val >> 8; \
- (void) 0; })
-# define put32u(addr, val) \
- ({ uint32_t __val = (val); \
- ((unsigned char *) (addr))[3] = __val; \
- __val >>= 8; \
- ((unsigned char *) (addr))[2] = __val; \
- __val >>= 8; \
- ((unsigned char *) (addr))[1] = __val; \
- __val >>= 8; \
- ((unsigned char *) (addr))[0] = __val; \
- (void) 0; })
-# endif
-#endif
-
-
/* For conversions from a fixed width character set to another fixed width
character set we can define RESET_INPUT_BUFFER in a very fast way. */
#if !defined RESET_INPUT_BUFFER && !defined SAVE_RESET_STATE
if (__glibc_likely (outbuf + 4 <= outend)) \
{ \
/* Write out the last character. */ \
- put32u (outbuf, ch); \
+ put32 (outbuf, ch); \
outbuf += 4; \
data->__statep->__count &= 7; \
data->__statep->__count |= ASCII_set; \
return (inptr == inend \
? __GCONV_EMPTY_INPUT : __GCONV_INCOMPLETE_INPUT); \
\
- if (get16u (inptr) == BOM) \
+ if (get16 (inptr) == BOM) \
/* Simply ignore the BOM character. */ \
*inptrp = inptr += 2; \
- else if (get16u (inptr) == BOM_OE) \
+ else if (get16 (inptr) == BOM_OE) \
{ \
data->__flags |= __GCONV_SWAP; \
*inptrp = inptr += 2; \
if (__glibc_unlikely (outbuf + 2 > outend)) \
return __GCONV_FULL_OUTPUT; \
\
- put16u (outbuf, BOM); \
+ put16 (outbuf, BOM); \
outbuf += 2; \
} \
swap = data->__flags & __GCONV_SWAP;
return (inptr == inend \
? __GCONV_EMPTY_INPUT : __GCONV_INCOMPLETE_INPUT); \
\
- if (get16u (inptr) == BOM) \
+ if (get16 (inptr) == BOM) \
/* Simply ignore the BOM character. */ \
*inptrp = inptr += 2; \
- else if (get16u (inptr) == BOM_OE) \
+ else if (get16 (inptr) == BOM_OE) \
{ \
data->__flags |= __GCONV_SWAP; \
*inptrp = inptr += 2; \
if (__glibc_unlikely (outbuf + 2 > outend)) \
return __GCONV_FULL_OUTPUT; \
\
- put16u (outbuf, BOM); \
+ put16 (outbuf, BOM); \
outbuf += 2; \
} \
} \
return (inptr == inend \
? __GCONV_EMPTY_INPUT : __GCONV_INCOMPLETE_INPUT); \
\
- if (get32u (inptr) == BOM) \
+ if (get32 (inptr) == BOM) \
/* Simply ignore the BOM character. */ \
*inptrp = inptr += 4; \
- else if (get32u (inptr) == BOM_OE) \
+ else if (get32 (inptr) == BOM_OE) \
{ \
data->__flags |= __GCONV_SWAP; \
*inptrp = inptr += 4; \
if (__glibc_unlikely (outbuf + 4 > outend)) \
return __GCONV_FULL_OUTPUT; \
\
- put32u (outbuf, BOM); \
+ put32 (outbuf, BOM); \
outbuf += 4; \
} \
else if (__builtin_expect (data->__invocation_counter == 0, 0) \
if (__glibc_unlikely (outbuf + 2 > outend)) \
return __GCONV_FULL_OUTPUT; \
\
- put16u (outbuf, BOM_UTF16); \
+ put16 (outbuf, BOM_UTF16); \
outbuf += 2; \
} \
else \
if (__glibc_unlikely (outbuf + 4 > outend)) \
return __GCONV_FULL_OUTPUT; \
\
- put32u (outbuf, BOM_UTF32); \
+ put32 (outbuf, BOM_UTF32); \
outbuf += 4; \
} \
}
if (__glibc_unlikely (outbuf + 2 > outend)) \
return __GCONV_FULL_OUTPUT; \
\
- put16u (outbuf, BOM_UTF16); \
+ put16 (outbuf, BOM_UTF16); \
outbuf += 2; \
}
if (__glibc_unlikely (outbuf + 4 > outend)) \
return __GCONV_FULL_OUTPUT; \
\
- put32u (outbuf, BOM); \
+ put32 (outbuf, BOM); \
outbuf += 4; \
}