// File: /workspace/github_cpp_makefile_star2_O3/skeeto[P]elisp-ffi/ffi-glue.cc
// Function: Machine::read_mem()
void read_mem() {
        int type = std::cin.get();
        Value out;
        uint8_t* ptr_bytes = static_cast<uint8_t*>(stack.pop().value.ptr);
        size_t offset = stack.pop().value.u64;
        void* ptr = ptr_bytes + offset;
        switch(type) {
        case 'u':
            out.type = &ffi_type_uint8;
            out.value.u8 = *static_cast<uint8_t*>(ptr);
            break;
        case 'v':
            out.type = &ffi_type_uint16;
            out.value.u16 = *static_cast<uint16_t*>(ptr);
            break;
        case 'w':
            out.type = &ffi_type_uint32;
            out.value.u32 = *static_cast<uint32_t*>(ptr);
            break;
        case 'x':
            out.type = &ffi_type_uint64;
            out.value.u64 = *static_cast<uint64_t*>(ptr);
            break;
        case 'i':
            out.type = &ffi_type_sint8;
            out.value.s8 = *static_cast<int8_t*>(ptr);
            break;
        case 'j':
            out.type = &ffi_type_sint16;
            out.value.s16 = *static_cast<int16_t*>(ptr);
            break;
        case 'k':
            out.type = &ffi_type_sint32;
            out.value.s32 = *static_cast<int32_t*>(ptr);
            break;
        case 'l':
            out.type = &ffi_type_sint64;
            out.value.s64 = *static_cast<int64_t*>(ptr);
            break;
        case 'f':
            out.type = &ffi_type_float;
            out.value.f = *static_cast<float*>(ptr);
            break;
        case 'd':
            out.type = &ffi_type_double;
            out.value.d = *static_cast<double*>(ptr);
            break;
        case 'p':
            out.type = &ffi_type_pointer;
            out.value.ptr = *static_cast<void**>(ptr);
            break;
        default:
            std::cerr << "invalid type in read_mem: " << static_cast<char>(type) << std::endl;
            return;
        }
        stack.push(out);
    }

// Assembly:
pushq %r14
pushq %rbx
subq $0x18, %rsp
movq %rdi, %rbx
movq 0x3205(%rip), %rdi      # 0x5fc8
callq 0x21c0
movl %eax, %r14d
movq 0x8(%rbx), %rsi
leaq -0x10(%rsi), %rcx
movq -0x8(%rsi), %rax
movq %rcx, 0x8(%rbx)
movq -0x18(%rsi), %rcx
addq $-0x20, %rsi
movq %rsi, 0x8(%rbx)
leal -0x64(%r14), %edx
cmpl $0x14, %edx
ja 0x2ee6
leaq 0x1325(%rip), %rdi      # 0x4120
movslq (%rdi,%rdx,4), %rdx
addq %rdi, %rdx
jmpq *%rdx
movq 0x3155(%rip), %rdx      # 0x5f60
movq %rdx, 0x8(%rsp)
movsd (%rax,%rcx), %xmm0
movsd %xmm0, 0x10(%rsp)
jmp 0x2ebc
movq 0x3169(%rip), %rdx      # 0x5f90
jmp 0x2e6d
movq 0x3150(%rip), %rdx      # 0x5f80
jmp 0x2e99
movq 0x3137(%rip), %rdx      # 0x5f70
jmp 0x2e6d
movq 0x3136(%rip), %rdx      # 0x5f78
jmp 0x2eae
movq 0x3175(%rip), %rdx      # 0x5fc0
jmp 0x2e84
movq 0x3134(%rip), %rdx      # 0x5f88
movq %rdx, 0x8(%rsp)
movss (%rax,%rcx), %xmm0
movss %xmm0, 0x10(%rsp)
jmp 0x2ebc
movq 0x316b(%rip), %rdx      # 0x5fd8
movq %rdx, 0x8(%rsp)
movq (%rax,%rcx), %rax
movq %rax, 0x10(%rsp)
jmp 0x2ebc
movq 0x312c(%rip), %rdx      # 0x5fb0
movq %rdx, 0x8(%rsp)
movb (%rax,%rcx), %al
movb %al, 0x10(%rsp)
jmp 0x2ebc
movq 0x3137(%rip), %rdx      # 0x5fd0
movq %rdx, 0x8(%rsp)
movl (%rax,%rcx), %eax
movl %eax, 0x10(%rsp)
jmp 0x2ebc
movq 0x30aa(%rip), %rdx      # 0x5f58
movq %rdx, 0x8(%rsp)
movzwl (%rax,%rcx), %eax
movw %ax, 0x10(%rsp)
cmpq 0x10(%rbx), %rsi
je 0x2ed1
movups 0x8(%rsp), %xmm0
movups %xmm0, (%rsi)
addq $0x10, 0x8(%rbx)
jmp 0x2ede
leaq 0x8(%rsp), %rdx
movq %rbx, %rdi
callq 0x383c
addq $0x18, %rsp
popq %rbx
popq %r14
retq
movq 0x3103(%rip), %rbx      # 0x5ff0
leaq 0x1322(%rip), %rsi      # 0x4216
movl $0x1a, %edx
movq %rbx, %rdi
callq 0x21b0
leaq 0x8(%rsp), %rsi
movb %r14b, (%rsi)
movl $0x1, %edx
movq %rbx, %rdi
callq 0x21b0
movq %rax, %rbx
movq (%rax), %rax
movq -0x18(%rax), %rdi
addq %rbx, %rdi
movl $0xa, %esi
callq 0x2170
movsbl %al, %esi
movq %rbx, %rdi
callq 0x2040
movq %rax, %rdi
callq 0x20f0
jmp 0x2ede