#define NULL ((void *)0)
typedef unsigned long size_t; // Customize by platform.
typedef long intptr_t;
typedef unsigned long uintptr_t;
typedef long scalar_t__; // Either arithmetic or pointer type.
/* By default, we understand bool (as a convenience). */
typedef int bool;
#define false 0
#define true 1

/* Forward declarations */

/* Type definitions */
typedef int int16_t;

/* Variables and functions */
int /*<<< orphan*/ aom_hadamard_8x8_c(int const *, int, int *);
void aom_hadamard_16x16_c(const int16_t *src_diff, int src_stride,
                          int16_t *coeff) {
  int idx;
  for (idx = 0; idx < 4; ++idx) {
    const int16_t *src_ptr =
        src_diff + (idx >> 1) * 8 * src_stride + (idx & 0x01) * 8;
    aom_hadamard_8x8_c(src_ptr, src_stride, coeff + idx * 64);
  }
  for (idx = 0; idx < 64; ++idx) {
    int16_t a0 = coeff[0];
    int16_t a1 = coeff[64];
    int16_t a2 = coeff[128];
    int16_t a3 = coeff[192];
    int16_t b0 = (a0 + a1) >> 1;
    int16_t b1 = (a0 - a1) >> 1;
    int16_t b2 = (a2 + a3) >> 1;
    int16_t b3 = (a2 - a3) >> 1;
    coeff[0] = b0 + b2;
    coeff[64] = b1 + b3;
    coeff[128] = b0 - b2;
    coeff[192] = b1 - b3;
    ++coeff;
  }
}


x86 assembly (clang, -O0):
<aom_hadamard_16x16_c>:
push   %rbp
mov    %rsp,%rbp
sub    $0x50,%rsp
mov    %rdi,-0x8(%rbp)
mov    %esi,-0xc(%rbp)
mov    %rdx,-0x18(%rbp)
movl   $0x0,-0x1c(%rbp)
cmpl   $0x4,-0x1c(%rbp)
jge    1193 <aom_hadamard_16x16_c+0x83>
mov    -0x8(%rbp),%rax
mov    -0x1c(%rbp),%ecx
sar    $0x1,%ecx
shl    $0x3,%ecx
imul   -0xc(%rbp),%ecx
movslq %ecx,%rcx
shl    $0x2,%rcx
add    %rcx,%rax
mov    -0x1c(%rbp),%ecx
and    $0x1,%ecx
shl    $0x3,%ecx
movslq %ecx,%rcx
shl    $0x2,%rcx
add    %rcx,%rax
mov    %rax,-0x28(%rbp)
mov    -0x28(%rbp),%rdi
mov    -0xc(%rbp),%esi
mov    -0x18(%rbp),%rdx
mov    -0x1c(%rbp),%eax
shl    $0x6,%eax
cltq
shl    $0x2,%rax
add    %rax,%rdx
call   1030 <aom_hadamard_8x8_c@plt>
mov    -0x1c(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x1c(%rbp)
jmp    112a <aom_hadamard_16x16_c+0x1a>
movl   $0x0,-0x1c(%rbp)
cmpl   $0x40,-0x1c(%rbp)
jge    125a <aom_hadamard_16x16_c+0x14a>
mov    -0x18(%rbp),%rax
mov    (%rax),%eax
mov    %eax,-0x2c(%rbp)
mov    -0x18(%rbp),%rax
mov    0x100(%rax),%eax
mov    %eax,-0x30(%rbp)
mov    -0x18(%rbp),%rax
mov    0x200(%rax),%eax
mov    %eax,-0x34(%rbp)
mov    -0x18(%rbp),%rax
mov    0x300(%rax),%eax
mov    %eax,-0x38(%rbp)
mov    -0x2c(%rbp),%eax
add    -0x30(%rbp),%eax
sar    $0x1,%eax
mov    %eax,-0x3c(%rbp)
mov    -0x2c(%rbp),%eax
sub    -0x30(%rbp),%eax
sar    $0x1,%eax
mov    %eax,-0x40(%rbp)
mov    -0x34(%rbp),%eax
add    -0x38(%rbp),%eax
sar    $0x1,%eax
mov    %eax,-0x44(%rbp)
mov    -0x34(%rbp),%eax
sub    -0x38(%rbp),%eax
sar    $0x1,%eax
mov    %eax,-0x48(%rbp)
mov    -0x3c(%rbp),%ecx
add    -0x44(%rbp),%ecx
mov    -0x18(%rbp),%rax
mov    %ecx,(%rax)
mov    -0x40(%rbp),%ecx
add    -0x48(%rbp),%ecx
mov    -0x18(%rbp),%rax
mov    %ecx,0x100(%rax)
mov    -0x3c(%rbp),%ecx
sub    -0x44(%rbp),%ecx
mov    -0x18(%rbp),%rax
mov    %ecx,0x200(%rax)
mov    -0x40(%rbp),%ecx
sub    -0x48(%rbp),%ecx
mov    -0x18(%rbp),%rax
mov    %ecx,0x300(%rax)
mov    -0x18(%rbp),%rax
add    $0x4,%rax
mov    %rax,-0x18(%rbp)
mov    -0x1c(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x1c(%rbp)
jmp    119a <aom_hadamard_16x16_c+0x8a>
add    $0x50,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<aom_hadamard_16x16_c>:
push   %r15
push   %r14
push   %r12
push   %rbx
push   %rax
mov    %rdx,%rbx
mov    %esi,%r14d
mov    %rdi,%r15
call   1030 <aom_hadamard_8x8_c@plt>
lea    0x20(%r15),%rdi
lea    0x100(%rbx),%rdx
mov    %r14d,%esi
call   1030 <aom_hadamard_8x8_c@plt>
lea    0x0(,%r14,8),%eax
movslq %eax,%r12
lea    (%r15,%r12,4),%rdi
lea    0x200(%rbx),%rdx
mov    %r14d,%esi
call   1030 <aom_hadamard_8x8_c@plt>
lea    (%r15,%r12,4),%rdi
add    $0x20,%rdi
lea    0x300(%rbx),%rdx
mov    %r14d,%esi
call   1030 <aom_hadamard_8x8_c@plt>
mov    $0xffffffffffffffc0,%rax
cs nopw 0x0(%rax,%rax,1)
nop
movdqu 0x100(%rbx,%rax,4),%xmm0
movdqu 0x200(%rbx,%rax,4),%xmm1
movdqu 0x300(%rbx,%rax,4),%xmm2
movdqu 0x400(%rbx,%rax,4),%xmm3
movdqa %xmm1,%xmm4
paddd  %xmm0,%xmm4
psrad  $0x1,%xmm4
psubd  %xmm1,%xmm0
psrad  $0x1,%xmm0
movdqa %xmm3,%xmm1
paddd  %xmm2,%xmm1
psrad  $0x1,%xmm1
psubd  %xmm3,%xmm2
psrad  $0x1,%xmm2
movdqa %xmm1,%xmm3
paddd  %xmm4,%xmm3
movdqu %xmm3,0x100(%rbx,%rax,4)
movdqa %xmm2,%xmm3
paddd  %xmm0,%xmm3
movdqu %xmm3,0x200(%rbx,%rax,4)
psubd  %xmm1,%xmm4
movdqu %xmm4,0x300(%rbx,%rax,4)
psubd  %xmm2,%xmm0
movdqu %xmm0,0x400(%rbx,%rax,4)
add    $0x4,%rax
jne    1180 <aom_hadamard_16x16_c+0x70>
add    $0x8,%rsp
pop    %rbx
pop    %r12
pop    %r14
pop    %r15
ret

LLVM IR (-O0):
define void @aom_hadamard_16x16_c(i32* %0, i32 %1, i32* %2) {
%4 = alloca i32*
%5 = alloca i32
%6 = alloca i32*
%7 = alloca i32
%8 = alloca i32*
%9 = alloca i32
%10 = alloca i32
%11 = alloca i32
%12 = alloca i32
%13 = alloca i32
%14 = alloca i32
%15 = alloca i32
%16 = alloca i32
store i32* %0, i32** %4
store i32 %1, i32* %5
store i32* %2, i32** %6
store i32 0, i32* %7
br label %17
17: ; preds = %42, %3
%18 = load i32, i32* %7
%19 = icmp slt i32 %18, 4
br i1 %19, label %20, label %45
20: ; preds = %17
%21 = load i32*, i32** %4
%22 = load i32, i32* %7
%23 = ashr i32 %22, 1
%24 = mul nsw i32 %23, 8
%25 = load i32, i32* %5
%26 = mul nsw i32 %24, %25
%27 = sext i32 %26 to i64
%28 = getelementptr inbounds i32, i32* %21, i64 %27
%29 = load i32, i32* %7
%30 = and i32 %29, 1
%31 = mul nsw i32 %30, 8
%32 = sext i32 %31 to i64
%33 = getelementptr inbounds i32, i32* %28, i64 %32
store i32* %33, i32** %8
%34 = load i32*, i32** %8
%35 = load i32, i32* %5
%36 = load i32*, i32** %6
%37 = load i32, i32* %7
%38 = mul nsw i32 %37, 64
%39 = sext i32 %38 to i64
%40 = getelementptr inbounds i32, i32* %36, i64 %39
%41 = call i32 @aom_hadamard_8x8_c(i32* %34, i32 %35, i32* %40)
br label %42
42: ; preds = %20
%43 = load i32, i32* %7
%44 = add nsw i32 %43, 1
store i32 %44, i32* %7
br label %17
45: ; preds = %17
store i32 0, i32* %7
br label %46
46: ; preds = %100, %45
%47 = load i32, i32* %7
%48 = icmp slt i32 %47, 64
br i1 %48, label %49, label %103
49: ; preds = %46
%50 = load i32*, i32** %6
%51 = getelementptr inbounds i32, i32* %50, i64 0
%52 = load i32, i32* %51
store i32 %52, i32* %9
%53 = load i32*, i32** %6
%54 = getelementptr inbounds i32, i32* %53, i64 64
%55 = load i32, i32* %54
store i32 %55, i32* %10
%56 = load i32*, i32** %6
%57 = getelementptr inbounds i32, i32* %56, i64 128
%58 = load i32, i32* %57
store i32 %58, i32* %11
%59 = load i32*, i32** %6
%60 = getelementptr inbounds i32, i32* %59, i64 192
%61 = load i32, i32* %60
store i32 %61, i32* %12
%62 = load i32, i32* %9
%63 = load i32, i32* %10
%64 = add nsw i32 %62, %63
%65 = ashr i32 %64, 1
store i32 %65, i32* %13
%66 = load i32, i32* %9
%67 = load i32, i32* %10
%68 = sub nsw i32 %66, %67
%69 = ashr i32 %68, 1
store i32 %69, i32* %14
%70 = load i32, i32* %11
%71 = load i32, i32* %12
%72 = add nsw i32 %70, %71
%73 = ashr i32 %72, 1
store i32 %73, i32* %15
%74 = load i32, i32* %11
%75 = load i32, i32* %12
%76 = sub nsw i32 %74, %75
%77 = ashr i32 %76, 1
store i32 %77, i32* %16
%78 = load i32, i32* %13
%79 = load i32, i32* %15
%80 = add nsw i32 %78, %79
%81 = load i32*, i32** %6
%82 = getelementptr inbounds i32, i32* %81, i64 0
store i32 %80, i32* %82
%83 = load i32, i32* %14
%84 = load i32, i32* %16
%85 = add nsw i32 %83, %84
%86 = load i32*, i32** %6
%87 = getelementptr inbounds i32, i32* %86, i64 64
store i32 %85, i32* %87
%88 = load i32, i32* %13
%89 = load i32, i32* %15
%90 = sub nsw i32 %88, %89
%91 = load i32*, i32** %6
%92 = getelementptr inbounds i32, i32* %91, i64 128
store i32 %90, i32* %92
%93 = load i32, i32* %14
%94 = load i32, i32* %16
%95 = sub nsw i32 %93, %94
%96 = load i32*, i32** %6
%97 = getelementptr inbounds i32, i32* %96, i64 192
store i32 %95, i32* %97
%98 = load i32*, i32** %6
%99 = getelementptr inbounds i32, i32* %98, i32 1
store i32* %99, i32** %6
br label %100
100: ; preds = %49
%101 = load i32, i32* %7
%102 = add nsw i32 %101, 1
store i32 %102, i32* %7
br label %46
103: ; preds = %46
ret void
}

LLVM IR (-O2):
define void @aom_hadamard_16x16_c(i32* %0, i32 %1, i32* %2) {
%4 = tail call i32 @aom_hadamard_8x8_c(i32* %0, i32 %1, i32* %2)
%5 = getelementptr inbounds i32, i32* %0, i64 8
%6 = getelementptr inbounds i32, i32* %2, i64 64
%7 = tail call i32 @aom_hadamard_8x8_c(i32* %5, i32 %1, i32* %6)
%8 = shl nsw i32 %1, 3
%9 = sext i32 %8 to i64
%10 = getelementptr inbounds i32, i32* %0, i64 %9
%11 = getelementptr inbounds i32, i32* %2, i64 128
%12 = tail call i32 @aom_hadamard_8x8_c(i32* %10, i32 %1, i32* %11)
%13 = getelementptr inbounds i32, i32* %10, i64 8
%14 = getelementptr inbounds i32, i32* %2, i64 192
%15 = tail call i32 @aom_hadamard_8x8_c(i32* %13, i32 %1, i32* %14)
br label %16
16: ; preds = %16, %3
%17 = phi i64 [ 0, %3 ], [ %46, %16 ]
%18 = getelementptr i32, i32* %2, i64 %17
%19 = bitcast i32* %18 to <4 x i32>*
%20 = load <4 x i32>, <4 x i32>* %19
%21 = getelementptr inbounds i32, i32* %18, i64 64
%22 = bitcast i32* %21 to <4 x i32>*
%23 = load <4 x i32>, <4 x i32>* %22
%24 = getelementptr inbounds i32, i32* %18, i64 128
%25 = bitcast i32* %24 to <4 x i32>*
%26 = load <4 x i32>, <4 x i32>* %25
%27 = getelementptr inbounds i32, i32* %18, i64 192
%28 = bitcast i32* %27 to <4 x i32>*
%29 = load <4 x i32>, <4 x i32>* %28
%30 = add nsw <4 x i32> %23, %20
%31 = ashr <4 x i32> %30, <i32 1, i32 1, i32 1, i32 1>
%32 = sub nsw <4 x i32> %20, %23
%33 = ashr <4 x i32> %32, <i32 1, i32 1, i32 1, i32 1>
%34 = add nsw <4 x i32> %29, %26
%35 = ashr <4 x i32> %34, <i32 1, i32 1, i32 1, i32 1>
%36 = sub nsw <4 x i32> %26, %29
%37 = ashr <4 x i32> %36, <i32 1, i32 1, i32 1, i32 1>
%38 = add nsw <4 x i32> %35, %31
%39 = bitcast i32* %18 to <4 x i32>*
store <4 x i32> %38, <4 x i32>* %39
%40 = add nsw <4 x i32> %37, %33
%41 = bitcast i32* %21 to <4 x i32>*
store <4 x i32> %40, <4 x i32>* %41
%42 = sub nsw <4 x i32> %31, %35
%43 = bitcast i32* %24 to <4 x i32>*
store <4 x i32> %42, <4 x i32>* %43
%44 = sub nsw <4 x i32> %33, %37
%45 = bitcast i32* %27 to <4 x i32>*
store <4 x i32> %44, <4 x i32>* %45
%46 = add nuw i64 %17, 4
%47 = icmp eq i64 %46, 64
br i1 %47, label %48, label %16
48: ; preds = %16
ret void
}