// File: Eshaancoding[P]AutoDiff/src/Variable/grad.cpp
// Function: Variable::dir_eval(double, op, double, bool)
double Variable::dir_eval (double x, op operation, double y, bool respect_x) {
    if (operation == op::add) return 1;
    if (operation == op::multiply) return y;
    if (operation == op::min) return 1;
    if (operation == op::max) return 1;
    if (operation == op::clip) return 1; 
    if (operation == op::sin_d_op) return d_to_r(cos(r_to_d(x))); 
    if (operation == op::sin_r_op) return cos(x);
    if (operation == op::cos_d_op) return d_to_r(-sin(r_to_d(x)));
    if (operation == op::cos_r_op) return -sin(x); 
    if (respect_x) {
        if (operation == op::subtract) return 1;
        if (operation == op::divide) return 1 / y;
        if (operation == op::exponent) return y * pow(x, y - 1);
    } else {
        if (operation == op::subtract) return -1;
        if (operation == op::divide) return (-y) / pow(x,2);
        if (operation == op::exponent) return pow(y,x)*log10(y);
    }
    cout<<"ERROR OPERATION: "<<operation<<endl; 
    throw invalid_argument("operation not valid when running dir_eval()");
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x60, %rsp
movb %dl, %al
movq %rdi, -0x10(%rbp)
movsd %xmm0, -0x18(%rbp)
movl %esi, -0x1c(%rbp)
movsd %xmm1, -0x28(%rbp)
andb $0x1, %al
movb %al, -0x29(%rbp)
cmpl $0x2, -0x1c(%rbp)
jne 0x6008
movsd 0x91f2(%rip), %xmm0     # 0xf1f0
movsd %xmm0, -0x8(%rbp)
jmp 0x62aa
cmpl $0x5, -0x1c(%rbp)
jne 0x601d
movsd -0x28(%rbp), %xmm0
movsd %xmm0, -0x8(%rbp)
jmp 0x62aa
cmpl $0x8, -0x1c(%rbp)
jne 0x6035
movsd 0x91c5(%rip), %xmm0     # 0xf1f0
movsd %xmm0, -0x8(%rbp)
jmp 0x62aa
cmpl $0x9, -0x1c(%rbp)
jne 0x604d
movsd 0x91ad(%rip), %xmm0     # 0xf1f0
movsd %xmm0, -0x8(%rbp)
jmp 0x62aa
cmpl $0xa, -0x1c(%rbp)
jne 0x6065
movsd 0x9195(%rip), %xmm0     # 0xf1f0
movsd %xmm0, -0x8(%rbp)
jmp 0x62aa
cmpl $0xb, -0x1c(%rbp)
jne 0x6089
movsd -0x18(%rbp), %xmm0
callq 0x5f90
callq 0x22b0
callq 0x5fb0
movsd %xmm0, -0x8(%rbp)
jmp 0x62aa
cmpl $0xd, -0x1c(%rbp)
jne 0x60a3
movsd -0x18(%rbp), %xmm0
callq 0x22b0
movsd %xmm0, -0x8(%rbp)
jmp 0x62aa
cmpl $0xc, -0x1c(%rbp)
jne 0x60de
movsd -0x18(%rbp), %xmm0
callq 0x5f90
callq 0x2060
movq %xmm0, %rax
movabsq $-0x8000000000000000, %rcx # imm = 0x8000000000000000
xorq %rcx, %rax
movq %rax, %xmm0
callq 0x5fb0
movsd %xmm0, -0x8(%rbp)
jmp 0x62aa
cmpl $0xe, -0x1c(%rbp)
jne 0x610f
movsd -0x18(%rbp), %xmm0
callq 0x2060
movq %xmm0, %rax
movabsq $-0x8000000000000000, %rcx # imm = 0x8000000000000000
xorq %rcx, %rax
movq %rax, %xmm0
movsd %xmm0, -0x8(%rbp)
jmp 0x62aa
testb $0x1, -0x29(%rbp)
je 0x6190
cmpl $0x3, -0x1c(%rbp)
jne 0x612d
movsd 0x90cd(%rip), %xmm0     # 0xf1f0
movsd %xmm0, -0x8(%rbp)
jmp 0x62aa
cmpl $0x4, -0x1c(%rbp)
jne 0x614a
movsd 0x90b5(%rip), %xmm0     # 0xf1f0
divsd -0x28(%rbp), %xmm0
movsd %xmm0, -0x8(%rbp)
jmp 0x62aa
cmpl $0x6, -0x1c(%rbp)
jne 0x618b
movsd -0x28(%rbp), %xmm0
movsd %xmm0, -0x48(%rbp)
movsd -0x18(%rbp), %xmm0
movsd -0x28(%rbp), %xmm1
movsd 0x9084(%rip), %xmm2     # 0xf1f0
subsd %xmm2, %xmm1
callq 0x2270
movaps %xmm0, %xmm1
movsd -0x48(%rbp), %xmm0
mulsd %xmm1, %xmm0
movsd %xmm0, -0x8(%rbp)
jmp 0x62aa
jmp 0x622d
cmpl $0x3, -0x1c(%rbp)
jne 0x61a8
movsd 0x904a(%rip), %xmm0     # 0xf1e8
movsd %xmm0, -0x8(%rbp)
jmp 0x62aa
cmpl $0x4, -0x1c(%rbp)
jne 0x61f4
movsd -0x28(%rbp), %xmm0
movq %xmm0, %rax
movabsq $-0x8000000000000000, %rcx # imm = 0x8000000000000000
xorq %rcx, %rax
movq %rax, %xmm0
movsd %xmm0, -0x50(%rbp)
movsd -0x18(%rbp), %xmm0
movl $0x2, %edi
callq 0x6b80
movaps %xmm0, %xmm1
movsd -0x50(%rbp), %xmm0
divsd %xmm1, %xmm0
movsd %xmm0, -0x8(%rbp)
jmp 0x62aa
cmpl $0x6, -0x1c(%rbp)
jne 0x622b
movsd -0x28(%rbp), %xmm0
movsd -0x18(%rbp), %xmm1
callq 0x2270
movsd %xmm0, -0x58(%rbp)
movsd -0x28(%rbp), %xmm0
callq 0x20d0
movaps %xmm0, %xmm1
movsd -0x58(%rbp), %xmm0
mulsd %xmm1, %xmm0
movsd %xmm0, -0x8(%rbp)
jmp 0x62aa
jmp 0x622d
movq 0xed94(%rip), %rdi      # 0x14fc8
leaq 0x8fbd(%rip), %rsi      # 0xf1f8
callq 0x21b0
movq %rax, %rdi
movl -0x1c(%rbp), %esi
callq 0x2250
movq %rax, %rdi
movq 0xed63(%rip), %rsi      # 0x14fb8
callq 0x21d0
movl $0x10, %edi
callq 0x20c0
movq %rax, %rdi
movq %rdi, %rax
movq %rax, -0x60(%rbp)
leaq 0x8f95(%rip), %rsi      # 0xf20a
callq 0x22c0
jmp 0x627c
movq -0x60(%rbp), %rdi
movq 0xed59(%rip), %rsi      # 0x14fe0
movq 0xed42(%rip), %rdx      # 0x14fd0
callq 0x2240
movq -0x60(%rbp), %rdi
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x38(%rbp)
movl %eax, -0x3c(%rbp)
callq 0x2150
jmp 0x62b5
movsd -0x8(%rbp), %xmm0
addq $0x60, %rsp
popq %rbp
retq
movq -0x38(%rbp), %rdi
callq 0x2280
nop