void gfx_rgb2ycbcr(unsigned char r, unsigned char g, unsigned char b,
                   unsigned char *y, unsigned char *cb, unsigned char *cr) {
  *y = (unsigned char)((8432 * (unsigned long)r + 16425 * (unsigned long)g +
                        3176 * (unsigned long)b + 16 * 32768) >>
                       15);
  *cb = (unsigned char)((128 * 32768 + 14345 * (unsigned long)b -
                         4818 * (unsigned long)r - 9527 * (unsigned long)g) >>
                        15);
  *cr = (unsigned char)((128 * 32768 + 14345 * (unsigned long)r -
                         12045 * (unsigned long)g - 2300 * (unsigned long)b) >>
                        15);
}


x86 assembly (clang, -O0):
<gfx_rgb2ycbcr>:
push   %rbp
mov    %rsp,%rbp
mov    %dl,%al
mov    %sil,%dl
mov    %dil,%sil
mov    %sil,-0x1(%rbp)
mov    %dl,-0x2(%rbp)
mov    %al,-0x3(%rbp)
mov    %rcx,-0x10(%rbp)
mov    %r8,-0x18(%rbp)
mov    %r9,-0x20(%rbp)
movzbl -0x1(%rbp),%eax
imul   $0x20f0,%rax,%rax
movzbl -0x2(%rbp),%ecx
imul   $0x4029,%rcx,%rcx
add    %rcx,%rax
movzbl -0x3(%rbp),%ecx
imul   $0xc68,%rcx,%rcx
add    %rcx,%rax
add    $0x80000,%rax
shr    $0xf,%rax
mov    %al,%cl
mov    -0x10(%rbp),%rax
mov    %cl,(%rax)
movzbl -0x3(%rbp),%eax
imul   $0x3809,%rax,%rax
add    $0x400000,%rax
movzbl -0x1(%rbp),%ecx
imul   $0x12d2,%rcx,%rcx
sub    %rcx,%rax
movzbl -0x2(%rbp),%ecx
imul   $0x2537,%rcx,%rcx
sub    %rcx,%rax
shr    $0xf,%rax
mov    %al,%cl
mov    -0x18(%rbp),%rax
mov    %cl,(%rax)
movzbl -0x1(%rbp),%eax
imul   $0x3809,%rax,%rax
add    $0x400000,%rax
movzbl -0x2(%rbp),%ecx
imul   $0x2f0d,%rcx,%rcx
sub    %rcx,%rax
movzbl -0x3(%rbp),%ecx
imul   $0x8fc,%rcx,%rcx
sub    %rcx,%rax
shr    $0xf,%rax
mov    %al,%cl
mov    -0x20(%rbp),%rax
mov    %cl,(%rax)
pop    %rbp
ret

x86 assembly (clang, -O2):
<gfx_rgb2ycbcr>:
imul   $0x20f0,%edi,%r10d
imul   $0x4029,%esi,%r11d
add    %r10d,%r11d
imul   $0xc68,%edx,%eax
add    %r11d,%eax
add    $0x80000,%eax
shr    $0xf,%eax
mov    %al,(%rcx)
imul   $0x3809,%edx,%r10d
imul   $0xffffed2e,%edi,%ecx
imul   $0xffffdac9,%esi,%eax
add    %ecx,%eax
add    %r10d,%eax
add    $0x400000,%eax
shr    $0xf,%eax
mov    %al,(%r8)
imul   $0x3809,%edi,%eax
imul   $0xffffd0f3,%esi,%ecx
add    %eax,%ecx
imul   $0xfffff704,%edx,%eax
add    %ecx,%eax
add    $0x400000,%eax
shr    $0xf,%eax
mov    %al,(%r9)
ret

LLVM IR (-O0):
define void @gfx_rgb2ycbcr(i8 zeroext %0, i8 zeroext %1, i8 zeroext %2, i8* %3, i8* %4, i8* %5) {
%7 = alloca i8
%8 = alloca i8
%9 = alloca i8
%10 = alloca i8*
%11 = alloca i8*
%12 = alloca i8*
store i8 %0, i8* %7
store i8 %1, i8* %8
store i8 %2, i8* %9
store i8* %3, i8** %10
store i8* %4, i8** %11
store i8* %5, i8** %12
%13 = load i8, i8* %7
%14 = zext i8 %13 to i64
%15 = mul i64 8432, %14
%16 = load i8, i8* %8
%17 = zext i8 %16 to i64
%18 = mul i64 16425, %17
%19 = add i64 %15, %18
%20 = load i8, i8* %9
%21 = zext i8 %20 to i64
%22 = mul i64 3176, %21
%23 = add i64 %19, %22
%24 = add i64 %23, 524288
%25 = lshr i64 %24, 15
%26 = trunc i64 %25 to i8
%27 = load i8*, i8** %10
store i8 %26, i8* %27
%28 = load i8, i8* %9
%29 = zext i8 %28 to i64
%30 = mul i64 14345, %29
%31 = add i64 4194304, %30
%32 = load i8, i8* %7
%33 = zext i8 %32 to i64
%34 = mul i64 4818, %33
%35 = sub i64 %31, %34
%36 = load i8, i8* %8
%37 = zext i8 %36 to i64
%38 = mul i64 9527, %37
%39 = sub i64 %35, %38
%40 = lshr i64 %39, 15
%41 = trunc i64 %40 to i8
%42 = load i8*, i8** %11
store i8 %41, i8* %42
%43 = load i8, i8* %7
%44 = zext i8 %43 to i64
%45 = mul i64 14345, %44
%46 = add i64 4194304, %45
%47 = load i8, i8* %8
%48 = zext i8 %47 to i64
%49 = mul i64 12045, %48
%50 = sub i64 %46, %49
%51 = load i8, i8* %9
%52 = zext i8 %51 to i64
%53 = mul i64 2300, %52
%54 = sub i64 %50, %53
%55 = lshr i64 %54, 15
%56 = trunc i64 %55 to i8
%57 = load i8*, i8** %12
store i8 %56, i8* %57
ret void
}

LLVM IR (-O2):
define void @gfx_rgb2ycbcr(i8 zeroext %0, i8 zeroext %1, i8 zeroext %2, i8* nocapture writeonly %3, i8* nocapture writeonly %4, i8* nocapture writeonly %5) {
%7 = zext i8 %0 to i64
%8 = mul nuw nsw i64 %7, 8432
%9 = zext i8 %1 to i64
%10 = mul nuw nsw i64 %9, 16425
%11 = zext i8 %2 to i64
%12 = mul nuw nsw i64 %11, 3176
%13 = add nuw nsw i64 %8, 524288
%14 = add nuw nsw i64 %13, %10
%15 = add nuw nsw i64 %14, %12
%16 = lshr i64 %15, 15
%17 = trunc i64 %16 to i8
store i8 %17, i8* %3
%18 = mul nuw nsw i64 %11, 14345
%19 = mul nsw i64 %7, -4818
%20 = mul nsw i64 %9, -9527
%21 = add nsw i64 %19, 4194304
%22 = add nsw i64 %21, %20
%23 = add nuw nsw i64 %22, %18
%24 = lshr i64 %23, 15
%25 = trunc i64 %24 to i8
store i8 %25, i8* %4
%26 = mul nuw nsw i64 %7, 14345
%27 = or i64 %26, 4194304
%28 = mul nsw i64 %9, -12045
%29 = add nsw i64 %27, %28
%30 = mul nsw i64 %11, -2300
%31 = add nsw i64 %29, %30
%32 = lshr i64 %31, 15
%33 = trunc i64 %32 to i8
store i8 %33, i8* %5
ret void
}