#define FROM_LOOP	from_ibm1390
#define TO_LOOP		to_ibm1390
#define SB_TO_UCS4	(*klpe___ibm1390sb_to_ucs4)
#define DB_TO_UCS4_IDX	(*klpe___ibm1390db_to_ucs4_idx)
#define DB_TO_UCS4	(*klpe___ibm1390db_to_ucs4)
#define UCS4_TO_SB_IDX	(*klpe___ucs4_to_ibm1390sb_idx)
#define UCS4_TO_SB	(*klpe___ucs4_to_ibm1390sb)
#define UCS4_TO_DB_IDX	(*klpe___ucs4_to_ibm1390db_idx)
#define UCS4_TO_DB	(*klpe___ucs4_to_ibm1390db)
#define DB_TO_UCS4_COMB	(*klpe___ibm1390db_to_ucs4_combined)
#define UCS4_COMB_TO_DB	(*klpe___ucs4_combined_to_ibm1390db)
#define UCS_LIMIT	0xffffffff
#define __LEAF
#define __THROW	__attribute__ ((__nothrow__ __LEAF))
#define __COLD	__attribute__ ((__cold__))
#define __glibc_unlikely(cond)	__builtin_expect ((cond), 0)
#define __glibc_likely(cond)	__builtin_expect ((cond), 1)
/** clang-extract: from /usr/lib64/clang/21/include/__stddef_size_t.h:18:1 */
typedef __SIZE_TYPE__ size_t;

#define DL_CALL_FCT(fctp, args) \
  (_dl_mcount_wrapper_check ((void *) (fctp)), (*(fctp)) args)
/** clang-extract: from ../bits/dlfcn.h:60:1 */
extern void _dl_mcount_wrapper_check (void *__selfpc) __THROW;

/** clang-extract: from ../posix/bits/types.h:40:1 */
typedef unsigned short int __uint16_t;

/** clang-extract: from ../posix/bits/types.h:41:1 */
typedef signed int __int32_t;

/** clang-extract: from ../posix/bits/types.h:42:1 */
typedef unsigned int __uint32_t;

/** clang-extract: from ../bits/stdint-intn.h:26:1 */
typedef __int32_t int32_t;

/** clang-extract: from ../bits/stdint-uintn.h:25:1 */
typedef __uint16_t uint16_t;

/** clang-extract: from ../bits/stdint-uintn.h:26:1 */
typedef __uint32_t uint32_t;

/** clang-extract: from ../stdlib/stdint.h:83:1 */
typedef unsigned long int	uintptr_t;

#ifdef __powerpc64__
typedef unsigned long int uint64_t;
/* Manually extracted from sysdeps/powerpc/nptl/tls.h */
typedef struct
{


  uint64_t hwcap_extn;


  uint64_t hwcap;
# 82 "../sysdeps/powerpc/nptl/tls.h"
  uint32_t __unused;


  uint32_t at_platform;


  uintptr_t dso_slot2;
  uintptr_t dso_slot1;

  uintptr_t tar_save;

  void *__private_ss;

  uintptr_t ebb_handler;
  uintptr_t ebb_ctx_pointer;
  uintptr_t ebb_reserved1;
  uintptr_t ebb_reserved2;
  uintptr_t pointer_guard;
  uintptr_t stack_guard;
  void *dtv;
} tcbhead_t;
#else
/** clang-extract: from ../sysdeps/generic/dl-dtv.h:22:1 */
struct dtv_pointer
{
  void *val;                    /* Pointer to data, or TLS_DTV_UNALLOCATED.  */
  void *to_free;                /* Unaligned pointer, for deallocation.  */
};

/** clang-extract: from ../sysdeps/generic/dl-dtv.h:29:1 */
typedef union dtv
{
  size_t counter;
  struct dtv_pointer pointer;
} dtv_t;

/** clang-extract: from ../sysdeps/x86_64/nptl/tls.h:36:1 */
typedef struct
{
  int i[4];
} __128bits;

/** clang-extract: from ../sysdeps/x86_64/nptl/tls.h:42:1 */
typedef struct
{
  void *tcb;		/* Pointer to the TCB.  Not necessarily the
			   thread descriptor used by libpthread.  */
  dtv_t *dtv;
  void *self;		/* Pointer to the thread descriptor.  */
  int multiple_threads;
  int gscope_flag;
  uintptr_t sysinfo;
  uintptr_t stack_guard;
  uintptr_t pointer_guard;
  unsigned long int unused_vgetcpu_cache[2];
  /* Bit 0: X86_FEATURE_1_IBT.
     Bit 1: X86_FEATURE_1_SHSTK.
   */
  unsigned int feature_1;
  int __glibc_unused1;
  /* Reservation of some values for the TM ABI.  */
  void *__private_tm[4];
  /* GCC split stack support.  */
  void *__private_ss;
  /* The marker for the current shadow stack.  */
  unsigned long long int ssp_base;
  /* Must be kept even if it is no longer used by glibc since programs,
     like AddressSanitizer, depend on the size of tcbhead_t.  */
  __128bits __glibc_unused2[8][4] __attribute__ ((aligned (32)));

  void *__padding[8];
} tcbhead_t;
#endif

/** clang-extract: from ../string/string.h:65:1 */
extern void *memset (void *__s, int __c, size_t __n) __THROW;

#define NULL ((void*)0)
/** clang-extract: from ../wcsmbs/bits/types/wint_t.h:20:1 */
typedef __WINT_TYPE__ wint_t;

/** clang-extract: from ../wcsmbs/bits/types/__mbstate_t.h:13:1 */
typedef struct
{
  int __count;
  union
  {
    __WINT_TYPE__ __wch;
    char __wchb[4];
  } __value;		/* Value so far.  */
} __mbstate_t;

/** clang-extract: from ../wcsmbs/bits/types/mbstate_t.h:6:1 */
typedef __mbstate_t mbstate_t;

/** clang-extract: from ./ibm1390.h:24:1 */
struct gap
{
  uint32_t start;
  uint32_t end;
  int32_t  idx;
};

/** clang-extract: from ./ibm1390.h:31:1 */
__attribute__((used)) static const uint32_t (*klpe___ibm1390sb_to_ucs4)[256];

/** clang-extract: from ./ibm1390.h:99:1 */
__attribute__((used)) static const struct gap (*klpe___ibm1390db_to_ucs4_idx)[14];

/** clang-extract: from ./ibm1390.h:117:1 */
__attribute__((used)) static const uint32_t (*klpe___ibm1390db_to_ucs4)[30914];

/** clang-extract: from ./ibm1390.h:7852:1 */
struct divide
{
  uint16_t res1;
  uint16_t res2;
};

#define __TO_UCS4_COMBINED_MIN 0xecb5
#define __TO_UCS4_COMBINED_MAX 0xeccd
/** clang-extract: from ./ibm1390.h:7859:1 */
__attribute__((used)) static const struct divide (*klpe___ibm1390db_to_ucs4_combined)[25];

/** clang-extract: from ./ibm1390.h:7888:1 */
__attribute__((used)) static const struct gap (*klpe___ucs4_to_ibm1390sb_idx)[10];

/** clang-extract: from ./ibm1390.h:7902:1 */
__attribute__((used)) static const char (*klpe___ucs4_to_ibm1390sb)[237][1];

/** clang-extract: from ./ibm1390.h:7936:1 */
__attribute__((used)) static const struct gap (*klpe___ucs4_to_ibm1390db_idx)[134];

/** clang-extract: from ./ibm1390.h:8074:1 */
__attribute__((used)) static const char (*klpe___ucs4_to_ibm1390db)[44951][2];

/** clang-extract: from ./ibm1390.h:15570:1 */
struct combine
{
  uint32_t res1;
  uint16_t res2;
  char ch[2];
};

/** clang-extract: from ./ibm1390.h:15576:1 */
__attribute__((used)) static const struct combine (*klpe___ucs4_combined_to_ibm1390db)[26];

#define SI 		0x0F
#define SO 		0x0E
#define MIN_NEEDED_FROM	1
#define MAX_NEEDED_FROM	2
#define MIN_NEEDED_TO	4
#define MAX_NEEDED_TO	8
#define ONE_DIRECTION	0
#define PREPARE_LOOP \
  int save_curcs;							      \
  int *curcsp = &data->__statep->__count;
#define EXTRA_LOOP_ARGS		, curcsp
#define EMIT_SHIFT_TO_INIT \
  if ((data->__statep->__count & ~7) != sb)				      \
    {									      \
      if (FROM_DIRECTION)						      \
	{								      \
	  uint32_t ch = data->__statep->__count >> 7;			      \
	  if (__glibc_unlikely (ch != 0))				      \
	    {								      \
	      if (__glibc_unlikely (outend - outbuf < 4))		      \
		status = __GCONV_FULL_OUTPUT;				      \
	      else							      \
		{							      \
		  put32 (outbuf, ch);					      \
		  outbuf += 4;						      \
		  /* Clear character and db bit.  */			      \
		  data->__statep->__count &= 7;				      \
		}							      \
	    }								      \
	  else								      \
	    data->__statep->__count &= 7;				      \
	}								      \
      else								      \
	{								      \
	  /* We are not in the initial state.  To switch back we have	      \
	     to emit `SI'.  */						      \
	  if (__glibc_unlikely (outbuf >= outend))			      \
	    /* We don't have enough room in the output buffer.  */	      \
	    status = __GCONV_FULL_OUTPUT;				      \
	  else								      \
	    {								      \
	      /* Write out the shift sequence.  */			      \
	      *outbuf++ = SI;						      \
	      data->__statep->__count &= 7;				      \
	    }								      \
	}								      \
    }
#define SAVE_RESET_STATE(Save) \
  if (Save)								      \
    save_curcs = *curcsp;						      \
  else									      \
    *curcsp = save_curcs
/** clang-extract: from ./ibm1364.c:103:1 */
enum
{
  sb = 0,			/* Single byte mode.  */
  db = 64			/* Double byte mode.  */
};

#define SUB_COMBINED_UCS_FROM_IBM13XX \
  {									      \
    if (res != UCS_LIMIT || ch < __TO_UCS4_COMBINED_MIN			      \
	|| ch > __TO_UCS4_COMBINED_MAX)					      \
      {									      \
	put32 (outptr, res);						      \
	outptr += 4;							      \
      }									      \
    else								      \
      {									      \
	const struct divide *cmbp					      \
	  = &DB_TO_UCS4_COMB[ch - __TO_UCS4_COMBINED_MIN];		      \
	assert (cmbp->res1 != 0 && cmbp->res2 != 0);			      \
									      \
	put32 (outptr, cmbp->res1);					      \
	outptr += 4;							      \
									      \
	/* See whether we have room for the second character.  */	      \
	if (outend - outptr >= 4)					      \
	  {								      \
	    put32 (outptr, cmbp->res2);					      \
	    outptr += 4;						      \
	  }								      \
	else								      \
	  {								      \
	    /* Otherwise store only the first character now, and	      \
	       put the second one into the queue.  */			      \
	    curcs |= cmbp->res2 << 7;					      \
	    inptr += 2;							      \
	    /* Tell the caller why we terminate the loop.  */		      \
	    result = __GCONV_FULL_OUTPUT;				      \
	    break;							      \
	  }								      \
      }									      \
  }
#define MIN_NEEDED_INPUT  	MIN_NEEDED_FROM
#define MAX_NEEDED_INPUT  	MAX_NEEDED_FROM
#define MIN_NEEDED_OUTPUT 	MIN_NEEDED_TO
#define LOOPFCT 		FROM_LOOP
#define BODY \
  {									      \
    uint32_t ch;							      \
									      \
    ch = curcs >> 7;							      \
    if (__glibc_unlikely (ch != 0))					      \
      {									      \
	put32 (outptr, ch);						      \
	outptr += 4;							      \
	/* Remove the pending character, but preserve state bits.  */	      \
	curcs &= (1 << 7) - 1;						      \
	continue;							      \
      }									      \
									      \
    /* Otherwise read the next input byte.  */				      \
    ch = *inptr;							      \
									      \
    if (__builtin_expect (ch, 0) == SO)					      \
      {									      \
	/* Shift OUT, change to DBCS converter (redundant escape okay).  */   \
	curcs = db;							      \
	++inptr;							      \
	continue;							      \
      }									      \
    if (__builtin_expect (ch, 0) == SI)					      \
      {									      \
	/* Shift IN, change to SBCS converter (redundant escape okay).  */    \
	curcs = sb;							      \
	++inptr;							      \
	continue;							      \
      }									      \
									      \
    if (curcs == sb)							      \
      {									      \
	/* Use the IBM13XX table for single byte.  */			      \
	uint32_t res = SB_TO_UCS4[ch];				      \
	if (__builtin_expect (res, L'\1') == L'\0' && ch != '\0')	      \
	  {								      \
	    /* This is an illegal character.  */			      \
	    if (! ignore_errors_p ())					      \
	      {								      \
		result = __gconv_mark_illegal_input (step_data);	      \
		break;							      \
	      }								      \
	    ++*irreversible;						      \
	  }								      \
	else								      \
	  {								      \
	    put32 (outptr, res);					      \
	    outptr += 4;						      \
	  }								      \
	++inptr;							      \
      }									      \
    else								      \
      {									      \
	assert (curcs == db);						      \
									      \
	if (__glibc_unlikely (inptr + 1 >= inend))			      \
	  {								      \
	    /* The second character is not available.  Store the	      \
	       intermediate result.  */					      \
	    result = __GCONV_INCOMPLETE_INPUT;				      \
	    break;							      \
	  }								      \
									      \
	ch = (ch * 0x100) + inptr[1];					      \
									      \
	/* Use the IBM1364 table for double byte.  */			      \
	const struct gap *rp2 = DB_TO_UCS4_IDX;				      \
	while (ch > rp2->end)						      \
	  ++rp2;							      \
									      \
	uint32_t res;							      \
	if (__builtin_expect (rp2->start == 0xffff, 0)			      \
	    || __builtin_expect (ch < rp2->start, 0)			      \
	    || (res = DB_TO_UCS4[ch + rp2->idx],			      \
		__builtin_expect (res, L'\1') == L'\0' && ch != '\0'))	      \
	  {								      \
	    /* This is an illegal character.  */			      \
	    if (! ignore_errors_p ())					      \
	      {								      \
		result = __gconv_mark_illegal_input (step_data);	      \
		break;							      \
	      }								      \
	    ++*irreversible;						      \
	  }								      \
	else								      \
	  {								      \
	    SUB_COMBINED_UCS_FROM_IBM13XX;				      \
	  }								      \
	inptr += 2;							      \
      }									      \
  }
#define LOOP_NEED_FLAGS
#define EXTRA_LOOP_DECLS	, int *curcsp
#define INIT_PARAMS		int curcs = *curcsp & ~7
#define UPDATE_PARAMS		*curcsp = curcs
/** clang-extract: from ../assert/assert.h:94:1 */
extern void __assert_fail (const char *__assertion, const char *__file,
			   unsigned int __line, const char *__function)
     __THROW __attribute__ ((__noreturn__)) __COLD;

/** clang-extract: from ../assert/assert.h:114:1 */
extern _Bool __assert_single_arg (_Bool);

#define assert(...)							\
    ((void) sizeof (__assert_single_arg (__VA_ARGS__)), __extension__ ({ \
      if (__VA_ARGS__)							\
        ; /* empty */							\
      else								\
        __assert_fail (#__VA_ARGS__, __FILE__, __LINE__, __ASSERT_FUNCTION); \
    }))
#define __ASSERT_FUNCTION	__extension__ __PRETTY_FUNCTION__
/** clang-extract: from ../include/assert.h:7:1 */
extern void __assert_fail (const char *__assertion, const char *__file,
			   unsigned int __line, const char *__function)
     __THROW __attribute__ ((__noreturn__));

/** clang-extract: from ../iconv/gconv.h:37:1 */
enum
{
  __GCONV_OK = 0,
  __GCONV_NOCONV,
  __GCONV_NODB,
  __GCONV_NOMEM,

  __GCONV_EMPTY_INPUT,
  __GCONV_FULL_OUTPUT,
  __GCONV_ILLEGAL_INPUT,
  __GCONV_INCOMPLETE_INPUT,

  __GCONV_ILLEGAL_DESCRIPTOR,
  __GCONV_INTERNAL_ERROR
};

/** clang-extract: from ../iconv/gconv.h:55:1 */
enum
{
  __GCONV_IS_LAST = 0x0001,
  __GCONV_IGNORE_ERRORS = 0x0002,
  __GCONV_SWAP = 0x0004,
  __GCONV_TRANSLIT = 0x0008
};

/** clang-extract: from ../iconv/gconv.h:65:1 */
struct __gconv_step;/* Full definition was removed.  */

/** clang-extract: from ../iconv/gconv.h:66:1 */
struct __gconv_step_data;/* Full definition was removed.  */

/** clang-extract: from ../iconv/gconv.h:67:1 */
struct __gconv_loaded_object;/* Full definition was removed.  */

/** clang-extract: from ../iconv/gconv.h:71:1 */
typedef int (*__gconv_fct) (struct __gconv_step *, struct __gconv_step_data *,
			    const unsigned char **, const unsigned char *,
			    unsigned char **, size_t *, int, int);

/** clang-extract: from ../iconv/gconv.h:76:1 */
typedef wint_t (*__gconv_btowc_fct) (struct __gconv_step *, unsigned char);

/** clang-extract: from ../iconv/gconv.h:79:1 */
typedef int (*__gconv_init_fct) (struct __gconv_step *);

/** clang-extract: from ../iconv/gconv.h:80:1 */
typedef void (*__gconv_end_fct) (struct __gconv_step *);

/** clang-extract: from ../iconv/gconv.h:84:1 */
struct __gconv_step
{
  struct __gconv_loaded_object *__shlib_handle;
  const char *__modname;

  /* For internal use by glibc.  (Accesses to this member must occur
     when the internal __gconv_lock mutex is acquired).  */
  int __counter;

  char *__from_name;
  char *__to_name;

  __gconv_fct __fct;
  __gconv_btowc_fct __btowc_fct;
  __gconv_init_fct __init_fct;
  __gconv_end_fct __end_fct;

  /* Information about the number of bytes needed or produced in this
     step.  This helps optimizing the buffer sizes.  */
  int __min_needed_from;
  int __max_needed_from;
  int __min_needed_to;
  int __max_needed_to;

  /* Flag whether this is a stateful encoding or not.  */
  int __stateful;

  void *__data;		/* Pointer to step-local data.  */
};

/** clang-extract: from ../iconv/gconv.h:116:1 */
struct __gconv_step_data
{
  unsigned char *__outbuf;    /* Output buffer for this step.  */
  unsigned char *__outbufend; /* Address of first byte after the output
				 buffer.  */

  /* Is this the last module in the chain.  */
  int __flags;

  /* Counter for number of invocations of the module function for this
     descriptor.  */
  int __invocation_counter;

  /* Flag whether this is an internal use of the module (in the mb*towc*
     and wc*tomb* functions) or regular with iconv(3).  */
  int __internal_use;

  __mbstate_t *__statep;
  __mbstate_t __state;	/* This element must not be used directly by
			   any module; always use STATEP!  */
};

#define get32(addr)							\
({									\
  const struct { uint32_t r; } __attribute__ ((__packed__)) *__ptr	\
    = (__typeof(__ptr))(addr);						\
  __ptr->r;								\
})
#define put32(addr, val)						\
do {									\
   struct { uint32_t r; } __attribute__ ((__packed__)) *__ptr		\
    = (__typeof(__ptr))(addr);						\
   __ptr->r = val;							\
} while (0)
/** clang-extract: from ../iconv/gconv_int.h:338:1 */
enum
  {
    /* The conversion encountered an illegal input character at one
       point.  */
    __GCONV_ENCOUNTERED_ILLEGAL_INPUT = 1U << 30,
  };

/** clang-extract: from ../iconv/gconv_int.h:347:1 */
static inline int
__gconv_mark_illegal_input (struct __gconv_step_data *step_data)
{
  step_data->__flags |= __GCONV_ENCOUNTERED_ILLEGAL_INPUT;
  return __GCONV_ILLEGAL_INPUT;
}

#define FCTNAME(name) name
#define ignore_errors_p() \
  (irreversible != NULL && (flags & __GCONV_IGNORE_ERRORS))
/** clang-extract: from ../iconv/loop.c:215:1 */
static inline int
__attribute ((always_inline))
FCTNAME (LOOPFCT) (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 EXTRA_LOOP_DECLS)
{
#ifdef LOOP_NEED_STATE
  mbstate_t *state = step_data->__statep;
#endif
#ifdef LOOP_NEED_FLAGS
  int flags = step_data->__flags;
#endif
#ifdef LOOP_NEED_DATA
  void *data = step->__data;
#endif
  int result = __GCONV_EMPTY_INPUT;
  const unsigned char *inptr = *inptrp;
  unsigned char *outptr = *outptrp;

#ifdef INIT_PARAMS
  INIT_PARAMS;
#endif

  while (inptr != inend)
    {
      /* `if' cases for MIN_NEEDED_OUTPUT ==/!= 1 is made to help the
	 compiler generating better code.  They will be optimized away
	 since MIN_NEEDED_OUTPUT is always a constant.  */
      if (MIN_NEEDED_INPUT > 1
	  && __builtin_expect (inptr + MIN_NEEDED_INPUT > inend, 0))
	{
	  /* We don't have enough input for another complete input
	     character.  */
	  result = __GCONV_INCOMPLETE_INPUT;
	  break;
	}
      if ((MIN_NEEDED_OUTPUT != 1
	   && __builtin_expect (outptr + MIN_NEEDED_OUTPUT > outend, 0))
	  || (MIN_NEEDED_OUTPUT == 1
	      && __builtin_expect (outptr >= outend, 0)))
	{
	  /* Overflow in the output buffer.  */
	  result = __GCONV_FULL_OUTPUT;
	  break;
	}

      /* Here comes the body the user provides.  It can stop with
	 RESULT set to GCONV_INCOMPLETE_INPUT (if the size of the
	 input characters vary in size), GCONV_ILLEGAL_INPUT, or
	 GCONV_FULL_OUTPUT (if the output characters vary in size).  */
      BODY
    }

  /* Update the pointers pointed to by the parameters.  */
  *inptrp = inptr;
  *outptrp = outptr;
  UPDATE_PARAMS;

  return result;
}

#define SINGLE(fct) SINGLE2 (fct)
#define SINGLE2(fct) fct##_single
/** clang-extract: from ../iconv/loop.c:282:1 */
static inline int
__attribute ((always_inline))
SINGLE(LOOPFCT) (struct __gconv_step *step,
		 struct __gconv_step_data *step_data,
		 const unsigned char **inptrp, const unsigned char *inend,
		 unsigned char **outptrp, unsigned char *outend,
		 size_t *irreversible EXTRA_LOOP_DECLS)
{
  mbstate_t *state = step_data->__statep;
# ifdef LOOP_NEED_FLAGS
  int flags = step_data->__flags;
# endif
# ifdef LOOP_NEED_DATA
  void *data = step->__data;
# 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
  INIT_PARAMS;
# endif

# ifdef UNPACK_BYTES
  UNPACK_BYTES
# 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

  /* 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

      /* Building with -O3 GCC emits a `array subscript is above array
	 bounds' warning.  GCC BZ #64739 has been opened for this.  */
      DIAG_PUSH_NEEDS_COMMENT;
      DIAG_IGNORE_NEEDS_COMMENT (4.9, "-Warray-bounds");
      while (inptr < inend)
	bytebuf[inlen++] = *inptr++;
      DIAG_POP_NEEDS_COMMENT;

      inptr = bytebuf;
      inptrp = &inptr;
      inend = &bytebuf[inlen];

      STORE_REST
# 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

      return __GCONV_INCOMPLETE_INPUT;
    }

  /* Enough space in output buffer.  */
  if ((MIN_NEEDED_OUTPUT != 1 && outptr + MIN_NEEDED_OUTPUT > outend)
      || (MIN_NEEDED_OUTPUT == 1 && outptr >= outend))
    /* Overflow in the output buffer.  */
    return __GCONV_FULL_OUTPUT;

  /*  Now add characters from the normal input buffer.  */
  if (inlen >= MAX_NEEDED_INPUT || inptr >= inend)
    /* Avoid a -Wstringop-overflow= warning when this loop is
       unrolled.  The compiler cannot otherwise see that this is
       unreachable because it depends on (state->__count & 7) not
       being too large after a previous conversion step.
       Starting with GCC 12, we also have mark the inptr >= inend
       case as unreachable to omit the warning.  Note that this SINGLE
       function is only used to implement the mb*towc*() or wc*tomb*()
       functions.  Those functions use inptr and inend pointing to a
       variable on stack, compute the inend pointer or explicitly check
       the arguments which always leads to inptr < inend.  */
    __builtin_unreachable ();
  do
    bytebuf[inlen++] = *inptr++;
  while (inlen < MAX_NEEDED_INPUT && inptr < inend);

  inptr = bytebuf;
  inend = &bytebuf[inlen];

  do
    {
      BODY
    }
  while (0);

  /* Now we either have produced an output character and consumed all the
     bytes from the state and at least one more, or the character is still
     incomplete, or we have some other error (like illegal input character,
     no space in output buffer).  */
  if (__glibc_likely (inptr != bytebuf))
    {
      /* We found a new character.  */
      assert (inptr - bytebuf > (state->__count & 7));

      *inptrp += inptr - bytebuf - (state->__count & 7);
      *outptrp = outptr;

      result = __GCONV_OK;

      /* Clear the state buffer.  */
# ifdef CLEAR_STATE
      CLEAR_STATE;
# else
      state->__count &= ~7;
# endif
    }
  else if (result == __GCONV_INCOMPLETE_INPUT)
    {
      /* This can only happen if we have less than MAX_NEEDED_INPUT bytes
	 available.  */
      assert (inend != &bytebuf[MAX_NEEDED_INPUT]);

      *inptrp += inend - bytebuf - (state->__count & 7);
# ifdef STORE_REST
      inptrp = &inptr;

      STORE_REST
# else
      /* We don't have enough input for another complete input
	 character.  */
      assert (inend - inptr > (state->__count & ~7));
      assert (inend - inptr <= sizeof (state->__value.__wchb));
      state->__count = (state->__count & ~7) | (inend - inptr);
      for (inlen = 0; inlen < inend - inptr; inlen++)
	state->__value.__wchb[inlen] = inptr[inlen];
      inptr = inend;
# endif
    }

  return result;
}

#undef SINGLE
#undef SINGLE2
#undef MIN_NEEDED_INPUT
#undef MAX_NEEDED_INPUT
#undef MIN_NEEDED_OUTPUT
#undef LOOPFCT
#undef BODY
#undef EXTRA_LOOP_DECLS
#undef INIT_PARAMS
#undef UPDATE_PARAMS
#undef LOOP_NEED_FLAGS
#define SUB_COMBINED_UCS_TO_IBM13XX \
  {									      \
    const struct combine *cmbp = UCS4_COMB_TO_DB;			      \
    while (cmbp->res1 < ch)						      \
      ++cmbp;								      \
    /* XXX if last char is beginning of combining store in state */	      \
    if (cmbp->res1 == ch && inptr + 4 < inend)				      \
      {									      \
	/* See if input is part of a combined character.  */		      \
	uint32_t ch_next = get32 (inptr + 4);				      \
	while (cmbp->res2 != ch_next)					      \
	  {								      \
	    ++cmbp;							      \
	    if (cmbp->res1 != ch)					      \
	      goto not_combined;					      \
	  }								      \
									      \
	/* It is a combined character.  First make sure we are in	      \
	   double byte mode.  */					      \
	if (curcs == sb)						      \
	  {								      \
	    /* We know there is room for at least one byte.  */		      \
	    *outptr++ = SO;						      \
	    curcs = db;							      \
	  }								      \
									      \
	if (__glibc_unlikely (outptr + 2 > outend))			      \
	  {								      \
	    result = __GCONV_FULL_OUTPUT;				      \
	    break;							      \
	  }								      \
	*outptr++ = cmbp->ch[0];					      \
	*outptr++ = cmbp->ch[1];					      \
	inptr += 8;							      \
	continue;							      \
									      \
      not_combined:;							      \
      }									      \
  }
#define MIN_NEEDED_INPUT	MIN_NEEDED_TO
#define MAX_NEEDED_INPUT  	MAX_NEEDED_TO
#define MIN_NEEDED_OUTPUT	MIN_NEEDED_FROM
#define LOOPFCT			TO_LOOP
#define BODY \
  {									      \
    uint32_t ch = get32 (inptr);					      \
									      \
    if (__glibc_unlikely (ch >= UCS_LIMIT))				      \
      {									      \
	UNICODE_TAG_HANDLER (ch, 4);					      \
									      \
	if (! ignore_errors_p ())					      \
	  {								      \
	    result = __gconv_mark_illegal_input (step_data);		      \
	    break;							      \
	  }								      \
	++*irreversible;						      \
	inptr += 4;							      \
	continue;							      \
      }									      \
									      \
    SUB_COMBINED_UCS_TO_IBM13XX;					      \
									      \
    const struct gap *rp1 = UCS4_TO_SB_IDX;				      \
    while (ch > rp1->end)						      \
      ++rp1;								      \
									      \
    /* Use the UCS4 table for single byte.  */				      \
    const char *cp;							      \
    if (__builtin_expect (ch < rp1->start, 0)				      \
	|| (cp = UCS4_TO_SB[ch + rp1->idx],				      \
	    __builtin_expect (cp[0], L'\1') == L'\0' && ch != '\0'))	      \
      {									      \
	/* Use the UCS4 table for double byte.  */			      \
	const struct gap *rp2 = UCS4_TO_DB_IDX;				      \
	while (ch > rp2->end)						      \
	  ++rp2;							      \
									      \
	if (__builtin_expect (ch < rp2->start, 0)			      \
	    || (cp = UCS4_TO_DB[ch + rp2->idx],				      \
		__builtin_expect (cp[0], L'\1') == L'\0' && ch != '\0'))      \
	  {								      \
	    /* This is an illegal character.  */			      \
	    if (! ignore_errors_p ())					      \
	      {								      \
		result = __gconv_mark_illegal_input (step_data);	      \
		break;							      \
	      }								      \
	    ++*irreversible;						      \
	  }								      \
	else								      \
	  {								      \
	    if (curcs == sb)						      \
	      {								      \
		/* We know there is room for at least one byte.  */	      \
		*outptr++ = SO;						      \
		curcs = db;						      \
	      }								      \
									      \
	    if (__glibc_unlikely (outptr + 2 > outend))			      \
	      {								      \
		result = __GCONV_FULL_OUTPUT;				      \
		break;							      \
	      }								      \
	    *outptr++ = cp[0];						      \
	    *outptr++ = cp[1];						      \
	  }								      \
      }									      \
    else								      \
      {									      \
	if (__glibc_unlikely (curcs == db))				      \
	  {								      \
	    /* We know there is room for at least one byte.  */		      \
	    *outptr++ = SI;						      \
	    curcs = sb;							      \
									      \
	    if (__glibc_unlikely (outptr >= outend))			      \
	      {								      \
		result = __GCONV_FULL_OUTPUT;				      \
		break;							      \
	      }								      \
	  }								      \
									      \
	*outptr++ = cp[0];						      \
      }									      \
									      \
    /* Now that we wrote the output increment the input pointer.  */	      \
    inptr += 4;								      \
  }
#define LOOP_NEED_FLAGS
#define EXTRA_LOOP_DECLS	, int *curcsp
#define INIT_PARAMS		int curcs = *curcsp & ~7
#define UPDATE_PARAMS		*curcsp = curcs
#undef assert
/** clang-extract: from ../assert/assert.h:94:1 */
extern void __assert_fail (const char *__assertion, const char *__file,
			   unsigned int __line, const char *__function)
     __THROW __attribute__ ((__noreturn__)) __COLD;

#define assert(...)							\
    ((void) sizeof (__assert_single_arg (__VA_ARGS__)), __extension__ ({ \
      if (__VA_ARGS__)							\
        ; /* empty */							\
      else								\
        __assert_fail (#__VA_ARGS__, __FILE__, __LINE__, __ASSERT_FUNCTION); \
    }))
#define __ASSERT_FUNCTION	__extension__ __PRETTY_FUNCTION__
#define FCTNAME(name) name
#define ignore_errors_p() \
  (irreversible != NULL && (flags & __GCONV_IGNORE_ERRORS))
#define UNICODE_TAG_HANDLER(Character, Incr) \
  {									      \
    /* TAG characters are those in the range U+E0000..U+E007F.  */	      \
    if (((Character) >> 7) == (0xe0000 >> 7))				      \
      {									      \
	inptr += Incr;							      \
	continue;							      \
      }									      \
  }
/** clang-extract: from ../iconv/loop.c:215:1 */
static inline int
__attribute ((always_inline))
FCTNAME (LOOPFCT) (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 EXTRA_LOOP_DECLS)
{
#ifdef LOOP_NEED_STATE
  mbstate_t *state = step_data->__statep;
#endif
#ifdef LOOP_NEED_FLAGS
  int flags = step_data->__flags;
#endif
#ifdef LOOP_NEED_DATA
  void *data = step->__data;
#endif
  int result = __GCONV_EMPTY_INPUT;
  const unsigned char *inptr = *inptrp;
  unsigned char *outptr = *outptrp;

#ifdef INIT_PARAMS
  INIT_PARAMS;
#endif

  while (inptr != inend)
    {
      /* `if' cases for MIN_NEEDED_OUTPUT ==/!= 1 is made to help the
	 compiler generating better code.  They will be optimized away
	 since MIN_NEEDED_OUTPUT is always a constant.  */
      if (MIN_NEEDED_INPUT > 1
	  && __builtin_expect (inptr + MIN_NEEDED_INPUT > inend, 0))
	{
	  /* We don't have enough input for another complete input
	     character.  */
	  result = __GCONV_INCOMPLETE_INPUT;
	  break;
	}
      if ((MIN_NEEDED_OUTPUT != 1
	   && __builtin_expect (outptr + MIN_NEEDED_OUTPUT > outend, 0))
	  || (MIN_NEEDED_OUTPUT == 1
	      && __builtin_expect (outptr >= outend, 0)))
	{
	  /* Overflow in the output buffer.  */
	  result = __GCONV_FULL_OUTPUT;
	  break;
	}

      /* Here comes the body the user provides.  It can stop with
	 RESULT set to GCONV_INCOMPLETE_INPUT (if the size of the
	 input characters vary in size), GCONV_ILLEGAL_INPUT, or
	 GCONV_FULL_OUTPUT (if the output characters vary in size).  */
      BODY
    }

  /* Update the pointers pointed to by the parameters.  */
  *inptrp = inptr;
  *outptrp = outptr;
  UPDATE_PARAMS;

  return result;
}

#define SINGLE(fct) SINGLE2 (fct)
#define SINGLE2(fct) fct##_single
/** clang-extract: from ../iconv/loop.c:282:1 */
static inline int
__attribute ((always_inline))
SINGLE(LOOPFCT) (struct __gconv_step *step,
		 struct __gconv_step_data *step_data,
		 const unsigned char **inptrp, const unsigned char *inend,
		 unsigned char **outptrp, unsigned char *outend,
		 size_t *irreversible EXTRA_LOOP_DECLS)
{
  mbstate_t *state = step_data->__statep;
# ifdef LOOP_NEED_FLAGS
  int flags = step_data->__flags;
# endif
# ifdef LOOP_NEED_DATA
  void *data = step->__data;
# 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
  INIT_PARAMS;
# endif

# ifdef UNPACK_BYTES
  UNPACK_BYTES
# 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

  /* 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

      /* Building with -O3 GCC emits a `array subscript is above array
	 bounds' warning.  GCC BZ #64739 has been opened for this.  */
      DIAG_PUSH_NEEDS_COMMENT;
      DIAG_IGNORE_NEEDS_COMMENT (4.9, "-Warray-bounds");
      while (inptr < inend)
	bytebuf[inlen++] = *inptr++;
      DIAG_POP_NEEDS_COMMENT;

      inptr = bytebuf;
      inptrp = &inptr;
      inend = &bytebuf[inlen];

      STORE_REST
# 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

      return __GCONV_INCOMPLETE_INPUT;
    }

  /* Enough space in output buffer.  */
  if ((MIN_NEEDED_OUTPUT != 1 && outptr + MIN_NEEDED_OUTPUT > outend)
      || (MIN_NEEDED_OUTPUT == 1 && outptr >= outend))
    /* Overflow in the output buffer.  */
    return __GCONV_FULL_OUTPUT;

  /*  Now add characters from the normal input buffer.  */
  if (inlen >= MAX_NEEDED_INPUT || inptr >= inend)
    /* Avoid a -Wstringop-overflow= warning when this loop is
       unrolled.  The compiler cannot otherwise see that this is
       unreachable because it depends on (state->__count & 7) not
       being too large after a previous conversion step.
       Starting with GCC 12, we also have mark the inptr >= inend
       case as unreachable to omit the warning.  Note that this SINGLE
       function is only used to implement the mb*towc*() or wc*tomb*()
       functions.  Those functions use inptr and inend pointing to a
       variable on stack, compute the inend pointer or explicitly check
       the arguments which always leads to inptr < inend.  */
    __builtin_unreachable ();
  do
    bytebuf[inlen++] = *inptr++;
  while (inlen < MAX_NEEDED_INPUT && inptr < inend);

  inptr = bytebuf;
  inend = &bytebuf[inlen];

  do
    {
      BODY
    }
  while (0);

  /* Now we either have produced an output character and consumed all the
     bytes from the state and at least one more, or the character is still
     incomplete, or we have some other error (like illegal input character,
     no space in output buffer).  */
  if (__glibc_likely (inptr != bytebuf))
    {
      /* We found a new character.  */
      assert (inptr - bytebuf > (state->__count & 7));

      *inptrp += inptr - bytebuf - (state->__count & 7);
      *outptrp = outptr;

      result = __GCONV_OK;

      /* Clear the state buffer.  */
# ifdef CLEAR_STATE
      CLEAR_STATE;
# else
      state->__count &= ~7;
# endif
    }
  else if (result == __GCONV_INCOMPLETE_INPUT)
    {
      /* This can only happen if we have less than MAX_NEEDED_INPUT bytes
	 available.  */
      assert (inend != &bytebuf[MAX_NEEDED_INPUT]);

      *inptrp += inend - bytebuf - (state->__count & 7);
# ifdef STORE_REST
      inptrp = &inptr;

      STORE_REST
# else
      /* We don't have enough input for another complete input
	 character.  */
      assert (inend - inptr > (state->__count & ~7));
      assert (inend - inptr <= sizeof (state->__value.__wchb));
      state->__count = (state->__count & ~7) | (inend - inptr);
      for (inlen = 0; inlen < inend - inptr; inlen++)
	state->__value.__wchb[inlen] = inptr[inlen];
      inptr = inend;
# endif
    }

  return result;
}

#undef SINGLE
#undef SINGLE2
#undef MIN_NEEDED_INPUT
#undef MAX_NEEDED_INPUT
#undef MIN_NEEDED_OUTPUT
#undef LOOPFCT
#undef BODY
#undef EXTRA_LOOP_DECLS
#undef INIT_PARAMS
#undef UPDATE_PARAMS
#undef LOOP_NEED_FLAGS
#undef assert
/** clang-extract: from ../assert/assert.h:94:1 */
extern void __assert_fail (const char *__assertion, const char *__file,
			   unsigned int __line, const char *__function)
     __THROW __attribute__ ((__noreturn__)) __COLD;

#define assert(...)							\
    ((void) sizeof (__assert_single_arg (__VA_ARGS__)), __extension__ ({ \
      if (__VA_ARGS__)							\
        ; /* empty */							\
      else								\
        __assert_fail (#__VA_ARGS__, __FILE__, __LINE__, __ASSERT_FUNCTION); \
    }))
#define __ASSERT_FUNCTION	__extension__ __PRETTY_FUNCTION__
#undef NULL
#define NULL ((void*)0)
#ifdef __powerpc64__
/* manually extracted from sysdeps/powerpc/nptl/tls.h and
   sysdeps/unix/sysv/linux/powerpc/pointer_guard.h .*/
register void *__thread_register asm ("r13");
# define TLS_TCB_OFFSET 0x7000
# define THREAD_GET_POINTER_GUARD() \
    (((tcbhead_t *) ((char *) __thread_register                               \
                     - TLS_TCB_OFFSET))[-1].pointer_guard)

#  define PTR_MANGLE(var) \
  (var) = (__typeof (var)) ((uintptr_t) (var) ^ THREAD_GET_POINTER_GUARD ())
#  define PTR_DEMANGLE(var)     PTR_MANGLE (var)

#else
#define LP_SIZE "8"
#define PTR_DEMANGLE(var)						      \
    do {								      \
      asm ("ror $2*" LP_SIZE "+1, %0" : "+r" (var));			      \
      (var) = (__typeof (var)) ((uintptr_t) (var)			      \
				^ ((tcbhead_t __seg_fs *)0)->pointer_guard);  \
    } while (0)
#endif
#define FROM_DIRECTION_VAL NULL
#define FROM_DIRECTION (step->__data == FROM_DIRECTION_VAL)
#define FROM_LOOP_MAX_NEEDED_FROM	MAX_NEEDED_FROM
#define TO_LOOP_MAX_NEEDED_FROM	MAX_NEEDED_TO
#define FUNCTION_NAME	gconv_lp
#define SINGLE(fct) SINGLE2 (fct)
#define SINGLE2(fct) fct##_single
/** clang-extract: from ../iconv/skeleton.c:320:1 */
extern int FUNCTION_NAME (struct __gconv_step *step,
			  struct __gconv_step_data *data,
			  const unsigned char **inptrp,
			  const unsigned char *inend,
			  unsigned char **outbufstart, size_t *irreversible,
			  int do_flush, int consume_incomplete);

/** clang-extract: from ../iconv/skeleton.c:326:1 */
__attribute__((visibility ("default")))
int
FUNCTION_NAME (struct __gconv_step *step, struct __gconv_step_data *data,
	       const unsigned char **inptrp, const unsigned char *inend,
	       unsigned char **outbufstart, size_t *irreversible, int do_flush,
	       int consume_incomplete)
{
  struct __gconv_step *next_step = step + 1;
  struct __gconv_step_data *next_data = data + 1;
  __gconv_fct fct = NULL;
  int status;

  if ((data->__flags & __GCONV_IS_LAST) == 0)
    {
      fct = next_step->__fct;
      if (next_step->__shlib_handle != NULL)
	PTR_DEMANGLE (fct);
    }

  /* If the function is called with no input this means we have to reset
     to the initial state.  The possibly partly converted input is
     dropped.  */
  if (__glibc_unlikely (do_flush))
    {
      /* This should never happen during error handling.  */
      assert (outbufstart == NULL);

      status = __GCONV_OK;

#ifdef EMIT_SHIFT_TO_INIT
      if (do_flush == 1)
	{
	  /* We preserve the initial values of the pointer variables.  */
	  unsigned char *outbuf = data->__outbuf;
	  unsigned char *outstart = outbuf;
	  unsigned char *outend = data->__outbufend;

# ifdef PREPARE_LOOP
	  PREPARE_LOOP
# endif

# ifdef SAVE_RESET_STATE
	  SAVE_RESET_STATE (1);
# endif

	  /* Emit the escape sequence to reset the state.  */
	  EMIT_SHIFT_TO_INIT;

	  /* Call the steps down the chain if there are any but only if we
	     successfully emitted the escape sequence.  This should only
	     fail if the output buffer is full.  If the input is invalid
	     it should be discarded since the user wants to start from a
	     clean state.  */
	  if (status == __GCONV_OK)
	    {
	      if (data->__flags & __GCONV_IS_LAST)
		/* Store information about how many bytes are available.  */
		data->__outbuf = outbuf;
	      else
		{
		  /* Write out all output which was produced.  */
		  if (outbuf > outstart)
		    {
		      const unsigned char *outerr = outstart;
		      int result;

		      result = DL_CALL_FCT (fct, (next_step, next_data,
						  &outerr, outbuf, NULL,
						  irreversible, 0,
						  consume_incomplete));

		      if (result != __GCONV_EMPTY_INPUT)
			{
			  if (__glibc_unlikely (outerr != outbuf))
			    {
			      /* We have a problem.  Undo the conversion.  */
			      outbuf = outstart;

			      /* Restore the state.  */
# ifdef SAVE_RESET_STATE
			      SAVE_RESET_STATE (0);
# endif
			    }

			  /* Change the status.  */
			  status = result;
			}
		    }

		  if (status == __GCONV_OK)
		    /* Now flush the remaining steps.  */
		    status = DL_CALL_FCT (fct, (next_step, next_data, NULL,
						NULL, NULL, irreversible, 1,
						consume_incomplete));
		}
	    }
	}
      else
#endif
	{
	  /* Clear the state object.  There might be bytes in there from
	     previous calls with CONSUME_INCOMPLETE == 1.  But don't emit
	     escape sequences.  */
	  memset (data->__statep, '\0', sizeof (*data->__statep));

	  if (! (data->__flags & __GCONV_IS_LAST))
	    /* Now flush the remaining steps.  */
	    status = DL_CALL_FCT (fct, (next_step, next_data, NULL, NULL,
					NULL, irreversible, do_flush,
					consume_incomplete));
	}
    }
  else
    {
      /* We preserve the initial values of the pointer variables,
	 but only some conversion modules need it.  */
      const unsigned char *inptr __attribute__ ((__unused__)) = *inptrp;
      unsigned char *outbuf = (__builtin_expect (outbufstart == NULL, 1)
			       ? data->__outbuf : *outbufstart);
      unsigned char *outend = data->__outbufend;
      unsigned char *outstart;
      /* This variable is used to count the number of characters we
	 actually converted.  */
      size_t lirreversible = 0;
      size_t *lirreversiblep = irreversible ? &lirreversible : NULL;

#ifdef PREPARE_LOOP
      PREPARE_LOOP
#endif

#if FROM_LOOP_MAX_NEEDED_FROM > 1 || TO_LOOP_MAX_NEEDED_FROM > 1
      /* If the function is used to implement the mb*towc*() or wc*tomb*()
	 functions we must test whether any bytes from the last call are
	 stored in the `state' object.  */
      if (((FROM_LOOP_MAX_NEEDED_FROM > 1 && TO_LOOP_MAX_NEEDED_FROM > 1)
	   || (FROM_LOOP_MAX_NEEDED_FROM > 1 && FROM_DIRECTION)
	   || (TO_LOOP_MAX_NEEDED_FROM > 1 && !FROM_DIRECTION))
	  && consume_incomplete && (data->__statep->__count & 7) != 0)
	{
	  /* Yep, we have some bytes left over.  Process them now.
	     But this must not happen while we are called from an
	     error handler.  */
	  assert (outbufstart == NULL);

# if FROM_LOOP_MAX_NEEDED_FROM > 1
	  if (TO_LOOP_MAX_NEEDED_FROM == 1 || FROM_DIRECTION)
	    status = SINGLE(FROM_LOOP) (step, data, inptrp, inend, &outbuf,
					outend, lirreversiblep
					EXTRA_LOOP_ARGS);
# endif
# if !ONE_DIRECTION
#  if FROM_LOOP_MAX_NEEDED_FROM > 1 && TO_LOOP_MAX_NEEDED_FROM > 1
	  else
#  endif
#  if TO_LOOP_MAX_NEEDED_FROM > 1
	    status = SINGLE(TO_LOOP) (step, data, inptrp, inend, &outbuf,
				      outend, lirreversiblep EXTRA_LOOP_ARGS);
#  endif
# endif

	  if (__builtin_expect (status, __GCONV_OK) != __GCONV_OK)
	    return status;
	}
#endif

      while (1)
	{
	  /* Remember the start value for this round.  */
	  inptr = *inptrp;
	  /* The outbuf buffer is empty.  */
	  outstart = outbuf;
#ifdef RESET_INPUT_BUFFER
	  /* Remember how many irreversible characters were skipped before
	     this round.  */
	  size_t loop_irreversible
	    = lirreversible + (irreversible ? *irreversible : 0);
#endif

#ifdef SAVE_RESET_STATE
	  SAVE_RESET_STATE (1);
#endif

	  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 we were called as part of an error handling module we
	     don't do anything else here.  */
	  if (__glibc_unlikely (outbufstart != NULL))
	    {
	      *outbufstart = outbuf;
	      return status;
	    }

	  /* We finished one use of the loops.  */
	  ++data->__invocation_counter;

	  /* If this is the last step leave the loop, there is nothing
	     we can do.  */
	  if (__glibc_unlikely (data->__flags & __GCONV_IS_LAST))
	    {
	      /* Store information about how many bytes are available.  */
	      data->__outbuf = outbuf;

	      /* Remember how many non-identical characters we
		 converted in an irreversible way.  */
	      *irreversible += lirreversible;

	      break;
	    }

	  /* Write out all output which was produced.  */
	  if (__glibc_likely (outbuf > outstart))
	    {
	      const unsigned char *outerr = data->__outbuf;
	      int result;

	      result = DL_CALL_FCT (fct, (next_step, next_data, &outerr,
					  outbuf, NULL, irreversible, 0,
					  consume_incomplete));

	      if (result != __GCONV_EMPTY_INPUT)
		{
		  if (__glibc_unlikely (outerr != outbuf))
		    {
#ifdef RESET_INPUT_BUFFER
		      /* RESET_INPUT_BUFFER can only work when there were
			 no new irreversible characters skipped during
			 this round.  */
		      if (loop_irreversible
			  == lirreversible + (irreversible ? *irreversible : 0))
			{
			  RESET_INPUT_BUFFER;
			  goto done_reset;
			}
#endif
		      /* We have a problem in one of the functions below.
			 Undo the conversion upto the error point.  */
		      size_t nstatus __attribute__ ((unused));

		      /* Reload the pointers.  */
		      *inptrp = inptr;
		      outbuf = outstart;

		      /* Restore the state.  */
#ifdef SAVE_RESET_STATE
		      SAVE_RESET_STATE (0);
#endif

		      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);

		      /* We must run out of output buffer space in this
			 rerun.  */
		      assert (outbuf == outerr);
		      assert (nstatus == __GCONV_FULL_OUTPUT);

		      /* If we haven't consumed a single byte decrement
			 the invocation counter.  */
		      if (__glibc_unlikely (outbuf == outstart))
			--data->__invocation_counter;
		    }

#ifdef RESET_INPUT_BUFFER
		done_reset:
#endif
		  /* Change the status.  */
		  status = result;
		}
	      else
		/* All the output is consumed, we can make another run
		   if everything was ok.  */
		if (status == __GCONV_FULL_OUTPUT)
		  {
		    status = __GCONV_OK;
		    outbuf = data->__outbuf;
		  }
	    }

	  if (status != __GCONV_OK)
	    break;

	  /* Reset the output buffer pointer for the next round.  */
	  outbuf = data->__outbuf;
	}

#ifdef END_LOOP
      END_LOOP
#endif

      /* If we are supposed to consume all character store now all of the
	 remaining characters in the `state' object.  */
#if FROM_LOOP_MAX_NEEDED_FROM > 1 || TO_LOOP_MAX_NEEDED_FROM > 1
      if (((FROM_LOOP_MAX_NEEDED_FROM > 1 && TO_LOOP_MAX_NEEDED_FROM > 1)
	   || (FROM_LOOP_MAX_NEEDED_FROM > 1 && FROM_DIRECTION)
	   || (TO_LOOP_MAX_NEEDED_FROM > 1 && !FROM_DIRECTION))
	  && __builtin_expect (consume_incomplete, 0)
	  && status == __GCONV_INCOMPLETE_INPUT)
	{
# ifdef STORE_REST
	  mbstate_t *state = data->__statep;

	  STORE_REST
# else
	  /* Make sure the remaining bytes fit into the state objects
	     buffer.  */
	  size_t cnt_after = inend - *inptrp;
	  assert (cnt_after <= sizeof (data->__statep->__value.__wchb));

	  size_t cnt;
	  for (cnt = 0; cnt < cnt_after; ++cnt)
	    data->__statep->__value.__wchb[cnt] = (*inptrp)[cnt];
	  *inptrp = inend;
	  data->__statep->__count &= ~7;
	  data->__statep->__count |= cnt;
# endif
	}
#endif
#undef unaligned
#undef POSSIBLY_UNALIGNED
    }

  return status;
}

#undef MIN_NEEDED_FROM
#undef MIN_NEEDED_TO
#undef MAX_NEEDED_FROM
#undef MAX_NEEDED_TO
#undef FROM_LOOP_MAX_NEEDED_FROM
#undef TO_LOOP_MAX_NEEDED_FROM
#undef FROM_DIRECTION
#undef EMIT_SHIFT_TO_INIT
#undef FROM_LOOP
#undef TO_LOOP
#undef ONE_DIRECTION
#undef SAVE_RESET_STATE
#undef FUNCTION_NAME
#undef PREPARE_LOOP
#undef EXTRA_LOOP_ARGS
