// File: /workspace/github_cpp_makefile_star2_O2/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 0x4245(%rip), %rdi      # 0x6fc8
callq 0x21f0
movl %eax, %r14d
movq 0x8(%rbx), %rdx
leaq -0x10(%rdx), %rcx
movq -0x8(%rdx), %rax
movq %rcx, 0x8(%rbx)
movq -0x18(%rdx), %rcx
addq $-0x20, %rdx
movq %rdx, 0x8(%rbx)
leal -0x64(%r14), %edx
cmpl $0x14, %edx
ja 0x2e91
leaq 0x1331(%rip), %rsi      # 0x40ec
movslq (%rsi,%rdx,4), %rdx
addq %rsi, %rdx
jmpq *%rdx
movq 0x4195(%rip), %rdx      # 0x6f60
movq %rdx, 0x8(%rsp)
movsd (%rax,%rcx), %xmm0
movsd %xmm0, 0x10(%rsp)
jmp 0x2e7c
movq 0x41a9(%rip), %rdx      # 0x6f90
jmp 0x2e2d
movq 0x4190(%rip), %rdx      # 0x6f80
jmp 0x2e59
movq 0x4177(%rip), %rdx      # 0x6f70
jmp 0x2e2d
movq 0x4176(%rip), %rdx      # 0x6f78
jmp 0x2e6e
movq 0x41b5(%rip), %rdx      # 0x6fc0
jmp 0x2e44
movq 0x4174(%rip), %rdx      # 0x6f88
movq %rdx, 0x8(%rsp)
movss (%rax,%rcx), %xmm0
movss %xmm0, 0x10(%rsp)
jmp 0x2e7c
movq 0x41ab(%rip), %rdx      # 0x6fd8
movq %rdx, 0x8(%rsp)
movq (%rax,%rcx), %rax
movq %rax, 0x10(%rsp)
jmp 0x2e7c
movq 0x416c(%rip), %rdx      # 0x6fb0
movq %rdx, 0x8(%rsp)
movb (%rax,%rcx), %al
movb %al, 0x10(%rsp)
jmp 0x2e7c
movq 0x4177(%rip), %rdx      # 0x6fd0
movq %rdx, 0x8(%rsp)
movl (%rax,%rcx), %eax
movl %eax, 0x10(%rsp)
jmp 0x2e7c
movq 0x40ea(%rip), %rdx      # 0x6f58
movq %rdx, 0x8(%rsp)
movzwl (%rax,%rcx), %eax
movw %ax, 0x10(%rsp)
leaq 0x8(%rsp), %rsi
movq %rbx, %rdi
callq 0x3652
addq $0x18, %rsp
popq %rbx
popq %r14
retq
movq 0x4158(%rip), %rdi      # 0x6ff0
leaq 0x1343(%rip), %rsi      # 0x41e2
callq 0x21a0
movsbl %r14b, %esi
movq %rax, %rdi
callq 0x21e0
movq %rax, %rdi
addq $0x18, %rsp
popq %rbx
popq %r14
jmp 0x20a0
nop