// File: /workspace/github_c_makefile_star2_O3/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, %r14d
movq %rdx, %r15
movq %rsi, %r12
movq %rdi, %rbx
movl $0x1e, %edi
callq 0x1200
movq %rax, %rcx
movq $0x0, (%rbx)
movl $0xffffffff, 0x18(%rbx) # imm = 0xFFFFFFFF
movq %r15, 0x10(%rbx)
movq %r15, %rax
xorl %edx, %edx
divq %rcx
incq %rax
imulq %rcx, %rax
testq %rdx, %rdx
cmoveq %r15, %rax
movq %rax, 0x8(%rbx)
xorl %ecx, %ecx
testb $0x3, %r14b
setne %cl
movl %r14d, %r13d
shll $0x5, %r13d
andl $0x8000, %r13d          # imm = 0x8000
btl $0xb, %r14d
leal (%rcx,%rcx,2), %edx
adcl $-0x1, %r13d
testq %r12, %r12
je 0x62b4
movl %edx, 0x14(%rsp)
movq %r15, (%rsp)
movl %r14d, %r15d
andl $0x4, %r15d
movl %r15d, %eax
shll $0x4, %eax
leal (%rax,%rcx,2), %eax
movl %r14d, %ebp
andl $0x8, %ebp
shll $0x4, %ebp
orl %eax, %ebp
leaq 0x18(%rsp), %rsi
movq %r12, 0x8(%rsp)
movq %r12, %rdi
callq 0x1140
testl %eax, %eax
je 0x62c9
movl $0x2, %r12d
testl %r15d, %r15d
je 0x64c6
movq 0x8(%rsp), %rdi
movl %ebp, %esi
movl $0x1a4, %edx            # imm = 0x1A4
xorl %eax, %eax
callq 0x11d0
testl %eax, %eax
js 0x63bb
movl %eax, %ebp
movl %eax, %edi
xorl %esi, %esi
movq (%rsp), %rdx
callq 0x1150
cmpl $0x9, %eax
je 0x6310
movl %eax, %r12d
testl %eax, %eax
je 0x6310
jmp 0x64c6
xorl %edi, %edi
movq %rax, %rsi
movl $0x22, %ecx
movl $0xffffffff, %r8d       # imm = 0xFFFFFFFF
jmp 0x63a5
movl $0xf000, %eax           # imm = 0xF000
andl 0x30(%rsp), %eax
movl $0x3e9, %r12d           # imm = 0x3E9
cmpl $0x8000, %eax           # imm = 0x8000
jne 0x64c6
movl $0x3ea, %r12d           # imm = 0x3EA
movq (%rsp), %rax
cmpq %rax, 0x48(%rsp)
jne 0x64c6
movq 0x8(%rsp), %rdi
movl %ebp, %esi
xorl %eax, %eax
callq 0x11d0
movl %eax, %ebp
testl %eax, %eax
js 0x63bb
btl $0xc, %r14d
movq (%rsp), %r15
jae 0x632c
movl %ebp, %edi
xorl %esi, %esi
movq %r15, %rdx
movl $0x5, %ecx
callq 0x1120
btl $0x8, %r14d
jae 0x6344
movl %ebp, %edi
xorl %esi, %esi
movq %r15, %rdx
movl $0x1, %ecx
callq 0x1120
btl $0x9, %r14d
jae 0x635c
movl %ebp, %edi
xorl %esi, %esi
movq %r15, %rdx
movl $0x2, %ecx
callq 0x1120
btl $0xe, %r14d
movq 0x8(%rsp), %r12
jae 0x6379
movl %ebp, %edi
xorl %esi, %esi
movq %r15, %rdx
movl $0x4, %ecx
callq 0x1120
addl $0x2, %r13d
btl $0xd, %r14d
jae 0x6395
movl %ebp, %edi
xorl %esi, %esi
movq %r15, %rdx
movl $0x3, %ecx
callq 0x1120
movq 0x8(%rbx), %rsi
xorl %edi, %edi
movl 0x14(%rsp), %edx
movl %r13d, %ecx
movl %ebp, %r8d
xorl %r9d, %r9d
callq 0x10b0
movq %rax, (%rbx)
testq %rax, %rax
je 0x63c8
cmpq $-0x1, %rax
jne 0x63d3
callq 0x1040
movl (%rax), %r12d
jmp 0x64c6
movl $0xc, %r12d
jmp 0x64c6
btl $0x8, %r14d
jae 0x6400
movq %r12, %r13
movq 0x8(%rbx), %rsi
movq %rax, %rdi
movl $0x1, %edx
callq 0x1220
movl %eax, %r12d
movq (%rbx), %rax
testl %r12d, %r12d
jne 0x6480
movq %r13, %r12
btl $0x9, %r14d
jae 0x6429
movq %r12, %r13
movq 0x8(%rbx), %rsi
movq %rax, %rdi
movl $0x2, %edx
callq 0x1220
movl %eax, %r12d
movq (%rbx), %rax
testl %r12d, %r12d
jne 0x6480
movq %r13, %r12
btl $0xe, %r14d
jae 0x6452
movq %r12, %r13
movq 0x8(%rbx), %rsi
movq %rax, %rdi
movl $0x4, %edx
callq 0x1220
movl %eax, %r12d
movq (%rbx), %rax
testl %r12d, %r12d
jne 0x6480
movq %r13, %r12
testq %r12, %r12
sete %cl
btl $0xd, %r14d
setae %dl
orb %cl, %dl
jne 0x6495
movq 0x8(%rbx), %rsi
movq %rax, %rdi
movl $0x3, %edx
callq 0x1220
movl %eax, %r12d
movq (%rbx), %rax
testl %r12d, %r12d
je 0x6495
movq 0x8(%rbx), %rsi
movq %rax, %rdi
callq 0x11b0
movq $0x0, (%rbx)
jmp 0x64c6
cmpq $0x4000001, %r15        # imm = 0x4000001
jb 0x64b2
movq 0x8(%rbx), %rsi
movq %rax, %rdi
movl $0xe, %edx
callq 0x11c0
movq (%rbx), %rax
movq 0x8(%rbx), %rsi
movq %rax, %rdi
movl $0x10, %edx
callq 0x11c0
xorl %r12d, %r12d
movl %r12d, %eax
addq $0xa8, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq