// File: Krymancer[P]Matrix-cpp/src/main.cpp
// Function: main
int main() {
    Matrix a;           //Empty matrix, no data (maybe can resize in futere verions?)
    Matrix b(3, 3);     //A 3x3 Matrix with 0 as a inital value
    Matrix c(3, 3, 1);  // A 3x3 Matrix with 1 as initial value
    Matrix d(3, 4, 5);  // A 4x3 Matrix with 5 as inital value

    b *= c;         // Mutiply two Matrixes (mutiple matrix not suported yet ex: b *= c + c)
    c += b;         //  Sum two Matrixes (mutiple matrix not suported yet ex: c += c + c)
    b = c + b - c;  // Atribuition works (not mix +/- with *);
    b = c * d;      // For now i dont recomend make mutiple operations with mutiplication in the same statement

    //Scalar operations

    b = b + 1;
    b = b - 5;
    b = b * 10;
    b = b / 2;

    b += 3;
    b *= 0.5;
    b -= 4;
    b /= 2;

    b.map(idenity); // Map apply a function in each element of the Matrix

    a.print();  // is equivalent a std::cout << a;

    std::cout
        << "Matrix A:\n"
        << a
        << "Matrix B:\n"
        << b
        << "Matrix C:\n"
        << c
        << "Matrix D:\n"
        << d
        << std::endl;

    std::cout << "[PASS]" << std::endl;
    return 0;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x2a0, %rsp            # imm = 0x2A0
movl $0x0, -0x4(%rbp)
leaq -0x28(%rbp), %rdi
callq 0x2ce0
leaq -0x48(%rbp), %rdi
movl $0x3, %edx
movl %edx, %esi
callq 0x2620
jmp 0xc1bd
leaq -0x78(%rbp), %rdi
movl $0x3, %edx
movsd 0xe3a(%rip), %xmm0      # 0xd008
movl %edx, %esi
callq 0x2550
jmp 0xc1d7
leaq -0x98(%rbp), %rdi
movl $0x3, %esi
movl $0x4, %edx
movsd 0x1018(%rip), %xmm0     # 0xd208
callq 0x2550
jmp 0xc1f7
leaq -0xb8(%rbp), %rdi
leaq -0x48(%rbp), %rsi
leaq -0x78(%rbp), %rdx
callq 0x35b0
jmp 0xc20d
leaq -0xb8(%rbp), %rdi
callq 0x5420
leaq -0xd8(%rbp), %rdi
leaq -0x78(%rbp), %rsi
leaq -0x48(%rbp), %rdx
callq 0x3330
jmp 0xc22f
leaq -0xd8(%rbp), %rdi
callq 0x5420
leaq -0x118(%rbp), %rdi
leaq -0x78(%rbp), %rsi
leaq -0x48(%rbp), %rdx
callq 0x2d20
jmp 0xc251
leaq -0xf8(%rbp), %rdi
leaq -0x118(%rbp), %rsi
leaq -0x78(%rbp), %rdx
callq 0x2f30
jmp 0xc26a
leaq -0x48(%rbp), %rdi
leaq -0xf8(%rbp), %rsi
callq 0x5440
jmp 0xc27c
leaq -0xf8(%rbp), %rdi
callq 0x5420
leaq -0x118(%rbp), %rdi
callq 0x5420
leaq -0x138(%rbp), %rdi
leaq -0x78(%rbp), %rsi
leaq -0x98(%rbp), %rdx
callq 0x3100
jmp 0xc2ad
leaq -0x48(%rbp), %rdi
leaq -0x138(%rbp), %rsi
callq 0x5440
jmp 0xc2bf
leaq -0x138(%rbp), %rdi
callq 0x5420
leaq -0x158(%rbp), %rdi
leaq -0x48(%rbp), %rsi
movsd 0xd2a(%rip), %xmm0      # 0xd008
callq 0x37f0
jmp 0xc2e5
leaq -0x48(%rbp), %rdi
leaq -0x158(%rbp), %rsi
callq 0x5440
jmp 0xc2f7
leaq -0x158(%rbp), %rdi
callq 0x5420
leaq -0x178(%rbp), %rdi
leaq -0x48(%rbp), %rsi
movsd 0xef2(%rip), %xmm0      # 0xd208
callq 0x3900
jmp 0xc31d
leaq -0x48(%rbp), %rdi
leaq -0x178(%rbp), %rsi
callq 0x5440
jmp 0xc32f
leaq -0x178(%rbp), %rdi
callq 0x5420
leaq -0x198(%rbp), %rdi
leaq -0x48(%rbp), %rsi
movsd 0xec2(%rip), %xmm0      # 0xd210
callq 0x3a10
jmp 0xc355
leaq -0x48(%rbp), %rdi
leaq -0x198(%rbp), %rsi
callq 0x5440
jmp 0xc367
leaq -0x198(%rbp), %rdi
callq 0x5420
leaq -0x1b8(%rbp), %rdi
leaq -0x48(%rbp), %rsi
movsd 0xe92(%rip), %xmm0      # 0xd218
callq 0x3b20
jmp 0xc38d
leaq -0x48(%rbp), %rdi
leaq -0x1b8(%rbp), %rsi
callq 0x5440
jmp 0xc39f
leaq -0x1b8(%rbp), %rdi
callq 0x5420
leaq -0x1d8(%rbp), %rdi
leaq -0x48(%rbp), %rsi
movsd 0xe62(%rip), %xmm0      # 0xd220
callq 0x3c30
jmp 0xc3c5
leaq -0x1d8(%rbp), %rdi
callq 0x5420
leaq -0x1f8(%rbp), %rdi
leaq -0x48(%rbp), %rsi
movsd 0xe44(%rip), %xmm0      # 0xd228
callq 0x3df0
jmp 0xc3eb
leaq -0x1f8(%rbp), %rdi
callq 0x5420
leaq -0x218(%rbp), %rdi
leaq -0x48(%rbp), %rsi
movsd 0xe26(%rip), %xmm0      # 0xd230
callq 0x3d10
jmp 0xc411
leaq -0x218(%rbp), %rdi
callq 0x5420
leaq -0x238(%rbp), %rdi
leaq -0x48(%rbp), %rsi
movsd 0xde8(%rip), %xmm0      # 0xd218
callq 0x3ed0
jmp 0xc437
leaq -0x238(%rbp), %rdi
callq 0x5420
leaq -0x2ca(%rip), %rdx      # 0xc180
leaq -0x258(%rbp), %rdi
leaq -0x48(%rbp), %rsi
callq 0x4db0
jmp 0xc45c
leaq -0x258(%rbp), %rdi
callq 0x5420
leaq -0x28(%rbp), %rdi
callq 0x4160
jmp 0xc473
movq 0x6b5e(%rip), %rdi      # 0x12fd8
leaq 0xdb7(%rip), %rsi       # 0xd238
callq 0x21d0
movq %rax, -0x260(%rbp)
jmp 0xc48f
movq -0x260(%rbp), %rdi
leaq -0x28(%rbp), %rsi
callq 0x4240
movq %rax, -0x268(%rbp)
jmp 0xc4a8
movq -0x268(%rbp), %rdi
leaq 0xd8d(%rip), %rsi       # 0xd243
callq 0x21d0
movq %rax, -0x270(%rbp)
jmp 0xc4c4
movq -0x270(%rbp), %rdi
leaq -0x48(%rbp), %rsi
callq 0x4240
movq %rax, -0x278(%rbp)
jmp 0xc4dd
movq -0x278(%rbp), %rdi
leaq 0xd63(%rip), %rsi       # 0xd24e
callq 0x21d0
movq %rax, -0x280(%rbp)
jmp 0xc4f9
movq -0x280(%rbp), %rdi
leaq -0x78(%rbp), %rsi
callq 0x4240
movq %rax, -0x288(%rbp)
jmp 0xc512
movq -0x288(%rbp), %rdi
leaq 0xd39(%rip), %rsi       # 0xd259
callq 0x21d0
movq %rax, -0x290(%rbp)
jmp 0xc52e
movq -0x290(%rbp), %rdi
leaq -0x98(%rbp), %rsi
callq 0x4240
movq %rax, -0x298(%rbp)
jmp 0xc54a
movq -0x298(%rbp), %rdi
movq 0x6a70(%rip), %rsi      # 0x12fc8
callq 0x2200
jmp 0xc55f
movq 0x6a72(%rip), %rdi      # 0x12fd8
leaq 0xcf7(%rip), %rsi       # 0xd264
callq 0x21d0
movq %rax, -0x2a0(%rbp)
jmp 0xc57b
movq -0x2a0(%rbp), %rdi
movq 0x6a3f(%rip), %rsi      # 0x12fc8
callq 0x2200
jmp 0xc590
movl $0x0, -0x4(%rbp)
leaq -0x98(%rbp), %rdi
callq 0x5420
leaq -0x78(%rbp), %rdi
callq 0x5420
leaq -0x48(%rbp), %rdi
callq 0x5420
leaq -0x28(%rbp), %rdi
callq 0x5420
movl -0x4(%rbp), %eax
addq $0x2a0, %rsp            # imm = 0x2A0
popq %rbp
retq
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x50(%rbp)
movl %eax, -0x54(%rbp)
jmp 0xc6e3
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x50(%rbp)
movl %eax, -0x54(%rbp)
jmp 0xc6da
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x50(%rbp)
movl %eax, -0x54(%rbp)
jmp 0xc6d1
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x50(%rbp)
movl %eax, -0x54(%rbp)
jmp 0xc6c5
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x50(%rbp)
movl %eax, -0x54(%rbp)
jmp 0xc634
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x50(%rbp)
movl %eax, -0x54(%rbp)
leaq -0xf8(%rbp), %rdi
callq 0x5420
leaq -0x118(%rbp), %rdi
callq 0x5420
jmp 0xc6c5
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x50(%rbp)
movl %eax, -0x54(%rbp)
leaq -0x138(%rbp), %rdi
callq 0x5420
jmp 0xc6c5
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x50(%rbp)
movl %eax, -0x54(%rbp)
leaq -0x158(%rbp), %rdi
callq 0x5420
jmp 0xc6c5
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x50(%rbp)
movl %eax, -0x54(%rbp)
leaq -0x178(%rbp), %rdi
callq 0x5420
jmp 0xc6c5
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x50(%rbp)
movl %eax, -0x54(%rbp)
leaq -0x198(%rbp), %rdi
callq 0x5420
jmp 0xc6c5
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x50(%rbp)
movl %eax, -0x54(%rbp)
leaq -0x1b8(%rbp), %rdi
callq 0x5420
leaq -0x98(%rbp), %rdi
callq 0x5420
leaq -0x78(%rbp), %rdi
callq 0x5420
leaq -0x48(%rbp), %rdi
callq 0x5420
leaq -0x28(%rbp), %rdi
callq 0x5420
movq -0x50(%rbp), %rdi
callq 0x2350