// File: /workspace/github_c_makefile_star2_O2/jiribenes[P]scheme/src/value.c
// Function: val_equal
bool val_equal(value_t a, value_t b) {
    if (val_eq(a, b)) {
        return true;
    }

    if (IS_VAL(a) || IS_VAL(b)) {
        // if both are only plain values,
        // they should have been equal by <eq?>
        return false;
    }

    ptrvalue_t *pa = AS_PTR(a);
    ptrvalue_t *pb = AS_PTR(b);

    if (pa->type != pb->type) {
        return false;
    }

    if (pa->type == T_CONS) {
        cons_t *consa = (cons_t *) pa;
        cons_t *consb = (cons_t *) pb;

        return val_equal(consa->car, consb->car) &&
               val_equal(consa->cdr, consb->cdr);
    } else if (pa->type == T_STRING) {
        string_t *stra = (string_t *) pa;
        string_t *strb = (string_t *) pb;

        return stra->len == strb->len && stra->hash == strb->hash &&
               memcmp(stra->value, strb->value, stra->len * sizeof(char)) == 0;

    } else if (pa->type == T_SYMBOL) {
        symbol_t *syma = (symbol_t *) pa;
        symbol_t *symb = (symbol_t *) pb;
        if ((syma->len == symb->len) &&
            (memcmp(syma->name, symb->name, syma->len * sizeof(char)) == 0)) {
            // we should never get here! - two symbols with same name are eq?
            fprintf(stderr, "Error: symbol not interned!");
        }
        return false;
    } else if (pa->type == T_VECTOR) {
        vector_t *veca = (vector_t *) pa;
        vector_t *vecb = (vector_t *) pb;

        if (veca->count != vecb->count) {
            return false;
        }

        for (uint32_t i = 0; i < veca->count; i++) {
            if (!val_equal(veca->data[i], vecb->data[i])) {
                return false;
            }
        }
        return true;
    }

    return false;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
pushq %rax
movq %rsi, %rbx
movq %rdi, %r14
movabsq $-0x4000000000001, %r15 # imm = 0xFFFBFFFFFFFFFFFF
movabsq $0x3ffffffffffff, %r12  # imm = 0x3FFFFFFFFFFFF
leaq 0x2521(%rip), %r13      # 0x69cc
cmpq %rbx, %r14
sete %bpl
je 0x45bb
cmpq %r15, %r14
jbe 0x45bb
cmpq %r15, %rbx
jbe 0x45bb
andq %r12, %r14
andq %r12, %rbx
movl (%r14), %eax
cmpl (%rbx), %eax
jne 0x45bb
cmpl $0x6, %eax
ja 0x45bb
movl %eax, %eax
movslq (%r13,%rax,4), %rax
addq %r13, %rax
jmpq *%rax
movq 0x10(%r14), %rdi
movq 0x10(%rbx), %rsi
callq 0x447f
testb %al, %al
je 0x45bb
movq 0x18(%r14), %r14
movq 0x18(%rbx), %rbx
jmp 0x44ab
movl 0x10(%r14), %edx
cmpl 0x10(%rbx), %edx
jne 0x45b9
addq $0x20, %r14
addq $0x20, %rbx
movq %r14, %rdi
movq %rbx, %rsi
callq 0x1170
testl %eax, %eax
jne 0x45b9
movq 0x5aba(%rip), %rax      # 0x9ff8
movq (%rax), %rcx
leaq 0x24d2(%rip), %rdi      # 0x6a1a
pushq $0x1b
popq %rsi
pushq $0x1
popq %rdx
callq 0x11c0
jmp 0x45b9
movl 0x14(%r14), %eax
cmpl 0x14(%rbx), %eax
jne 0x45b9
xorl %r15d, %r15d
movl 0x14(%r14), %eax
cmpq %rax, %r15
setae %bpl
jae 0x45bb
movq 0x18(%r14), %rax
movq (%rax,%r15,8), %rdi
movq 0x18(%rbx), %rax
movq (%rax,%r15,8), %rsi
callq 0x447f
incq %r15
testb %al, %al
jne 0x4561
jmp 0x45bb
movl 0x10(%r14), %edx
cmpl 0x10(%rbx), %edx
jne 0x45b9
movl 0x14(%r14), %eax
cmpl 0x14(%rbx), %eax
jne 0x45b9
addq $0x18, %r14
addq $0x18, %rbx
movq %r14, %rdi
movq %rbx, %rsi
callq 0x1170
testl %eax, %eax
sete %bpl
jmp 0x45bb
xorl %ebp, %ebp
movl %ebp, %eax
addq $0x8, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq