void rgb_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 & 0xC000000) >> 30;
  R = (rgb1 & 0x3FF00000) >> 20;
  G = (rgb1 & 0x000FFC00) >> 10;
  B = (rgb1 & 0x000003FF) >> 0;
  Y = (((YKr * (R & 0x3FF)) + (YKg * (G & 0x3FF)) + (YKb * (B & 0x3FF))) /
       100000);
  Cb = (((-CbKr * (R & 0x3FF)) - (CbKg * (G & 0x3FF)) + (CbKb * (B & 0x3FF)) +
         51200000) /
        100000);
  Cr = (((CrKr * (R & 0x3FF)) - (CrKg * (G & 0x3FF)) - (CrKb * (B & 0x3FF)) +
         51200000) /
        100000);
  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):
<rgb_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    $0xc000000,%eax
shr    $0x1e,%eax
mov    %eax,-0x1c(%rbp)
mov    -0x4(%rbp),%eax
and    $0x3ff00000,%eax
shr    $0x14,%eax
mov    %eax,-0x20(%rbp)
mov    -0x4(%rbp),%eax
and    $0xffc00,%eax
shr    $0xa,%eax
mov    %eax,-0x24(%rbp)
mov    -0x4(%rbp),%eax
and    $0x3ff,%eax
shr    $0x0,%eax
mov    %eax,-0x28(%rbp)
mov    0x2e79(%rip),%eax
mov    -0x20(%rbp),%ecx
and    $0x3ff,%ecx
imul   %ecx,%eax
mov    0x2e6b(%rip),%ecx
mov    -0x24(%rbp),%edx
and    $0x3ff,%edx
imul   %edx,%ecx
add    %ecx,%eax
mov    0x2e5b(%rip),%ecx
mov    -0x28(%rbp),%edx
and    $0x3ff,%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    $0x3ff,%ecx
imul   %ecx,%eax
mov    0x2e3b(%rip),%ecx
mov    -0x24(%rbp),%edx
and    $0x3ff,%edx
imul   %edx,%ecx
sub    %ecx,%eax
mov    0x2e2b(%rip),%ecx
mov    -0x28(%rbp),%edx
and    $0x3ff,%edx
imul   %edx,%ecx
add    %ecx,%eax
add    $0x30d4000,%eax
mov    $0x186a0,%ecx
xor    %edx,%edx
div    %ecx
mov    %eax,-0x30(%rbp)
mov    0x2df2(%rip),%eax
mov    -0x20(%rbp),%ecx
and    $0x3ff,%ecx
imul   %ecx,%eax
mov    0x2de4(%rip),%ecx
mov    -0x24(%rbp),%edx
and    $0x3ff,%edx
imul   %edx,%ecx
sub    %ecx,%eax
mov    0x2dd4(%rip),%ecx
mov    -0x28(%rbp),%edx
and    $0x3ff,%edx
imul   %edx,%ecx
sub    %ecx,%eax
add    $0x30d4000,%eax
mov    $0x186a0,%ecx
xor    %edx,%edx
div    %ecx
mov    %eax,-0x34(%rbp)
cmpb   $0x0,-0x15(%rbp)
je     12ae <rgb_to_yuv_2101010+0x1ae>
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    12ca <rgb_to_yuv_2101010+0x1ca>
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):
<rgb_to_yuv_2101010>:
mov    %edi,%r9d
shr    $0x14,%r9d
and    $0x3ff,%r9d
mov    %edi,%eax
shr    $0xa,%eax
and    $0x3ff,%eax
and    $0x3ff,%edi
imul   $0x74cc,%r9d,%r8d
imul   $0xe54c,%eax,%r10d
imul   $0x2c88,%edi,%edx
add    %r10d,%edx
add    %r8d,%edx
shr    $0x5,%edx
imul   $0xa7c5ac5,%rdx,%r8
shr    $0x27,%r8
imul   $0xffffbe1c,%r9d,%r11d
imul   $0xffff7ead,%eax,%r10d
imul   $0xc332,%edi,%edx
add    %r11d,%edx
add    %r10d,%edx
add    $0x30d4000,%edx
shr    $0x5,%edx
imul   $0xa7c5ac5,%rdx,%rdx
shr    $0x20,%rdx
shl    $0x3,%edx
and    $0x3fffc00,%edx
imul   $0xc33c,%r9d,%r9d
imul   $0xffff5c86,%eax,%eax
imul   $0xffffe040,%edi,%edi
add    %r9d,%edi
add    %edi,%eax
add    $0x30d4000,%eax
shr    $0x5,%eax
imul   $0xa7c5ac5,%rax,%r9
shr    $0x27,%r9
mov    %r9d,%edi
shl    $0x14,%edi
or     %r8d,%edi
mov    %r8d,%eax
shl    $0x14,%eax
or     %r9d,%eax
or     %edx,%eax
or     %edx,%edi
test   %ecx,%ecx
cmove  %eax,%edi
mov    %edi,(%rsi)
ret

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

LLVM IR (-O2):
define void @rgb_to_yuv_2101010(i32 %0, i32* nocapture writeonly %1, i32 %2, i8 zeroext %3) {
%5 = lshr i32 %0, 20
%6 = and i32 %5, 1023
%7 = lshr i32 %0, 10
%8 = and i32 %7, 1023
%9 = and i32 %0, 1023
%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, 51200000
%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, 51200000
%27 = add nuw nsw i32 %26, %23
%28 = add nsw i32 %27, %24
%29 = udiv i32 %28, 100000
%30 = icmp eq i8 %3, 0
%31 = shl nuw nsw i32 %15, 20
%32 = shl nuw nsw i32 %22, 10
%33 = shl nuw nsw i32 %29, 20
%34 = shl nuw nsw i32 %22, 10
%35 = or i32 %29, %31
%36 = or i32 %34, %15
%37 = or i32 %35, %32
%38 = or i32 %36, %33
%39 = select i1 %30, i32 %37, i32 %38
store i32 %39, i32* %1
ret void
}