int nv12_border(char *pic, int pic_w, int pic_h, int rect_x, int rect_y,
                int rect_w, int rect_h, int R, int G, int B) {
  const int border = 5;
  int Y, U, V;
  Y = 0.299 * R + 0.587 * G + 0.114 * B;
  U = -0.1687 * R + 0.3313 * G + 0.5 * B + 128;
  V = 0.5 * R - 0.4187 * G - 0.0813 * B + 128;
  printf("%d %d %d\n", Y, U, V);
  int j, k;
  for (j = rect_y; j < rect_y + rect_h; j++) {
    for (k = rect_x; k < rect_x + rect_w; k++) {
      if (k < (rect_x + border) || k > (rect_x + rect_w - border) ||
          j < (rect_y + border) || j > (rect_y + rect_h - border)) {
        int y_index = j * pic_w + k;
        int u_index =
            (y_index / 2 - pic_w / 2 * ((j + 1) / 2)) * 2 + pic_w * pic_h;
        int v_index = u_index + 1;
        pic[y_index] = Y;
        pic[u_index] = U;
        pic[v_index] = V;
      }
    }
  }
  return 0;
}


x86 assembly (clang, -O0):
<nv12_border>:
push   %rbp
mov    %rsp,%rbp
sub    $0x50,%rsp
mov    0x28(%rbp),%eax
mov    0x20(%rbp),%eax
mov    0x18(%rbp),%eax
mov    0x10(%rbp),%eax
mov    %rdi,-0x8(%rbp)
mov    %esi,-0xc(%rbp)
mov    %edx,-0x10(%rbp)
mov    %ecx,-0x14(%rbp)
mov    %r8d,-0x18(%rbp)
mov    %r9d,-0x1c(%rbp)
movl   $0x5,-0x20(%rbp)
cvtsi2sdl 0x18(%rbp),%xmm1
cvtsi2sdl 0x20(%rbp),%xmm2
movsd  0xeee(%rip),%xmm0
mulsd  %xmm2,%xmm0
movsd  0xeda(%rip),%xmm2
mulsd  %xmm2,%xmm1
addsd  %xmm0,%xmm1
cvtsi2sdl 0x28(%rbp),%xmm0
movsd  0xebd(%rip),%xmm2
mulsd  %xmm2,%xmm0
addsd  %xmm1,%xmm0
cvttsd2si %xmm0,%eax
mov    %eax,-0x24(%rbp)
cvtsi2sdl 0x18(%rbp),%xmm1
cvtsi2sdl 0x20(%rbp),%xmm2
movsd  0xe94(%rip),%xmm0
mulsd  %xmm2,%xmm0
movsd  0xe80(%rip),%xmm2
mulsd  %xmm2,%xmm1
addsd  %xmm0,%xmm1
cvtsi2sdl 0x28(%rbp),%xmm0
movsd  0xe5b(%rip),%xmm2
mulsd  %xmm2,%xmm0
addsd  %xmm1,%xmm0
movsd  0xe3b(%rip),%xmm1
addsd  %xmm1,%xmm0
cvttsd2si %xmm0,%eax
mov    %eax,-0x28(%rbp)
cvtsi2sdl 0x18(%rbp),%xmm1
cvtsi2sdl 0x20(%rbp),%xmm2
movsd  0xe36(%rip),%xmm0
mulsd  %xmm2,%xmm0
movq   %xmm0,%rax
movabs $0x8000000000000000,%rcx
xor    %rcx,%rax
movq   %rax,%xmm0
movsd  0xe0b(%rip),%xmm2
mulsd  %xmm2,%xmm1
addsd  %xmm0,%xmm1
cvtsi2sdl 0x28(%rbp),%xmm0
movsd  0xdee(%rip),%xmm2
mulsd  %xmm2,%xmm0
addsd  %xmm1,%xmm0
movsd  0xdd6(%rip),%xmm1
addsd  %xmm1,%xmm0
cvttsd2si %xmm0,%eax
mov    %eax,-0x2c(%rbp)
mov    -0x24(%rbp),%esi
mov    -0x28(%rbp),%edx
mov    -0x2c(%rbp),%ecx
lea    0xe03(%rip),%rdi
mov    $0x0,%al
call   1030 <printf@plt>
mov    -0x18(%rbp),%eax
mov    %eax,-0x30(%rbp)
mov    -0x30(%rbp),%eax
mov    -0x18(%rbp),%ecx
add    0x10(%rbp),%ecx
cmp    %ecx,%eax
jge    1372 <nv12_border+0x262>
mov    -0x14(%rbp),%eax
mov    %eax,-0x34(%rbp)
mov    -0x34(%rbp),%eax
mov    -0x14(%rbp),%ecx
add    -0x1c(%rbp),%ecx
cmp    %ecx,%eax
jge    135f <nv12_border+0x24f>
mov    -0x34(%rbp),%eax
mov    -0x14(%rbp),%ecx
add    $0x5,%ecx
cmp    %ecx,%eax
jl     12c4 <nv12_border+0x1b4>
mov    -0x34(%rbp),%eax
mov    -0x14(%rbp),%ecx
add    -0x1c(%rbp),%ecx
sub    $0x5,%ecx
cmp    %ecx,%eax
jg     12c4 <nv12_border+0x1b4>
mov    -0x30(%rbp),%eax
mov    -0x18(%rbp),%ecx
add    $0x5,%ecx
cmp    %ecx,%eax
jl     12c4 <nv12_border+0x1b4>
mov    -0x30(%rbp),%eax
mov    -0x18(%rbp),%ecx
add    0x10(%rbp),%ecx
sub    $0x5,%ecx
cmp    %ecx,%eax
jle    134c <nv12_border+0x23c>
mov    -0x30(%rbp),%eax
imul   -0xc(%rbp),%eax
add    -0x34(%rbp),%eax
mov    %eax,-0x38(%rbp)
mov    -0x38(%rbp),%eax
mov    $0x2,%ecx
cltd
idiv   %ecx
mov    %eax,-0x44(%rbp)
mov    -0xc(%rbp),%eax
mov    $0x2,%ecx
cltd
idiv   %ecx
mov    %eax,%ecx
mov    -0x30(%rbp),%eax
add    $0x1,%eax
mov    $0x2,%esi
cltd
idiv   %esi
mov    %eax,%edx
mov    -0x44(%rbp),%eax
imul   %edx,%ecx
sub    %ecx,%eax
shl    $0x1,%eax
mov    -0xc(%rbp),%ecx
imul   -0x10(%rbp),%ecx
add    %ecx,%eax
mov    %eax,-0x3c(%rbp)
mov    -0x3c(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x40(%rbp)
mov    -0x24(%rbp),%eax
mov    %al,%dl
mov    -0x8(%rbp),%rax
movslq -0x38(%rbp),%rcx
mov    %dl,(%rax,%rcx,1)
mov    -0x28(%rbp),%eax
mov    %al,%dl
mov    -0x8(%rbp),%rax
movslq -0x3c(%rbp),%rcx
mov    %dl,(%rax,%rcx,1)
mov    -0x2c(%rbp),%eax
mov    %al,%dl
mov    -0x8(%rbp),%rax
movslq -0x40(%rbp),%rcx
mov    %dl,(%rax,%rcx,1)
jmp    1351 <nv12_border+0x241>
mov    -0x34(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x34(%rbp)
jmp    1269 <nv12_border+0x159>
jmp    1364 <nv12_border+0x254>
mov    -0x30(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x30(%rbp)
jmp    1252 <nv12_border+0x142>
xor    %eax,%eax
add    $0x50,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<nv12_border>:
push   %rbp
push   %r15
push   %r14
push   %r13
push   %r12
push   %rbx
sub    $0x48,%rsp
mov    %r9,0x20(%rsp)
mov    %r8d,%r14d
mov    %rcx,0x18(%rsp)
mov    %rdx,(%rsp)
mov    %esi,%r12d
mov    %rdi,%r13
mov    0x80(%rsp),%ebx
cvtsi2sdl 0x88(%rsp),%xmm0
cvtsi2sdl 0x90(%rsp),%xmm1
movsd  0xeaa(%rip),%xmm3
mulsd  %xmm1,%xmm3
movsd  0xea6(%rip),%xmm4
mulsd  %xmm0,%xmm4
cvtsi2sdl 0x98(%rsp),%xmm2
addsd  %xmm3,%xmm4
movsd  0xe95(%rip),%xmm3
mulsd  %xmm2,%xmm3
addsd  %xmm4,%xmm3
cvttsd2si %xmm3,%esi
movsd  0xe89(%rip),%xmm3
mulsd  %xmm1,%xmm3
movsd  0xe85(%rip),%xmm4
mulsd  %xmm0,%xmm4
addsd  %xmm3,%xmm4
movsd  0xe7d(%rip),%xmm3
movapd %xmm2,%xmm5
mulsd  %xmm3,%xmm5
addsd  %xmm4,%xmm5
movsd  0xe71(%rip),%xmm4
addsd  %xmm4,%xmm5
cvttsd2si %xmm5,%edx
mulsd  0xe69(%rip),%xmm1
mulsd  %xmm3,%xmm0
addsd  %xmm1,%xmm0
mulsd  0xe61(%rip),%xmm2
addsd  %xmm0,%xmm2
addsd  %xmm4,%xmm2
cvttsd2si %xmm2,%ecx
lea    0xe56(%rip),%rdi
mov    %esi,0x14(%rsp)
mov    %edx,0x10(%rsp)
mov    %ecx,%r15d
xor    %eax,%eax
call   1030 <printf@plt>
test   %ebx,%ebx
jle    1352 <nv12_border+0x242>
add    %r14d,%ebx
mov    0x20(%rsp),%rax
mov    0x18(%rsp),%rsi
lea    (%rax,%rsi,1),%edi
lea    0x5(%rsi),%ecx
lea    -0x5(%rax,%rsi,1),%edx
lea    0x5(%r14),%ebp
lea    -0x5(%rbx),%eax
mov    %rbx,%r8
mov    %r12d,%ebx
shr    $0x1f,%ebx
add    %r12d,%ebx
sar    %ebx
mov    %ebx,0xc(%rsp)
mov    (%rsp),%rbx
imul   %r12d,%ebx
mov    %rbx,(%rsp)
movslq %esi,%rsi
mov    %rsi,0x30(%rsp)
movslq %edx,%rdx
movslq %ecx,%rsi
movslq %edi,%rdi
movslq %r14d,%rcx
movslq %eax,%r14
movslq %ebp,%rbp
movslq %r12d,%rax
mov    %rax,0x28(%rsp)
movslq %r8d,%rax
mov    %rax,0x38(%rsp)
jmp    1293 <nv12_border+0x183>
cs nopw 0x0(%rax,%rax,1)
xchg   %ax,%ax
mov    0x40(%rsp),%rax
mov    %rax,%rcx
cmp    0x38(%rsp),%rax
jge    1352 <nv12_border+0x242>
cmpl   $0x0,0x20(%rsp)
jle    1340 <nv12_border+0x230>
mov    %rcx,%r9
mov    0x28(%rsp),%rax
imul   %rax,%r9
lea    0x1(%rcx),%rbx
mov    %ebx,%r11d
shr    $0x1f,%r11d
add    %ebx,%r11d
sar    %r11d
neg    %r11d
imul   0xc(%rsp),%r11d
mov    %rbx,0x40(%rsp)
lea    -0x1(%rbx),%r10d
imul   %eax,%r10d
add    0x18(%rsp),%r10d
add    %r13,%r9
mov    0x30(%rsp),%r8
jmp    1322 <nv12_border+0x212>
mov    %r10d,%r12d
shr    $0x1f,%r12d
add    %r10d,%r12d
shr    %r12d
add    %r11d,%r12d
mov    (%rsp),%rbx
lea    (%rbx,%r12,2),%ebx
movslq %ebx,%rbx
mov    0x14(%rsp),%eax
mov    %al,(%r9,%r8,1)
mov    0x10(%rsp),%eax
mov    %al,0x0(%r13,%rbx,1)
mov    %r15b,0x1(%r13,%rbx,1)
add    $0x1,%r8
add    $0x1,%r10d
cmp    %rdi,%r8
jge    1280 <nv12_border+0x170>
cmp    %rsi,%r8
jl     12e0 <nv12_border+0x1d0>
cmp    %rdx,%r8
jg     12e0 <nv12_border+0x1d0>
cmp    %rbp,%rcx
jl     12e0 <nv12_border+0x1d0>
cmp    %r14,%rcx
jle    1311 <nv12_border+0x201>
jmp    12e0 <nv12_border+0x1d0>
nopl   0x0(%rax,%rax,1)
add    $0x1,%rcx
mov    %rcx,%rax
cmp    0x38(%rsp),%rax
jl     1293 <nv12_border+0x183>
xor    %eax,%eax
add    $0x48,%rsp
pop    %rbx
pop    %r12
pop    %r13
pop    %r14
pop    %r15
pop    %rbp
ret

LLVM IR (-O0):
@.str = [10 x i8] c"%d %d %d\0A\00"
define i32 @nv12_border(i8* %0, i32 %1, i32 %2, i32 %3, i32 %4, i32 %5, i32 %6, i32 %7, i32 %8, i32 %9) {
%11 = alloca i8*
%12 = alloca i32
%13 = alloca i32
%14 = alloca i32
%15 = alloca i32
%16 = alloca i32
%17 = alloca i32
%18 = alloca i32
%19 = alloca i32
%20 = alloca i32
%21 = alloca i32
%22 = alloca i32
%23 = alloca i32
%24 = alloca i32
%25 = alloca i32
%26 = alloca i32
%27 = alloca i32
%28 = alloca i32
%29 = alloca i32
store i8* %0, i8** %11
store i32 %1, i32* %12
store i32 %2, i32* %13
store i32 %3, i32* %14
store i32 %4, i32* %15
store i32 %5, i32* %16
store i32 %6, i32* %17
store i32 %7, i32* %18
store i32 %8, i32* %19
store i32 %9, i32* %20
store i32 5, i32* %21
%30 = load i32, i32* %18
%31 = sitofp i32 %30 to double
%32 = load i32, i32* %19
%33 = sitofp i32 %32 to double
%34 = fmul double 5.870000e-01, %33
%35 = call double @llvm.fmuladd.f64(double 2.990000e-01, double %31, double %34)
%36 = load i32, i32* %20
%37 = sitofp i32 %36 to double
%38 = call double @llvm.fmuladd.f64(double 1.140000e-01, double %37, double %35)
%39 = fptosi double %38 to i32
store i32 %39, i32* %22
%40 = load i32, i32* %18
%41 = sitofp i32 %40 to double
%42 = load i32, i32* %19
%43 = sitofp i32 %42 to double
%44 = fmul double 3.313000e-01, %43
%45 = call double @llvm.fmuladd.f64(double -1.687000e-01, double %41, double %44)
%46 = load i32, i32* %20
%47 = sitofp i32 %46 to double
%48 = call double @llvm.fmuladd.f64(double 5.000000e-01, double %47, double %45)
%49 = fadd double %48, 1.280000e+02
%50 = fptosi double %49 to i32
store i32 %50, i32* %23
%51 = load i32, i32* %18
%52 = sitofp i32 %51 to double
%53 = load i32, i32* %19
%54 = sitofp i32 %53 to double
%55 = fmul double 4.187000e-01, %54
%56 = fneg double %55
%57 = call double @llvm.fmuladd.f64(double 5.000000e-01, double %52, double %56)
%58 = load i32, i32* %20
%59 = sitofp i32 %58 to double
%60 = call double @llvm.fmuladd.f64(double 0xBFB4D013A92A3055, double %59, double %57)
%61 = fadd double %60, 1.280000e+02
%62 = fptosi double %61 to i32
store i32 %62, i32* %24
%63 = load i32, i32* %22
%64 = load i32, i32* %23
%65 = load i32, i32* %24
%66 = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([10 x i8], [10 x i8]* @.str, i64 0, i64 0), i32 %63, i32 %64, i32 %65)
%67 = load i32, i32* %15
store i32 %67, i32* %25
br label %68
68: ; preds = %151, %10
%69 = load i32, i32* %25
%70 = load i32, i32* %15
%71 = load i32, i32* %17
%72 = add nsw i32 %70, %71
%73 = icmp slt i32 %69, %72
br i1 %73, label %74, label %154
74: ; preds = %68
%75 = load i32, i32* %14
store i32 %75, i32* %26
br label %76
76: ; preds = %147, %74
%77 = load i32, i32* %26
%78 = load i32, i32* %14
%79 = load i32, i32* %16
%80 = add nsw i32 %78, %79
%81 = icmp slt i32 %77, %80
br i1 %81, label %82, label %150
82: ; preds = %76
%83 = load i32, i32* %26
%84 = load i32, i32* %14
%85 = add nsw i32 %84, 5
%86 = icmp slt i32 %83, %85
br i1 %86, label %106, label %87
87: ; preds = %82
%88 = load i32, i32* %26
%89 = load i32, i32* %14
%90 = load i32, i32* %16
%91 = add nsw i32 %89, %90
%92 = sub nsw i32 %91, 5
%93 = icmp sgt i32 %88, %92
br i1 %93, label %106, label %94
94: ; preds = %87
%95 = load i32, i32* %25
%96 = load i32, i32* %15
%97 = add nsw i32 %96, 5
%98 = icmp slt i32 %95, %97
br i1 %98, label %106, label %99
99: ; preds = %94
%100 = load i32, i32* %25
%101 = load i32, i32* %15
%102 = load i32, i32* %17
%103 = add nsw i32 %101, %102
%104 = sub nsw i32 %103, 5
%105 = icmp sgt i32 %100, %104
br i1 %105, label %106, label %146
106: ; preds = %99, %94, %87, %82
%107 = load i32, i32* %25
%108 = load i32, i32* %12
%109 = mul nsw i32 %107, %108
%110 = load i32, i32* %26
%111 = add nsw i32 %109, %110
store i32 %111, i32* %27
%112 = load i32, i32* %27
%113 = sdiv i32 %112, 2
%114 = load i32, i32* %12
%115 = sdiv i32 %114, 2
%116 = load i32, i32* %25
%117 = add nsw i32 %116, 1
%118 = sdiv i32 %117, 2
%119 = mul nsw i32 %115, %118
%120 = sub nsw i32 %113, %119
%121 = mul nsw i32 %120, 2
%122 = load i32, i32* %12
%123 = load i32, i32* %13
%124 = mul nsw i32 %122, %123
%125 = add nsw i32 %121, %124
store i32 %125, i32* %28
%126 = load i32, i32* %28
%127 = add nsw i32 %126, 1
store i32 %127, i32* %29
%128 = load i32, i32* %22
%129 = trunc i32 %128 to i8
%130 = load i8*, i8** %11
%131 = load i32, i32* %27
%132 = sext i32 %131 to i64
%133 = getelementptr inbounds i8, i8* %130, i64 %132
store i8 %129, i8* %133
%134 = load i32, i32* %23
%135 = trunc i32 %134 to i8
%136 = load i8*, i8** %11
%137 = load i32, i32* %28
%138 = sext i32 %137 to i64
%139 = getelementptr inbounds i8, i8* %136, i64 %138
store i8 %135, i8* %139
%140 = load i32, i32* %24
%141 = trunc i32 %140 to i8
%142 = load i8*, i8** %11
%143 = load i32, i32* %29
%144 = sext i32 %143 to i64
%145 = getelementptr inbounds i8, i8* %142, i64 %144
store i8 %141, i8* %145
br label %146
146: ; preds = %106, %99
br label %147
147: ; preds = %146
%148 = load i32, i32* %26
%149 = add nsw i32 %148, 1
store i32 %149, i32* %26
br label %76
150: ; preds = %76
br label %151
151: ; preds = %150
%152 = load i32, i32* %25
%153 = add nsw i32 %152, 1
store i32 %153, i32* %25
br label %68
154: ; preds = %68
ret i32 0
}

LLVM IR (-O2):
@.str = [10 x i8] c"%d %d %d\0A\00"
define i32 @nv12_border(i8* nocapture writeonly %0, i32 %1, i32 %2, i32 %3, i32 %4, i32 %5, i32 %6, i32 %7, i32 %8, i32 %9) {
%11 = sitofp i32 %7 to double
%12 = sitofp i32 %8 to double
%13 = fmul double %12, 5.870000e-01
%14 = tail call double @llvm.fmuladd.f64(double %11, double 2.990000e-01, double %13)
%15 = sitofp i32 %9 to double
%16 = tail call double @llvm.fmuladd.f64(double %15, double 1.140000e-01, double %14)
%17 = fptosi double %16 to i32
%18 = fmul double %12, 3.313000e-01
%19 = tail call double @llvm.fmuladd.f64(double %11, double -1.687000e-01, double %18)
%20 = tail call double @llvm.fmuladd.f64(double %15, double 5.000000e-01, double %19)
%21 = fadd double %20, 1.280000e+02
%22 = fptosi double %21 to i32
%23 = fmul double %12, -4.187000e-01
%24 = tail call double @llvm.fmuladd.f64(double %11, double 5.000000e-01, double %23)
%25 = tail call double @llvm.fmuladd.f64(double %15, double 0xBFB4D013A92A3055, double %24)
%26 = fadd double %25, 1.280000e+02
%27 = fptosi double %26 to i32
%28 = tail call i32 (i8*, ...) @printf(i8* dereferenceable(1) getelementptr inbounds ([10 x i8], [10 x i8]* @.str, i64 0, i64 0), i32 %17, i32 %22, i32 %27)
%29 = add nsw i32 %6, %4
%30 = icmp sgt i32 %6, 0
br i1 %30, label %31, label %90
31: ; preds = %10
%32 = add nsw i32 %5, %3
%33 = icmp sgt i32 %5, 0
%34 = add nsw i32 %3, 5
%35 = add nsw i32 %32, -5
%36 = add nsw i32 %4, 5
%37 = add nsw i32 %29, -5
%38 = sdiv i32 %1, 2
%39 = mul nsw i32 %2, %1
%40 = trunc i32 %17 to i8
%41 = trunc i32 %22 to i8
%42 = trunc i32 %27 to i8
%43 = sext i32 %3 to i64
%44 = sext i32 %35 to i64
%45 = sext i32 %34 to i64
%46 = sext i32 %32 to i64
%47 = sext i32 %4 to i64
%48 = sext i32 %37 to i64
%49 = sext i32 %36 to i64
%50 = sext i32 %1 to i64
%51 = sext i32 %29 to i64
br label %52
52: ; preds = %31, %87
%53 = phi i64 [ %47, %31 ], [ %88, %87 ]
br i1 %33, label %56, label %54
54: ; preds = %52
%55 = add nsw i64 %53, 1
br label %87
56: ; preds = %52
%57 = icmp slt i64 %53, %49
%58 = icmp sgt i64 %53, %48
%59 = mul nsw i64 %53, %50
%60 = add nsw i64 %53, 1
%61 = trunc i64 %60 to i32
%62 = sdiv i32 %61, -2
%63 = mul i32 %62, %38
br label %64
64: ; preds = %56, %84
%65 = phi i64 [ %43, %56 ], [ %85, %84 ]
%66 = icmp slt i64 %65, %45
%67 = icmp sgt i64 %65, %44
%68 = select i1 %66, i1 true, i1 %67
%69 = select i1 %68, i1 true, i1 %57
%70 = select i1 %69, i1 true, i1 %58
br i1 %70, label %71, label %84
71: ; preds = %64
%72 = add nsw i64 %65, %59
%73 = trunc i64 %72 to i32
%74 = sdiv i32 %73, 2
%75 = add i32 %74, %63
%76 = shl nsw i32 %75, 1
%77 = add nsw i32 %76, %39
%78 = add nsw i32 %77, 1
%79 = getelementptr inbounds i8, i8* %0, i64 %72
store i8 %40, i8* %79
%80 = sext i32 %77 to i64
%81 = getelementptr inbounds i8, i8* %0, i64 %80
store i8 %41, i8* %81
%82 = sext i32 %78 to i64
%83 = getelementptr inbounds i8, i8* %0, i64 %82
store i8 %42, i8* %83
br label %84
84: ; preds = %64, %71
%85 = add nsw i64 %65, 1
%86 = icmp slt i64 %85, %46
br i1 %86, label %64, label %87
87: ; preds = %84, %54
%88 = phi i64 [ %55, %54 ], [ %60, %84 ]
%89 = icmp slt i64 %88, %51
br i1 %89, label %52, label %90
90: ; preds = %87, %10
ret i32 0
}