]> git.ipfire.org Git - thirdparty/glibc.git/commitdiff
iconv: Remove _STRING_ARCH_unaligned usage
authorAdhemerval Zanella <adhemerval.zanella@linaro.org>
Fri, 10 Feb 2023 19:37:36 +0000 (16:37 -0300)
committerAdhemerval Zanella <adhemerval.zanella@linaro.org>
Fri, 17 Feb 2023 18:56:54 +0000 (15:56 -0300)
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.

Reviewed-by: Wilco Dijkstra <Wilco.Dijkstra@arm.com>
iconv/gconv_simple.c
iconv/loop.c
iconv/skeleton.c

index c50ffd3bf0a24549976b099f5427f87ff5407185..c60cffad4c6aabe688991460e3e86370b4d346e3 100644 (file)
@@ -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))
index 9d8a7cceb3c43d359090a1e5cf2c36cdcb3732bd..b2a1727ad4cbe82efea6075bdef0117b9aa07dc3 100644 (file)
 #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
index 9423d3fc5af65024ca64fe5e9cb488fd9de0c34a..61cff234acbb0e8b9e2367ee9de9b0217aaeb5a3 100644 (file)
@@ -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.  */