// File: /workspace/github_c_makefile_star2_O3/ggerganov[P]font-rasterizer/./stb_truetype.h
// Function: stbtt_FindGlyphIndex
STBTT_DEF int stbtt_FindGlyphIndex(const stbtt_fontinfo *info, int unicode_codepoint)
{
   stbtt_uint8 *data = info->data;
   stbtt_uint32 index_map = info->index_map;

   stbtt_uint16 format = ttUSHORT(data + index_map + 0);
   if (format == 0) { // apple byte encoding
      stbtt_int32 bytes = ttUSHORT(data + index_map + 2);
      if (unicode_codepoint < bytes-6)
         return ttBYTE(data + index_map + 6 + unicode_codepoint);
      return 0;
   } else if (format == 6) {
      stbtt_uint32 first = ttUSHORT(data + index_map + 6);
      stbtt_uint32 count = ttUSHORT(data + index_map + 8);
      if ((stbtt_uint32) unicode_codepoint >= first && (stbtt_uint32) unicode_codepoint < first+count)
         return ttUSHORT(data + index_map + 10 + (unicode_codepoint - first)*2);
      return 0;
   } else if (format == 2) {
      STBTT_assert(0); // @TODO: high-byte mapping for japanese/chinese/korean
      return 0;
   } else if (format == 4) { // standard mapping for windows fonts: binary search collection of ranges
      stbtt_uint16 segcount = ttUSHORT(data+index_map+6) >> 1;
      stbtt_uint16 searchRange = ttUSHORT(data+index_map+8) >> 1;
      stbtt_uint16 entrySelector = ttUSHORT(data+index_map+10);
      stbtt_uint16 rangeShift = ttUSHORT(data+index_map+12) >> 1;

      // do a binary search of the segments
      stbtt_uint32 endCount = index_map + 14;
      stbtt_uint32 search = endCount;

      if (unicode_codepoint > 0xffff)
         return 0;

      // they lie from endCount .. endCount + segCount
      // but searchRange is the nearest power of two, so...
      if (unicode_codepoint >= ttUSHORT(data + search + rangeShift*2))
         search += rangeShift*2;

      // now decrement to bias correctly to find smallest
      search -= 2;
      while (entrySelector) {
         stbtt_uint16 end;
         searchRange >>= 1;
         end = ttUSHORT(data + search + searchRange*2);
         if (unicode_codepoint > end)
            search += searchRange*2;
         --entrySelector;
      }
      search += 2;

      {
         stbtt_uint16 offset, start;
         stbtt_uint16 item = (stbtt_uint16) ((search - endCount) >> 1);

         STBTT_assert(unicode_codepoint <= ttUSHORT(data + endCount + 2*item));
         start = ttUSHORT(data + index_map + 14 + segcount*2 + 2 + 2*item);
         if (unicode_codepoint < start)
            return 0;

         offset = ttUSHORT(data + index_map + 14 + segcount*6 + 2 + 2*item);
         if (offset == 0)
            return (stbtt_uint16) (unicode_codepoint + ttSHORT(data + index_map + 14 + segcount*4 + 2 + 2*item));

         return ttUSHORT(data + offset + (unicode_codepoint-start)*2 + index_map + 14 + segcount*6 + 2 + 2*item);
      }
   } else if (format == 12 || format == 13) {
      stbtt_uint32 ngroups = ttULONG(data+index_map+12);
      stbtt_int32 low,high;
      low = 0; high = (stbtt_int32)ngroups;
      // Binary search the right group.
      while (low < high) {
         stbtt_int32 mid = low + ((high-low) >> 1); // rounds down, so low <= mid < high
         stbtt_uint32 start_char = ttULONG(data+index_map+16+mid*12);
         stbtt_uint32 end_char = ttULONG(data+index_map+16+mid*12+4);
         if ((stbtt_uint32) unicode_codepoint < start_char)
            high = mid;
         else if ((stbtt_uint32) unicode_codepoint > end_char)
            low = mid+1;
         else {
            stbtt_uint32 start_glyph = ttULONG(data+index_map+16+mid*12+8);
            if (format == 12)
               return start_glyph + unicode_codepoint-start_char;
            else // format == 13
               return start_glyph;
         }
      }
      return 0; // not found
   }
   // @TODO
   STBTT_assert(0);
   return 0;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
pushq %rbx
pushq %rax
movq 0x8(%rdi), %rax
movl 0x34(%rdi), %edx
leaq (%rax,%rdx), %rcx
movzwl (%rax,%rdx), %edi
rolw $0x8, %di
cmpw $0x6, %di
ja 0x35ed
movzwl %di, %r8d
leaq 0x9a7c(%rip), %r9       # 0xd040
movslq (%r9,%r8,4), %r8
addq %r9, %r8
jmpq *%r8
movzwl 0x2(%rcx), %eax
rolw $0x8, %ax
movzwl %ax, %eax
addl $-0x6, %eax
cmpl %esi, %eax
jle 0x3658
movslq %esi, %rax
movzbl 0x6(%rcx,%rax), %eax
jmp 0x3802
movl %edi, %eax
andl $0xfffe, %eax           # imm = 0xFFFE
cmpw $0xc, %ax
jne 0x3809
movl 0xc(%rcx), %eax
bswapl %eax
testl %eax, %eax
jle 0x3658
xorl %edx, %edx
movl %eax, %r8d
subl %edx, %r8d
sarl %r8d
addl %edx, %r8d
movslq %r8d, %r9
shlq $0x2, %r9
leaq (%r9,%r9,2), %r9
movl 0x10(%rcx,%r9), %r11d
bswapl %r11d
movl %esi, %r10d
subl %r11d, %r10d
jae 0x3635
movl %r8d, %eax
jmp 0x364a
movl 0x14(%rcx,%r9), %edx
bswapl %edx
cmpl %esi, %edx
jae 0x3728
incl %r8d
movl %r8d, %edx
cmpl %eax, %edx
jl 0x3609
jmp 0x3658
cmpl $0xffff, %esi           # imm = 0xFFFF
jle 0x36a3
xorl %eax, %eax
jmp 0x3802
movzwl 0x6(%rcx), %eax
rolw $0x8, %ax
movzwl %ax, %edi
xorl %eax, %eax
movl %esi, %edx
subl %edi, %edx
jb 0x3802
movzwl 0x8(%rcx), %r8d
rolw $0x8, %r8w
movzwl %r8w, %r8d
addl %edi, %r8d
cmpl %esi, %r8d
jbe 0x3802
addl %edx, %edx
movzwl 0xa(%rcx,%rdx), %eax
rolw $0x8, %ax
movzwl %ax, %eax
jmp 0x3802
leal 0xe(%rdx), %r8d
movzbl 0xc(%rax,%rdx), %edi
movzwl 0xa(%rax,%rdx), %r9d
rolw $0x8, %r9w
shll $0x8, %edi
movzbl 0xd(%rax,%rdx), %r10d
andl $-0x2, %r10d
orq %rdi, %r10
addq %rax, %r8
movzwl (%r8,%r10), %edi
rolw $0x8, %di
movzwl %di, %edi
xorl %r11d, %r11d
cmpl %esi, %edi
cmovgl %r11d, %r10d
addl %edx, %r10d
addl $0xc, %r10d
testw %r9w, %r9w
je 0x3740
movzwl 0x8(%rcx), %r11d
rolw $0x8, %r11w
movzwl %r11w, %r11d
shrl %r11d
movl %r10d, %ebx
addq %rax, %rbx
movl %r11d, %edi
andl $-0x2, %edi
movzwl (%rdi,%rbx), %ebx
rolw $0x8, %bx
movzwl %bx, %ebx
cmpl %esi, %ebx
jl 0x371a
xorl %edi, %edi
addl %r10d, %edi
movl %edi, %r10d
decw %r9w
jne 0x36f6
jmp 0x3743
xorl %eax, %eax
cmpw $0xc, %di
movl 0x18(%rcx,%r9), %ecx
bswapl %ecx
cmovel %r10d, %eax
addl %ecx, %eax
jmp 0x3802
movl %r10d, %edi
subl %edx, %edi
addl $0x1fff4, %edi          # imm = 0x1FFF4
andl $0x1fffe, %edi          # imm = 0x1FFFE
movzwl (%r8,%rdi), %r8d
rolw $0x8, %r8w
movzwl %r8w, %r8d
cmpl %esi, %r8d
jl 0x3847
movzwl 0x6(%rcx), %r8d
rolw $0x8, %r8w
movzwl %r8w, %r8d
movl %r8d, %r9d
andl $-0x2, %r9d
addq %rcx, %r9
addq $0xe, %r9
movzwl 0x2(%rdi,%r9), %r9d
rolw $0x8, %r9w
movzwl %r9w, %r11d
xorl %r10d, %r10d
movl %esi, %r9d
subl %r11d, %r9d
jl 0x37fe
shrl %r8d
addq $0xe, %rcx
leal (%r8,%r8), %r10d
leaq (%r10,%r10,2), %r10
leaq (%rcx,%r10), %r11
movzwl 0x2(%rdi,%r11), %r11d
rolw $0x8, %r11w
testw %r11w, %r11w
je 0x37e7
movzwl %r11w, %ecx
addq %rcx, %rax
addl %r9d, %r9d
movslq %r9d, %rcx
addq %rdx, %rax
addq %r10, %rax
addq %rcx, %rax
movzwl 0x10(%rdi,%rax), %eax
rolw $0x8, %ax
movzwl %ax, %r10d
jmp 0x37fe
movl %r8d, %eax
leaq (%rcx,%rax,4), %rax
movzwl 0x2(%rdi,%rax), %eax
rolw $0x8, %ax
movzwl %ax, %r10d
addl %esi, %r10d
movzwl %r10w, %eax
addq $0x8, %rsp
popq %rbx
popq %rbp
retq
leaq 0xb556(%rip), %rdi      # 0xed66
leaq 0xb451(%rip), %rsi      # 0xec68
leaq 0xb45b(%rip), %rcx      # 0xec79
movl $0x5fd, %edx            # imm = 0x5FD
callq 0x10c0
leaq 0xb537(%rip), %rdi      # 0xed66
leaq 0xb432(%rip), %rsi      # 0xec68
leaq 0xb43c(%rip), %rcx      # 0xec79
movl $0x5b6, %edx            # imm = 0x5B6
callq 0x10c0
leaq 0xb461(%rip), %rdi      # 0xecaf
leaq 0xb413(%rip), %rsi      # 0xec68
leaq 0xb41d(%rip), %rcx      # 0xec79
movl $0x5da, %edx            # imm = 0x5DA
callq 0x10c0