diff options
Diffstat (limited to 'iconv')
-rw-r--r-- | iconv/gconv_int.h | 28 | ||||
-rw-r--r-- | iconv/loop.c | 73 | ||||
-rw-r--r-- | iconv/skeleton.c | 67 |
3 files changed, 28 insertions, 140 deletions
diff --git a/iconv/gconv_int.h b/iconv/gconv_int.h index da792a9..4b247a8 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 diff --git a/iconv/loop.c b/iconv/loop.c index 963c59c..9d8a7cc 100644 --- a/iconv/loop.c +++ b/iconv/loop.c @@ -57,75 +57,10 @@ #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) @@ -349,10 +284,6 @@ FCTNAME (LOOPFCT) (struct __gconv_step *step, #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 @@ -540,8 +471,4 @@ gconv_btowc (struct __gconv_step *step, unsigned char c) #undef LOOP_NEED_STATE #undef LOOP_NEED_FLAGS #undef LOOP_NEED_DATA -#undef get16 -#undef get32 -#undef put16 -#undef put32 #undef unaligned diff --git a/iconv/skeleton.c b/iconv/skeleton.c index 673b474..9423d3f 100644 --- a/iconv/skeleton.c +++ b/iconv/skeleton.c @@ -204,73 +204,6 @@ #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 |