unsigned short VIM_HAPI_RGB565toYUV422(unsigned char *pRGB, unsigned char *pYUV,
                                       unsigned short Width,
                                       unsigned short Height) {
  unsigned short i, j;
  unsigned char v0;
  unsigned char r, g, b;
  for (i = 0; i < Height; i++) {
    for (j = 0; j < Width; j++) {
      b = (((*pRGB) & 0x1f) << 3);
      g = ((*(pRGB + 1) & 0x7) << 5) | ((*(pRGB)&0xe0) >> 3);
      pRGB++;
      r = ((*pRGB) & 0xf8);
      pRGB++;
      if (!(j % 2)) {
        *pYUV = (-43 * r - 85 * g + 128 * b) / 256 + 128;
        pYUV++;
        v0 = (128 * r - 107 * g - 21 * b) / 256 + 128;
      } else {
        *pYUV = v0;
        pYUV++;
      }
      *pYUV = (77 * r + 150 * g + 29 * b) / 256;
      pYUV++;
    }
  }
  return 0;
}


x86 assembly (clang, -O0):
<VIM_HAPI_RGB565toYUV422>:
push   %rbp
mov    %rsp,%rbp
mov    %cx,%ax
mov    %dx,%cx
mov    %rdi,-0x8(%rbp)
mov    %rsi,-0x10(%rbp)
mov    %cx,-0x12(%rbp)
mov    %ax,-0x14(%rbp)
movw   $0x0,-0x16(%rbp)
movzwl -0x16(%rbp),%eax
movzwl -0x14(%rbp),%ecx
cmp    %ecx,%eax
jge    1294 <VIM_HAPI_RGB565toYUV422+0x194>
movw   $0x0,-0x18(%rbp)
movzwl -0x18(%rbp),%eax
movzwl -0x12(%rbp),%ecx
cmp    %ecx,%eax
jge    127e <VIM_HAPI_RGB565toYUV422+0x17e>
mov    -0x8(%rbp),%rax
movzbl (%rax),%eax
and    $0x1f,%eax
shl    $0x3,%eax
mov    %al,-0x1c(%rbp)
mov    -0x8(%rbp),%rax
movzbl 0x1(%rax),%eax
and    $0x7,%eax
shl    $0x5,%eax
mov    -0x8(%rbp),%rcx
movzbl (%rcx),%ecx
and    $0xe0,%ecx
sar    $0x3,%ecx
or     %ecx,%eax
mov    %al,-0x1b(%rbp)
mov    -0x8(%rbp),%rax
add    $0x1,%rax
mov    %rax,-0x8(%rbp)
mov    -0x8(%rbp),%rax
movzbl (%rax),%eax
and    $0xf8,%eax
mov    %al,-0x1a(%rbp)
mov    -0x8(%rbp),%rax
add    $0x1,%rax
mov    %rax,-0x8(%rbp)
movzwl -0x18(%rbp),%eax
mov    $0x2,%ecx
cltd
idiv   %ecx
cmp    $0x0,%edx
jne    1220 <VIM_HAPI_RGB565toYUV422+0x120>
movzbl -0x1a(%rbp),%eax
imul   $0xffffffd5,%eax,%eax
movzbl -0x1b(%rbp),%ecx
imul   $0x55,%ecx,%ecx
sub    %ecx,%eax
movzbl -0x1c(%rbp),%ecx
shl    $0x7,%ecx
add    %ecx,%eax
mov    $0x100,%ecx
cltd
idiv   %ecx
add    $0x80,%eax
mov    %al,%cl
mov    -0x10(%rbp),%rax
mov    %cl,(%rax)
mov    -0x10(%rbp),%rax
add    $0x1,%rax
mov    %rax,-0x10(%rbp)
movzbl -0x1a(%rbp),%eax
shl    $0x7,%eax
movzbl -0x1b(%rbp),%ecx
imul   $0x6b,%ecx,%ecx
sub    %ecx,%eax
movzbl -0x1c(%rbp),%ecx
imul   $0x15,%ecx,%ecx
sub    %ecx,%eax
mov    $0x100,%ecx
cltd
idiv   %ecx
add    $0x80,%eax
mov    %al,-0x19(%rbp)
jmp    1235 <VIM_HAPI_RGB565toYUV422+0x135>
mov    -0x19(%rbp),%cl
mov    -0x10(%rbp),%rax
mov    %cl,(%rax)
mov    -0x10(%rbp),%rax
add    $0x1,%rax
mov    %rax,-0x10(%rbp)
movzbl -0x1a(%rbp),%eax
imul   $0x4d,%eax,%eax
movzbl -0x1b(%rbp),%ecx
imul   $0x96,%ecx,%ecx
add    %ecx,%eax
movzbl -0x1c(%rbp),%ecx
imul   $0x1d,%ecx,%ecx
add    %ecx,%eax
mov    $0x100,%ecx
cltd
idiv   %ecx
mov    %al,%cl
mov    -0x10(%rbp),%rax
mov    %cl,(%rax)
mov    -0x10(%rbp),%rax
add    $0x1,%rax
mov    %rax,-0x10(%rbp)
mov    -0x18(%rbp),%ax
add    $0x1,%ax
mov    %ax,-0x18(%rbp)
jmp    1136 <VIM_HAPI_RGB565toYUV422+0x36>
jmp    1283 <VIM_HAPI_RGB565toYUV422+0x183>
mov    -0x16(%rbp),%ax
add    $0x1,%ax
mov    %ax,-0x16(%rbp)
jmp    1120 <VIM_HAPI_RGB565toYUV422+0x20>
xor    %eax,%eax
movzwl %ax,%eax
pop    %rbp
ret

x86 assembly (clang, -O2):
<VIM_HAPI_RGB565toYUV422>:
push   %rbp
push   %r15
push   %r14
push   %r13
push   %r12
push   %rbx
test   %ecx,%ecx
je     1213 <VIM_HAPI_RGB565toYUV422+0x113>
movzwl %dx,%r9d
xor    %r8d,%r8d
jmp    1134 <VIM_HAPI_RGB565toYUV422+0x34>
nopl   0x0(%rax,%rax,1)
sub    %r11,%rdi
sub    %r11,%rsi
add    $0x1,%r8d
cmp    %cx,%r8w
je     1213 <VIM_HAPI_RGB565toYUV422+0x113>
test   %dx,%dx
je     1126 <VIM_HAPI_RGB565toYUV422+0x26>
xor    %r11d,%r11d
xor    %ebx,%ebx
jmp    117f <VIM_HAPI_RGB565toYUV422+0x7f>
mov    %r10b,(%rsi,%rbx,2)
movzbl %r12b,%r12d
movzbl %al,%r15d
movzbl %r14b,%r14d
imul   $0x4d,%r12d,%ebp
imul   $0x96,%r15d,%r15d
lea    (%r14,%r14,8),%eax
lea    (%rax,%rax,2),%eax
add    %r14d,%eax
add    %r14d,%eax
add    %ebp,%eax
add    %r15d,%eax
mov    %ah,0x1(%rsi,%rbx,2)
add    $0x1,%rbx
add    $0xfffffffffffffffe,%r11
cmp    %bx,%r9w
je     1120 <VIM_HAPI_RGB565toYUV422+0x20>
movzbl (%rdi,%rbx,2),%ebp
lea    0x0(,%rbp,8),%r14d
movzbl 0x1(%rdi,%rbx,2),%r12d
shr    $0x3,%bpl
mov    %r12d,%eax
shl    $0x5,%al
or     %bpl,%al
and    $0xfc,%al
and    $0xfffffff8,%r12d
test   $0x1,%bl
jne    1140 <VIM_HAPI_RGB565toYUV422+0x40>
imul   $0xffffffd5,%r12d,%r10d
movzbl %al,%r15d
imul   $0xffffffab,%r15d,%r13d
movzbl %r14b,%r14d
mov    %r14d,%ebp
shl    $0x7,%ebp
add    %r10d,%ebp
lea    0x0(%rbp,%r13,1),%eax
add    %r13d,%ebp
add    $0xff,%ebp
test   %ax,%ax
cmovns %eax,%ebp
shr    $0x8,%ebp
xor    $0x80,%bpl
mov    %bpl,(%rsi,%rbx,2)
mov    %r12d,%eax
shl    $0x7,%eax
imul   $0xffffff95,%r15d,%r10d
imul   $0xffffffeb,%r14d,%ebp
add    %eax,%ebp
lea    (%r10,%rbp,1),%eax
add    %ebp,%r10d
add    $0xff,%r10d
test   %ax,%ax
cmovns %eax,%r10d
shr    $0x8,%r10d
xor    $0x80,%r10b
jmp    1150 <VIM_HAPI_RGB565toYUV422+0x50>
xor    %eax,%eax
pop    %rbx
pop    %r12
pop    %r13
pop    %r14
pop    %r15
pop    %rbp
ret

LLVM IR (-O0):
define zeroext i16 @VIM_HAPI_RGB565toYUV422(i8* %0, i8* %1, i16 zeroext %2, i16 zeroext %3) {
%5 = alloca i8*
%6 = alloca i8*
%7 = alloca i16
%8 = alloca i16
%9 = alloca i16
%10 = alloca i16
%11 = alloca i8
%12 = alloca i8
%13 = alloca i8
%14 = alloca i8
store i8* %0, i8** %5
store i8* %1, i8** %6
store i16 %2, i16* %7
store i16 %3, i16* %8
store i16 0, i16* %9
br label %15
15: ; preds = %119, %4
%16 = load i16, i16* %9
%17 = zext i16 %16 to i32
%18 = load i16, i16* %8
%19 = zext i16 %18 to i32
%20 = icmp slt i32 %17, %19
br i1 %20, label %21, label %122
21: ; preds = %15
store i16 0, i16* %10
br label %22
22: ; preds = %115, %21
%23 = load i16, i16* %10
%24 = zext i16 %23 to i32
%25 = load i16, i16* %7
%26 = zext i16 %25 to i32
%27 = icmp slt i32 %24, %26
br i1 %27, label %28, label %118
28: ; preds = %22
%29 = load i8*, i8** %5
%30 = load i8, i8* %29
%31 = zext i8 %30 to i32
%32 = and i32 %31, 31
%33 = shl i32 %32, 3
%34 = trunc i32 %33 to i8
store i8 %34, i8* %14
%35 = load i8*, i8** %5
%36 = getelementptr inbounds i8, i8* %35, i64 1
%37 = load i8, i8* %36
%38 = zext i8 %37 to i32
%39 = and i32 %38, 7
%40 = shl i32 %39, 5
%41 = load i8*, i8** %5
%42 = load i8, i8* %41
%43 = zext i8 %42 to i32
%44 = and i32 %43, 224
%45 = ashr i32 %44, 3
%46 = or i32 %40, %45
%47 = trunc i32 %46 to i8
store i8 %47, i8* %13
%48 = load i8*, i8** %5
%49 = getelementptr inbounds i8, i8* %48, i32 1
store i8* %49, i8** %5
%50 = load i8*, i8** %5
%51 = load i8, i8* %50
%52 = zext i8 %51 to i32
%53 = and i32 %52, 248
%54 = trunc i32 %53 to i8
store i8 %54, i8* %12
%55 = load i8*, i8** %5
%56 = getelementptr inbounds i8, i8* %55, i32 1
store i8* %56, i8** %5
%57 = load i16, i16* %10
%58 = zext i16 %57 to i32
%59 = srem i32 %58, 2
%60 = icmp ne i32 %59, 0
br i1 %60, label %93, label %61
61: ; preds = %28
%62 = load i8, i8* %12
%63 = zext i8 %62 to i32
%64 = mul nsw i32 -43, %63
%65 = load i8, i8* %13
%66 = zext i8 %65 to i32
%67 = mul nsw i32 85, %66
%68 = sub nsw i32 %64, %67
%69 = load i8, i8* %14
%70 = zext i8 %69 to i32
%71 = mul nsw i32 128, %70
%72 = add nsw i32 %68, %71
%73 = sdiv i32 %72, 256
%74 = add nsw i32 %73, 128
%75 = trunc i32 %74 to i8
%76 = load i8*, i8** %6
store i8 %75, i8* %76
%77 = load i8*, i8** %6
%78 = getelementptr inbounds i8, i8* %77, i32 1
store i8* %78, i8** %6
%79 = load i8, i8* %12
%80 = zext i8 %79 to i32
%81 = mul nsw i32 128, %80
%82 = load i8, i8* %13
%83 = zext i8 %82 to i32
%84 = mul nsw i32 107, %83
%85 = sub nsw i32 %81, %84
%86 = load i8, i8* %14
%87 = zext i8 %86 to i32
%88 = mul nsw i32 21, %87
%89 = sub nsw i32 %85, %88
%90 = sdiv i32 %89, 256
%91 = add nsw i32 %90, 128
%92 = trunc i32 %91 to i8
store i8 %92, i8* %11
br label %98
93: ; preds = %28
%94 = load i8, i8* %11
%95 = load i8*, i8** %6
store i8 %94, i8* %95
%96 = load i8*, i8** %6
%97 = getelementptr inbounds i8, i8* %96, i32 1
store i8* %97, i8** %6
br label %98
98: ; preds = %93, %61
%99 = load i8, i8* %12
%100 = zext i8 %99 to i32
%101 = mul nsw i32 77, %100
%102 = load i8, i8* %13
%103 = zext i8 %102 to i32
%104 = mul nsw i32 150, %103
%105 = add nsw i32 %101, %104
%106 = load i8, i8* %14
%107 = zext i8 %106 to i32
%108 = mul nsw i32 29, %107
%109 = add nsw i32 %105, %108
%110 = sdiv i32 %109, 256
%111 = trunc i32 %110 to i8
%112 = load i8*, i8** %6
store i8 %111, i8* %112
%113 = load i8*, i8** %6
%114 = getelementptr inbounds i8, i8* %113, i32 1
store i8* %114, i8** %6
br label %115
115: ; preds = %98
%116 = load i16, i16* %10
%117 = add i16 %116, 1
store i16 %117, i16* %10
br label %22
118: ; preds = %22
br label %119
119: ; preds = %118
%120 = load i16, i16* %9
%121 = add i16 %120, 1
store i16 %121, i16* %9
br label %15
122: ; preds = %15
ret i16 0
}

LLVM IR (-O2):
define zeroext i16 @VIM_HAPI_RGB565toYUV422(i8* nocapture %0, i8* nocapture writeonly %1, i16 zeroext %2, i16 zeroext %3) {
%5 = icmp eq i16 %3, 0
br i1 %5, label %78, label %6
6: ; preds = %4
%7 = icmp eq i16 %2, 0
br label %8
8: ; preds = %6, %72
%9 = phi i8* [ %0, %6 ], [ %75, %72 ]
%10 = phi i8* [ %1, %6 ], [ %74, %72 ]
%11 = phi i16 [ 0, %6 ], [ %76, %72 ]
%12 = phi i8 [ undef, %6 ], [ %73, %72 ]
br i1 %7, label %72, label %13
13: ; preds = %8, %56
%14 = phi i8* [ %27, %56 ], [ %9, %8 ]
%15 = phi i8* [ %69, %56 ], [ %10, %8 ]
%16 = phi i8 [ %60, %56 ], [ %12, %8 ]
%17 = phi i16 [ %70, %56 ], [ 0, %8 ]
%18 = load i8, i8* %14
%19 = shl i8 %18, 3
%20 = getelementptr inbounds i8, i8* %14, i64 1
%21 = load i8, i8* %20
%22 = shl i8 %21, 5
%23 = lshr i8 %18, 3
%24 = and i8 %23, 28
%25 = or i8 %22, %24
%26 = and i8 %21, -8
%27 = getelementptr inbounds i8, i8* %14, i64 2
%28 = and i16 %17, 1
%29 = icmp eq i16 %28, 0
br i1 %29, label %30, label %52
30: ; preds = %13
%31 = zext i8 %26 to i32
%32 = mul nsw i32 %31, -43
%33 = zext i8 %25 to i32
%34 = mul nsw i32 %33, -85
%35 = zext i8 %19 to i32
%36 = shl nuw nsw i32 %35, 7
%37 = add nsw i32 %32, %36
%38 = add nsw i32 %37, %34
%39 = trunc i32 %38 to i16
%40 = sdiv i16 %39, 256
%41 = trunc i16 %40 to i8
%42 = xor i8 %41, -128
store i8 %42, i8* %15
%43 = shl nuw nsw i32 %31, 7
%44 = mul nsw i32 %33, -107
%45 = mul nsw i32 %35, -21
%46 = add nsw i32 %43, %45
%47 = add nsw i32 %46, %44
%48 = trunc i32 %47 to i16
%49 = sdiv i16 %48, 256
%50 = trunc i16 %49 to i8
%51 = xor i8 %50, -128
br label %56
52: ; preds = %13
store i8 %16, i8* %15
%53 = zext i8 %26 to i32
%54 = zext i8 %25 to i32
%55 = zext i8 %19 to i32
br label %56
56: ; preds = %52, %30
%57 = phi i32 [ %55, %52 ], [ %35, %30 ]
%58 = phi i32 [ %54, %52 ], [ %33, %30 ]
%59 = phi i32 [ %53, %52 ], [ %31, %30 ]
%60 = phi i8 [ %16, %52 ], [ %51, %30 ]
%61 = getelementptr inbounds i8, i8* %15, i64 1
%62 = mul nuw nsw i32 %59, 77
%63 = mul nuw nsw i32 %58, 150
%64 = mul nuw nsw i32 %57, 29
%65 = add nuw nsw i32 %62, %64
%66 = add nuw nsw i32 %65, %63
%67 = lshr i32 %66, 8
%68 = trunc i32 %67 to i8
store i8 %68, i8* %61
%69 = getelementptr inbounds i8, i8* %15, i64 2
%70 = add nuw i16 %17, 1
%71 = icmp eq i16 %70, %2
br i1 %71, label %72, label %13
72: ; preds = %56, %8
%73 = phi i8 [ %12, %8 ], [ %60, %56 ]
%74 = phi i8* [ %10, %8 ], [ %69, %56 ]
%75 = phi i8* [ %9, %8 ], [ %27, %56 ]
%76 = add nuw i16 %11, 1
%77 = icmp eq i16 %76, %3
br i1 %77, label %78, label %8
78: ; preds = %72, %4
ret i16 0
}