// File: /workspace/github_c_makefile_star2_O2/ryancdotorg[P]bloomslice/mmapf.c
// Function: _bloomslice_mmapf
int mmapf(mmapf_ctx *ctx, const unsigned char *filename, size_t size, int flags) {
  size_t page_sz = sysconf(_SC_PAGESIZE);
  struct stat sb;

  int mmode = 0, mflags = 0;
  int fmode = 0;
  int ret, fd;

  // initialize
  ctx->mem = NULL;
  ctx->fd = -1;
  ctx->file_sz = size;

  // round up to the next multiple of the page size
  ctx->mmap_sz = size % page_sz ? (size/page_sz+1)*page_sz : size;

  mflags |= flags & MMAPF_COW ? MAP_PRIVATE : MAP_SHARED;

  if (flags & MMAPF_RW) {
    mmode |= PROT_READ|PROT_WRITE;
    fmode |= O_RDWR;
  } else if (flags & MMAPF_RD) {
    mflags |= MAP_NORESERVE;
    mmode |= PROT_READ;
    fmode |= O_RDONLY;
  } else if (flags & MMAPF_WR) {
    mmode |= PROT_WRITE;
    fmode |= O_WRONLY;
  }

  if (flags & MMAPF_CR) { fmode |= O_CREAT; }
  if (flags & MMAPF_EX) { fmode |= O_EXCL; }
  if (flags & MMAPF_PRE) { mflags |= MAP_POPULATE; }

  if (!filename) {
    ctx->mem = mmap(NULL, ctx->mmap_sz, mmode, MAP_ANONYMOUS|MAP_PRIVATE, -1, 0);
  } else {
    if (stat(filename, &sb) == 0) { // file exists
      if (!S_ISREG(sb.st_mode)) { return MMAPF_ENREG; } // not a regular file
      if (sb.st_size != (off_t)size) { return MMAPF_ESIZE; } // wrong size
      if ((fd = open64(filename, fmode)) < 0) { return errno; } // open failed
    } else if (flags & MMAPF_CR) { // file missing, but creation requested
      if ((fd = open64(filename, fmode, 0644)) < 0) { return errno; } // open failed
      if ((ret = posix_fallocate(fd, 0, size)) != 0) {
        // EBADF is returned on an unsupported filesystem, ignore it
        if (ret != EBADF) { return ret; }
      }
    } else { // file missing, creation *not* requested
      return ENOENT;
    }

    //if ((ret = posix_fadvise(fd, 0, size, fadv)) != 0) { return ret; }
    // ignore results
    if (flags & MMAPF_NOREUSE) posix_fadvise(fd, 0, size, POSIX_FADV_NOREUSE);
    if (flags & MMAPF_RND) posix_fadvise(fd, 0, size, POSIX_FADV_RANDOM);
    if (flags & MMAPF_SEQ) posix_fadvise(fd, 0, size, POSIX_FADV_SEQUENTIAL);
    if (flags & MMAPF_DONTNEED) posix_fadvise(fd, 0, size, POSIX_FADV_DONTNEED);
    if (flags & MMAPF_WILLNEED) posix_fadvise(fd, 0, size, POSIX_FADV_WILLNEED);

    ctx->mem = mmap(NULL, ctx->mmap_sz, mmode, mflags, fd, 0);
  }

  if (ctx->mem == MAP_FAILED) {
    return errno;
  } else if (ctx->mem == NULL) {
    return ENOMEM;
  }

  if (flags & MMAPF_RND && (ret = posix_madvise(ctx->mem, ctx->mmap_sz, POSIX_MADV_RANDOM)) != 0) {
    munmap(ctx->mem, ctx->mmap_sz);
    ctx->mem = NULL;
    return ret;
  }

  if (flags & MMAPF_SEQ && (ret = posix_madvise(ctx->mem, ctx->mmap_sz, POSIX_MADV_SEQUENTIAL)) != 0) {
    munmap(ctx->mem, ctx->mmap_sz);
    ctx->mem = NULL;
    return ret;
  }

  if (flags & MMAPF_DONTNEED && (ret = posix_madvise(ctx->mem, ctx->mmap_sz, POSIX_MADV_DONTNEED)) != 0) {
    munmap(ctx->mem, ctx->mmap_sz);
    ctx->mem = NULL;
    return ret;
  }

  if (flags & MMAPF_WILLNEED && filename && (ret = posix_madvise(ctx->mem, ctx->mmap_sz, POSIX_MADV_WILLNEED)) != 0) {
    munmap(ctx->mem, ctx->mmap_sz);
    ctx->mem = NULL;
    return ret;
  }

#ifdef MADV_HUGEPAGE
  // reduce overhead for large mappings
  if (size > (1<<26)) { madvise(ctx->mem, ctx->mmap_sz, MADV_HUGEPAGE); }
#endif
#ifdef MADV_DONTDUMP
  // don't include in a core dump
  madvise(ctx->mem, ctx->mmap_sz, MADV_DONTDUMP);
#endif

  return MMAPF_OKAY;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0xa8, %rsp
movl %ecx, %r15d
movq %rdx, %r14
movq %rsi, %rbp
movq %rdi, %rbx
pushq $0x1e
popq %rdi
callq 0x1200
andq $0x0, (%rbx)
orl $-0x1, 0x18(%rbx)
movq %rax, %rcx
movq %r14, 0x10(%rbx)
movq %r14, %rax
xorl %edx, %edx
divq %rcx
incq %rax
imulq %rcx, %rax
testq %rdx, %rdx
cmoveq %r14, %rax
movq %rax, 0x8(%rbx)
xorl %ecx, %ecx
testb $0x3, %r15b
setne %cl
movl %r15d, %r13d
shll $0x5, %r13d
andl $0x8000, %r13d          # imm = 0x8000
btl $0xb, %r15d
leal (%rcx,%rcx,2), %edx
adcl $-0x1, %r13d
testq %rbp, %rbp
je 0x5b3a
movl %edx, 0x14(%rsp)
movl %r15d, %r12d
andl $0x4, %r12d
movl %r12d, %eax
shll $0x4, %eax
leal (%rax,%rcx,2), %eax
movq %rbp, %rdi
movl %r15d, %ebp
andl $0x8, %ebp
shll $0x4, %ebp
orl %eax, %ebp
leaq 0x18(%rsp), %rsi
movq %rdi, 0x8(%rsp)
callq 0x1140
testl %eax, %eax
je 0x5b4b
testl %r12d, %r12d
jne 0x5b8f
pushq $0x2
jmp 0x5c7c
pushq $0x22
popq %rcx
pushq $-0x1
popq %r8
xorl %edi, %edi
movq %rax, %rsi
jmp 0x5c57
movl $0xf000, %eax           # imm = 0xF000
andl 0x30(%rsp), %eax
movl $0x3e9, %r12d           # imm = 0x3E9
cmpl $0x8000, %eax           # imm = 0x8000
jne 0x5d51
movl $0x3ea, %r12d           # imm = 0x3EA
cmpq %r14, 0x48(%rsp)
jne 0x5d51
movq 0x8(%rsp), %rdi
movl %ebp, %esi
xorl %eax, %eax
callq 0x11d0
movl %eax, %ebp
testl %eax, %eax
jns 0x5bc8
jmp 0x5c6d
movq 0x8(%rsp), %rdi
movl %ebp, %esi
movl $0x1a4, %edx            # imm = 0x1A4
xorl %eax, %eax
callq 0x11d0
testl %eax, %eax
js 0x5c6d
movl %eax, %ebp
movl %eax, %edi
xorl %esi, %esi
movq %r14, %rdx
callq 0x1150
cmpl $0x9, %eax
je 0x5bc8
movl %eax, %r12d
testl %eax, %eax
jne 0x5d51
btl $0xc, %r15d
movl %ebp, %r12d
jae 0x5be2
pushq $0x5
popq %rcx
movl %r12d, %edi
xorl %esi, %esi
movq %r14, %rdx
callq 0x1110
btl $0x8, %r15d
movq 0x8(%rsp), %rbp
jae 0x5bfe
pushq $0x1
popq %rcx
movl %r12d, %edi
xorl %esi, %esi
movq %r14, %rdx
callq 0x1110
btl $0x9, %r15d
jae 0x5c15
pushq $0x2
popq %rcx
movl %r12d, %edi
xorl %esi, %esi
movq %r14, %rdx
callq 0x1110
btl $0xe, %r15d
jae 0x5c2c
pushq $0x4
popq %rcx
movl %r12d, %edi
xorl %esi, %esi
movq %r14, %rdx
callq 0x1110
addl $0x2, %r13d
btl $0xd, %r15d
jae 0x5c47
pushq $0x3
popq %rcx
movl %r12d, %edi
xorl %esi, %esi
movq %r14, %rdx
callq 0x1110
movq 0x8(%rbx), %rsi
xorl %edi, %edi
movl 0x14(%rsp), %edx
movl %r13d, %ecx
movl %r12d, %r8d
xorl %r9d, %r9d
callq 0x10b0
movq %rax, (%rbx)
testq %rax, %rax
je 0x5c7a
cmpq $-0x1, %rax
jne 0x5c83
callq 0x1040
movl (%rax), %r12d
jmp 0x5d51
pushq $0xc
popq %r12
jmp 0x5d51
btl $0x8, %r15d
jae 0x5ca4
movq 0x8(%rbx), %rsi
pushq $0x1
popq %rdx
movq %rax, %rdi
callq 0x1220
movl %eax, %r12d
movq (%rbx), %rax
testl %r12d, %r12d
jne 0x5d12
btl $0x9, %r15d
jae 0x5cc5
movq 0x8(%rbx), %rsi
pushq $0x2
popq %rdx
movq %rax, %rdi
callq 0x1220
movl %eax, %r12d
movq (%rbx), %rax
testl %r12d, %r12d
jne 0x5d12
btl $0xe, %r15d
jae 0x5ce6
movq 0x8(%rbx), %rsi
pushq $0x4
popq %rdx
movq %rax, %rdi
callq 0x1220
movl %eax, %r12d
movq (%rbx), %rax
testl %r12d, %r12d
jne 0x5d12
testq %rbp, %rbp
sete %cl
btl $0xd, %r15d
setae %dl
orb %cl, %dl
jne 0x5d24
movq 0x8(%rbx), %rsi
pushq $0x3
popq %rdx
movq %rax, %rdi
callq 0x1220
movl %eax, %r12d
movq (%rbx), %rax
testl %r12d, %r12d
je 0x5d24
movq 0x8(%rbx), %rsi
movq %rax, %rdi
callq 0x11b0
andq $0x0, (%rbx)
jmp 0x5d51
cmpq $0x4000001, %r14        # imm = 0x4000001
jb 0x5d3f
movq 0x8(%rbx), %rsi
pushq $0xe
popq %rdx
movq %rax, %rdi
callq 0x11c0
movq (%rbx), %rax
movq 0x8(%rbx), %rsi
pushq $0x10
popq %rdx
movq %rax, %rdi
callq 0x11c0
xorl %r12d, %r12d
movl %r12d, %eax
addq $0xa8, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq