:128]\n"
		"1:\n"
			"sub     %[x], %[x], #16\n"
			"sub     %[position], %[position], #8\n"
			"vld1.8  {d4, d5}, [%[pcm]]!\n"
			"vtbl.8  d16, {d4, d5}, d0\n"
			"vtbl.8  d17, {d4, d5}, d1\n"
			"vst1.16 {d16, d17}, [%[x], :128]\n"
			"subs    %[nsamples], %[nsamples], #8\n"
			"bgt     1b\n"
			:
			  [x]        "+r" (x),
			  [pcm]      "+r" (pcm),
			  [nsamples] "+r" (nsamples),
			  [position] "+r" (position)
			:
			  [perm]      "r" (big_endian ? perm_be : perm_le)
			: "cc", "memory", "d0", "d1", "d2", "d3", "d4",
			  "d5", "d6", "d7", "d16", "d17", "d18", "d19");
	}
	return position;
}

static SBC_ALWAYS_INLINE int sbc_enc_process_input_8s_neon_internal(
	int position,
	const uint8_t *pcm, int16_t X[2][SBC_X_BUFFER_SIZE],
	int nsamples, int nchannels, int big_endian)
{
	static SBC_ALIGNED uint8_t perm_be[4][8] = {
		PERM_BE(15, 7, 14, 8),
		PERM_BE(13, 9, 12, 10),
		PERM_BE(11, 3, 6,  0),
		PERM_BE(5,  1, 4,  2)
	};
	static SBC_ALIGNED uint8_t perm_le[4][8] = {
		PERM_LE(15, 7, 14, 8),
		PERM_LE(13, 9, 12, 10),
		PERM_LE(11, 3, 6,  0),
		PERM_LE(5,  1, 4,  2)
	};
	/* handle X buffer wraparound */
	if (position < nsamples) {
		int16_t *dst = &X[0][SBC_X_BUFFER_SIZE - 72];
		int16_t *src = &X[0][position];
		asm volatile (
			"vld1.16 {d0, d1, d2, d3}, [%[src], :128]!\n"
			"vst1.16 {d0, d1, d2, d3}, [%[dst], :128]!\n"
			"vld1.16 {d0, d1, d2, d3}, [%[src], :128]!\n"
			"vst1.16 {d0, d1, d2, d3}, [%[dst], :128]!\n"
			"vld1.16 {d0, d1, d2, d3}, [%[src], :128]!\n"
			"vst1.16 {d0, d1, d2, d3}, [%[dst], :128]!\n"
			"vld1.16 {d0, d1, d2, d3}, [%[src], :128]!\n"
			"vst1.16 {d0, d1, d2, d3}, [%[dst], :128]!\n"
			"vld1.16 {d0, d1}, [%[src], :128]!\n"
			"vst1.16 {d0, d1}, [%[dst], :128]!\n"
			:
			  [dst] "+r" (dst),
			  [src] "+r" (src)
			: : "memory", "d0", "d1", "d2", "d3");
		if (nchannels > 1) {
			dst = &X[1][SBC_X_BUFFER_SIZE - 72];
			src = &X[1][position];
			asm volatile (
				"vld1.16 {d0, d1, d2, d3}, [%[src], :128]!\n"
				"vst1.16 {d0, d1, d2, d3}, [%[dst], :128]!\n"
				"vld1.16 {d0, d1, 