void TexConv_AI44_ARGB4444(unsigned char *_src, unsigned char *_dst, int width,
                           int height) {
  int _size = width * height;
  asm volatile("0: \n"
               "mov (%[_src]), %%eax     \n"
               "add $4, %[_src]          \n"
               "mov %%eax, %%edx       \n"
               "shl $16, %%eax         \n"
               "and $0xFF000000, %%eax \n"
               "mov %%eax, %%ecx       \n"
               "and $0x0F000000, %%eax \n"
               "shr $4, %%eax          \n"
               "or %%eax, %%ecx        \n"
               "shr $4, %%eax          \n"
               "or %%eax, %%ecx        \n"
               "mov %%edx, %%eax       \n"
               "shl $8, %%eax          \n"
               "and $0x0000FF00, %%eax \n"
               "or %%eax, %%ecx        \n"
               "and $0x00000F00, %%eax \n"
               "shr $4, %%eax          \n"
               "or %%eax, %%ecx        \n"
               "shr $4, %%eax          \n"
               "or %%eax, %%ecx        \n"
               "mov %%ecx, (%[_dst])     \n"
               "add $4, %[_dst]          \n"
               "mov %%edx, %%eax       \n"
               "and $0xFF000000, %%eax \n"
               "mov %%eax, %%ecx       \n"
               "and $0x0F000000, %%eax \n"
               "shr $4, %%eax          \n"
               "or %%eax, %%ecx        \n"
               "shr $4, %%eax          \n"
               "or %%eax, %%ecx        \n"
               "shr $8, %%edx          \n"
               "and $0x0000FF00, %%edx \n"
               "or %%edx, %%ecx        \n"
               "and $0x00000F00, %%edx \n"
               "shr $4, %%edx          \n"
               "or %%edx, %%ecx        \n"
               "shr $4, %%edx          \n"
               "or %%edx, %%ecx        \n"
               "mov %%ecx, (%[_dst])     \n"
               "add $4, %[_dst]          \n"
               "decl %[_size]            \n"
               "jnz 0b \n"
               : [_src] "+S"(_src), [_dst] "+D"(_dst), [_size] "+g"(_size)
               :
               : "memory", "cc", "eax", "edx", "ecx");
}


x86 assembly (clang, -O0):
<TexConv_AI44_ARGB4444>:
push   %rbp
mov    %rsp,%rbp
mov    %rdi,-0x8(%rbp)
mov    %rsi,-0x10(%rbp)
mov    %edx,-0x14(%rbp)
mov    %ecx,-0x18(%rbp)
mov    -0x14(%rbp),%eax
imul   -0x18(%rbp),%eax
mov    %eax,-0x1c(%rbp)
mov    -0x8(%rbp),%rsi
mov    -0x10(%rbp),%rdi
mov    -0x1c(%rbp),%r8d
mov    (%rsi),%eax
add    $0x4,%rsi
mov    %eax,%edx
shl    $0x10,%eax
and    $0xff000000,%eax
mov    %eax,%ecx
and    $0xf000000,%eax
shr    $0x4,%eax
or     %eax,%ecx
shr    $0x4,%eax
or     %eax,%ecx
mov    %edx,%eax
shl    $0x8,%eax
and    $0xff00,%eax
or     %eax,%ecx
and    $0xf00,%eax
shr    $0x4,%eax
or     %eax,%ecx
shr    $0x4,%eax
or     %eax,%ecx
mov    %ecx,(%rdi)
add    $0x4,%rdi
mov    %edx,%eax
and    $0xff000000,%eax
mov    %eax,%ecx
and    $0xf000000,%eax
shr    $0x4,%eax
or     %eax,%ecx
shr    $0x4,%eax
or     %eax,%ecx
shr    $0x8,%edx
and    $0xff00,%edx
or     %edx,%ecx
and    $0xf00,%edx
shr    $0x4,%edx
or     %edx,%ecx
shr    $0x4,%edx
or     %edx,%ecx
mov    %ecx,(%rdi)
add    $0x4,%rdi
dec    %r8d
jne    1128 <TexConv_AI44_ARGB4444+0x28>
mov    %r8d,-0x20(%rbp)
mov    -0x20(%rbp),%eax
mov    %eax,-0x1c(%rbp)
mov    %rsi,-0x8(%rbp)
mov    %rdi,-0x10(%rbp)
pop    %rbp
ret

x86 assembly (clang, -O2):
<TexConv_AI44_ARGB4444>:
mov    %edx,%r8d
mov    %rdi,%rax
imul   %ecx,%r8d
mov    %r8d,-0x4(%rsp)
mov    %rsi,%rdi
mov    %rax,%rsi
mov    (%rsi),%eax
add    $0x4,%rsi
mov    %eax,%edx
shl    $0x10,%eax
and    $0xff000000,%eax
mov    %eax,%ecx
and    $0xf000000,%eax
shr    $0x4,%eax
or     %eax,%ecx
shr    $0x4,%eax
or     %eax,%ecx
mov    %edx,%eax
shl    $0x8,%eax
and    $0xff00,%eax
or     %eax,%ecx
and    $0xf00,%eax
shr    $0x4,%eax
or     %eax,%ecx
shr    $0x4,%eax
or     %eax,%ecx
mov    %ecx,(%rdi)
add    $0x4,%rdi
mov    %edx,%eax
and    $0xff000000,%eax
mov    %eax,%ecx
and    $0xf000000,%eax
shr    $0x4,%eax
or     %eax,%ecx
shr    $0x4,%eax
or     %eax,%ecx
shr    $0x8,%edx
and    $0xff00,%edx
or     %edx,%ecx
and    $0xf00,%edx
shr    $0x4,%edx
or     %edx,%ecx
shr    $0x4,%edx
or     %edx,%ecx
mov    %ecx,(%rdi)
add    $0x4,%rdi
dec    %r8d
jne    1115 <TexConv_AI44_ARGB4444+0x15>
ret

LLVM IR (-O0):
define void @TexConv_AI44_ARGB4444(i8* %0, i8* %1, i32 %2, i32 %3) {
%5 = alloca i8*
%6 = alloca i8*
%7 = alloca i32
%8 = alloca i32
%9 = alloca i32
store i8* %0, i8** %5
store i8* %1, i8** %6
store i32 %2, i32* %7
store i32 %3, i32* %8
%10 = load i32, i32* %7
%11 = load i32, i32* %8
%12 = mul nsw i32 %10, %11
store i32 %12, i32* %9
%13 = load i8*, i8** %5
%14 = load i8*, i8** %6
%15 = load i32, i32* %9
%16 = call { i8*, i8* } asm sideeffect "0: \0Amov ($0), %eax \0Aadd $$4, $0 \0Amov %eax, %edx \0Ashl $$16, %eax \0Aand $$0xFF000000, %eax \0Amov %eax, %ecx \0Aand $$0x0F000000, %eax \0Ashr $$4, %eax \0Aor %eax, %ecx \0Ashr $$4, %eax \0Aor %eax, %ecx \0Amov %edx, %eax \0Ashl $$8, %eax \0Aand $$0x0000FF00, %eax \0Aor %eax, %ecx \0Aand $$0x00000F00, %eax \0Ashr $$4, %eax \0Aor %eax, %ecx \0Ashr $$4, %eax \0Aor %eax, %ecx \0Amov %ecx, ($1) \0Aadd $$4, $1 \0Amov %edx, %eax \0Aand $$0xFF000000, %eax \0Amov %eax, %ecx \0Aand $$0x0F000000, %eax \0Ashr $$4, %eax \0Aor %eax, %ecx \0Ashr $$4, %eax \0Aor %eax, %ecx \0Ashr $$8, %edx \0Aand $$0x0000FF00, %edx \0Aor %edx, %ecx \0Aand $$0x00000F00, %edx \0Ashr $$4, %edx \0Aor %edx, %ecx \0Ashr $$4, %edx \0Aor %edx, %ecx \0Amov %ecx, ($1) \0Aadd $$4, $1 \0Adecl $2 \0Ajnz 0b \0A", "={si},={di},=*imr,0,1,2,~{memory},~{cc},~{eax},~{edx},~{ecx},~{dirflag},~{fpsr},~{flags}"(i32* elementtype(i32) %9, i8* %13, i8* %14, i32 %15)
%17 = extractvalue { i8*, i8* } %16, 0
%18 = extractvalue { i8*, i8* } %16, 1
store i8* %17, i8** %5
store i8* %18, i8** %6
ret void
}

LLVM IR (-O2):
define void @TexConv_AI44_ARGB4444(i8* %0, i8* %1, i32 %2, i32 %3) {
%5 = alloca i32
%6 = bitcast i32* %5 to i8*
%7 = mul nsw i32 %3, %2
store i32 %7, i32* %5
%8 = call { i8*, i8* } asm sideeffect "0: \0Amov ($0), %eax \0Aadd $$4, $0 \0Amov %eax, %edx \0Ashl $$16, %eax \0Aand $$0xFF000000, %eax \0Amov %eax, %ecx \0Aand $$0x0F000000, %eax \0Ashr $$4, %eax \0Aor %eax, %ecx \0Ashr $$4, %eax \0Aor %eax, %ecx \0Amov %edx, %eax \0Ashl $$8, %eax \0Aand $$0x0000FF00, %eax \0Aor %eax, %ecx \0Aand $$0x00000F00, %eax \0Ashr $$4, %eax \0Aor %eax, %ecx \0Ashr $$4, %eax \0Aor %eax, %ecx \0Amov %ecx, ($1) \0Aadd $$4, $1 \0Amov %edx, %eax \0Aand $$0xFF000000, %eax \0Amov %eax, %ecx \0Aand $$0x0F000000, %eax \0Ashr $$4, %eax \0Aor %eax, %ecx \0Ashr $$4, %eax \0Aor %eax, %ecx \0Ashr $$8, %edx \0Aand $$0x0000FF00, %edx \0Aor %edx, %ecx \0Aand $$0x00000F00, %edx \0Ashr $$4, %edx \0Aor %edx, %ecx \0Ashr $$4, %edx \0Aor %edx, %ecx \0Amov %ecx, ($1) \0Aadd $$4, $1 \0Adecl $2 \0Ajnz 0b \0A", "={si},={di},=*imr,0,1,2,~{memory},~{cc},~{eax},~{edx},~{ecx},~{dirflag},~{fpsr},~{flags}"(i32* elementtype(i32) %5, i8* %0, i8* %1, i32 %7)
ret void
}