void rgb888_to_yuv_2101010(unsigned int rgb1, unsigned int *yuv, int bpp,
                           unsigned char swap_color) {
  static unsigned int YKr, YKg, YKb;
  static unsigned int CrKr, CrKg, CrKb;
  static unsigned int CbKr, CbKg, CbKb;
  unsigned int A, R, G, B;
  unsigned int Y, Cb, Cr;
  unsigned int yuv_pix;
  YKr = 29900;
  YKg = 58700;
  YKb = 11400;
  CbKr = 16868;
  CbKg = 33107;
  CbKb = 49970;
  CrKr = 49980;
  CrKg = 41850;
  CrKb = 8128;
  A = (rgb1 & 0xFF000000) >> 24;
  R = (rgb1 & 0x00FF0000) >> 16;
  G = (rgb1 & 0x0000FF00) >> 8;
  B = (rgb1 & 0x000000FF) >> 0;
  Y = (((YKr * (R & 0xFF)) + (YKg * (G & 0xFF)) + (YKb * (B & 0xFF))) / 100000);
  Cb = (((-CbKr * (R & 0xFF)) - (CbKg * (G & 0xFF)) + (CbKb * (B & 0xFF)) +
         12800000) /
        100000);
  Cr = (((CrKr * (R & 0xFF)) - (CrKg * (G & 0xFF)) - (CrKb * (B & 0xFF)) +
         12800000) /
        100000);
  Y = Y * ((1 << 10) - 1) / 255;
  Cr = Cr * ((1 << 10) - 1) / 255;
  Cb = Cb * ((1 << 10) - 1) / 255;
  if (swap_color)
    yuv_pix = (A << 30) | (Cr << 20) | (Cb << 10) | Y;
  else
    yuv_pix = (A << 30) | (Y << 20) | (Cb << 10) | Cr;
  *yuv = yuv_pix;
}


x86 assembly (clang, -O0):
<rgb888_to_yuv_2101010>:
push   %rbp
mov    %rsp,%rbp
mov    %cl,%al
mov    %edi,-0x4(%rbp)
mov    %rsi,-0x10(%rbp)
mov    %edx,-0x14(%rbp)
mov    %al,-0x15(%rbp)
movl   $0x74cc,0x2f07(%rip)
movl   $0xe54c,0x2f01(%rip)
movl   $0x2c88,0x2efb(%rip)
movl   $0x41e4,0x2f01(%rip)
movl   $0x8153,0x2efb(%rip)
movl   $0xc332,0x2ef5(%rip)
movl   $0xc33c,0x2ed7(%rip)
movl   $0xa37a,0x2ed1(%rip)
movl   $0x1fc0,0x2ecb(%rip)
mov    -0x4(%rbp),%eax
and    $0xff000000,%eax
shr    $0x18,%eax
mov    %eax,-0x1c(%rbp)
mov    -0x4(%rbp),%eax
and    $0xff0000,%eax
shr    $0x10,%eax
mov    %eax,-0x20(%rbp)
mov    -0x4(%rbp),%eax
and    $0xff00,%eax
shr    $0x8,%eax
mov    %eax,-0x24(%rbp)
mov    -0x4(%rbp),%eax
and    $0xff,%eax
shr    $0x0,%eax
mov    %eax,-0x28(%rbp)
mov    0x2e79(%rip),%eax
mov    -0x20(%rbp),%ecx
and    $0xff,%ecx
imul   %ecx,%eax
mov    0x2e6b(%rip),%ecx
mov    -0x24(%rbp),%edx
and    $0xff,%edx
imul   %edx,%ecx
add    %ecx,%eax
mov    0x2e5b(%rip),%ecx
mov    -0x28(%rbp),%edx
and    $0xff,%edx
imul   %edx,%ecx
add    %ecx,%eax
mov    $0x186a0,%ecx
xor    %edx,%edx
div    %ecx
mov    %eax,-0x2c(%rbp)
xor    %eax,%eax
sub    0x2e49(%rip),%eax
mov    -0x20(%rbp),%ecx
and    $0xff,%ecx
imul   %ecx,%eax
mov    0x2e3b(%rip),%ecx
mov    -0x24(%rbp),%edx
and    $0xff,%edx
imul   %edx,%ecx
sub    %ecx,%eax
mov    0x2e2b(%rip),%ecx
mov    -0x28(%rbp),%edx
and    $0xff,%edx
imul   %edx,%ecx
add    %ecx,%eax
add    $0xc35000,%eax
mov    $0x186a0,%ecx
xor    %edx,%edx
div    %ecx
mov    %eax,-0x30(%rbp)
mov    0x2df2(%rip),%eax
mov    -0x20(%rbp),%ecx
and    $0xff,%ecx
imul   %ecx,%eax
mov    0x2de4(%rip),%ecx
mov    -0x24(%rbp),%edx
and    $0xff,%edx
imul   %edx,%ecx
sub    %ecx,%eax
mov    0x2dd4(%rip),%ecx
mov    -0x28(%rbp),%edx
and    $0xff,%edx
imul   %edx,%ecx
sub    %ecx,%eax
add    $0xc35000,%eax
mov    $0x186a0,%ecx
xor    %edx,%edx
div    %ecx
mov    %eax,-0x34(%rbp)
imul   $0x3ff,-0x2c(%rbp),%eax
mov    $0xff,%ecx
xor    %edx,%edx
div    %ecx
mov    %eax,-0x2c(%rbp)
imul   $0x3ff,-0x34(%rbp),%eax
mov    $0xff,%ecx
xor    %edx,%edx
div    %ecx
mov    %eax,-0x34(%rbp)
imul   $0x3ff,-0x30(%rbp),%eax
mov    $0xff,%ecx
xor    %edx,%edx
div    %ecx
mov    %eax,-0x30(%rbp)
cmpb   $0x0,-0x15(%rbp)
je     12e7 <rgb888_to_yuv_2101010+0x1e7>
mov    -0x1c(%rbp),%eax
shl    $0x1e,%eax
mov    -0x34(%rbp),%ecx
shl    $0x14,%ecx
or     %ecx,%eax
mov    -0x30(%rbp),%ecx
shl    $0xa,%ecx
or     %ecx,%eax
or     -0x2c(%rbp),%eax
mov    %eax,-0x38(%rbp)
jmp    1303 <rgb888_to_yuv_2101010+0x203>
mov    -0x1c(%rbp),%eax
shl    $0x1e,%eax
mov    -0x2c(%rbp),%ecx
shl    $0x14,%ecx
or     %ecx,%eax
mov    -0x30(%rbp),%ecx
shl    $0xa,%ecx
or     %ecx,%eax
or     -0x34(%rbp),%eax
mov    %eax,-0x38(%rbp)
mov    -0x38(%rbp),%ecx
mov    -0x10(%rbp),%rax
mov    %ecx,(%rax)
pop    %rbp
ret

x86 assembly (clang, -O2):
<rgb888_to_yuv_2101010>:
push   %rbp
push   %rbx
mov    %ecx,%r8d
mov    %edi,%ecx
mov    %edi,%eax
shr    $0x10,%eax
movzbl %al,%r9d
movzbl %ch,%ebp
movzbl %cl,%edx
imul   $0x74cc,%r9d,%r10d
imul   $0xe54c,%ebp,%ebx
imul   $0x2c88,%edx,%eax
add    %ebx,%eax
add    %r10d,%eax
shr    $0x5,%eax
imul   $0xa7c5ac5,%rax,%rax
shr    $0x27,%rax
imul   $0xffffbe1c,%r9d,%ebx
imul   $0xffff7ead,%ebp,%r10d
imul   $0xc332,%edx,%edi
add    %ebx,%edi
add    %r10d,%edi
add    $0xc35000,%edi
shr    $0x5,%edi
imul   $0xa7c5ac5,%rdi,%rbx
shr    $0x27,%rbx
imul   $0xc33c,%r9d,%edi
imul   $0xffff5c86,%ebp,%ebp
imul   $0xffffe040,%edx,%edx
add    %edi,%edx
add    %ebp,%edx
add    $0xc35000,%edx
shr    $0x5,%edx
imul   $0xa7c5ac5,%rdx,%rbp
shr    $0x27,%rbp
mov    %eax,%edx
shl    $0xa,%edx
sub    %eax,%edx
mov    $0x80808081,%r9d
imul   %r9,%rdx
shr    $0x27,%rdx
mov    %ebp,%edi
shl    $0xa,%edi
sub    %ebp,%edi
imul   %r9,%rdi
shr    $0x27,%rdi
mov    %ebx,%eax
shl    $0xa,%eax
sub    %ebx,%eax
imul   %r9,%rax
shr    $0x27,%rax
shl    $0x6,%ecx
and    $0xc0000000,%ecx
test   %r8d,%r8d
je     11df <rgb888_to_yuv_2101010+0xdf>
shl    $0x14,%edi
shl    $0xa,%eax
or     %ecx,%edx
jmp    11e7 <rgb888_to_yuv_2101010+0xe7>
shl    $0x14,%edx
or     %ecx,%edx
shl    $0xa,%eax
or     %edi,%edx
or     %eax,%edx
mov    %edx,(%rsi)
pop    %rbx
pop    %rbp
ret

LLVM IR (-O0):
@rgb888_to_yuv_2101010.YKr = internal global i32 0
@rgb888_to_yuv_2101010.YKg = internal global i32 0
@rgb888_to_yuv_2101010.YKb = internal global i32 0
@rgb888_to_yuv_2101010.CrKr = internal global i32 0
@rgb888_to_yuv_2101010.CrKg = internal global i32 0
@rgb888_to_yuv_2101010.CrKb = internal global i32 0
@rgb888_to_yuv_2101010.CbKr = internal global i32 0
@rgb888_to_yuv_2101010.CbKg = internal global i32 0
@rgb888_to_yuv_2101010.CbKb = internal global i32 0
define void @rgb888_to_yuv_2101010(i32 %0, i32* %1, i32 %2, i8 zeroext %3) {
%5 = alloca i32
%6 = alloca i32*
%7 = alloca i32
%8 = alloca i8
%9 = alloca i32
%10 = alloca i32
%11 = alloca i32
%12 = alloca i32
%13 = alloca i32
%14 = alloca i32
%15 = alloca i32
%16 = alloca i32
store i32 %0, i32* %5
store i32* %1, i32** %6
store i32 %2, i32* %7
store i8 %3, i8* %8
store i32 29900, i32* @rgb888_to_yuv_2101010.YKr
store i32 58700, i32* @rgb888_to_yuv_2101010.YKg
store i32 11400, i32* @rgb888_to_yuv_2101010.YKb
store i32 16868, i32* @rgb888_to_yuv_2101010.CbKr
store i32 33107, i32* @rgb888_to_yuv_2101010.CbKg
store i32 49970, i32* @rgb888_to_yuv_2101010.CbKb
store i32 49980, i32* @rgb888_to_yuv_2101010.CrKr
store i32 41850, i32* @rgb888_to_yuv_2101010.CrKg
store i32 8128, i32* @rgb888_to_yuv_2101010.CrKb
%17 = load i32, i32* %5
%18 = and i32 %17, -16777216
%19 = lshr i32 %18, 24
store i32 %19, i32* %9
%20 = load i32, i32* %5
%21 = and i32 %20, 16711680
%22 = lshr i32 %21, 16
store i32 %22, i32* %10
%23 = load i32, i32* %5
%24 = and i32 %23, 65280
%25 = lshr i32 %24, 8
store i32 %25, i32* %11
%26 = load i32, i32* %5
%27 = and i32 %26, 255
%28 = lshr i32 %27, 0
store i32 %28, i32* %12
%29 = load i32, i32* @rgb888_to_yuv_2101010.YKr
%30 = load i32, i32* %10
%31 = and i32 %30, 255
%32 = mul i32 %29, %31
%33 = load i32, i32* @rgb888_to_yuv_2101010.YKg
%34 = load i32, i32* %11
%35 = and i32 %34, 255
%36 = mul i32 %33, %35
%37 = add i32 %32, %36
%38 = load i32, i32* @rgb888_to_yuv_2101010.YKb
%39 = load i32, i32* %12
%40 = and i32 %39, 255
%41 = mul i32 %38, %40
%42 = add i32 %37, %41
%43 = udiv i32 %42, 100000
store i32 %43, i32* %13
%44 = load i32, i32* @rgb888_to_yuv_2101010.CbKr
%45 = sub i32 0, %44
%46 = load i32, i32* %10
%47 = and i32 %46, 255
%48 = mul i32 %45, %47
%49 = load i32, i32* @rgb888_to_yuv_2101010.CbKg
%50 = load i32, i32* %11
%51 = and i32 %50, 255
%52 = mul i32 %49, %51
%53 = sub i32 %48, %52
%54 = load i32, i32* @rgb888_to_yuv_2101010.CbKb
%55 = load i32, i32* %12
%56 = and i32 %55, 255
%57 = mul i32 %54, %56
%58 = add i32 %53, %57
%59 = add i32 %58, 12800000
%60 = udiv i32 %59, 100000
store i32 %60, i32* %14
%61 = load i32, i32* @rgb888_to_yuv_2101010.CrKr
%62 = load i32, i32* %10
%63 = and i32 %62, 255
%64 = mul i32 %61, %63
%65 = load i32, i32* @rgb888_to_yuv_2101010.CrKg
%66 = load i32, i32* %11
%67 = and i32 %66, 255
%68 = mul i32 %65, %67
%69 = sub i32 %64, %68
%70 = load i32, i32* @rgb888_to_yuv_2101010.CrKb
%71 = load i32, i32* %12
%72 = and i32 %71, 255
%73 = mul i32 %70, %72
%74 = sub i32 %69, %73
%75 = add i32 %74, 12800000
%76 = udiv i32 %75, 100000
store i32 %76, i32* %15
%77 = load i32, i32* %13
%78 = mul i32 %77, 1023
%79 = udiv i32 %78, 255
store i32 %79, i32* %13
%80 = load i32, i32* %15
%81 = mul i32 %80, 1023
%82 = udiv i32 %81, 255
store i32 %82, i32* %15
%83 = load i32, i32* %14
%84 = mul i32 %83, 1023
%85 = udiv i32 %84, 255
store i32 %85, i32* %14
%86 = load i8, i8* %8
%87 = icmp ne i8 %86, 0
br i1 %87, label %88, label %99
88: ; preds = %4
%89 = load i32, i32* %9
%90 = shl i32 %89, 30
%91 = load i32, i32* %15
%92 = shl i32 %91, 20
%93 = or i32 %90, %92
%94 = load i32, i32* %14
%95 = shl i32 %94, 10
%96 = or i32 %93, %95
%97 = load i32, i32* %13
%98 = or i32 %96, %97
store i32 %98, i32* %16
br label %110
99: ; preds = %4
%100 = load i32, i32* %9
%101 = shl i32 %100, 30
%102 = load i32, i32* %13
%103 = shl i32 %102, 20
%104 = or i32 %101, %103
%105 = load i32, i32* %14
%106 = shl i32 %105, 10
%107 = or i32 %104, %106
%108 = load i32, i32* %15
%109 = or i32 %107, %108
store i32 %109, i32* %16
br label %110
110: ; preds = %99, %88
%111 = load i32, i32* %16
%112 = load i32*, i32** %6
store i32 %111, i32* %112
ret void
}

LLVM IR (-O2):
define void @rgb888_to_yuv_2101010(i32 %0, i32* nocapture writeonly %1, i32 %2, i8 zeroext %3) {
%5 = lshr i32 %0, 16
%6 = and i32 %5, 255
%7 = lshr i32 %0, 8
%8 = and i32 %7, 255
%9 = and i32 %0, 255
%10 = mul nuw nsw i32 %6, 29900
%11 = mul nuw nsw i32 %8, 58700
%12 = mul nuw nsw i32 %9, 11400
%13 = add nuw nsw i32 %11, %12
%14 = add nuw nsw i32 %13, %10
%15 = udiv i32 %14, 100000
%16 = mul nsw i32 %6, -16868
%17 = mul nsw i32 %8, -33107
%18 = mul nuw nsw i32 %9, 49970
%19 = add nuw nsw i32 %18, 12800000
%20 = add nsw i32 %19, %16
%21 = add nsw i32 %20, %17
%22 = udiv i32 %21, 100000
%23 = mul nuw nsw i32 %6, 49980
%24 = mul nsw i32 %8, -41850
%25 = mul nsw i32 %9, -8128
%26 = add nsw i32 %25, 12800000
%27 = add nuw nsw i32 %26, %23
%28 = add nsw i32 %27, %24
%29 = udiv i32 %28, 100000
%30 = mul nuw nsw i32 %15, 1023
%31 = udiv i32 %30, 255
%32 = mul nuw nsw i32 %29, 1023
%33 = udiv i32 %32, 255
%34 = mul nuw nsw i32 %22, 1023
%35 = udiv i32 %34, 255
%36 = icmp eq i8 %3, 0
%37 = shl i32 %0, 6
%38 = and i32 %37, -1073741824
br i1 %36, label %45, label %39
39: ; preds = %4
%40 = shl nuw nsw i32 %33, 20
%41 = shl nuw nsw i32 %35, 10
%42 = or i32 %31, %38
%43 = or i32 %42, %40
%44 = or i32 %43, %41
br label %51
45: ; preds = %4
%46 = shl nuw nsw i32 %31, 20
%47 = or i32 %46, %38
%48 = shl nuw nsw i32 %35, 10
%49 = or i32 %47, %33
%50 = or i32 %49, %48
br label %51
51: ; preds = %45, %39
%52 = phi i32 [ %44, %39 ], [ %50, %45 ]
store i32 %52, i32* %1
ret void
}