// File: jvanns[P]verbatim/sub/lmdb/libraries/liblmdb/mdb.c
// Function: mdb_cursor_prev
static int
mdb_cursor_prev(MDB_cursor *mc, MDB_val *key, MDB_val *data, MDB_cursor_op op)
{
	MDB_page	*mp;
	MDB_node	*leaf;
	int rc;

	mdb_cassert(mc, mc->mc_flags & C_INITIALIZED);

	mp = mc->mc_pg[mc->mc_top];

	if (mc->mc_db->md_flags & MDB_DUPSORT) {
		leaf = NODEPTR(mp, mc->mc_ki[mc->mc_top]);
		if (F_ISSET(leaf->mn_flags, F_DUPDATA)) {
			if (op == MDB_PREV || op == MDB_PREV_DUP) {
				rc = mdb_cursor_prev(&mc->mc_xcursor->mx_cursor, data, NULL, MDB_PREV);
				if (op != MDB_PREV || rc != MDB_NOTFOUND) {
					if (rc == MDB_SUCCESS) {
						MDB_GET_KEY(leaf, key);
						mc->mc_flags &= ~C_EOF;
					}
					return rc;
				}
			}
		} else {
			mc->mc_xcursor->mx_cursor.mc_flags &= ~(C_INITIALIZED|C_EOF);
			if (op == MDB_PREV_DUP)
				return MDB_NOTFOUND;
		}
	}

	DPRINTF(("cursor_prev: top page is %"Z"u in cursor %p",
		mdb_dbg_pgno(mp), (void *) mc));

	if (mc->mc_ki[mc->mc_top] == 0)  {
		DPUTS("=====> move to prev sibling page");
		if ((rc = mdb_cursor_sibling(mc, 0)) != MDB_SUCCESS) {
			return rc;
		}
		mp = mc->mc_pg[mc->mc_top];
		mc->mc_ki[mc->mc_top] = NUMKEYS(mp) - 1;
		DPRINTF(("prev page is %"Z"u, key index %u", mp->mp_pgno, mc->mc_ki[mc->mc_top]));
	} else
		mc->mc_ki[mc->mc_top]--;

	mc->mc_flags &= ~C_EOF;

	DPRINTF(("==> cursor points to page %"Z"u with %u keys, key index %u",
	    mdb_dbg_pgno(mp), NUMKEYS(mp), mc->mc_ki[mc->mc_top]));

	if (IS_LEAF2(mp)) {
		key->mv_size = mc->mc_db->md_pad;
		key->mv_data = LEAF2KEY(mp, mc->mc_ki[mc->mc_top], key->mv_size);
		return MDB_SUCCESS;
	}

	mdb_cassert(mc, IS_LEAF(mp));
	leaf = NODEPTR(mp, mc->mc_ki[mc->mc_top]);

	if (F_ISSET(leaf->mn_flags, F_DUPDATA)) {
		mdb_xcursor_init1(mc, leaf);
	}
	if (data) {
		if ((rc = mdb_node_read(mc->mc_txn, leaf, data)) != MDB_SUCCESS)
			return rc;

		if (F_ISSET(leaf->mn_flags, F_DUPDATA)) {
			rc = mdb_cursor_last(&mc->mc_xcursor->mx_cursor, data, NULL);
			if (rc != MDB_SUCCESS)
				return rc;
		}
	}

	MDB_GET_KEY(leaf, key);
	return MDB_SUCCESS;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x40, %rsp
movq %rdi, -0x10(%rbp)
movq %rsi, -0x18(%rbp)
movq %rdx, -0x20(%rbp)
movl %ecx, -0x24(%rbp)
movq -0x10(%rbp), %rax
movl 0x44(%rax), %eax
andl $0x1, %eax
cmpl $0x0, %eax
je 0x9378
jmp 0x93a4
movq -0x10(%rbp), %rax
movq 0x18(%rax), %rax
movq 0x20(%rax), %rdi
leaq 0xe74d(%rip), %rsi      # 0x17ad8
leaq 0xe783(%rip), %rdx      # 0x17b15
leaq 0xe076(%rip), %rcx      # 0x1740f
movl $0x1679, %r8d           # imm = 0x1679
callq 0x133a0
movq -0x10(%rbp), %rax
movq -0x10(%rbp), %rcx
movzwl 0x42(%rcx), %ecx
movq 0x48(%rax,%rcx,8), %rax
movq %rax, -0x30(%rbp)
movq -0x10(%rbp), %rax
movq 0x28(%rax), %rax
movzwl 0x4(%rax), %eax
andl $0x4, %eax
cmpl $0x0, %eax
je 0x94b9
movq -0x30(%rbp), %rax
movq -0x30(%rbp), %rcx
movq -0x10(%rbp), %rdx
movq -0x10(%rbp), %rsi
movzwl 0x42(%rsi), %esi
movzwl 0x148(%rdx,%rsi,2), %edx
movzwl 0x10(%rcx,%rdx,2), %ecx
movslq %ecx, %rcx
addq %rcx, %rax
movq %rax, -0x38(%rbp)
movq -0x38(%rbp), %rax
movzwl 0x4(%rax), %eax
andl $0x4, %eax
cmpl $0x4, %eax
jne 0x9492
cmpl $0xc, -0x24(%rbp)
je 0x941c
cmpl $0xd, -0x24(%rbp)
jne 0x9490
movq -0x10(%rbp), %rax
movq 0x10(%rax), %rdi
movq -0x20(%rbp), %rsi
xorl %eax, %eax
movl %eax, %edx
movl $0xc, %ecx
callq 0x9350
movl %eax, -0x3c(%rbp)
cmpl $0xc, -0x24(%rbp)
jne 0x9448
cmpl $0xffff87b2, -0x3c(%rbp) # imm = 0xFFFF87B2
je 0x948e
cmpl $0x0, -0x3c(%rbp)
jne 0x9483
cmpq $0x0, -0x18(%rbp)
je 0x9476
movq -0x38(%rbp), %rax
movzwl 0x6(%rax), %eax
movl %eax, %ecx
movq -0x18(%rbp), %rax
movq %rcx, (%rax)
movq -0x38(%rbp), %rcx
addq $0x8, %rcx
movq -0x18(%rbp), %rax
movq %rcx, 0x8(%rax)
movq -0x10(%rbp), %rax
movl 0x44(%rax), %ecx
andl $-0x3, %ecx
movl %ecx, 0x44(%rax)
movl -0x3c(%rbp), %eax
movl %eax, -0x4(%rbp)
jmp 0x96d4
jmp 0x9490
jmp 0x94b7
movq -0x10(%rbp), %rax
movq 0x10(%rax), %rax
movl 0x44(%rax), %ecx
andl $-0x4, %ecx
movl %ecx, 0x44(%rax)
cmpl $0xd, -0x24(%rbp)
jne 0x94b5
movl $0xffff87b2, -0x4(%rbp) # imm = 0xFFFF87B2
jmp 0x96d4
jmp 0x94b7
jmp 0x94b9
movq -0x10(%rbp), %rax
movq -0x10(%rbp), %rcx
movzwl 0x42(%rcx), %ecx
movzwl 0x148(%rax,%rcx,2), %eax
cmpl $0x0, %eax
jne 0x952e
movq -0x10(%rbp), %rdi
xorl %esi, %esi
callq 0xfe30
movl %eax, -0x3c(%rbp)
cmpl $0x0, %eax
je 0x94f0
movl -0x3c(%rbp), %eax
movl %eax, -0x4(%rbp)
jmp 0x96d4
movq -0x10(%rbp), %rax
movq -0x10(%rbp), %rcx
movzwl 0x42(%rcx), %ecx
movq 0x48(%rax,%rcx,8), %rax
movq %rax, -0x30(%rbp)
movq -0x30(%rbp), %rax
movzwl 0xc(%rax), %eax
subl $0x10, %eax
shrl %eax
subl $0x1, %eax
movw %ax, %dx
movq -0x10(%rbp), %rax
movq -0x10(%rbp), %rcx
movzwl 0x42(%rcx), %ecx
movw %dx, 0x148(%rax,%rcx,2)
jmp 0x954e
movq -0x10(%rbp), %rax
movq -0x10(%rbp), %rcx
movzwl 0x42(%rcx), %ecx
movw 0x148(%rax,%rcx,2), %dx
addw $-0x1, %dx
movw %dx, 0x148(%rax,%rcx,2)
movq -0x10(%rbp), %rax
movl 0x44(%rax), %ecx
andl $-0x3, %ecx
movl %ecx, 0x44(%rax)
movq -0x30(%rbp), %rax
movzwl 0xa(%rax), %eax
andl $0x20, %eax
cmpl $0x20, %eax
jne 0x95b9
movq -0x10(%rbp), %rax
movq 0x28(%rax), %rax
movl (%rax), %eax
movl %eax, %ecx
movq -0x18(%rbp), %rax
movq %rcx, (%rax)
movq -0x30(%rbp), %rcx
addq $0x10, %rcx
movq -0x10(%rbp), %rax
movq -0x10(%rbp), %rdx
movzwl 0x42(%rdx), %edx
movzwl 0x148(%rax,%rdx,2), %eax
movq -0x18(%rbp), %rdx
imulq (%rdx), %rax
addq %rax, %rcx
movq -0x18(%rbp), %rax
movq %rcx, 0x8(%rax)
movl $0x0, -0x4(%rbp)
jmp 0x96d4
movq -0x30(%rbp), %rax
movzwl 0xa(%rax), %eax
andl $0x2, %eax
cmpl $0x2, %eax
jne 0x95cb
jmp 0x95f7
movq -0x10(%rbp), %rax
movq 0x18(%rax), %rax
movq 0x20(%rax), %rdi
leaq 0xe47b(%rip), %rsi      # 0x17a59
leaq 0xe530(%rip), %rdx      # 0x17b15
leaq 0xde23(%rip), %rcx      # 0x1740f
movl $0x16aa, %r8d           # imm = 0x16AA
callq 0x133a0
movq -0x30(%rbp), %rax
movq -0x30(%rbp), %rcx
movq -0x10(%rbp), %rdx
movq -0x10(%rbp), %rsi
movzwl 0x42(%rsi), %esi
movzwl 0x148(%rdx,%rsi,2), %edx
movzwl 0x10(%rcx,%rdx,2), %ecx
movslq %ecx, %rcx
addq %rcx, %rax
movq %rax, -0x38(%rbp)
movq -0x38(%rbp), %rax
movzwl 0x4(%rax), %eax
andl $0x4, %eax
cmpl $0x4, %eax
jne 0x963f
movq -0x10(%rbp), %rdi
movq -0x38(%rbp), %rsi
callq 0x8800
cmpq $0x0, -0x20(%rbp)
je 0x96a5
movq -0x10(%rbp), %rax
movq 0x18(%rax), %rdi
movq -0x38(%rbp), %rsi
movq -0x20(%rbp), %rdx
callq 0x8a10
movl %eax, -0x3c(%rbp)
cmpl $0x0, %eax
je 0x966b
movl -0x3c(%rbp), %eax
movl %eax, -0x4(%rbp)
jmp 0x96d4
movq -0x38(%rbp), %rax
movzwl 0x4(%rax), %eax
andl $0x4, %eax
cmpl $0x4, %eax
jne 0x96a3
movq -0x10(%rbp), %rax
movq 0x10(%rax), %rdi
movq -0x20(%rbp), %rsi
xorl %eax, %eax
movl %eax, %edx
callq 0x90d0
movl %eax, -0x3c(%rbp)
cmpl $0x0, -0x3c(%rbp)
je 0x96a1
movl -0x3c(%rbp), %eax
movl %eax, -0x4(%rbp)
jmp 0x96d4
jmp 0x96a3
jmp 0x96a5
cmpq $0x0, -0x18(%rbp)
je 0x96cd
movq -0x38(%rbp), %rax
movzwl 0x6(%rax), %eax
movl %eax, %ecx
movq -0x18(%rbp), %rax
movq %rcx, (%rax)
movq -0x38(%rbp), %rcx
addq $0x8, %rcx
movq -0x18(%rbp), %rax
movq %rcx, 0x8(%rax)
movl $0x0, -0x4(%rbp)
movl -0x4(%rbp), %eax
addq $0x40, %rsp
popq %rbp
retq
nopl (%rax)