// File: 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 %rbp
movq %rsp, %rbp
subq $0x70, %rsp
movq %rdi, -0x8(%rbp)
movq -0x8(%rbp), %rax
movq %rax, -0x68(%rbp)
movq 0x7b4d(%rip), %rdi      # 0xafc8
callq 0x2210
movq -0x68(%rbp), %rdi
movl %eax, -0xc(%rbp)
callq 0x3260
movq -0x68(%rbp), %rdi
movq %rax, -0x38(%rbp)
movq %rdx, -0x30(%rbp)
movq -0x30(%rbp), %rax
movq %rax, -0x28(%rbp)
callq 0x3260
movq %rax, -0x50(%rbp)
movq %rdx, -0x48(%rbp)
movq -0x48(%rbp), %rax
movq %rax, -0x40(%rbp)
movq -0x28(%rbp), %rax
movq -0x40(%rbp), %rcx
addq %rcx, %rax
movq %rax, -0x58(%rbp)
movl -0xc(%rbp), %eax
addl $-0x64, %eax
movl %eax, %ecx
movq %rcx, -0x60(%rbp)
subl $0x14, %eax
ja 0x3606
movq -0x60(%rbp), %rax
leaq 0x3d08(%rip), %rcx      # 0x71ec
movslq (%rcx,%rax,4), %rax
addq %rcx, %rax
jmpq *%rax
movq 0x7abc(%rip), %rax      # 0xafb0
movq %rax, -0x20(%rbp)
movq -0x58(%rbp), %rax
movb (%rax), %al
movb %al, -0x18(%rbp)
jmp 0x3638
movq 0x7a43(%rip), %rax      # 0xaf50
movq %rax, -0x20(%rbp)
movq -0x58(%rbp), %rax
movw (%rax), %ax
movw %ax, -0x18(%rbp)
jmp 0x3638
movq 0x7aa8(%rip), %rax      # 0xafd0
movq %rax, -0x20(%rbp)
movq -0x58(%rbp), %rax
movl (%rax), %eax
movl %eax, -0x18(%rbp)
jmp 0x3638
movq 0x7a4f(%rip), %rax      # 0xaf90
movq %rax, -0x20(%rbp)
movq -0x58(%rbp), %rax
movq (%rax), %rax
movq %rax, -0x18(%rbp)
jmp 0x3638
movq 0x7a64(%rip), %rax      # 0xafc0
movq %rax, -0x20(%rbp)
movq -0x58(%rbp), %rax
movb (%rax), %al
movb %al, -0x18(%rbp)
jmp 0x3638
movq 0x7a03(%rip), %rax      # 0xaf78
movq %rax, -0x20(%rbp)
movq -0x58(%rbp), %rax
movw (%rax), %ax
movw %ax, -0x18(%rbp)
jmp 0x3638
movq 0x79f0(%rip), %rax      # 0xaf80
movq %rax, -0x20(%rbp)
movq -0x58(%rbp), %rax
movl (%rax), %eax
movl %eax, -0x18(%rbp)
jmp 0x3638
movq 0x79bf(%rip), %rax      # 0xaf68
movq %rax, -0x20(%rbp)
movq -0x58(%rbp), %rax
movq (%rax), %rax
movq %rax, -0x18(%rbp)
jmp 0x3638
movq 0x79c7(%rip), %rax      # 0xaf88
movq %rax, -0x20(%rbp)
movq -0x58(%rbp), %rax
movss (%rax), %xmm0
movss %xmm0, -0x18(%rbp)
jmp 0x3638
movq 0x797d(%rip), %rax      # 0xaf58
movq %rax, -0x20(%rbp)
movq -0x58(%rbp), %rax
movsd (%rax), %xmm0
movsd %xmm0, -0x18(%rbp)
jmp 0x3638
movq 0x79e3(%rip), %rax      # 0xafd8
movq %rax, -0x20(%rbp)
movq -0x58(%rbp), %rax
movq (%rax), %rax
movq %rax, -0x18(%rbp)
jmp 0x3638
movq 0x79e3(%rip), %rdi      # 0xaff0
leaq 0x3cc2(%rip), %rsi      # 0x72d6
callq 0x21b0
movq %rax, %rdi
movl -0xc(%rbp), %eax
movsbl %al, %esi
callq 0x2200
movq %rax, %rdi
movq 0x793f(%rip), %rsi      # 0xaf70
callq 0x21e0
jmp 0x3645
movq -0x68(%rbp), %rdi
leaq -0x20(%rbp), %rsi
callq 0x5360
addq $0x70, %rsp
popq %rbp
retq
nopl (%rax,%rax)