void atiDecodeAlphaBlockATITCA4(unsigned char (*pAlphaOut)[4][4],
                                unsigned char *pEncodedData) {
  unsigned int encodedAlpha = *((unsigned int *)pEncodedData);
  unsigned int alpha;
  int row, col;
  for (row = 0; row < 2; row++) {
    for (col = 0; col < 4; col++) {
      alpha = encodedAlpha & 0x0000000F;
      alpha = alpha | (alpha << 4);
      (*pAlphaOut)[row][col] = (unsigned char)alpha;
      encodedAlpha >>= 4;
    }
  }
  encodedAlpha = *((unsigned int *)pEncodedData + 1);
  for (row = 2; row < 4; row++) {
    for (col = 0; col < 4; col++) {
      alpha = encodedAlpha & 0x0000000F;
      alpha = alpha | (alpha << 4);
      (*pAlphaOut)[row][col] = (unsigned char)alpha;
      encodedAlpha >>= 4;
    }
  }
}


x86 assembly (clang, -O0):
<atiDecodeAlphaBlockATITCA4>:
push   %rbp
mov    %rsp,%rbp
mov    %rdi,-0x8(%rbp)
mov    %rsi,-0x10(%rbp)
mov    -0x10(%rbp),%rax
mov    (%rax),%eax
mov    %eax,-0x14(%rbp)
movl   $0x0,-0x1c(%rbp)
cmpl   $0x2,-0x1c(%rbp)
jge    1193 <atiDecodeAlphaBlockATITCA4+0x93>
movl   $0x0,-0x20(%rbp)
cmpl   $0x4,-0x20(%rbp)
jge    1180 <atiDecodeAlphaBlockATITCA4+0x80>
mov    -0x14(%rbp),%eax
and    $0xf,%eax
mov    %eax,-0x18(%rbp)
mov    -0x18(%rbp),%eax
mov    -0x18(%rbp),%ecx
shl    $0x4,%ecx
or     %ecx,%eax
mov    %eax,-0x18(%rbp)
mov    -0x18(%rbp),%eax
mov    %al,%dl
mov    -0x8(%rbp),%rax
movslq -0x1c(%rbp),%rcx
shl    $0x2,%rcx
add    %rcx,%rax
movslq -0x20(%rbp),%rcx
mov    %dl,(%rax,%rcx,1)
mov    -0x14(%rbp),%eax
shr    $0x4,%eax
mov    %eax,-0x14(%rbp)
mov    -0x20(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x20(%rbp)
jmp    112d <atiDecodeAlphaBlockATITCA4+0x2d>
jmp    1185 <atiDecodeAlphaBlockATITCA4+0x85>
mov    -0x1c(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x1c(%rbp)
jmp    111c <atiDecodeAlphaBlockATITCA4+0x1c>
mov    -0x10(%rbp),%rax
mov    0x4(%rax),%eax
mov    %eax,-0x14(%rbp)
movl   $0x2,-0x1c(%rbp)
cmpl   $0x4,-0x1c(%rbp)
jge    121b <atiDecodeAlphaBlockATITCA4+0x11b>
movl   $0x0,-0x20(%rbp)
cmpl   $0x4,-0x20(%rbp)
jge    1208 <atiDecodeAlphaBlockATITCA4+0x108>
mov    -0x14(%rbp),%eax
and    $0xf,%eax
mov    %eax,-0x18(%rbp)
mov    -0x18(%rbp),%eax
mov    -0x18(%rbp),%ecx
shl    $0x4,%ecx
or     %ecx,%eax
mov    %eax,-0x18(%rbp)
mov    -0x18(%rbp),%eax
mov    %al,%dl
mov    -0x8(%rbp),%rax
movslq -0x1c(%rbp),%rcx
shl    $0x2,%rcx
add    %rcx,%rax
movslq -0x20(%rbp),%rcx
mov    %dl,(%rax,%rcx,1)
mov    -0x14(%rbp),%eax
shr    $0x4,%eax
mov    %eax,-0x14(%rbp)
mov    -0x20(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x20(%rbp)
jmp    11b5 <atiDecodeAlphaBlockATITCA4+0xb5>
jmp    120d <atiDecodeAlphaBlockATITCA4+0x10d>
mov    -0x1c(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x1c(%rbp)
jmp    11a4 <atiDecodeAlphaBlockATITCA4+0xa4>
pop    %rbp
ret

x86 assembly (clang, -O2):
<atiDecodeAlphaBlockATITCA4>:
push   %rbp
push   %rbx
mov    (%rsi),%edx
mov    %edx,%r8d
mov    %edx,%r9d
mov    %edx,%r10d
mov    %edx,%r11d
mov    %edx,%ecx
mov    %edx,%eax
mov    %edx,%ebx
shr    $0x1c,%ebx
shld   $0x4,%edx,%ebx
and    $0xf,%dl
movzbl %dl,%edx
mov    %edx,%ebp
shl    $0x4,%ebp
add    %edx,%ebp
mov    %bpl,(%rdi)
shr    $0x4,%r8b
movzbl %r8b,%ebp
mov    %ebp,%edx
shl    $0x4,%edx
add    %ebp,%edx
mov    %dl,0x1(%rdi)
shr    $0x8,%r9d
and    $0xf,%r9b
movzbl %r9b,%ebp
mov    %ebp,%edx
shl    $0x4,%edx
add    %ebp,%edx
mov    %dl,0x2(%rdi)
shr    $0xc,%r10d
and    $0xf,%r10b
movzbl %r10b,%ebp
mov    %ebp,%edx
shl    $0x4,%edx
add    %ebp,%edx
mov    %dl,0x3(%rdi)
shr    $0x10,%r11d
and    $0xf,%r11b
movzbl %r11b,%ebp
mov    %ebp,%edx
shl    $0x4,%edx
add    %ebp,%edx
mov    %dl,0x4(%rdi)
shr    $0x14,%ecx
and    $0xf,%cl
movzbl %cl,%ecx
mov    %ecx,%edx
shl    $0x4,%edx
add    %ecx,%edx
mov    %dl,0x5(%rdi)
shr    $0x18,%eax
and    $0xf,%al
movzbl %al,%eax
mov    %eax,%ecx
shl    $0x4,%ecx
add    %eax,%ecx
mov    %cl,0x6(%rdi)
mov    %bl,0x7(%rdi)
mov    0x4(%rsi),%eax
mov    %eax,%r8d
mov    %eax,%r9d
mov    %eax,%r10d
mov    %eax,%ecx
mov    %eax,%edx
mov    %eax,%esi
mov    %eax,%ebp
shr    $0x1c,%ebp
shld   $0x4,%eax,%ebp
and    $0xf,%al
movzbl %al,%ebx
mov    %ebx,%eax
shl    $0x4,%eax
add    %ebx,%eax
mov    %al,0x8(%rdi)
shr    $0x4,%r8b
movzbl %r8b,%ebx
mov    %ebx,%eax
shl    $0x4,%eax
add    %ebx,%eax
mov    %al,0x9(%rdi)
shr    $0x8,%r9d
and    $0xf,%r9b
movzbl %r9b,%ebx
mov    %ebx,%eax
shl    $0x4,%eax
add    %ebx,%eax
mov    %al,0xa(%rdi)
shr    $0xc,%r10d
and    $0xf,%r10b
movzbl %r10b,%ebx
mov    %ebx,%eax
shl    $0x4,%eax
add    %ebx,%eax
mov    %al,0xb(%rdi)
shr    $0x10,%ecx
and    $0xf,%cl
movzbl %cl,%eax
mov    %eax,%ecx
shl    $0x4,%ecx
add    %eax,%ecx
mov    %cl,0xc(%rdi)
shr    $0x14,%edx
and    $0xf,%dl
movzbl %dl,%eax
mov    %eax,%ecx
shl    $0x4,%ecx
add    %eax,%ecx
mov    %cl,0xd(%rdi)
shr    $0x18,%esi
and    $0xf,%sil
movzbl %sil,%eax
mov    %eax,%ecx
shl    $0x4,%ecx
add    %eax,%ecx
mov    %cl,0xe(%rdi)
mov    %bpl,0xf(%rdi)
pop    %rbx
pop    %rbp
ret

LLVM IR (-O0):
define void @atiDecodeAlphaBlockATITCA4([4 x [4 x i8]]* %0, i8* %1) {
%3 = alloca [4 x [4 x i8]]*
%4 = alloca i8*
%5 = alloca i32
%6 = alloca i32
%7 = alloca i32
%8 = alloca i32
store [4 x [4 x i8]]* %0, [4 x [4 x i8]]** %3
store i8* %1, i8** %4
%9 = load i8*, i8** %4
%10 = bitcast i8* %9 to i32*
%11 = load i32, i32* %10
store i32 %11, i32* %5
store i32 0, i32* %7
br label %12
12: ; preds = %41, %2
%13 = load i32, i32* %7
%14 = icmp slt i32 %13, 2
br i1 %14, label %15, label %44
15: ; preds = %12
store i32 0, i32* %8
br label %16
16: ; preds = %37, %15
%17 = load i32, i32* %8
%18 = icmp slt i32 %17, 4
br i1 %18, label %19, label %40
19: ; preds = %16
%20 = load i32, i32* %5
%21 = and i32 %20, 15
store i32 %21, i32* %6
%22 = load i32, i32* %6
%23 = load i32, i32* %6
%24 = shl i32 %23, 4
%25 = or i32 %22, %24
store i32 %25, i32* %6
%26 = load i32, i32* %6
%27 = trunc i32 %26 to i8
%28 = load [4 x [4 x i8]]*, [4 x [4 x i8]]** %3
%29 = load i32, i32* %7
%30 = sext i32 %29 to i64
%31 = getelementptr inbounds [4 x [4 x i8]], [4 x [4 x i8]]* %28, i64 0, i64 %30
%32 = load i32, i32* %8
%33 = sext i32 %32 to i64
%34 = getelementptr inbounds [4 x i8], [4 x i8]* %31, i64 0, i64 %33
store i8 %27, i8* %34
%35 = load i32, i32* %5
%36 = lshr i32 %35, 4
store i32 %36, i32* %5
br label %37
37: ; preds = %19
%38 = load i32, i32* %8
%39 = add nsw i32 %38, 1
store i32 %39, i32* %8
br label %16
40: ; preds = %16
br label %41
41: ; preds = %40
%42 = load i32, i32* %7
%43 = add nsw i32 %42, 1
store i32 %43, i32* %7
br label %12
44: ; preds = %12
%45 = load i8*, i8** %4
%46 = bitcast i8* %45 to i32*
%47 = getelementptr inbounds i32, i32* %46, i64 1
%48 = load i32, i32* %47
store i32 %48, i32* %5
store i32 2, i32* %7
br label %49
49: ; preds = %78, %44
%50 = load i32, i32* %7
%51 = icmp slt i32 %50, 4
br i1 %51, label %52, label %81
52: ; preds = %49
store i32 0, i32* %8
br label %53
53: ; preds = %74, %52
%54 = load i32, i32* %8
%55 = icmp slt i32 %54, 4
br i1 %55, label %56, label %77
56: ; preds = %53
%57 = load i32, i32* %5
%58 = and i32 %57, 15
store i32 %58, i32* %6
%59 = load i32, i32* %6
%60 = load i32, i32* %6
%61 = shl i32 %60, 4
%62 = or i32 %59, %61
store i32 %62, i32* %6
%63 = load i32, i32* %6
%64 = trunc i32 %63 to i8
%65 = load [4 x [4 x i8]]*, [4 x [4 x i8]]** %3
%66 = load i32, i32* %7
%67 = sext i32 %66 to i64
%68 = getelementptr inbounds [4 x [4 x i8]], [4 x [4 x i8]]* %65, i64 0, i64 %67
%69 = load i32, i32* %8
%70 = sext i32 %69 to i64
%71 = getelementptr inbounds [4 x i8], [4 x i8]* %68, i64 0, i64 %70
store i8 %64, i8* %71
%72 = load i32, i32* %5
%73 = lshr i32 %72, 4
store i32 %73, i32* %5
br label %74
74: ; preds = %56
%75 = load i32, i32* %8
%76 = add nsw i32 %75, 1
store i32 %76, i32* %8
br label %53
77: ; preds = %53
br label %78
78: ; preds = %77
%79 = load i32, i32* %7
%80 = add nsw i32 %79, 1
store i32 %80, i32* %7
br label %49
81: ; preds = %49
ret void
}

LLVM IR (-O2):
define void @atiDecodeAlphaBlockATITCA4([4 x [4 x i8]]* nocapture writeonly %0, i8* nocapture %1) {
%3 = bitcast i8* %1 to i32*
%4 = load i32, i32* %3
%5 = trunc i32 %4 to i8
%6 = and i8 %5, 15
%7 = mul nuw i8 %6, 17
%8 = getelementptr inbounds [4 x [4 x i8]], [4 x [4 x i8]]* %0, i64 0, i64 0, i64 0
store i8 %7, i8* %8
%9 = trunc i32 %4 to i8
%10 = lshr i8 %9, 4
%11 = mul nuw i8 %10, 17
%12 = getelementptr inbounds [4 x [4 x i8]], [4 x [4 x i8]]* %0, i64 0, i64 0, i64 1
store i8 %11, i8* %12
%13 = lshr i32 %4, 8
%14 = trunc i32 %13 to i8
%15 = and i8 %14, 15
%16 = mul nuw i8 %15, 17
%17 = getelementptr inbounds [4 x [4 x i8]], [4 x [4 x i8]]* %0, i64 0, i64 0, i64 2
store i8 %16, i8* %17
%18 = lshr i32 %4, 12
%19 = trunc i32 %18 to i8
%20 = and i8 %19, 15
%21 = mul nuw i8 %20, 17
%22 = getelementptr inbounds [4 x [4 x i8]], [4 x [4 x i8]]* %0, i64 0, i64 0, i64 3
store i8 %21, i8* %22
%23 = lshr i32 %4, 16
%24 = trunc i32 %23 to i8
%25 = and i8 %24, 15
%26 = mul nuw i8 %25, 17
%27 = getelementptr inbounds [4 x [4 x i8]], [4 x [4 x i8]]* %0, i64 0, i64 1, i64 0
store i8 %26, i8* %27
%28 = lshr i32 %4, 20
%29 = trunc i32 %28 to i8
%30 = and i8 %29, 15
%31 = mul nuw i8 %30, 17
%32 = getelementptr inbounds [4 x [4 x i8]], [4 x [4 x i8]]* %0, i64 0, i64 1, i64 1
store i8 %31, i8* %32
%33 = lshr i32 %4, 24
%34 = trunc i32 %33 to i8
%35 = and i8 %34, 15
%36 = mul nuw i8 %35, 17
%37 = getelementptr inbounds [4 x [4 x i8]], [4 x [4 x i8]]* %0, i64 0, i64 1, i64 2
store i8 %36, i8* %37
%38 = lshr i32 %4, 28
%39 = trunc i32 %38 to i8
%40 = mul nuw i8 %39, 17
%41 = getelementptr inbounds [4 x [4 x i8]], [4 x [4 x i8]]* %0, i64 0, i64 1, i64 3
store i8 %40, i8* %41
%42 = getelementptr inbounds i8, i8* %1, i64 4
%43 = bitcast i8* %42 to i32*
%44 = load i32, i32* %43
%45 = trunc i32 %44 to i8
%46 = and i8 %45, 15
%47 = mul nuw i8 %46, 17
%48 = getelementptr inbounds [4 x [4 x i8]], [4 x [4 x i8]]* %0, i64 0, i64 2, i64 0
store i8 %47, i8* %48
%49 = trunc i32 %44 to i8
%50 = lshr i8 %49, 4
%51 = mul nuw i8 %50, 17
%52 = getelementptr inbounds [4 x [4 x i8]], [4 x [4 x i8]]* %0, i64 0, i64 2, i64 1
store i8 %51, i8* %52
%53 = lshr i32 %44, 8
%54 = trunc i32 %53 to i8
%55 = and i8 %54, 15
%56 = mul nuw i8 %55, 17
%57 = getelementptr inbounds [4 x [4 x i8]], [4 x [4 x i8]]* %0, i64 0, i64 2, i64 2
store i8 %56, i8* %57
%58 = lshr i32 %44, 12
%59 = trunc i32 %58 to i8
%60 = and i8 %59, 15
%61 = mul nuw i8 %60, 17
%62 = getelementptr inbounds [4 x [4 x i8]], [4 x [4 x i8]]* %0, i64 0, i64 2, i64 3
store i8 %61, i8* %62
%63 = lshr i32 %44, 16
%64 = trunc i32 %63 to i8
%65 = and i8 %64, 15
%66 = mul nuw i8 %65, 17
%67 = getelementptr inbounds [4 x [4 x i8]], [4 x [4 x i8]]* %0, i64 0, i64 3, i64 0
store i8 %66, i8* %67
%68 = lshr i32 %44, 20
%69 = trunc i32 %68 to i8
%70 = and i8 %69, 15
%71 = mul nuw i8 %70, 17
%72 = getelementptr inbounds [4 x [4 x i8]], [4 x [4 x i8]]* %0, i64 0, i64 3, i64 1
store i8 %71, i8* %72
%73 = lshr i32 %44, 24
%74 = trunc i32 %73 to i8
%75 = and i8 %74, 15
%76 = mul nuw i8 %75, 17
%77 = getelementptr inbounds [4 x [4 x i8]], [4 x [4 x i8]]* %0, i64 0, i64 3, i64 2
store i8 %76, i8* %77
%78 = lshr i32 %44, 28
%79 = trunc i32 %78 to i8
%80 = mul nuw i8 %79, 17
%81 = getelementptr inbounds [4 x [4 x i8]], [4 x [4 x i8]]* %0, i64 0, i64 3, i64 3
store i8 %80, i8* %81
ret void
}