// File: /workspace/github_cpp_makefile_star2_O3/Alcaro[P]bridges/arlib/image.cpp
// Function: void convert_scanline_rgb888_nrgb8888<4278190080u>(unsigned int*, unsigned char const*, unsigned long)
void convert_scanline_rgb888_nrgb8888(uint32_t* out, const uint8_t* in, size_t npx)
{
	uint32_t* out32 = (uint32_t*)out;
	size_t x = 0;
#if defined(__SSE2__)
	// we wish to read 12 bytes at the time, but loadu_si28 does 16, so -2 to ensure we don't read out of bounds
	// except put the -2 at the x side, (size_t)1-2 isn't less than anything
	while (x+4+2 <= npx)
	{
		uint8_t* src = (uint8_t*)in + x*3;
		
		__m128i pix = _mm_loadu_si128((__m128i*)src);
		//pix = u8*16 { rgbrgbrgbrgbXXXX }
		pix = _mm_bslli_si128(pix, 2);
		//pix = u8*16 { 00rgbrgbrgbrgbXX }
		pix = _mm_shufflehi_epi16(pix, _MM_SHUFFLE(2,1,0,3));
		//pix = u8*16 { 00rgbrgbXXrgbrgb }
		if (newalpha == 0x00000000)
		{
			pix = _mm_srli_epi64(pix, 2*8);
			//pix = u8*16 { rgbrgb00rgbrgb00 }
			pix = _mm_slli_epi64(pix, 1*8);
			//pix = u8*16 { 0rgbrgb00rgbrgb0 }
		}
		else
		{
			pix = _mm_srli_epi64(pix, 1*8);
			//pix = u8*16 { 0rgbrgb0Xrgbrgb0 }
		}
		
		__m128i pix1 = _mm_unpacklo_epi8(pix, _mm_setzero_si128());
		__m128i pix2 = _mm_unpackhi_epi8(pix, _mm_setzero_si128());
		pix1 = _mm_shufflelo_epi16(pix1, _MM_SHUFFLE(0,1,2,3)); // 0rgb -> 0bgr
		pix1 = _mm_shufflehi_epi16(pix1, _MM_SHUFFLE(3,0,1,2)); // rgb0 -> 0bgr
		pix2 = _mm_shufflelo_epi16(pix2, _MM_SHUFFLE(0,1,2,3)); // Xrgb -> Xbgr
		pix2 = _mm_shufflehi_epi16(pix2, _MM_SHUFFLE(3,0,1,2)); // rgb0 -> 0bgr
		pix = _mm_packus_epi16(pix1, pix2);
		//pix = u8*16 { 0bgr0bgrXbgr0bgr }
		
		if (newalpha == 0xFF000000)
			pix = _mm_or_si128(pix, _mm_set1_epi32(0xFF000000));
		
		_mm_storeu_si128((__m128i*)(out32 + x), pix);
		
		x += 4;
	}
	SIMD_LOOP_TAIL
#endif
	// Clang can vectorize this, but it emits some quite messy code, so keep the SSE2 anyways
	// (in fact, Clang flattens the above all the way to a single pshufb, if -mssse3)
	// gcc doesn't vectorize the below, nor do anything interesting to the above
	while (x < npx)
	{
		uint8_t* src = (uint8_t*)in + x*3;
		out32[x] = src[0]<<16 | src[1]<<8 | src[2];
		if (newalpha == 0xFF000000)
			out32[x] |= 0xFF000000;
		x++;
	}
}

// Assembly:
cmpq $0x6, %rdx
jae 0xd359
xorl %eax, %eax
jmp 0xd425
xorl %ecx, %ecx
movdqa 0x226ad(%rip), %xmm0    # 0x2fa10
pxor %xmm1, %xmm1
movdqa 0x22681(%rip), %xmm2    # 0x2f9f0
movdqa 0x22689(%rip), %xmm3    # 0x2fa00
movdqa 0x22611(%rip), %xmm4    # 0x2f990
movq %rsi, %r8
leaq 0x4(%rcx), %rax
movdqu (%r8), %xmm5
pshufd $0xd8, %xmm5, %xmm5     # xmm5 = xmm5[0,2,1,3]
pand %xmm0, %xmm5
pshufhw $0xc6, %xmm5, %xmm5     # xmm5 = xmm5[0,1,2,3,6,5,4,7]
pshufd $0x6c, %xmm5, %xmm5     # xmm5 = xmm5[0,3,2,1]
pshuflw $0x93, %xmm5, %xmm5     # xmm5 = xmm5[3,0,1,2,4,5,6,7]
psrlq $0x8, %xmm5
movdqa %xmm5, %xmm6
punpcklbw %xmm1, %xmm6    # xmm6 = xmm6[0],xmm1[0],xmm6[1],xmm1[1],xmm6[2],xmm1[2],xmm6[3],xmm1[3],xmm6[4],xmm1[4],xmm6[5],xmm1[5],xmm6[6],xmm1[6],xmm6[7],xmm1[7]
movdqa %xmm6, %xmm7
punpckhbw %xmm1, %xmm7    # xmm7 = xmm7[8],xmm1[8],xmm7[9],xmm1[9],xmm7[10],xmm1[10],xmm7[11],xmm1[11],xmm7[12],xmm1[12],xmm7[13],xmm1[13],xmm7[14],xmm1[14],xmm7[15],xmm1[15]
pshufd $0xc6, %xmm7, %xmm7     # xmm7 = xmm7[2,1,0,3]
punpcklbw %xmm1, %xmm6    # xmm6 = xmm6[0],xmm1[0],xmm6[1],xmm1[1],xmm6[2],xmm1[2],xmm6[3],xmm1[3],xmm6[4],xmm1[4],xmm6[5],xmm1[5],xmm6[6],xmm1[6],xmm6[7],xmm1[7]
pshufd $0xc6, %xmm6, %xmm6     # xmm6 = xmm6[2,1,0,3]
pshuflw $0xec, %xmm6, %xmm6     # xmm6 = xmm6[0,3,2,3,4,5,6,7]
pshufd $0x9c, %xmm6, %xmm6     # xmm6 = xmm6[0,3,1,2]
pshuflw $0xc6, %xmm6, %xmm6     # xmm6 = xmm6[2,1,0,3,4,5,6,7]
pand %xmm2, %xmm6
packuswb %xmm7, %xmm6
punpckhbw %xmm1, %xmm5    # xmm5 = xmm5[8],xmm1[8],xmm5[9],xmm1[9],xmm5[10],xmm1[10],xmm5[11],xmm1[11],xmm5[12],xmm1[12],xmm5[13],xmm1[13],xmm5[14],xmm1[14],xmm5[15],xmm1[15]
movdqa %xmm5, %xmm7
punpcklbw %xmm1, %xmm7    # xmm7 = xmm7[0],xmm1[0],xmm7[1],xmm1[1],xmm7[2],xmm1[2],xmm7[3],xmm1[3],xmm7[4],xmm1[4],xmm7[5],xmm1[5],xmm7[6],xmm1[6],xmm7[7],xmm1[7]
pshufd $0x1b, %xmm7, %xmm7     # xmm7 = xmm7[3,2,1,0]
punpckhbw %xmm1, %xmm5    # xmm5 = xmm5[8],xmm1[8],xmm5[9],xmm1[9],xmm5[10],xmm1[10],xmm5[11],xmm1[11],xmm5[12],xmm1[12],xmm5[13],xmm1[13],xmm5[14],xmm1[14],xmm5[15],xmm1[15]
pshuflw $0xec, %xmm5, %xmm5     # xmm5 = xmm5[0,3,2,3,4,5,6,7]
pshufd $0xc6, %xmm5, %xmm5     # xmm5 = xmm5[2,1,0,3]
pand %xmm3, %xmm5
packuswb %xmm5, %xmm7
packuswb %xmm7, %xmm6
por %xmm4, %xmm6
movdqu %xmm6, (%rdi,%rcx,4)
addq $0xa, %rcx
addq $0xc, %r8
cmpq %rdx, %rcx
movq %rax, %rcx
jbe 0xd382
cmpq %rdx, %rax
jae 0xd463
leaq (%rax,%rax,2), %rcx
addq %rsi, %rcx
addq $0x2, %rcx
movzbl -0x2(%rcx), %esi
shll $0x10, %esi
movzbl -0x1(%rcx), %r8d
shll $0x8, %r8d
orl %esi, %r8d
movzbl (%rcx), %esi
orl %r8d, %esi
orl $0xff000000, %esi       # imm = 0xFF000000
movl %esi, (%rdi,%rax,4)
incq %rax
addq $0x3, %rcx
cmpq %rax, %rdx
jne 0xd435
retq