diff mbox series

[6/7] iconv: Remove _STRING_ARCH_unaligned usage

Message ID 20230213135558.3328727-7-adhemerval.zanella@linaro.org
State New
Headers show
Series Remove _STRING_ARCH_unaligned | expand

Commit Message

Adhemerval Zanella Netto Feb. 13, 2023, 1:55 p.m. UTC
Use put/get macros __builtin_bswap32 instead.  It allows to remove
the unaligned routines, the compiler will generate unaligned access
if the ABI allows it.

Checked on x86_64-linux-gnu and i686-linux-gnu.
---
 iconv/gconv_simple.c | 282 +++----------------------------------------
 iconv/loop.c         |  66 ++++------
 iconv/skeleton.c     | 118 +++---------------
 3 files changed, 59 insertions(+), 407 deletions(-)

Comments

Wilco Dijkstra Feb. 15, 2023, 7:02 p.m. UTC | #1
Hi Adhemerval,

What a mess that was, great cleanup! LGTM.

Reviewed-by: Wilco Dijkstra  <Wilco.Dijkstra@arm.com>


diff --git a/iconv/gconv_simple.c b/iconv/gconv_simple.c
index c50ffd3bf0..c60cffad4c 100644
--- a/iconv/gconv_simple.c
+++ b/iconv/gconv_simple.c
@@ -86,69 +86,22 @@ internal_ucs4_loop (struct __gconv_step *step,
 #if __BYTE_ORDER == __LITTLE_ENDIAN
   /* Sigh, we have to do some real work.  */
   size_t cnt;
-  uint32_t *outptr32 = (uint32_t *) outptr;
-
-  for (cnt = 0; cnt < n_convert; ++cnt, inptr += 4)
-    *outptr32++ = bswap_32 (*(const uint32_t *) inptr);
-
-  *inptrp = inptr;
-  *outptrp = (unsigned char *) outptr32;
-#elif __BYTE_ORDER == __BIG_ENDIAN
-  /* Simply copy the data.  */
-  *inptrp = inptr + n_convert * 4;
-  *outptrp = __mempcpy (outptr, inptr, n_convert * 4);
-#else
-# error "This endianess is not supported."
-#endif
-
-  /* Determine the status.  */
-  if (*inptrp == inend)
-    result = __GCONV_EMPTY_INPUT;
-  else if (*outptrp + 4 > outend)
-    result = __GCONV_FULL_OUTPUT;
-  else
-    result = __GCONV_INCOMPLETE_INPUT;
-
-  return result;
-}
-
-#if !_STRING_ARCH_unaligned
-static inline int
-__attribute ((always_inline))
-internal_ucs4_loop_unaligned (struct __gconv_step *step,
-                             struct __gconv_step_data *step_data,
-                             const unsigned char **inptrp,
-                             const unsigned char *inend,
-                             unsigned char **outptrp,
-                             const unsigned char *outend,
-                             size_t *irreversible)
-{
-  const unsigned char *inptr = *inptrp;
-  unsigned char *outptr = *outptrp;
-  size_t n_convert = MIN (inend - inptr, outend - outptr) / 4;
-  int result;
-
-# if __BYTE_ORDER == __LITTLE_ENDIAN
-  /* Sigh, we have to do some real work.  */
-  size_t cnt;
 
   for (cnt = 0; cnt < n_convert; ++cnt, inptr += 4, outptr += 4)
     {
-      outptr[0] = inptr[3];
-      outptr[1] = inptr[2];
-      outptr[2] = inptr[1];
-      outptr[3] = inptr[0];
+      uint32_t val = get32 (inptr);
+      put32 (outptr, __builtin_bswap32 (val));
     }
 
   *inptrp = inptr;
   *outptrp = outptr;
-# elif __BYTE_ORDER == __BIG_ENDIAN
+#elif __BYTE_ORDER == __BIG_ENDIAN
   /* Simply copy the data.  */
   *inptrp = inptr + n_convert * 4;
   *outptrp = __mempcpy (outptr, inptr, n_convert * 4);
-# else
-#  error "This endianess is not supported."
-# endif
+#else
+# error "This endianess is not supported."
+#endif
 
   /* Determine the status.  */
   if (*inptrp == inend)
@@ -160,7 +113,6 @@ internal_ucs4_loop_unaligned (struct __gconv_step *step,
 
   return result;
 }
-#endif
 
 
 static inline int
@@ -242,12 +194,9 @@ ucs4_internal_loop (struct __gconv_step *step,
 
   for (; inptr + 4 <= inend && outptr + 4 <= outend; inptr += 4)
     {
-      uint32_t inval;
-
+      uint32_t inval = get32 (inptr);
 #if __BYTE_ORDER == __LITTLE_ENDIAN
-      inval = bswap_32 (*(const uint32_t *) inptr);
-#else
-      inval = *(const uint32_t *) inptr;
+      inval = __builtin_bswap32 (inval);
 #endif
 
       if (__glibc_unlikely (inval > 0x7fffffff))
@@ -272,7 +221,7 @@ ucs4_internal_loop (struct __gconv_step *step,
           return __GCONV_ILLEGAL_INPUT;
         }
 
-      *((uint32_t *) outptr) = inval;
+      put32 (outptr, inval);
       outptr += sizeof (uint32_t);
     }
 
@@ -290,75 +239,6 @@ ucs4_internal_loop (struct __gconv_step *step,
   return result;
 }
 
-#if !_STRING_ARCH_unaligned
-static inline int
-__attribute ((always_inline))
-ucs4_internal_loop_unaligned (struct __gconv_step *step,
-                             struct __gconv_step_data *step_data,
-                             const unsigned char **inptrp,
-                             const unsigned char *inend,
-                             unsigned char **outptrp,
-                             const unsigned char *outend,
-                             size_t *irreversible)
-{
-  int flags = step_data->__flags;
-  const unsigned char *inptr = *inptrp;
-  unsigned char *outptr = *outptrp;
-  int result;
-
-  for (; inptr + 4 <= inend && outptr + 4 <= outend; inptr += 4)
-    {
-      if (__glibc_unlikely (inptr[0] > 0x80))
-       {
-         /* The value is too large.  We don't try transliteration here since
-            this is not an error because of the lack of possibilities to
-            represent the result.  This is a genuine bug in the input since
-            UCS4 does not allow such values.  */
-         if (irreversible == NULL)
-           /* We are transliterating, don't try to correct anything.  */
-           return __GCONV_ILLEGAL_INPUT;
-
-         if (flags & __GCONV_IGNORE_ERRORS)
-           {
-             /* Just ignore this character.  */
-             ++*irreversible;
-             continue;
-           }
-
-         *inptrp = inptr;
-         *outptrp = outptr;
-         return __GCONV_ILLEGAL_INPUT;
-       }
-
-# if __BYTE_ORDER == __LITTLE_ENDIAN
-      outptr[3] = inptr[0];
-      outptr[2] = inptr[1];
-      outptr[1] = inptr[2];
-      outptr[0] = inptr[3];
-# else
-      outptr[0] = inptr[0];
-      outptr[1] = inptr[1];
-      outptr[2] = inptr[2];
-      outptr[3] = inptr[3];
-# endif
-      outptr += 4;
-    }
-
-  *inptrp = inptr;
-  *outptrp = outptr;
-
-  /* Determine the status.  */
-  if (*inptrp == inend)
-    result = __GCONV_EMPTY_INPUT;
-  else if (*outptrp + 4 > outend)
-    result = __GCONV_FULL_OUTPUT;
-  else
-    result = __GCONV_INCOMPLETE_INPUT;
-
-  return result;
-}
-#endif
-
 
 static inline int
 __attribute ((always_inline))
@@ -453,11 +333,12 @@ internal_ucs4le_loop (struct __gconv_step *step,
 #if __BYTE_ORDER == __BIG_ENDIAN
   /* Sigh, we have to do some real work.  */
   size_t cnt;
-  uint32_t *outptr32 = (uint32_t *) outptr;
 
-  for (cnt = 0; cnt < n_convert; ++cnt, inptr += 4)
-    *outptr32++ = bswap_32 (*(const uint32_t *) inptr);
-  outptr = (unsigned char *) outptr32;
+  for (cnt = 0; cnt < n_convert; ++cnt, inptr += 4, outptr += 4)
+    {
+      uint32_t val = get32 (inptr);
+      put32 (outptr, __builtin_bswap32 (val));
+    }
 
   *inptrp = inptr;
   *outptrp = outptr;
@@ -480,59 +361,6 @@ internal_ucs4le_loop (struct __gconv_step *step,
   return result;
 }
 
-#if !_STRING_ARCH_unaligned
-static inline int
-__attribute ((always_inline))
-internal_ucs4le_loop_unaligned (struct __gconv_step *step,
-                               struct __gconv_step_data *step_data,
-                               const unsigned char **inptrp,
-                               const unsigned char *inend,
-                               unsigned char **outptrp,
-                               const unsigned char *outend,
-                               size_t *irreversible)
-{
-  const unsigned char *inptr = *inptrp;
-  unsigned char *outptr = *outptrp;
-  size_t n_convert = MIN (inend - inptr, outend - outptr) / 4;
-  int result;
-
-# if __BYTE_ORDER == __BIG_ENDIAN
-  /* Sigh, we have to do some real work.  */
-  size_t cnt;
-
-  for (cnt = 0; cnt < n_convert; ++cnt, inptr += 4, outptr += 4)
-    {
-      outptr[0] = inptr[3];
-      outptr[1] = inptr[2];
-      outptr[2] = inptr[1];
-      outptr[3] = inptr[0];
-    }
-
-  *inptrp = inptr;
-  *outptrp = outptr;
-# elif __BYTE_ORDER == __LITTLE_ENDIAN
-  /* Simply copy the data.  */
-  *inptrp = inptr + n_convert * 4;
-  *outptrp = __mempcpy (outptr, inptr, n_convert * 4);
-# else
-#  error "This endianess is not supported."
-# endif
-
-  /* Determine the status.  */
-  if (*inptrp == inend)
-    result = __GCONV_EMPTY_INPUT;
-  else if (*inptrp + 4 > inend)
-    result = __GCONV_INCOMPLETE_INPUT;
-  else
-    {
-      assert (*outptrp + 4 > outend);
-      result = __GCONV_FULL_OUTPUT;
-    }
-
-  return result;
-}
-#endif
-
 
 static inline int
 __attribute ((always_inline))
@@ -612,12 +440,9 @@ ucs4le_internal_loop (struct __gconv_step *step,
 
   for (; inptr + 4 <= inend && outptr + 4 <= outend; inptr += 4)
     {
-      uint32_t inval;
-
+      uint32_t inval = get32 (inptr);
 #if __BYTE_ORDER == __BIG_ENDIAN
-      inval = bswap_32 (*(const uint32_t *) inptr);
-#else
-      inval = *(const uint32_t *) inptr;
+      inval = __builtin_bswap32 (inval);
 #endif
 
       if (__glibc_unlikely (inval > 0x7fffffff))
@@ -642,7 +467,7 @@ ucs4le_internal_loop (struct __gconv_step *step,
           return __GCONV_ILLEGAL_INPUT;
         }
 
-      *((uint32_t *) outptr) = inval;
+      put32 (outptr, inval);
       outptr += sizeof (uint32_t);
     }
 
@@ -663,79 +488,6 @@ ucs4le_internal_loop (struct __gconv_step *step,
   return result;
 }
 
-#if !_STRING_ARCH_unaligned
-static inline int
-__attribute ((always_inline))
-ucs4le_internal_loop_unaligned (struct __gconv_step *step,
-                               struct __gconv_step_data *step_data,
-                               const unsigned char **inptrp,
-                               const unsigned char *inend,
-                               unsigned char **outptrp,
-                               const unsigned char *outend,
-                               size_t *irreversible)
-{
-  int flags = step_data->__flags;
-  const unsigned char *inptr = *inptrp;
-  unsigned char *outptr = *outptrp;
-  int result;
-
-  for (; inptr + 4 <= inend && outptr + 4 <= outend; inptr += 4)
-    {
-      if (__glibc_unlikely (inptr[3] > 0x80))
-       {
-         /* The value is too large.  We don't try transliteration here since
-            this is not an error because of the lack of possibilities to
-            represent the result.  This is a genuine bug in the input since
-            UCS4 does not allow such values.  */
-         if (irreversible == NULL)
-           /* We are transliterating, don't try to correct anything.  */
-           return __GCONV_ILLEGAL_INPUT;
-
-         if (flags & __GCONV_IGNORE_ERRORS)
-           {
-             /* Just ignore this character.  */
-             ++*irreversible;
-             continue;
-           }
-
-         *inptrp = inptr;
-         *outptrp = outptr;
-         return __GCONV_ILLEGAL_INPUT;
-       }
-
-# if __BYTE_ORDER == __BIG_ENDIAN
-      outptr[3] = inptr[0];
-      outptr[2] = inptr[1];
-      outptr[1] = inptr[2];
-      outptr[0] = inptr[3];
-# else
-      outptr[0] = inptr[0];
-      outptr[1] = inptr[1];
-      outptr[2] = inptr[2];
-      outptr[3] = inptr[3];
-# endif
-
-      outptr += 4;
-    }
-
-  *inptrp = inptr;
-  *outptrp = outptr;
-
-  /* Determine the status.  */
-  if (*inptrp == inend)
-    result = __GCONV_EMPTY_INPUT;
-  else if (*inptrp + 4 > inend)
-    result = __GCONV_INCOMPLETE_INPUT;
-  else
-    {
-      assert (*outptrp + 4 > outend);
-      result = __GCONV_FULL_OUTPUT;
-    }
-
-  return result;
-}
-#endif
-
 
 static inline int
 __attribute ((always_inline))

OK

diff --git a/iconv/loop.c b/iconv/loop.c
index 9d8a7cceb3..b2a1727ad4 100644
--- a/iconv/loop.c
+++ b/iconv/loop.c
@@ -58,12 +58,7 @@
 #include <libc-diag.h>
 
 #undef FCTNAME2
-#if _STRING_ARCH_unaligned || !defined DEFINE_UNALIGNED
-# define FCTNAME2(name) name
-#else
-# define FCTNAME2(name) name##_unaligned
-#endif
-#define FCTNAME(name) FCTNAME2(name)
+#define FCTNAME(name) name
 
 
 /* We need at least one byte for the next round.  */
@@ -279,20 +274,9 @@ FCTNAME (LOOPFCT) (struct __gconv_step *step,
 }
 
 
-/* Include the file a second time to define the function to handle
-   unaligned access.  */
-#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 unaligned
-
-# define DEFINE_UNALIGNED
-# include "loop.c"
-# undef DEFINE_UNALIGNED
-#else
-# if MAX_NEEDED_INPUT > 1
-#  define SINGLE(fct) SINGLE2 (fct)
-#  define SINGLE2(fct) fct##_single
+#if MAX_NEEDED_INPUT > 1
+# define SINGLE(fct) SINGLE2 (fct)
+# define SINGLE2(fct) fct##_single
 static inline int
 __attribute ((always_inline))
 SINGLE(LOOPFCT) (struct __gconv_step *step,
@@ -302,37 +286,37 @@ SINGLE(LOOPFCT) (struct __gconv_step *step,
                  size_t *irreversible EXTRA_LOOP_DECLS)
 {
   mbstate_t *state = step_data->__statep;
-#  ifdef LOOP_NEED_FLAGS
+# ifdef LOOP_NEED_FLAGS
   int flags = step_data->__flags;
-#  endif
-#  ifdef LOOP_NEED_DATA
+# endif
+# ifdef LOOP_NEED_DATA
   void *data = step->__data;
-#  endif
+# endif
   int result = __GCONV_OK;
   unsigned char bytebuf[MAX_NEEDED_INPUT];
   const unsigned char *inptr = *inptrp;
   unsigned char *outptr = *outptrp;
   size_t inlen;
 
-#  ifdef INIT_PARAMS
+# ifdef INIT_PARAMS
   INIT_PARAMS;
-#  endif
+# endif
 
-#  ifdef UNPACK_BYTES
+# ifdef UNPACK_BYTES
   UNPACK_BYTES
-#  else
+# else
   /* Add the bytes from the state to the input buffer.  */
   assert ((state->__count & 7) <= sizeof (state->__value));
   for (inlen = 0; inlen < (size_t) (state->__count & 7); ++inlen)
     bytebuf[inlen] = state->__value.__wchb[inlen];
-#  endif
+# endif
 
   /* Are there enough bytes in the input buffer?  */
   if (MIN_NEEDED_INPUT > 1
       && __builtin_expect (inptr + (MIN_NEEDED_INPUT - inlen) > inend, 0))
     {
       *inptrp = inend;
-#  ifdef STORE_REST
+# ifdef STORE_REST
 
       /* Building with -O3 GCC emits a `array subscript is above array
          bounds' warning.  GCC BZ #64739 has been opened for this.  */
@@ -347,14 +331,14 @@ SINGLE(LOOPFCT) (struct __gconv_step *step,
       inend = &bytebuf[inlen];
 
       STORE_REST
-#  else
+# else
       /* We don't have enough input for another complete input
          character.  */
       size_t inlen_after = inlen + (inend - inptr);
       assert (inlen_after <= sizeof (state->__value.__wchb));
       for (; inlen < inlen_after; inlen++)
         state->__value.__wchb[inlen] = *inptr++;
-#  endif
+# endif
 
       return __GCONV_INCOMPLETE_INPUT;
     }
@@ -406,11 +390,11 @@ SINGLE(LOOPFCT) (struct __gconv_step *step,
       result = __GCONV_OK;
 
       /* Clear the state buffer.  */
-#  ifdef CLEAR_STATE
+# ifdef CLEAR_STATE
       CLEAR_STATE;
-#  else
+# else
       state->__count &= ~7;
-#  endif
+# endif
     }
   else if (result == __GCONV_INCOMPLETE_INPUT)
     {
@@ -419,11 +403,11 @@ SINGLE(LOOPFCT) (struct __gconv_step *step,
       assert (inend != &bytebuf[MAX_NEEDED_INPUT]);
 
       *inptrp += inend - bytebuf - (state->__count & 7);
-#  ifdef STORE_REST
+# ifdef STORE_REST
       inptrp = &inptr;
 
       STORE_REST
-#  else
+# else
       /* We don't have enough input for another complete input
          character.  */
       assert (inend - inptr > (state->__count & ~7));
@@ -432,14 +416,13 @@ SINGLE(LOOPFCT) (struct __gconv_step *step,
       for (inlen = 0; inlen < inend - inptr; inlen++)
         state->__value.__wchb[inlen] = inptr[inlen];
       inptr = inend;
-#  endif
+# endif
     }
 
   return result;
 }
-#  undef SINGLE
-#  undef SINGLE2
-# endif
+# undef SINGLE
+# undef SINGLE2
 
 
 # ifdef ONEBYTE_BODY
@@ -471,4 +454,3 @@ gconv_btowc (struct __gconv_step *step, unsigned char c)
 #undef LOOP_NEED_STATE
 #undef LOOP_NEED_FLAGS
 #undef LOOP_NEED_DATA
-#undef unaligned

OK

diff --git a/iconv/skeleton.c b/iconv/skeleton.c
index 9423d3fc5a..61cff234ac 100644
--- a/iconv/skeleton.c
+++ b/iconv/skeleton.c
@@ -448,33 +448,6 @@ FUNCTION_NAME (struct __gconv_step *step, struct __gconv_step_data *data,
       size_t lirreversible = 0;
       size_t *lirreversiblep = irreversible ? &lirreversible : NULL;
 
-      /* The following assumes that encodings, which have a variable length
-        what might unalign a buffer even though it is an aligned in the
-        beginning, either don't have the minimal number of bytes as a divisor
-        of the maximum length or have a minimum length of 1.  This is true
-        for all known and supported encodings.
-        We use && instead of || to combine the subexpression for the FROM
-        encoding and for the TO encoding, because usually one of them is
-        INTERNAL, for which the subexpression evaluates to 1, but INTERNAL
-        buffers are always aligned correctly.  */
-#define POSSIBLY_UNALIGNED \
-  (!_STRING_ARCH_unaligned                                                   \
-   && (((FROM_LOOP_MIN_NEEDED_FROM != 1                                              \
-        && FROM_LOOP_MAX_NEEDED_FROM % FROM_LOOP_MIN_NEEDED_FROM == 0)        \
-       && (FROM_LOOP_MIN_NEEDED_TO != 1                                      \
-           && FROM_LOOP_MAX_NEEDED_TO % FROM_LOOP_MIN_NEEDED_TO == 0))        \
-       || ((TO_LOOP_MIN_NEEDED_FROM != 1                                     \
-           && TO_LOOP_MAX_NEEDED_FROM % TO_LOOP_MIN_NEEDED_FROM == 0)         \
-          && (TO_LOOP_MIN_NEEDED_TO != 1                                      \
-              && TO_LOOP_MAX_NEEDED_TO % TO_LOOP_MIN_NEEDED_TO == 0))))
-#if POSSIBLY_UNALIGNED
-      int unaligned;
-# define GEN_unaligned(name) GEN_unaligned2 (name)
-# define GEN_unaligned2(name) name##_unaligned
-#else
-# define unaligned 0
-#endif
-
 #ifdef PREPARE_LOOP
       PREPARE_LOOP
 #endif
@@ -514,18 +487,6 @@ FUNCTION_NAME (struct __gconv_step *step, struct __gconv_step_data *data,
         }
 #endif
 
-#if POSSIBLY_UNALIGNED
-      unaligned =
-       ((FROM_DIRECTION
-         && ((uintptr_t) inptr % FROM_LOOP_MIN_NEEDED_FROM != 0
-             || ((data->__flags & __GCONV_IS_LAST)
-                 && (uintptr_t) outbuf % FROM_LOOP_MIN_NEEDED_TO != 0)))
-        || (!FROM_DIRECTION
-            && (((data->__flags & __GCONV_IS_LAST)
-                 && (uintptr_t) outbuf % TO_LOOP_MIN_NEEDED_TO != 0)
-                || (uintptr_t) inptr % TO_LOOP_MIN_NEEDED_FROM != 0)));
-#endif
-
       while (1)
         {
           /* Remember the start value for this round.  */
@@ -543,34 +504,14 @@ FUNCTION_NAME (struct __gconv_step *step, struct __gconv_step_data *data,
           SAVE_RESET_STATE (1);
 #endif
 
-         if (__glibc_likely (!unaligned))
-           {
-             if (FROM_DIRECTION)
-               /* Run the conversion loop.  */
-               status = FROM_LOOP (step, data, inptrp, inend, &outbuf, outend,
-                                   lirreversiblep EXTRA_LOOP_ARGS);
-             else
-               /* Run the conversion loop.  */
-               status = TO_LOOP (step, data, inptrp, inend, &outbuf, outend,
-                                 lirreversiblep EXTRA_LOOP_ARGS);
-           }
-#if POSSIBLY_UNALIGNED
+         if (FROM_DIRECTION)
+           /* Run the conversion loop.  */
+           status = FROM_LOOP (step, data, inptrp, inend, &outbuf, outend,
+                               lirreversiblep EXTRA_LOOP_ARGS);
           else
-           {
-             if (FROM_DIRECTION)
-               /* Run the conversion loop.  */
-               status = GEN_unaligned (FROM_LOOP) (step, data, inptrp, inend,
-                                                   &outbuf, outend,
-                                                   lirreversiblep
-                                                   EXTRA_LOOP_ARGS);
-             else
-               /* Run the conversion loop.  */
-               status = GEN_unaligned (TO_LOOP) (step, data, inptrp, inend,
-                                                 &outbuf, outend,
-                                                 lirreversiblep
-                                                 EXTRA_LOOP_ARGS);
-           }
-#endif
+           /* Run the conversion loop.  */
+           status = TO_LOOP (step, data, inptrp, inend, &outbuf, outend,
+                             lirreversiblep EXTRA_LOOP_ARGS);
 
           /* If we were called as part of an error handling module we
              don't do anything else here.  */
@@ -635,41 +576,18 @@ FUNCTION_NAME (struct __gconv_step *step, struct __gconv_step_data *data,
                       SAVE_RESET_STATE (0);
 #endif
 
-                     if (__glibc_likely (!unaligned))
-                       {
-                         if (FROM_DIRECTION)
-                           /* Run the conversion loop.  */
-                           nstatus = FROM_LOOP (step, data, inptrp, inend,
-                                                &outbuf, outerr,
-                                                lirreversiblep
-                                                EXTRA_LOOP_ARGS);
-                         else
-                           /* Run the conversion loop.  */
-                           nstatus = TO_LOOP (step, data, inptrp, inend,
-                                              &outbuf, outerr,
-                                              lirreversiblep
-                                              EXTRA_LOOP_ARGS);
-                       }
-#if POSSIBLY_UNALIGNED
+                     if (FROM_DIRECTION)
+                       /* Run the conversion loop.  */
+                       nstatus = FROM_LOOP (step, data, inptrp, inend,
+                                            &outbuf, outerr,
+                                            lirreversiblep
+                                            EXTRA_LOOP_ARGS);
                       else
-                       {
-                         if (FROM_DIRECTION)
-                           /* Run the conversion loop.  */
-                           nstatus = GEN_unaligned (FROM_LOOP) (step, data,
-                                                                inptrp, inend,
-                                                                &outbuf,
-                                                                outerr,
-                                                                lirreversiblep
-                                                                EXTRA_LOOP_ARGS);
-                         else
-                           /* Run the conversion loop.  */
-                           nstatus = GEN_unaligned (TO_LOOP) (step, data,
-                                                              inptrp, inend,
-                                                              &outbuf, outerr,
-                                                              lirreversiblep
-                                                              EXTRA_LOOP_ARGS);
-                       }
-#endif
+                       /* Run the conversion loop.  */
+                       nstatus = TO_LOOP (step, data, inptrp, inend,
+                                          &outbuf, outerr,
+                                          lirreversiblep
+                                          EXTRA_LOOP_ARGS);
 
                       /* We must run out of output buffer space in this
                          rerun.  */

OK
diff mbox series

Patch

diff --git a/iconv/gconv_simple.c b/iconv/gconv_simple.c
index c50ffd3bf0..c60cffad4c 100644
--- a/iconv/gconv_simple.c
+++ b/iconv/gconv_simple.c
@@ -86,69 +86,22 @@  internal_ucs4_loop (struct __gconv_step *step,
 #if __BYTE_ORDER == __LITTLE_ENDIAN
   /* Sigh, we have to do some real work.  */
   size_t cnt;
-  uint32_t *outptr32 = (uint32_t *) outptr;
-
-  for (cnt = 0; cnt < n_convert; ++cnt, inptr += 4)
-    *outptr32++ = bswap_32 (*(const uint32_t *) inptr);
-
-  *inptrp = inptr;
-  *outptrp = (unsigned char *) outptr32;
-#elif __BYTE_ORDER == __BIG_ENDIAN
-  /* Simply copy the data.  */
-  *inptrp = inptr + n_convert * 4;
-  *outptrp = __mempcpy (outptr, inptr, n_convert * 4);
-#else
-# error "This endianess is not supported."
-#endif
-
-  /* Determine the status.  */
-  if (*inptrp == inend)
-    result = __GCONV_EMPTY_INPUT;
-  else if (*outptrp + 4 > outend)
-    result = __GCONV_FULL_OUTPUT;
-  else
-    result = __GCONV_INCOMPLETE_INPUT;
-
-  return result;
-}
-
-#if !_STRING_ARCH_unaligned
-static inline int
-__attribute ((always_inline))
-internal_ucs4_loop_unaligned (struct __gconv_step *step,
-			      struct __gconv_step_data *step_data,
-			      const unsigned char **inptrp,
-			      const unsigned char *inend,
-			      unsigned char **outptrp,
-			      const unsigned char *outend,
-			      size_t *irreversible)
-{
-  const unsigned char *inptr = *inptrp;
-  unsigned char *outptr = *outptrp;
-  size_t n_convert = MIN (inend - inptr, outend - outptr) / 4;
-  int result;
-
-# if __BYTE_ORDER == __LITTLE_ENDIAN
-  /* Sigh, we have to do some real work.  */
-  size_t cnt;
 
   for (cnt = 0; cnt < n_convert; ++cnt, inptr += 4, outptr += 4)
     {
-      outptr[0] = inptr[3];
-      outptr[1] = inptr[2];
-      outptr[2] = inptr[1];
-      outptr[3] = inptr[0];
+      uint32_t val = get32 (inptr);
+      put32 (outptr, __builtin_bswap32 (val));
     }
 
   *inptrp = inptr;
   *outptrp = outptr;
-# elif __BYTE_ORDER == __BIG_ENDIAN
+#elif __BYTE_ORDER == __BIG_ENDIAN
   /* Simply copy the data.  */
   *inptrp = inptr + n_convert * 4;
   *outptrp = __mempcpy (outptr, inptr, n_convert * 4);
-# else
-#  error "This endianess is not supported."
-# endif
+#else
+# error "This endianess is not supported."
+#endif
 
   /* Determine the status.  */
   if (*inptrp == inend)
@@ -160,7 +113,6 @@  internal_ucs4_loop_unaligned (struct __gconv_step *step,
 
   return result;
 }
-#endif
 
 
 static inline int
@@ -242,12 +194,9 @@  ucs4_internal_loop (struct __gconv_step *step,
 
   for (; inptr + 4 <= inend && outptr + 4 <= outend; inptr += 4)
     {
-      uint32_t inval;
-
+      uint32_t inval = get32 (inptr);
 #if __BYTE_ORDER == __LITTLE_ENDIAN
-      inval = bswap_32 (*(const uint32_t *) inptr);
-#else
-      inval = *(const uint32_t *) inptr;
+      inval = __builtin_bswap32 (inval);
 #endif
 
       if (__glibc_unlikely (inval > 0x7fffffff))
@@ -272,7 +221,7 @@  ucs4_internal_loop (struct __gconv_step *step,
 	  return __GCONV_ILLEGAL_INPUT;
 	}
 
-      *((uint32_t *) outptr) = inval;
+      put32 (outptr, inval);
       outptr += sizeof (uint32_t);
     }
 
@@ -290,75 +239,6 @@  ucs4_internal_loop (struct __gconv_step *step,
   return result;
 }
 
-#if !_STRING_ARCH_unaligned
-static inline int
-__attribute ((always_inline))
-ucs4_internal_loop_unaligned (struct __gconv_step *step,
-			      struct __gconv_step_data *step_data,
-			      const unsigned char **inptrp,
-			      const unsigned char *inend,
-			      unsigned char **outptrp,
-			      const unsigned char *outend,
-			      size_t *irreversible)
-{
-  int flags = step_data->__flags;
-  const unsigned char *inptr = *inptrp;
-  unsigned char *outptr = *outptrp;
-  int result;
-
-  for (; inptr + 4 <= inend && outptr + 4 <= outend; inptr += 4)
-    {
-      if (__glibc_unlikely (inptr[0] > 0x80))
-	{
-	  /* The value is too large.  We don't try transliteration here since
-	     this is not an error because of the lack of possibilities to
-	     represent the result.  This is a genuine bug in the input since
-	     UCS4 does not allow such values.  */
-	  if (irreversible == NULL)
-	    /* We are transliterating, don't try to correct anything.  */
-	    return __GCONV_ILLEGAL_INPUT;
-
-	  if (flags & __GCONV_IGNORE_ERRORS)
-	    {
-	      /* Just ignore this character.  */
-	      ++*irreversible;
-	      continue;
-	    }
-
-	  *inptrp = inptr;
-	  *outptrp = outptr;
-	  return __GCONV_ILLEGAL_INPUT;
-	}
-
-# if __BYTE_ORDER == __LITTLE_ENDIAN
-      outptr[3] = inptr[0];
-      outptr[2] = inptr[1];
-      outptr[1] = inptr[2];
-      outptr[0] = inptr[3];
-# else
-      outptr[0] = inptr[0];
-      outptr[1] = inptr[1];
-      outptr[2] = inptr[2];
-      outptr[3] = inptr[3];
-# endif
-      outptr += 4;
-    }
-
-  *inptrp = inptr;
-  *outptrp = outptr;
-
-  /* Determine the status.  */
-  if (*inptrp == inend)
-    result = __GCONV_EMPTY_INPUT;
-  else if (*outptrp + 4 > outend)
-    result = __GCONV_FULL_OUTPUT;
-  else
-    result = __GCONV_INCOMPLETE_INPUT;
-
-  return result;
-}
-#endif
-
 
 static inline int
 __attribute ((always_inline))
@@ -453,11 +333,12 @@  internal_ucs4le_loop (struct __gconv_step *step,
 #if __BYTE_ORDER == __BIG_ENDIAN
   /* Sigh, we have to do some real work.  */
   size_t cnt;
-  uint32_t *outptr32 = (uint32_t *) outptr;
 
-  for (cnt = 0; cnt < n_convert; ++cnt, inptr += 4)
-    *outptr32++ = bswap_32 (*(const uint32_t *) inptr);
-  outptr = (unsigned char *) outptr32;
+  for (cnt = 0; cnt < n_convert; ++cnt, inptr += 4, outptr += 4)
+    {
+      uint32_t val = get32 (inptr);
+      put32 (outptr, __builtin_bswap32 (val));
+    }
 
   *inptrp = inptr;
   *outptrp = outptr;
@@ -480,59 +361,6 @@  internal_ucs4le_loop (struct __gconv_step *step,
   return result;
 }
 
-#if !_STRING_ARCH_unaligned
-static inline int
-__attribute ((always_inline))
-internal_ucs4le_loop_unaligned (struct __gconv_step *step,
-				struct __gconv_step_data *step_data,
-				const unsigned char **inptrp,
-				const unsigned char *inend,
-				unsigned char **outptrp,
-				const unsigned char *outend,
-				size_t *irreversible)
-{
-  const unsigned char *inptr = *inptrp;
-  unsigned char *outptr = *outptrp;
-  size_t n_convert = MIN (inend - inptr, outend - outptr) / 4;
-  int result;
-
-# if __BYTE_ORDER == __BIG_ENDIAN
-  /* Sigh, we have to do some real work.  */
-  size_t cnt;
-
-  for (cnt = 0; cnt < n_convert; ++cnt, inptr += 4, outptr += 4)
-    {
-      outptr[0] = inptr[3];
-      outptr[1] = inptr[2];
-      outptr[2] = inptr[1];
-      outptr[3] = inptr[0];
-    }
-
-  *inptrp = inptr;
-  *outptrp = outptr;
-# elif __BYTE_ORDER == __LITTLE_ENDIAN
-  /* Simply copy the data.  */
-  *inptrp = inptr + n_convert * 4;
-  *outptrp = __mempcpy (outptr, inptr, n_convert * 4);
-# else
-#  error "This endianess is not supported."
-# endif
-
-  /* Determine the status.  */
-  if (*inptrp == inend)
-    result = __GCONV_EMPTY_INPUT;
-  else if (*inptrp + 4 > inend)
-    result = __GCONV_INCOMPLETE_INPUT;
-  else
-    {
-      assert (*outptrp + 4 > outend);
-      result = __GCONV_FULL_OUTPUT;
-    }
-
-  return result;
-}
-#endif
-
 
 static inline int
 __attribute ((always_inline))
@@ -612,12 +440,9 @@  ucs4le_internal_loop (struct __gconv_step *step,
 
   for (; inptr + 4 <= inend && outptr + 4 <= outend; inptr += 4)
     {
-      uint32_t inval;
-
+      uint32_t inval = get32 (inptr);
 #if __BYTE_ORDER == __BIG_ENDIAN
-      inval = bswap_32 (*(const uint32_t *) inptr);
-#else
-      inval = *(const uint32_t *) inptr;
+      inval = __builtin_bswap32 (inval);
 #endif
 
       if (__glibc_unlikely (inval > 0x7fffffff))
@@ -642,7 +467,7 @@  ucs4le_internal_loop (struct __gconv_step *step,
 	  return __GCONV_ILLEGAL_INPUT;
 	}
 
-      *((uint32_t *) outptr) = inval;
+      put32 (outptr, inval);
       outptr += sizeof (uint32_t);
     }
 
@@ -663,79 +488,6 @@  ucs4le_internal_loop (struct __gconv_step *step,
   return result;
 }
 
-#if !_STRING_ARCH_unaligned
-static inline int
-__attribute ((always_inline))
-ucs4le_internal_loop_unaligned (struct __gconv_step *step,
-				struct __gconv_step_data *step_data,
-				const unsigned char **inptrp,
-				const unsigned char *inend,
-				unsigned char **outptrp,
-				const unsigned char *outend,
-				size_t *irreversible)
-{
-  int flags = step_data->__flags;
-  const unsigned char *inptr = *inptrp;
-  unsigned char *outptr = *outptrp;
-  int result;
-
-  for (; inptr + 4 <= inend && outptr + 4 <= outend; inptr += 4)
-    {
-      if (__glibc_unlikely (inptr[3] > 0x80))
-	{
-	  /* The value is too large.  We don't try transliteration here since
-	     this is not an error because of the lack of possibilities to
-	     represent the result.  This is a genuine bug in the input since
-	     UCS4 does not allow such values.  */
-	  if (irreversible == NULL)
-	    /* We are transliterating, don't try to correct anything.  */
-	    return __GCONV_ILLEGAL_INPUT;
-
-	  if (flags & __GCONV_IGNORE_ERRORS)
-	    {
-	      /* Just ignore this character.  */
-	      ++*irreversible;
-	      continue;
-	    }
-
-	  *inptrp = inptr;
-	  *outptrp = outptr;
-	  return __GCONV_ILLEGAL_INPUT;
-	}
-
-# if __BYTE_ORDER == __BIG_ENDIAN
-      outptr[3] = inptr[0];
-      outptr[2] = inptr[1];
-      outptr[1] = inptr[2];
-      outptr[0] = inptr[3];
-# else
-      outptr[0] = inptr[0];
-      outptr[1] = inptr[1];
-      outptr[2] = inptr[2];
-      outptr[3] = inptr[3];
-# endif
-
-      outptr += 4;
-    }
-
-  *inptrp = inptr;
-  *outptrp = outptr;
-
-  /* Determine the status.  */
-  if (*inptrp == inend)
-    result = __GCONV_EMPTY_INPUT;
-  else if (*inptrp + 4 > inend)
-    result = __GCONV_INCOMPLETE_INPUT;
-  else
-    {
-      assert (*outptrp + 4 > outend);
-      result = __GCONV_FULL_OUTPUT;
-    }
-
-  return result;
-}
-#endif
-
 
 static inline int
 __attribute ((always_inline))
diff --git a/iconv/loop.c b/iconv/loop.c
index 9d8a7cceb3..b2a1727ad4 100644
--- a/iconv/loop.c
+++ b/iconv/loop.c
@@ -58,12 +58,7 @@ 
 #include <libc-diag.h>
 
 #undef FCTNAME2
-#if _STRING_ARCH_unaligned || !defined DEFINE_UNALIGNED
-# define FCTNAME2(name) name
-#else
-# define FCTNAME2(name) name##_unaligned
-#endif
-#define FCTNAME(name) FCTNAME2(name)
+#define FCTNAME(name) name
 
 
 /* We need at least one byte for the next round.  */
@@ -279,20 +274,9 @@  FCTNAME (LOOPFCT) (struct __gconv_step *step,
 }
 
 
-/* Include the file a second time to define the function to handle
-   unaligned access.  */
-#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 unaligned
-
-# define DEFINE_UNALIGNED
-# include "loop.c"
-# undef DEFINE_UNALIGNED
-#else
-# if MAX_NEEDED_INPUT > 1
-#  define SINGLE(fct) SINGLE2 (fct)
-#  define SINGLE2(fct) fct##_single
+#if MAX_NEEDED_INPUT > 1
+# define SINGLE(fct) SINGLE2 (fct)
+# define SINGLE2(fct) fct##_single
 static inline int
 __attribute ((always_inline))
 SINGLE(LOOPFCT) (struct __gconv_step *step,
@@ -302,37 +286,37 @@  SINGLE(LOOPFCT) (struct __gconv_step *step,
 		 size_t *irreversible EXTRA_LOOP_DECLS)
 {
   mbstate_t *state = step_data->__statep;
-#  ifdef LOOP_NEED_FLAGS
+# ifdef LOOP_NEED_FLAGS
   int flags = step_data->__flags;
-#  endif
-#  ifdef LOOP_NEED_DATA
+# endif
+# ifdef LOOP_NEED_DATA
   void *data = step->__data;
-#  endif
+# endif
   int result = __GCONV_OK;
   unsigned char bytebuf[MAX_NEEDED_INPUT];
   const unsigned char *inptr = *inptrp;
   unsigned char *outptr = *outptrp;
   size_t inlen;
 
-#  ifdef INIT_PARAMS
+# ifdef INIT_PARAMS
   INIT_PARAMS;
-#  endif
+# endif
 
-#  ifdef UNPACK_BYTES
+# ifdef UNPACK_BYTES
   UNPACK_BYTES
-#  else
+# else
   /* Add the bytes from the state to the input buffer.  */
   assert ((state->__count & 7) <= sizeof (state->__value));
   for (inlen = 0; inlen < (size_t) (state->__count & 7); ++inlen)
     bytebuf[inlen] = state->__value.__wchb[inlen];
-#  endif
+# endif
 
   /* Are there enough bytes in the input buffer?  */
   if (MIN_NEEDED_INPUT > 1
       && __builtin_expect (inptr + (MIN_NEEDED_INPUT - inlen) > inend, 0))
     {
       *inptrp = inend;
-#  ifdef STORE_REST
+# ifdef STORE_REST
 
       /* Building with -O3 GCC emits a `array subscript is above array
 	 bounds' warning.  GCC BZ #64739 has been opened for this.  */
@@ -347,14 +331,14 @@  SINGLE(LOOPFCT) (struct __gconv_step *step,
       inend = &bytebuf[inlen];
 
       STORE_REST
-#  else
+# else
       /* We don't have enough input for another complete input
 	 character.  */
       size_t inlen_after = inlen + (inend - inptr);
       assert (inlen_after <= sizeof (state->__value.__wchb));
       for (; inlen < inlen_after; inlen++)
 	state->__value.__wchb[inlen] = *inptr++;
-#  endif
+# endif
 
       return __GCONV_INCOMPLETE_INPUT;
     }
@@ -406,11 +390,11 @@  SINGLE(LOOPFCT) (struct __gconv_step *step,
       result = __GCONV_OK;
 
       /* Clear the state buffer.  */
-#  ifdef CLEAR_STATE
+# ifdef CLEAR_STATE
       CLEAR_STATE;
-#  else
+# else
       state->__count &= ~7;
-#  endif
+# endif
     }
   else if (result == __GCONV_INCOMPLETE_INPUT)
     {
@@ -419,11 +403,11 @@  SINGLE(LOOPFCT) (struct __gconv_step *step,
       assert (inend != &bytebuf[MAX_NEEDED_INPUT]);
 
       *inptrp += inend - bytebuf - (state->__count & 7);
-#  ifdef STORE_REST
+# ifdef STORE_REST
       inptrp = &inptr;
 
       STORE_REST
-#  else
+# else
       /* We don't have enough input for another complete input
 	 character.  */
       assert (inend - inptr > (state->__count & ~7));
@@ -432,14 +416,13 @@  SINGLE(LOOPFCT) (struct __gconv_step *step,
       for (inlen = 0; inlen < inend - inptr; inlen++)
 	state->__value.__wchb[inlen] = inptr[inlen];
       inptr = inend;
-#  endif
+# endif
     }
 
   return result;
 }
-#  undef SINGLE
-#  undef SINGLE2
-# endif
+# undef SINGLE
+# undef SINGLE2
 
 
 # ifdef ONEBYTE_BODY
@@ -471,4 +454,3 @@  gconv_btowc (struct __gconv_step *step, unsigned char c)
 #undef LOOP_NEED_STATE
 #undef LOOP_NEED_FLAGS
 #undef LOOP_NEED_DATA
-#undef unaligned
diff --git a/iconv/skeleton.c b/iconv/skeleton.c
index 9423d3fc5a..61cff234ac 100644
--- a/iconv/skeleton.c
+++ b/iconv/skeleton.c
@@ -448,33 +448,6 @@  FUNCTION_NAME (struct __gconv_step *step, struct __gconv_step_data *data,
       size_t lirreversible = 0;
       size_t *lirreversiblep = irreversible ? &lirreversible : NULL;
 
-      /* The following assumes that encodings, which have a variable length
-	 what might unalign a buffer even though it is an aligned in the
-	 beginning, either don't have the minimal number of bytes as a divisor
-	 of the maximum length or have a minimum length of 1.  This is true
-	 for all known and supported encodings.
-	 We use && instead of || to combine the subexpression for the FROM
-	 encoding and for the TO encoding, because usually one of them is
-	 INTERNAL, for which the subexpression evaluates to 1, but INTERNAL
-	 buffers are always aligned correctly.  */
-#define POSSIBLY_UNALIGNED \
-  (!_STRING_ARCH_unaligned					              \
-   && (((FROM_LOOP_MIN_NEEDED_FROM != 1					      \
-	 && FROM_LOOP_MAX_NEEDED_FROM % FROM_LOOP_MIN_NEEDED_FROM == 0)	      \
-	&& (FROM_LOOP_MIN_NEEDED_TO != 1				      \
-	    && FROM_LOOP_MAX_NEEDED_TO % FROM_LOOP_MIN_NEEDED_TO == 0))	      \
-       || ((TO_LOOP_MIN_NEEDED_FROM != 1				      \
-	    && TO_LOOP_MAX_NEEDED_FROM % TO_LOOP_MIN_NEEDED_FROM == 0)	      \
-	   && (TO_LOOP_MIN_NEEDED_TO != 1				      \
-	       && TO_LOOP_MAX_NEEDED_TO % TO_LOOP_MIN_NEEDED_TO == 0))))
-#if POSSIBLY_UNALIGNED
-      int unaligned;
-# define GEN_unaligned(name) GEN_unaligned2 (name)
-# define GEN_unaligned2(name) name##_unaligned
-#else
-# define unaligned 0
-#endif
-
 #ifdef PREPARE_LOOP
       PREPARE_LOOP
 #endif
@@ -514,18 +487,6 @@  FUNCTION_NAME (struct __gconv_step *step, struct __gconv_step_data *data,
 	}
 #endif
 
-#if POSSIBLY_UNALIGNED
-      unaligned =
-	((FROM_DIRECTION
-	  && ((uintptr_t) inptr % FROM_LOOP_MIN_NEEDED_FROM != 0
-	      || ((data->__flags & __GCONV_IS_LAST)
-		  && (uintptr_t) outbuf % FROM_LOOP_MIN_NEEDED_TO != 0)))
-	 || (!FROM_DIRECTION
-	     && (((data->__flags & __GCONV_IS_LAST)
-		  && (uintptr_t) outbuf % TO_LOOP_MIN_NEEDED_TO != 0)
-		 || (uintptr_t) inptr % TO_LOOP_MIN_NEEDED_FROM != 0)));
-#endif
-
       while (1)
 	{
 	  /* Remember the start value for this round.  */
@@ -543,34 +504,14 @@  FUNCTION_NAME (struct __gconv_step *step, struct __gconv_step_data *data,
 	  SAVE_RESET_STATE (1);
 #endif
 
-	  if (__glibc_likely (!unaligned))
-	    {
-	      if (FROM_DIRECTION)
-		/* Run the conversion loop.  */
-		status = FROM_LOOP (step, data, inptrp, inend, &outbuf, outend,
-				    lirreversiblep EXTRA_LOOP_ARGS);
-	      else
-		/* Run the conversion loop.  */
-		status = TO_LOOP (step, data, inptrp, inend, &outbuf, outend,
-				  lirreversiblep EXTRA_LOOP_ARGS);
-	    }
-#if POSSIBLY_UNALIGNED
+	  if (FROM_DIRECTION)
+	    /* Run the conversion loop.  */
+	    status = FROM_LOOP (step, data, inptrp, inend, &outbuf, outend,
+				lirreversiblep EXTRA_LOOP_ARGS);
 	  else
-	    {
-	      if (FROM_DIRECTION)
-		/* Run the conversion loop.  */
-		status = GEN_unaligned (FROM_LOOP) (step, data, inptrp, inend,
-						    &outbuf, outend,
-						    lirreversiblep
-						    EXTRA_LOOP_ARGS);
-	      else
-		/* Run the conversion loop.  */
-		status = GEN_unaligned (TO_LOOP) (step, data, inptrp, inend,
-						  &outbuf, outend,
-						  lirreversiblep
-						  EXTRA_LOOP_ARGS);
-	    }
-#endif
+	    /* Run the conversion loop.  */
+	    status = TO_LOOP (step, data, inptrp, inend, &outbuf, outend,
+			      lirreversiblep EXTRA_LOOP_ARGS);
 
 	  /* If we were called as part of an error handling module we
 	     don't do anything else here.  */
@@ -635,41 +576,18 @@  FUNCTION_NAME (struct __gconv_step *step, struct __gconv_step_data *data,
 		      SAVE_RESET_STATE (0);
 #endif
 
-		      if (__glibc_likely (!unaligned))
-			{
-			  if (FROM_DIRECTION)
-			    /* Run the conversion loop.  */
-			    nstatus = FROM_LOOP (step, data, inptrp, inend,
-						 &outbuf, outerr,
-						 lirreversiblep
-						 EXTRA_LOOP_ARGS);
-			  else
-			    /* Run the conversion loop.  */
-			    nstatus = TO_LOOP (step, data, inptrp, inend,
-					       &outbuf, outerr,
-					       lirreversiblep
-					       EXTRA_LOOP_ARGS);
-			}
-#if POSSIBLY_UNALIGNED
+		      if (FROM_DIRECTION)
+			/* Run the conversion loop.  */
+			nstatus = FROM_LOOP (step, data, inptrp, inend,
+					     &outbuf, outerr,
+					     lirreversiblep
+					     EXTRA_LOOP_ARGS);
 		      else
-			{
-			  if (FROM_DIRECTION)
-			    /* Run the conversion loop.  */
-			    nstatus = GEN_unaligned (FROM_LOOP) (step, data,
-								 inptrp, inend,
-								 &outbuf,
-								 outerr,
-								 lirreversiblep
-								 EXTRA_LOOP_ARGS);
-			  else
-			    /* Run the conversion loop.  */
-			    nstatus = GEN_unaligned (TO_LOOP) (step, data,
-							       inptrp, inend,
-							       &outbuf, outerr,
-							       lirreversiblep
-							       EXTRA_LOOP_ARGS);
-			}
-#endif
+			/* Run the conversion loop.  */
+			nstatus = TO_LOOP (step, data, inptrp, inend,
+					   &outbuf, outerr,
+					   lirreversiblep
+					   EXTRA_LOOP_ARGS);
 
 		      /* We must run out of output buffer space in this
 			 rerun.  */