void RGB444toRGB444_ROW_STRETCH2X(unsigned char *dest_ptr, int dest_dx,
                                  unsigned char *src_ptr, int src_dx) {
  register unsigned char *d = dest_ptr;
  register unsigned char *s = src_ptr;
  register int count = src_dx;
  if (count) {
    register unsigned int da_rgb;
    register unsigned int sa_rgb;
    sa_rgb = *(unsigned short *)(s);
    da_rgb = sa_rgb;
    s += 2;
    count--;
    *(unsigned short *)(d) = da_rgb;
    d += 2;
    while (count >= 2) {
      register unsigned int db_rgb;
      register unsigned int sa_rgb;
      sa_rgb = *(unsigned short *)(s);
      db_rgb = sa_rgb;
      da_rgb =
          (((da_rgb ^ db_rgb) >> 1) & (((1U << (8 + 4 - 1)) - (1U << 8)) |
                                       ((1U << (4 + 4 - 1)) - (1U << 4)) |
                                       ((1U << (0 + 4 - 1)) - (1U << 0)))) +
          (da_rgb & db_rgb);
      *(unsigned short *)(d) = da_rgb;
      *(unsigned short *)(d + 2) = db_rgb;
      sa_rgb = *(unsigned short *)(s + 2);
      da_rgb = sa_rgb;
      db_rgb =
          (((db_rgb ^ da_rgb) >> 1) & (((1U << (8 + 4 - 1)) - (1U << 8)) |
                                       ((1U << (4 + 4 - 1)) - (1U << 4)) |
                                       ((1U << (0 + 4 - 1)) - (1U << 0)))) +
          (db_rgb & da_rgb);
      *(unsigned short *)(d + 2 * 2) = db_rgb;
      *(unsigned short *)(d + 3 * 2) = da_rgb;
      s += 4;
      d += 4 * 2;
      count -= 2;
    }
    if (count) {
      register unsigned int db_rgb;
      register unsigned int sa_rgb;
      sa_rgb = *(unsigned short *)(s);
      db_rgb = sa_rgb;
      da_rgb =
          (((da_rgb ^ db_rgb) >> 1) & (((1U << (8 + 4 - 1)) - (1U << 8)) |
                                       ((1U << (4 + 4 - 1)) - (1U << 4)) |
                                       ((1U << (0 + 4 - 1)) - (1U << 0)))) +
          (da_rgb & db_rgb);
      *(unsigned short *)(d) = da_rgb;
      *(unsigned short *)(d + 2) = db_rgb;
      *(unsigned short *)(d + 2 * 2) = db_rgb;
    } else {
      *(unsigned short *)(d) = da_rgb;
    }
  }
}


x86 assembly (clang, -O0):
<RGB444toRGB444_ROW_STRETCH2X>:
push   %rbp
mov    %rsp,%rbp
mov    %rdi,-0x8(%rbp)
mov    %esi,-0xc(%rbp)
mov    %rdx,-0x18(%rbp)
mov    %ecx,-0x1c(%rbp)
mov    -0x8(%rbp),%rax
mov    %rax,-0x28(%rbp)
mov    -0x18(%rbp),%rax
mov    %rax,-0x30(%rbp)
mov    -0x1c(%rbp),%eax
mov    %eax,-0x34(%rbp)
cmpl   $0x0,-0x34(%rbp)
je     129d <RGB444toRGB444_ROW_STRETCH2X+0x19d>
mov    -0x30(%rbp),%rax
movzwl (%rax),%eax
mov    %eax,-0x3c(%rbp)
mov    -0x3c(%rbp),%eax
mov    %eax,-0x38(%rbp)
mov    -0x30(%rbp),%rax
add    $0x2,%rax
mov    %rax,-0x30(%rbp)
mov    -0x34(%rbp),%eax
add    $0xffffffff,%eax
mov    %eax,-0x34(%rbp)
mov    -0x38(%rbp),%eax
mov    %ax,%cx
mov    -0x28(%rbp),%rax
mov    %cx,(%rax)
mov    -0x28(%rbp),%rax
add    $0x2,%rax
mov    %rax,-0x28(%rbp)
cmpl   $0x2,-0x34(%rbp)
jl     122a <RGB444toRGB444_ROW_STRETCH2X+0x12a>
mov    -0x30(%rbp),%rax
movzwl (%rax),%eax
mov    %eax,-0x44(%rbp)
mov    -0x44(%rbp),%eax
mov    %eax,-0x40(%rbp)
mov    -0x38(%rbp),%eax
xor    -0x40(%rbp),%eax
shr    $0x1,%eax
and    $0x777,%eax
mov    -0x38(%rbp),%ecx
and    -0x40(%rbp),%ecx
add    %ecx,%eax
mov    %eax,-0x38(%rbp)
mov    -0x38(%rbp),%eax
mov    %ax,%cx
mov    -0x28(%rbp),%rax
mov    %cx,(%rax)
mov    -0x40(%rbp),%eax
mov    %ax,%cx
mov    -0x28(%rbp),%rax
mov    %cx,0x2(%rax)
mov    -0x30(%rbp),%rax
movzwl 0x2(%rax),%eax
mov    %eax,-0x44(%rbp)
mov    -0x44(%rbp),%eax
mov    %eax,-0x38(%rbp)
mov    -0x40(%rbp),%eax
xor    -0x38(%rbp),%eax
shr    $0x1,%eax
and    $0x777,%eax
mov    -0x40(%rbp),%ecx
and    -0x38(%rbp),%ecx
add    %ecx,%eax
mov    %eax,-0x40(%rbp)
mov    -0x40(%rbp),%eax
mov    %ax,%cx
mov    -0x28(%rbp),%rax
mov    %cx,0x4(%rax)
mov    -0x38(%rbp),%eax
mov    %ax,%cx
mov    -0x28(%rbp),%rax
mov    %cx,0x6(%rax)
mov    -0x30(%rbp),%rax
add    $0x4,%rax
mov    %rax,-0x30(%rbp)
mov    -0x28(%rbp),%rax
add    $0x8,%rax
mov    %rax,-0x28(%rbp)
mov    -0x34(%rbp),%eax
sub    $0x2,%eax
mov    %eax,-0x34(%rbp)
jmp    1170 <RGB444toRGB444_ROW_STRETCH2X+0x70>
cmpl   $0x0,-0x34(%rbp)
je     128b <RGB444toRGB444_ROW_STRETCH2X+0x18b>
mov    -0x30(%rbp),%rax
movzwl (%rax),%eax
mov    %eax,-0x4c(%rbp)
mov    -0x4c(%rbp),%eax
mov    %eax,-0x48(%rbp)
mov    -0x38(%rbp),%eax
xor    -0x48(%rbp),%eax
shr    $0x1,%eax
and    $0x777,%eax
mov    -0x38(%rbp),%ecx
and    -0x48(%rbp),%ecx
add    %ecx,%eax
mov    %eax,-0x38(%rbp)
mov    -0x38(%rbp),%eax
mov    %ax,%cx
mov    -0x28(%rbp),%rax
mov    %cx,(%rax)
mov    -0x48(%rbp),%eax
mov    %ax,%cx
mov    -0x28(%rbp),%rax
mov    %cx,0x2(%rax)
mov    -0x48(%rbp),%eax
mov    %ax,%cx
mov    -0x28(%rbp),%rax
mov    %cx,0x4(%rax)
jmp    1298 <RGB444toRGB444_ROW_STRETCH2X+0x198>
mov    -0x38(%rbp),%eax
mov    %ax,%cx
mov    -0x28(%rbp),%rax
mov    %cx,(%rax)
jmp    129d <RGB444toRGB444_ROW_STRETCH2X+0x19d>
pop    %rbp
ret

x86 assembly (clang, -O2):
<RGB444toRGB444_ROW_STRETCH2X>:
test   %ecx,%ecx
je     11ae <RGB444toRGB444_ROW_STRETCH2X+0xae>
movzwl (%rdx),%r9d
add    $0x2,%rdx
mov    %r9w,(%rdi)
add    $0x2,%rdi
cmp    $0x3,%ecx
jl     117e <RGB444toRGB444_ROW_STRETCH2X+0x7e>
add    $0x1,%ecx
movzwl (%rdx),%r8d
mov    %r8d,%esi
xor    %r9d,%esi
shr    %esi
and    $0x777,%esi
and    %r8d,%r9d
add    %esi,%r9d
mov    %r9w,(%rdi)
mov    %r8w,0x2(%rdi)
movzwl 0x2(%rdx),%r9d
mov    %r9d,%esi
xor    %r8d,%esi
shr    %esi
and    $0x777,%esi
mov    %r9d,%eax
and    %r8d,%eax
add    %esi,%eax
mov    %ax,0x4(%rdi)
mov    %r9w,0x6(%rdi)
add    $0x4,%rdx
add    $0x8,%rdi
add    $0xfffffffe,%ecx
cmp    $0x3,%ecx
ja     1120 <RGB444toRGB444_ROW_STRETCH2X+0x20>
add    $0xfffffffe,%ecx
test   %ecx,%ecx
jne    1185 <RGB444toRGB444_ROW_STRETCH2X+0x85>
jmp    11aa <RGB444toRGB444_ROW_STRETCH2X+0xaa>
add    $0xffffffff,%ecx
test   %ecx,%ecx
je     11aa <RGB444toRGB444_ROW_STRETCH2X+0xaa>
movzwl (%rdx),%eax
mov    %eax,%ecx
xor    %r9d,%ecx
shr    %ecx
and    $0x777,%ecx
mov    %eax,%edx
and    %r9d,%edx
add    %ecx,%edx
mov    %dx,(%rdi)
mov    %ax,0x2(%rdi)
add    $0x4,%rdi
mov    %eax,%r9d
mov    %r9w,(%rdi)
ret

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

LLVM IR (-O2):
define void @RGB444toRGB444_ROW_STRETCH2X(i8* nocapture writeonly %0, i32 %1, i8* nocapture %2, i32 %3) {
%5 = icmp eq i32 %3, 0
br i1 %5, label %67, label %6
6: ; preds = %4
%7 = bitcast i8* %2 to i16*
%8 = load i16, i16* %7
%9 = getelementptr inbounds i8, i8* %2, i64 2
%10 = add nsw i32 %3, -1
%11 = bitcast i8* %0 to i16*
store i16 %8, i16* %11
%12 = getelementptr inbounds i8, i8* %0, i64 2
%13 = icmp sgt i32 %3, 2
br i1 %13, label %14, label %45
14: ; preds = %6, %14
%15 = phi i8* [ %42, %14 ], [ %12, %6 ]
%16 = phi i8* [ %41, %14 ], [ %9, %6 ]
%17 = phi i32 [ %43, %14 ], [ %10, %6 ]
%18 = phi i16 [ %31, %14 ], [ %8, %6 ]
%19 = bitcast i8* %16 to i16*
%20 = load i16, i16* %19
%21 = xor i16 %20, %18
%22 = lshr i16 %21, 1
%23 = and i16 %22, 1911
%24 = and i16 %20, %18
%25 = add i16 %23, %24
%26 = bitcast i8* %15 to i16*
store i16 %25, i16* %26
%27 = getelementptr inbounds i8, i8* %15, i64 2
%28 = bitcast i8* %27 to i16*
store i16 %20, i16* %28
%29 = getelementptr inbounds i8, i8* %16, i64 2
%30 = bitcast i8* %29 to i16*
%31 = load i16, i16* %30
%32 = xor i16 %31, %20
%33 = lshr i16 %32, 1
%34 = and i16 %33, 1911
%35 = and i16 %31, %20
%36 = add i16 %34, %35
%37 = getelementptr inbounds i8, i8* %15, i64 4
%38 = bitcast i8* %37 to i16*
store i16 %36, i16* %38
%39 = getelementptr inbounds i8, i8* %15, i64 6
%40 = bitcast i8* %39 to i16*
store i16 %31, i16* %40
%41 = getelementptr inbounds i8, i8* %16, i64 4
%42 = getelementptr inbounds i8, i8* %15, i64 8
%43 = add nsw i32 %17, -2
%44 = icmp ugt i32 %17, 3
br i1 %44, label %14, label %45
45: ; preds = %14, %6
%46 = phi i16 [ %8, %6 ], [ %31, %14 ]
%47 = phi i32 [ %10, %6 ], [ %43, %14 ]
%48 = phi i8* [ %9, %6 ], [ %41, %14 ]
%49 = phi i8* [ %12, %6 ], [ %42, %14 ]
%50 = icmp eq i32 %47, 0
br i1 %50, label %63, label %51
51: ; preds = %45
%52 = bitcast i8* %48 to i16*
%53 = load i16, i16* %52
%54 = xor i16 %53, %46
%55 = lshr i16 %54, 1
%56 = and i16 %55, 1911
%57 = and i16 %53, %46
%58 = add i16 %56, %57
%59 = bitcast i8* %49 to i16*
store i16 %58, i16* %59
%60 = getelementptr inbounds i8, i8* %49, i64 2
%61 = bitcast i8* %60 to i16*
store i16 %53, i16* %61
%62 = getelementptr inbounds i8, i8* %49, i64 4
br label %63
63: ; preds = %45, %51
%64 = phi i8* [ %62, %51 ], [ %49, %45 ]
%65 = phi i16 [ %53, %51 ], [ %46, %45 ]
%66 = bitcast i8* %64 to i16*
store i16 %65, i16* %66
br label %67
67: ; preds = %63, %4
ret void
}