// File: ef-gy[P]libefgy/src/test-case/matrix.cpp
// Function: testAddition(std::ostream&)
bool testAddition(std::ostream &log) {
  matrix<int, 3, 4> m;
  for (int i = 0; i < 3; i++) {
    for (int k = 0; k < 4; k++) {
      m[i][k] = i * k;
    }
  }

  matrix<int, 3, 4> n;

  for (int i = 0; i < 3; i++) {
    for (int k = 0; k < 4; k++) {
      n[i][k] = 0;
    }
  }

  // results of left and right addition of
  // neutral element to m
  matrix<int, 3, 4> leftNeutral = n + m;
  matrix<int, 3, 4> rightNeutral = m + n;

  // test addition of neutral element;
  bool allCorrectLeft = true;
  bool allCorrectRight = true;
  for (int i = 0; i < 3; i++) {
    for (int k = 0; k < 4; k++) {
      allCorrectLeft &= (leftNeutral[i][k] == (i * k));
      allCorrectRight &= (rightNeutral[i][k] == (i * k));
    }
  }
  if (!allCorrectLeft) {
    log << "n + m, where n is the neutral element: ";
    for (int i = 0; i < 3; i++) {
      for (int k = 0; k < 4; k++) {
        log << leftNeutral[i][k];
      }
      log << "\n";
    }
    log << "\n";
    log << "m (original matrix):";
    for (int i = 0; i < 3; i++) {
      for (int k = 0; k < 4; k++) {
        log << m[i][k];
      }
      log << "\n";
    }

    log << "Unexpected result of left addition of neutral element to matrix.";
    return false;
  }
  if (!allCorrectRight) {
    log << "m + n, where n is the neutral element: ";
    for (int i = 0; i < 3; i++) {
      for (int k = 0; k < 4; k++) {
        log << rightNeutral[i][k];
      }
      log << "\n";
    }

    log << "\n";
    log << "m (original matrix):";
    for (int i = 0; i < 3; i++) {
      for (int k = 0; k < 4; k++) {
        log << m[i][k];
      }
      log << "\n";
    }
    log << "Unexpected result of right addition of neutral element to matrix.";
    return false;
  }

  // another test for addition of two non-neutral elements
  matrix<int, 3, 4> m2;

  for (int i = 0; i < 3; i++) {
    for (int k = 0; k < 4; k++) {
      m2[i][k] = i + k;
    }
  }

  matrix<int, 3, 4> sum = m + m2;

  bool allCorrectSum = true;
  for (int i = 0; i < 3; i++) {
    for (int k = 0; k < 3; k++) {
      allCorrectSum &= (sum[i][k] == (i * k) + (i + k));
    }
  }

  if (!allCorrectSum) {
    log << "Unexpected result adding two matrices.";
    return false;
  }

  return true;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x1b0, %rsp            # imm = 0x1B0
movq %rdi, -0x10(%rbp)
movl $0x0, -0x44(%rbp)
cmpl $0x3, -0x44(%rbp)
jge 0x612f
movl $0x0, -0x48(%rbp)
cmpl $0x4, -0x48(%rbp)
jge 0x6122
movl -0x44(%rbp), %eax
imull -0x48(%rbp), %eax
movl %eax, -0x184(%rbp)
movslq -0x44(%rbp), %rsi
leaq -0x40(%rbp), %rdi
callq 0x74b0
movq %rax, %rdi
movslq -0x48(%rbp), %rsi
callq 0x74e0
movl -0x184(%rbp), %ecx
movl %ecx, (%rax)
movl -0x48(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x48(%rbp)
jmp 0x60e3
jmp 0x6124
movl -0x44(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x44(%rbp)
jmp 0x60d6
movl $0x0, -0x7c(%rbp)
cmpl $0x3, -0x7c(%rbp)
jge 0x6180
movl $0x0, -0x80(%rbp)
cmpl $0x4, -0x80(%rbp)
jge 0x6173
movslq -0x7c(%rbp), %rsi
leaq -0x78(%rbp), %rdi
callq 0x74b0
movq %rax, %rdi
movslq -0x80(%rbp), %rsi
callq 0x74e0
movl $0x0, (%rax)
movl -0x80(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x80(%rbp)
jmp 0x6143
jmp 0x6175
movl -0x7c(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x7c(%rbp)
jmp 0x6136
leaq -0xb0(%rbp), %rdi
leaq -0x78(%rbp), %rsi
leaq -0x40(%rbp), %rdx
callq 0x7510
leaq -0xe0(%rbp), %rdi
leaq -0x40(%rbp), %rsi
leaq -0x78(%rbp), %rdx
callq 0x7510
movb $0x1, -0xe1(%rbp)
movb $0x1, -0xe2(%rbp)
movl $0x0, -0xe8(%rbp)
cmpl $0x3, -0xe8(%rbp)
jge 0x62ba
movl $0x0, -0xec(%rbp)
cmpl $0x4, -0xec(%rbp)
jge 0x62a4
movslq -0xe8(%rbp), %rsi
leaq -0xb0(%rbp), %rdi
callq 0x74b0
movq %rax, %rdi
movslq -0xec(%rbp), %rsi
callq 0x74e0
movl (%rax), %eax
movl -0xe8(%rbp), %ecx
imull -0xec(%rbp), %ecx
cmpl %ecx, %eax
sete %al
andb $0x1, %al
movzbl %al, %ecx
movb -0xe1(%rbp), %al
andb $0x1, %al
movzbl %al, %eax
andl %ecx, %eax
cmpl $0x0, %eax
setne %al
andb $0x1, %al
movb %al, -0xe1(%rbp)
movslq -0xe8(%rbp), %rsi
leaq -0xe0(%rbp), %rdi
callq 0x74b0
movq %rax, %rdi
movslq -0xec(%rbp), %rsi
callq 0x74e0
movl (%rax), %eax
movl -0xe8(%rbp), %ecx
imull -0xec(%rbp), %ecx
cmpl %ecx, %eax
sete %al
andb $0x1, %al
movzbl %al, %ecx
movb -0xe2(%rbp), %al
andb $0x1, %al
movzbl %al, %eax
andl %ecx, %eax
cmpl $0x0, %eax
setne %al
andb $0x1, %al
movb %al, -0xe2(%rbp)
movl -0xec(%rbp), %eax
addl $0x1, %eax
movl %eax, -0xec(%rbp)
jmp 0x61d7
jmp 0x62a6
movl -0xe8(%rbp), %eax
addl $0x1, %eax
movl %eax, -0xe8(%rbp)
jmp 0x61c0
testb $0x1, -0xe1(%rbp)
jne 0x6441
movq -0x10(%rbp), %rdi
leaq 0x2ef6e(%rip), %rsi     # 0x35240
callq 0x5390
movl $0x0, -0xf0(%rbp)
cmpl $0x3, -0xf0(%rbp)
jge 0x6371
movl $0x0, -0xf4(%rbp)
cmpl $0x4, -0xf4(%rbp)
jge 0x634d
movq -0x10(%rbp), %rax
movq %rax, -0x190(%rbp)
movslq -0xf0(%rbp), %rsi
leaq -0xb0(%rbp), %rdi
callq 0x74b0
movq %rax, %rdi
movslq -0xf4(%rbp), %rsi
callq 0x74e0
movq -0x190(%rbp), %rdi
movl (%rax), %esi
callq 0x55e0
movl -0xf4(%rbp), %eax
addl $0x1, %eax
movl %eax, -0xf4(%rbp)
jmp 0x62f8
movq -0x10(%rbp), %rdi
leaq 0x2efff(%rip), %rsi     # 0x35357
callq 0x5390
movl -0xf0(%rbp), %eax
addl $0x1, %eax
movl %eax, -0xf0(%rbp)
jmp 0x62e1
movq -0x10(%rbp), %rdi
leaq 0x2efdb(%rip), %rsi     # 0x35357
callq 0x5390
movq -0x10(%rbp), %rdi
leaq 0x2eedc(%rip), %rsi     # 0x35268
callq 0x5390
movl $0x0, -0xf8(%rbp)
cmpl $0x3, -0xf8(%rbp)
jge 0x6428
movl $0x0, -0xfc(%rbp)
cmpl $0x4, -0xfc(%rbp)
jge 0x6404
movq -0x10(%rbp), %rax
movq %rax, -0x198(%rbp)
movslq -0xf8(%rbp), %rsi
leaq -0x40(%rbp), %rdi
callq 0x74b0
movq %rax, %rdi
movslq -0xfc(%rbp), %rsi
callq 0x74e0
movq -0x198(%rbp), %rdi
movl (%rax), %esi
callq 0x55e0
movl -0xfc(%rbp), %eax
addl $0x1, %eax
movl %eax, -0xfc(%rbp)
jmp 0x63b2
movq -0x10(%rbp), %rdi
leaq 0x2ef48(%rip), %rsi     # 0x35357
callq 0x5390
movl -0xf8(%rbp), %eax
addl $0x1, %eax
movl %eax, -0xf8(%rbp)
jmp 0x639b
movq -0x10(%rbp), %rdi
leaq 0x2ee4a(%rip), %rsi     # 0x3527d
callq 0x5390
movb $0x0, -0x1(%rbp)
jmp 0x6744
testb $0x1, -0xe2(%rbp)
jne 0x65c8
movq -0x10(%rbp), %rdi
leaq 0x2ee65(%rip), %rsi     # 0x352be
callq 0x5390
movl $0x0, -0x100(%rbp)
cmpl $0x3, -0x100(%rbp)
jge 0x64f8
movl $0x0, -0x104(%rbp)
cmpl $0x4, -0x104(%rbp)
jge 0x64d4
movq -0x10(%rbp), %rax
movq %rax, -0x1a0(%rbp)
movslq -0x100(%rbp), %rsi
leaq -0xe0(%rbp), %rdi
callq 0x74b0
movq %rax, %rdi
movslq -0x104(%rbp), %rsi
callq 0x74e0
movq -0x1a0(%rbp), %rdi
movl (%rax), %esi
callq 0x55e0
movl -0x104(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x104(%rbp)
jmp 0x647f
movq -0x10(%rbp), %rdi
leaq 0x2ee78(%rip), %rsi     # 0x35357
callq 0x5390
movl -0x100(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x100(%rbp)
jmp 0x6468
movq -0x10(%rbp), %rdi
leaq 0x2ee54(%rip), %rsi     # 0x35357
callq 0x5390
movq -0x10(%rbp), %rdi
leaq 0x2ed55(%rip), %rsi     # 0x35268
callq 0x5390
movl $0x0, -0x108(%rbp)
cmpl $0x3, -0x108(%rbp)
jge 0x65af
movl $0x0, -0x10c(%rbp)
cmpl $0x4, -0x10c(%rbp)
jge 0x658b
movq -0x10(%rbp), %rax
movq %rax, -0x1a8(%rbp)
movslq -0x108(%rbp), %rsi
leaq -0x40(%rbp), %rdi
callq 0x74b0
movq %rax, %rdi
movslq -0x10c(%rbp), %rsi
callq 0x74e0
movq -0x1a8(%rbp), %rdi
movl (%rax), %esi
callq 0x55e0
movl -0x10c(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x10c(%rbp)
jmp 0x6539
movq -0x10(%rbp), %rdi
leaq 0x2edc1(%rip), %rsi     # 0x35357
callq 0x5390
movl -0x108(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x108(%rbp)
jmp 0x6522
movq -0x10(%rbp), %rdi
leaq 0x2ed2c(%rip), %rsi     # 0x352e6
callq 0x5390
movb $0x0, -0x1(%rbp)
jmp 0x6744
movl $0x0, -0x140(%rbp)
cmpl $0x3, -0x140(%rbp)
jge 0x664e
movl $0x0, -0x144(%rbp)
cmpl $0x4, -0x144(%rbp)
jge 0x663b
movl -0x140(%rbp), %eax
addl -0x144(%rbp), %eax
movl %eax, -0x1ac(%rbp)
movslq -0x140(%rbp), %rsi
leaq -0x13c(%rbp), %rdi
callq 0x74b0
movq %rax, %rdi
movslq -0x144(%rbp), %rsi
callq 0x74e0
movl -0x1ac(%rbp), %ecx
movl %ecx, (%rax)
movl -0x144(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x144(%rbp)
jmp 0x65e5
jmp 0x663d
movl -0x140(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x140(%rbp)
jmp 0x65d2
leaq -0x174(%rbp), %rdi
leaq -0x40(%rbp), %rsi
leaq -0x13c(%rbp), %rdx
callq 0x7510
movb $0x1, -0x175(%rbp)
movl $0x0, -0x17c(%rbp)
cmpl $0x3, -0x17c(%rbp)
jge 0x6721
movl $0x0, -0x180(%rbp)
cmpl $0x3, -0x180(%rbp)
jge 0x670b
movslq -0x17c(%rbp), %rsi
leaq -0x174(%rbp), %rdi
callq 0x74b0
movq %rax, %rdi
movslq -0x180(%rbp), %rsi
callq 0x74e0
movl (%rax), %eax
movl -0x17c(%rbp), %ecx
imull -0x180(%rbp), %ecx
movl -0x17c(%rbp), %edx
addl -0x180(%rbp), %edx
addl %edx, %ecx
cmpl %ecx, %eax
sete %al
andb $0x1, %al
movzbl %al, %ecx
movb -0x175(%rbp), %al
andb $0x1, %al
movzbl %al, %eax
andl %ecx, %eax
cmpl $0x0, %eax
setne %al
andb $0x1, %al
movb %al, -0x175(%rbp)
movl -0x180(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x180(%rbp)
jmp 0x668d
jmp 0x670d
movl -0x17c(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x17c(%rbp)
jmp 0x6676
testb $0x1, -0x175(%rbp)
jne 0x6740
movq -0x10(%rbp), %rdi
leaq 0x2ebf3(%rip), %rsi     # 0x35328
callq 0x5390
movb $0x0, -0x1(%rbp)
jmp 0x6744
movb $0x1, -0x1(%rbp)
movb -0x1(%rbp), %al
andb $0x1, %al
addq $0x1b0, %rsp            # imm = 0x1B0
popq %rbp
retq
nopw %cs:(%rax,%rax)