LLM4Binary/decompile-bench-makefile huggingface dataset:
// File: /workspace/github_c_makefile_star2_O1/justy989[P]ce/ce.c
// Function: ce_utf8_strlen
int64_t ce_utf8_strlen(const char* string){
     int64_t len = 0;
     int64_t byte_count = 0;

     while(*string){
          if((*string & 0x80) == 0){
               byte_count = 1;
          }else if((*string & 0xE0) == 0xC0){
               byte_count = 2;
          }else if((*string & 0xF0) == 0xE0){
               byte_count = 3;
          }else if((*string & 0xF8) == 0xF0){
               byte_count = 4;
          }else{
               assert(!"unicode character claiming it has more than 4 bytes?!");
               return -1;
          }

          // validate string doesn't early terminate
          for(int64_t i = 0; i < byte_count; i++){
               if(*string == 0) return -1;
               string++;
          }

          len++;
     }

     return len;
}

// Assembly:
pushq %rax
movb (%rdi), %dl
xorl %eax, %eax
testb %dl, %dl
je 0xe4f3
movl $0x1, %ecx
testb %dl, %dl
jns 0xe4ce
movzbl %dl, %edx
movl %edx, %esi
andl $-0x20, %esi
movl $0x2, %ecx
cmpl $0xc0, %esi
je 0xe4ce
movl %edx, %esi
andl $-0x10, %esi
movl $0x3, %ecx
cmpl $0xe0, %esi
je 0xe4ce
andl $-0x8, %edx
movl $0x4, %ecx
cmpl $0xf0, %edx
jne 0xe4f5
leaq (%rdi,%rcx), %rsi
xorl %edx, %edx
cmpb $0x0, (%rdi,%rdx)
je 0xe4ec
incq %rdx
cmpq %rdx, %rcx
jne 0xe4d4
incq %rax
movb (%rsi), %dl
movq %rsi, %rdi
jmp 0xe48a
movq $-0x1, %rax
popq %rcx
retq
leaq 0x20229(%rip), %rdi     # 0x2e725
leaq 0x20175(%rip), %rsi     # 0x2e678
leaq 0x20254(%rip), %rcx     # 0x2e75e
movl $0x531, %edx            # imm = 0x531
callq 0xd280
// File: /workspace/github_c_makefile_star2_O1/justy989[P]ce/ce.c
// Function: ce_buffer_point_is_valid
int64_t ce_buffer_point_is_valid(CeBuffer_t* buffer, CePoint_t point){
     if(point.y < 0 || point.y >= buffer->line_count || point.x < 0) return false;
     int64_t line_len = ce_utf8_strlen(buffer->lines[point.y]);
     if(point.x > line_len) return false;

     return true;
}

// Assembly:
testq %rdx, %rdx
js 0xe532
pushq %rbx
movq %rsi, %rbx
cmpq %rdx, 0x8(%rdi)
setle %al
testq %rsi, %rsi
sets %cl
orb %al, %cl
je 0xe535
xorl %eax, %eax
jmp 0xe54c
xorl %eax, %eax
retq
movq (%rdi), %rax
movq (%rax,%rdx,8), %rdi
callq 0xe485
movq %rax, %rcx
xorl %eax, %eax
cmpq %rbx, %rcx
setge %al
popq %rbx
retq
// File: /workspace/github_c_makefile_star2_O1/justy989[P]ce/ce.c
// Function: ce_buffer_get_rune
CeRune_t ce_buffer_get_rune(CeBuffer_t* buffer, CePoint_t point){
     if(!ce_buffer_point_is_valid(buffer, point)) return CE_UTF8_INVALID;

     char* str = ce_utf8_iterate_to(buffer->lines[point.y], point.x);
     int64_t rune_len = 0;
     return ce_utf8_decode(str, &rune_len);
}

// Assembly:
pushq %r15
pushq %r14
pushq %r12
pushq %rbx
pushq %rax
movl $0xffffffff, %ebx       # imm = 0xFFFFFFFF
testq %rdx, %rdx
js 0xe5b0
movq %rdx, %r15
movq %rsi, %r14
movq %rdi, %r12
cmpq %rdx, 0x8(%rdi)
setle %al
testq %rsi, %rsi
sets %cl
orb %al, %cl
jne 0xe5b0
movq (%r12), %rax
movq (%rax,%r15,8), %rdi
callq 0xe485
cmpq %r14, %rax
jl 0xe5b0
movq (%r12), %rax
movq (%rax,%r15,8), %rdi
movq %r14, %rsi
callq 0xe5be
movq %rsp, %rsi
movq $0x0, (%rsi)
movq %rax, %rdi
callq 0xe649
movl %eax, %ebx
movl %ebx, %eax
addq $0x8, %rsp
popq %rbx
popq %r12
popq %r14
popq %r15
retq
// File: /workspace/github_c_makefile_star2_O1/justy989[P]ce/ce.c
// Function: ce_utf8_iterate_to
char* ce_utf8_iterate_to(char* string, int64_t index){
     int64_t bytes = 0;
     while(index){
          if((*string & 0x80) == 0){
               bytes = 1;
          }else if((*string & 0xE0) == 0xC0){
               bytes = 2;
          }else if((*string & 0xF0) == 0xE0){
               bytes = 3;
          }else if((*string & 0xF8) == 0xF0){
               bytes = 4;
          }else{
               assert(!"unicode character claiming it has more than 4 bytes?!");
               return NULL;
          }

          for(int64_t i = 0; i < bytes; ++i){
               if(*string == 0){
                    return NULL;
               }
               string++;
          }

          index--;
     }

     return string;
}

// Assembly:
pushq %rax
testq %rsi, %rsi
je 0xe625
movzbl (%rdi), %eax
movl $0x1, %ecx
testb %al, %al
jns 0xe603
movl %eax, %edx
andl $-0x20, %edx
movl $0x2, %ecx
cmpl $0xc0, %edx
je 0xe603
movl %eax, %edx
andl $-0x10, %edx
movl $0x3, %ecx
cmpl $0xe0, %edx
je 0xe603
andl $-0x8, %eax
movl $0x4, %ecx
cmpl $0xf0, %eax
jne 0xe62a
leaq (%rdi,%rcx), %rax
xorl %edx, %edx
cmpb $0x0, (%rdi,%rdx)
je 0xe621
incq %rdx
cmpq %rdx, %rcx
jne 0xe609
movq %rax, %rdi
decq %rsi
jne 0xe5c4
jmp 0xe628
xorl %eax, %eax
jmp 0xe628
movq %rdi, %rax
popq %rcx
retq
leaq 0x200f4(%rip), %rdi     # 0x2e725
leaq 0x20040(%rip), %rsi     # 0x2e678
leaq 0x2017f(%rip), %rcx     # 0x2e7be
movl $0x572, %edx            # imm = 0x572
callq 0xd280
// File: /workspace/github_c_makefile_star2_O1/justy989[P]ce/ce.c
// Function: ce_utf8_decode
CeRune_t ce_utf8_decode(const char* string, int64_t* bytes_consumed){
     CeRune_t rune = CE_UTF8_INVALID;

     // 0xxxxxxx is just ascii
     if((*string & 0x80) == 0){
          *bytes_consumed = 1;
          rune = string[0];
     // 110xxxxx is a 2 byte utf8 string
     }else if((*string & 0xE0) == 0xC0){
          *bytes_consumed = 2;
          rune = string[0] & 0x1F;
          rune <<= 6;
          rune |= string[1] & 0x3F;
     // 1110xxxx is a 3 byte utf8 string
     }else if((*string & 0xF0) == 0xE0){
          *bytes_consumed = 3;
          rune = string[0] & 0x0F;
          rune <<= 6;
          rune |= string[1] & 0x3F;
          rune <<= 6;
          rune |= string[2] & 0x3F;
     // 11110xxx is a 4 byte utf8 string
     }else if((*string & 0xF8) == 0xF0){
          *bytes_consumed = 4;
          rune = string[0] & 0x0F;
          rune <<= 6;
          rune |= string[1] & 0x3F;
          rune <<= 6;
          rune |= string[2] & 0x3F;
          rune <<= 6;
          rune |= string[3] & 0x3F;
     }

     return rune;
}

// Assembly:
movzbl (%rdi), %ecx
testb %cl, %cl
js 0xe65b
movq $0x1, (%rsi)
movsbl (%rdi), %eax
retq
movl %ecx, %eax
andl $-0x20, %eax
cmpl $0xc0, %eax
jne 0xe67d
movq $0x2, (%rsi)
movzbl (%rdi), %ecx
andl $0x1f, %ecx
shll $0x6, %ecx
movzbl 0x1(%rdi), %eax
jmp 0xe6a9
movl %ecx, %eax
andl $-0x10, %eax
cmpl $0xe0, %eax
jne 0xe6af
movq $0x3, (%rsi)
movzbl (%rdi), %eax
andl $0xf, %eax
movzbl 0x1(%rdi), %ecx
andl $0x3f, %ecx
shll $0xc, %eax
shll $0x6, %ecx
orl %eax, %ecx
movzbl 0x2(%rdi), %eax
andl $0x3f, %eax
orl %ecx, %eax
retq
andl $-0x8, %ecx
movl $0xffffffff, %eax       # imm = 0xFFFFFFFF
cmpl $0xf0, %ecx
jne 0xe6f0
movq $0x4, (%rsi)
movzbl (%rdi), %eax
andl $0xf, %eax
movzbl 0x1(%rdi), %ecx
andl $0x3f, %ecx
shll $0xc, %eax
shll $0x6, %ecx
orl %eax, %ecx
movzbl 0x2(%rdi), %edx
andl $0x3f, %edx
orl %ecx, %edx
shll $0x6, %edx
movzbl 0x3(%rdi), %eax
andl $0x3f, %eax
orl %edx, %eax
retq
// File: /workspace/github_c_makefile_star2_O1/justy989[P]ce/ce.c
// Function: ce_buffer_search_forward
CePoint_t ce_buffer_search_forward(CeBuffer_t* buffer, CePoint_t start, const char* pattern){
     CePoint_t result = (CePoint_t){-1, -1};

     if(!ce_buffer_point_is_valid(buffer, start)) return result;

     int64_t save_y = start.y;
     char* itr = ce_utf8_iterate_to(buffer->lines[start.y], start.x);
     char* match = NULL;

     // try to match the pattern on each line to the end
     while(true){
          match = strstr(itr, pattern);
          if(match) break;
          start.y++;
          if(start.y >= buffer->line_count) break;
          itr = buffer->lines[start.y];
     }

     if(match){
          // figure out index in the line
          int64_t index = 0;
          int64_t rune_len = 0;
          while(match > itr){
               ce_utf8_decode(itr, &rune_len);
               itr += rune_len;
               index++;
          }

          if(start.y == save_y){
               // if we are on the same line, use the starting x plus the index
               result.x = start.x + index;
          }else{
               result.x = index;
          }
          result.y = start.y;
     }

     return result;
}

// Assembly:
movq $-0x1, %rax
testq %rdx, %rdx
js 0xe734
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x28, %rsp
movq %rcx, %rbp
movq %rdx, %r15
movq %rsi, %r14
movq %rdi, %rbx
cmpq %rdx, 0x8(%rdi)
setle %dl
testq %rsi, %rsi
sets %cl
orb %dl, %cl
je 0xe73c
movq $-0x1, %rdx
jmp 0xe831
movq $-0x1, %rdx
retq
movq (%rbx), %rax
movq (%rax,%r15,8), %rdi
callq 0xe485
cmpq %r14, %rax
jge 0xe760
movq $-0x1, %rdx
movq $-0x1, %rax
jmp 0xe831
movq (%rbx), %rax
movq (%rax,%r15,8), %rdi
movq %r14, 0x18(%rsp)
movq %r14, %rsi
callq 0xe5be
movq %rax, %r12
movq %rax, %rdi
movq %rbp, %rsi
callq 0xd6f0
movq %rax, %r13
testq %rax, %rax
sete %cl
je 0xe792
movq %r15, %r14
jmp 0xe7e1
movq 0x8(%rbx), %rdx
leaq 0x1(%r15), %r14
movq %r14, %rax
cmpq %r14, %rdx
movq %rdx, 0x20(%rsp)
cmovgq %rdx, %rax
jle 0xe7de
movq %rax, 0x10(%rsp)
movq (%rbx), %rbx
movq (%rbx,%r14,8), %r12
movq %r12, %rdi
movq %rbp, %rsi
callq 0xd6f0
movq %rax, %r13
testq %rax, %rax
sete %cl
jne 0xe7e1
incq %r14
cmpq 0x20(%rsp), %r14
jl 0xe7b3
movq 0x10(%rsp), %r14
jmp 0xe7e1
movq %rax, %r14
movq $-0x1, %rax
movq $-0x1, %rdx
testb %cl, %cl
jne 0xe831
movq $0x0, 0x8(%rsp)
xorl %ebp, %ebp
cmpq %r12, %r13
jbe 0xe820
leaq 0x8(%rsp), %rbx
movq %r12, %rdi
movq %rbx, %rsi
callq 0xe649
addq 0x8(%rsp), %r12
incq %rbp
cmpq %r12, %r13
ja 0xe808
xorl %eax, %eax
cmpq %r15, %r14
cmoveq 0x18(%rsp), %rax
addq %rbp, %rax
movq %r14, %rdx
addq $0x28, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
// File: /workspace/github_c_makefile_star2_O1/justy989[P]ce/ce.c
// Function: ce_buffer_search_backward
CePoint_t ce_buffer_search_backward(CeBuffer_t* buffer, CePoint_t start, const char* pattern){
     CePoint_t result = (CePoint_t){-1, -1};

     if(!ce_buffer_point_is_valid(buffer, start)) return result;

     char* beginning_of_line = buffer->lines[start.y];
     char* itr = ce_utf8_iterate_to(beginning_of_line, start.x);
     bool match = false;
     size_t pattern_len = strlen(pattern);

     // try to match the pattern on each line to the end
     while(true){
          while(itr > beginning_of_line){
               if(strncmp(itr, pattern, pattern_len) == 0){
                    match = true;
                    break;
               }

               itr--;
          }
          if(match) break;
          start.y--;
          if(start.y < 0) break;
          beginning_of_line = buffer->lines[start.y];
          itr = beginning_of_line + ce_utf8_last_index(beginning_of_line);
     }

     if(match){
          // figure out index in the line
          int64_t index = 0;
          int64_t rune_len = 0;
          while(itr > beginning_of_line){
               ce_utf8_decode(beginning_of_line, &rune_len);
               beginning_of_line += rune_len;
               index++;
          }

          result.x = index;
          result.y = start.y;
     }

     return result;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x18, %rsp
movq $-0x1, %rbx
testq %rdx, %rdx
js 0xe888
movq %rcx, %r12
movq %rdx, %r14
movq %rsi, %r13
movq %rdi, %r15
cmpq %rdx, 0x8(%rdi)
setle %al
testq %rsi, %rsi
sets %cl
orb %al, %cl
jne 0xe888
movq (%r15), %rax
movq (%rax,%r14,8), %rdi
callq 0xe485
cmpq %r13, %rax
jge 0xe8a1
movq $-0x1, %rdx
movq %rbx, %rax
addq $0x18, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
movq %r15, 0x10(%rsp)
movq (%r15), %rax
movq (%rax,%r14,8), %r15
movq %r15, %rdi
movq %r13, %rsi
callq 0xe5be
movq %rax, %r13
movq %r12, %rdi
callq 0xd210
movq %rax, %rbp
movl $0x0, 0x4(%rsp)
cmpq %r15, %r13
jbe 0xe8f8
movq %r13, %rdi
movq %r12, %rsi
movq %rbp, %rdx
callq 0xd0d0
testl %eax, %eax
je 0xe8f2
decq %r13
cmpq %r15, %r13
ja 0xe8d3
movq %r15, %r13
jmp 0xe8f8
movb $0x1, %al
movl %eax, 0x4(%rsp)
testb $0x1, 0x4(%rsp)
jne 0xe936
testq %r14, %r14
jle 0xe92f
movq 0x10(%rsp), %rax
movq (%rax), %rax
movq -0x8(%rax,%r14,8), %r15
decq %r14
movq %r15, %rdi
callq 0xe485
movq %rax, %r13
xorl %eax, %eax
testq %r13, %r13
setg %al
addq %r15, %r13
subq %rax, %r13
jmp 0xe8ce
movq $-0x1, %r14
movq $-0x1, %rdx
testb $0x1, 0x4(%rsp)
je 0xe88f
movq $0x0, 0x8(%rsp)
xorl %ebx, %ebx
cmpq %r15, %r13
jbe 0xe975
leaq 0x8(%rsp), %r12
movq %r15, %rdi
movq %r12, %rsi
callq 0xe649
addq 0x8(%rsp), %r15
incq %rbx
cmpq %r15, %r13
ja 0xe95d
movq %r14, %rdx
jmp 0xe88f
// File: /workspace/github_c_makefile_star2_O1/justy989[P]ce/ce.c
// Function: ce_buffer_regex_search_forward
CeRegexSearchResult_t ce_buffer_regex_search_forward(CeBuffer_t* buffer, CePoint_t start, CeRegex_t regex){
     CeRegexSearchResult_t result = {(CePoint_t){-1, -1}, -1};

     if(!ce_buffer_point_is_valid(buffer, start)) return result;

     while(start.y < buffer->line_count){
          CeRegexResult_t regex_result = ce_regex_match(regex,
                                                        buffer->lines[start.y] + start.x);
          if(regex_result.error_message != NULL){
               ce_log("ce_regex_match() failed: %s", regex_result.error_message);
               free(regex_result.error_message);
               break;
          }
          if(regex_result.match_start != CE_REGEX_NO_MATCH){
               result.point = start;
               result.point.x += regex_result.match_start;
               result.length = regex_result.match_length;
               break;
          }
          start.y++;
          start.x = 0;
     }

     return result;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x38, %rsp
movq %rdi, %rbx
pcmpeqd %xmm0, %xmm0
movdqu %xmm0, (%rdi)
movq $-0x1, 0x10(%rdi)
testq %rcx, %rcx
js 0xea9e
movq %rcx, %r15
movq %rdx, %r13
movq %rsi, %r12
cmpq %rcx, 0x8(%rsi)
setle %al
testq %rdx, %rdx
sets %cl
orb %al, %cl
jne 0xea9e
movq %r8, %r14
movq (%r12), %rax
movq (%rax,%r15,8), %rdi
callq 0xe485
cmpq %r13, %rax
jl 0xea9e
movq (%rbx), %rax
movq %rax, 0x10(%rsp)
movq 0x8(%rbx), %rax
movq %rax, 0x8(%rsp)
movq 0x10(%rbx), %rax
movq %rax, 0x18(%rsp)
cmpq 0x8(%r12), %r15
jge 0xea84
movq (%r12), %rax
movq (%rax,%r15,8), %rdx
addq %r13, %rdx
leaq 0x20(%rsp), %rdi
movq %r14, %rsi
callq 0x1f4a0
movq 0x20(%rsp), %rsi
testq %rsi, %rsi
je 0xea50
xorl %ebp, %ebp
leaq 0x1fc12(%rip), %rdi     # 0x2e64f
xorl %eax, %eax
callq 0xd954
movq 0x20(%rsp), %rdi
callq 0xd090
jmp 0xea7f
movq 0x28(%rsp), %rax
cmpq $-0x1, %rax
je 0xea76
addq %r13, %rax
movq 0x30(%rsp), %rcx
movq %rcx, 0x18(%rsp)
xorl %ebp, %ebp
movq %r15, 0x8(%rsp)
movq %rax, 0x10(%rsp)
jmp 0xea7f
incq %r15
movb $0x1, %bpl
xorl %r13d, %r13d
testb %bpl, %bpl
jne 0xea0b
movq 0x8(%rsp), %rax
movq %rax, 0x8(%rbx)
movq 0x18(%rsp), %rax
movq %rax, 0x10(%rbx)
movq 0x10(%rsp), %rax
movq %rax, (%rbx)
movq %rbx, %rax
addq $0x38, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
// File: /workspace/github_c_makefile_star2_O1/justy989[P]ce/ce.c
// Function: ce_buffer_range_len
int64_t ce_buffer_range_len(CeBuffer_t* buffer, CePoint_t start, CePoint_t end){
     if(!ce_buffer_point_is_valid(buffer, start)) return -1;
     if(!ce_buffer_point_is_valid(buffer, end)) return -1;
     if(ce_point_after(start, end)) return -1; // TODO: calculate negative value?

     // easy case where they are on the same line
     if(start.y == end.y) return (end.x - start.x) + 1;

     int64_t length = 0;
     for(int64_t y = start.y; y <= end.y; ++y){
          if(y == start.y){
               // count from the star to the end of the line
               length = ce_utf8_strlen(ce_utf8_iterate_to(buffer->lines[y], start.x)) + 1;
          }else if(y == end.y){
               length += end.x + 1;
          }else{
               // count entire line
               int64_t line_length = ce_utf8_strlen(buffer->lines[y]) + 1;
               if(line_length == 0) length++;
               length += line_length;
          }
     }

     return length;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x18, %rsp
movq $-0x1, %rbp
testq %rdx, %rdx
js 0xede9
movq %rcx, %r14
movq %rdx, %r15
movq %rsi, %r12
movq %rdi, %r13
cmpq %rdx, 0x8(%rdi)
setle %al
testq %rsi, %rsi
sets %cl
orb %al, %cl
jne 0xede9
movq %r8, %rbx
movq (%r13), %rax
movq (%rax,%r15,8), %rdi
callq 0xe485
cmpq %r12, %rax
jl 0xede9
movb $0x1, %al
testq %rbx, %rbx
js 0xed38
cmpq %rbx, 0x8(%r13)
setle %cl
testq %r14, %r14
sets %dl
orb %cl, %dl
jne 0xed38
movq (%r13), %rax
movq (%rax,%rbx,8), %rdi
callq 0xe485
cmpq %r14, %rax
setl %al
cmpq %r15, %rbx
setl %cl
orb %al, %cl
jne 0xede9
cmpq %r15, %rbx
sete %cl
movq %r14, %rax
subq %r12, %rax
setl %dl
testb %dl, %cl
jne 0xede9
cmpq %rbx, %r15
jne 0xed6a
incq %rax
movq %rax, %rbp
jmp 0xede9
jle 0xed70
xorl %ebp, %ebp
jmp 0xede9
incq %r14
leaq 0x1(%rbx), %rax
movq %rax, 0x10(%rsp)
xorl %eax, %eax
xorl %ebp, %ebp
movq %r14, 0x8(%rsp)
subq $0x1, %rax
jae 0xedb6
movq %rax, %r14
movq (%r13), %rax
movq (%rax,%r15,8), %rdi
movq %r12, %rsi
callq 0xe5be
movq %rax, %rdi
callq 0xe485
movq %rax, %rbp
movq %r14, %rax
movq 0x8(%rsp), %r14
incq %rbp
jmp 0xeddf
cmpq %r15, %rbx
jne 0xedc0
addq %r14, %rbp
jmp 0xeddf
movq %rax, %r14
movq (%r13), %rax
movq (%rax,%r15,8), %rdi
callq 0xe485
addq $0x1, %rax
adcq %rax, %rbp
movq %r14, %rax
movq 0x8(%rsp), %r14
incq %r15
cmpq %r15, 0x10(%rsp)
jne 0xed85
movq %rbp, %rax
addq $0x18, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
// File: /workspace/github_c_makefile_star2_O1/justy989[P]ce/ce.c
// Function: ce_buffer_move_point
CePoint_t ce_buffer_move_point(CeBuffer_t* buffer, CePoint_t point, CePoint_t delta, int64_t tab_width, CeClampX_t clamp_x){
     if(delta.y){
          CE_CLAMP(point.y, 0, (buffer->line_count - 1));

          // figure out where we are visibly (due to tabs being variable length)
          int64_t cur_visible_index = ce_util_string_index_to_visible_index(buffer->lines[point.y], point.x, tab_width);

          // move to the new line
          point.y += delta.y;

          // always clamp y
          CE_CLAMP(point.y, 0, (buffer->line_count - 1));

          // convert the x from visible index to a string index
          point.x = ce_util_visible_index_to_string_index(buffer->lines[point.y], cur_visible_index, tab_width);
     }

     point.x += delta.x;
     int64_t line_len = ce_buffer_line_len(buffer, point.y);

     switch(clamp_x){
     case CE_CLAMP_X_NONE:
          break;
     case CE_CLAMP_X_ON:
          CE_CLAMP(point.x, 0, line_len);
          break;
     case CE_CLAMP_X_INSIDE:
          if(line_len == 0){
               point.x = 0;
          }else{
               CE_CLAMP(point.x, 0, (line_len - 1));
          }
          break;
     }

     return point;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
pushq %rax
movq %rcx, %r15
movq %rdx, %rbx
movq %rsi, %r14
movq %rdi, %r12
testq %r8, %r8
je 0xeeb3
movq %r9, %r13
movq %r8, %rbp
movq %r15, (%rsp)
testq %rbx, %rbx
js 0xee6a
movq 0x8(%r12), %rax
leaq -0x1(%rax), %r15
cmpq %rbx, %rax
cmovgq %rbx, %r15
jmp 0xee6d
xorl %r15d, %r15d
movq (%r12), %rax
movq (%rax,%r15,8), %rdi
movq %r14, %rsi
movq %r13, %rdx
callq 0xef1b
addq %r15, %rbp
js 0xee97
movq 0x8(%r12), %rcx
leaq -0x1(%rcx), %rbx
cmpq %rcx, %rbp
cmovlq %rbp, %rbx
jmp 0xee99
xorl %ebx, %ebx
movq (%rsp), %r15
movq (%r12), %rcx
movq (%rcx,%rbx,8), %rdi
movq %rax, %rsi
movq %r13, %rdx
callq 0xef8d
movq %rax, %r14
movl 0x40(%rsp), %ebp
movq $-0x1, %rax
testq %rbx, %rbx
js 0xeed7
cmpq %rbx, 0x8(%r12)
jle 0xeed7
movq (%r12), %rax
movq (%rax,%rbx,8), %rdi
callq 0xe485
addq %r15, %r14
cmpl $0x2, %ebp
je 0xeee6
cmpl $0x1, %ebp
je 0xeeee
jmp 0xef01
testq %rax, %rax
je 0xef16
decq %rax
cmpq %rax, %r14
cmovlq %r14, %rax
xorl %ecx, %ecx
testq %r14, %r14
cmovnsq %rax, %rcx
movq %rcx, %r14
movq %r14, %rax
movq %rbx, %rdx
addq $0x8, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
xorl %r14d, %r14d
jmp 0xef01
// File: /workspace/github_c_makefile_star2_O1/justy989[P]ce/ce.c
// Function: ce_util_string_index_to_visible_index
int64_t ce_util_string_index_to_visible_index(const char* string, int64_t index, int64_t tab_width){
     int64_t x = 0;
     int64_t rune_len = 0;
     CeRune_t rune = 1;

     while(rune > 0 && index > 0){
          rune = ce_utf8_decode(string, &rune_len);

          if(rune > 0){
               if(rune == CE_TAB){
                    x += tab_width;
               }else{
                    x++;
               }
          }else{
               x++;
          }

          string += rune_len;
          index--;
     }

     return x;
}

// Assembly:
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x10, %rsp
movq $0x0, 0x8(%rsp)
testq %rsi, %rsi
jle 0xef7d
movq %rdx, %rbx
movq %rsi, %r15
movq %rdi, %r14
xorl %eax, %eax
leaq 0x8(%rsp), %r12
movq %rax, %r13
movq %r14, %rdi
movq %r12, %rsi
callq 0xe649
movl %eax, %ecx
cmpl $0x9, %eax
movl $0x1, %eax
cmoveq %rbx, %rax
addq %r13, %rax
testl %ecx, %ecx
jle 0xef7f
addq 0x8(%rsp), %r14
leaq -0x1(%r15), %rcx
cmpq $0x1, %r15
movq %rcx, %r15
jg 0xef46
jmp 0xef7f
xorl %eax, %eax
addq $0x10, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
retq
// File: /workspace/github_c_makefile_star2_O1/justy989[P]ce/ce.c
// Function: ce_util_visible_index_to_string_index
int64_t ce_util_visible_index_to_string_index(const char* string, int64_t index, int64_t tab_width){
     int64_t x = 0;
     int64_t rune_len = 0;
     CeRune_t rune = 1;

     while(rune > 0 && index > 0){
          rune = ce_utf8_decode(string, &rune_len);

          if(rune > 0){
               if(rune == CE_TAB){
                    index -= tab_width;
               }else{
                    index--;
               }
          }else{
               index--;
          }

          string += rune_len;
          x++;
     }

     return x;
}

// Assembly:
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x10, %rsp
movq $0x0, 0x8(%rsp)
testq %rsi, %rsi
jle 0xefe7
movq %rdx, %r14
movq %rsi, %r15
movq %rdi, %r12
xorl %ebx, %ebx
leaq 0x8(%rsp), %r13
movq %r12, %rdi
movq %r13, %rsi
callq 0xe649
testl %eax, %eax
jle 0xefd1
cmpl $0x9, %eax
jne 0xefd1
subq %r14, %r15
jmp 0xefd4
decq %r15
incq %rbx
testl %eax, %eax
jle 0xefe9
addq 0x8(%rsp), %r12
testq %r15, %r15
jg 0xefb8
jmp 0xefe9
xorl %ebx, %ebx
movq %rbx, %rax
addq $0x10, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
retq
// File: /workspace/github_c_makefile_star2_O1/justy989[P]ce/ce.c
// Function: ce_buffer_clamp_point
CePoint_t ce_buffer_clamp_point(CeBuffer_t* buffer, CePoint_t point, CeClampX_t clamp_x){
     switch(clamp_x){
     case CE_CLAMP_X_NONE:
          return point;
     case CE_CLAMP_X_ON:
          if(buffer->line_count){
               CE_CLAMP(point.y, 0, (buffer->line_count - 1));
               int64_t line_len = ce_utf8_strlen(buffer->lines[point.y]);
               CE_CLAMP(point.x, 0, line_len);
          }else{
               point.x = 0;
               point.y = 0;
          }
          break;
     case CE_CLAMP_X_INSIDE:
          if(buffer->line_count){
               CE_CLAMP(point.y, 0, (buffer->line_count - 1));
               int64_t line_len = ce_utf8_strlen(buffer->lines[point.y]);
               if(line_len){
                    CE_CLAMP(point.x, 0, (line_len - 1));
               }else{
                    point.x = 0;
               }
          }else{
               point.x = 0;
               point.y = 0;
          }
          break;
     }

     return point;
}

// Assembly:
pushq %r15
pushq %r14
pushq %r12
pushq %rbx
pushq %rax
movq %rdx, %r14
movq %rsi, %rbx
cmpl $0x2, %ecx
je 0xf172
cmpl $0x1, %ecx
jne 0xf1c4
movq 0x8(%rdi), %rax
testq %rax, %rax
je 0xf1bb
leaq -0x1(%rax), %r15
cmpq %r14, %rax
cmovgq %r14, %r15
xorl %r12d, %r12d
testq %r14, %r14
cmovsq %r12, %r15
movq (%rdi), %rax
movq (%rax,%r15,8), %rdi
callq 0xe485
cmpq %rbx, %rax
cmovgeq %rbx, %rax
testq %rbx, %rbx
cmovsq %r12, %rax
movq %rax, %rbx
movq %r15, %r14
jmp 0xf1c4
movq 0x8(%rdi), %rax
testq %rax, %rax
je 0xf1bb
leaq -0x1(%rax), %rcx
cmpq %r14, %rax
cmovgq %r14, %rcx
xorl %eax, %eax
testq %r14, %r14
movq %rcx, %r14
cmovsq %rax, %r14
movq (%rdi), %rax
movq (%rax,%r14,8), %rdi
callq 0xe485
testq %rax, %rax
je 0xf1c2
decq %rax
cmpq %rbx, %rax
cmovgeq %rbx, %rax
xorl %ecx, %ecx
testq %rbx, %rbx
cmovnsq %rax, %rcx
movq %rcx, %rbx
jmp 0xf1c4
xorl %ebx, %ebx
xorl %r14d, %r14d
jmp 0xf1c4
xorl %ebx, %ebx
movq %rbx, %rax
movq %r14, %rdx
addq $0x8, %rsp
popq %rbx
popq %r12
popq %r14
popq %r15
retq
// File: /workspace/github_c_makefile_star2_O1/justy989[P]ce/ce.c
// Function: buffer_realloc_lines
static bool buffer_realloc_lines(CeBuffer_t* buffer, int64_t new_line_count){
     // if we want to realloc 0 lines, clear everything
     if(new_line_count == 0){
          free(buffer->lines);
          buffer->lines = NULL;
          buffer->line_count = 0;
          return true;
     }else if(new_line_count == buffer->line_count){
          return true;
     }

     buffer->lines = realloc(buffer->lines, new_line_count * sizeof(buffer->lines[0]));
     if(buffer->lines == NULL) return false;
     buffer->line_count = new_line_count;
     return true;
}

// Assembly:
pushq %r15
pushq %r14
pushq %rbx
movq %rdi, %r14
testq %rsi, %rsi
je 0xf219
movq %rsi, %r15
movb $0x1, %bl
cmpq %rsi, 0x8(%r14)
je 0xf22e
movq (%r14), %rdi
leaq (,%r15,8), %rsi
callq 0xd520
movq %rax, (%r14)
testq %rax, %rax
je 0xf22c
movq %r15, 0x8(%r14)
jmp 0xf22e
movq (%r14), %rdi
callq 0xd090
xorps %xmm0, %xmm0
movups %xmm0, (%r14)
movb $0x1, %bl
jmp 0xf22e
xorl %ebx, %ebx
movl %ebx, %eax
popq %rbx
popq %r14
popq %r15
retq
// File: /workspace/github_c_makefile_star2_O1/justy989[P]ce/ce.c
// Function: ce_buffer_insert_rune
bool ce_buffer_insert_rune(CeBuffer_t* buffer, CeRune_t rune, CePoint_t point){
     char str[5];
     int64_t written = 0;
     ce_utf8_encode(rune, str, 5, &written);
     str[written] = 0;
     return ce_buffer_insert_string(buffer, str, point);
}

// Assembly:
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x10, %rsp
movq %rcx, %rbx
movq %rdx, %r14
movq %rdi, %r15
leaq 0x8(%rsp), %r12
movq $0x0, (%r12)
leaq 0x3(%rsp), %r13
movl $0x5, %edx
movl %esi, %edi
movq %r13, %rsi
movq %r12, %rcx
callq 0xf298
movq (%r12), %rax
movb $0x0, 0x3(%rsp,%rax)
movq %r15, %rdi
movq %r13, %rsi
movq %r14, %rdx
movq %rbx, %rcx
callq 0xda6e
addq $0x10, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
retq
// File: /workspace/github_c_makefile_star2_O1/justy989[P]ce/ce.c
// Function: ce_utf8_encode
bool ce_utf8_encode(CeRune_t u, char* string, int64_t string_len, int64_t* bytes_written){
     if(u < 0x80){
          if(string_len < 1) return false;
          *bytes_written = 1;

          // leave as-is
          string[0] = u;
     }else if(u < 0x0800){
          if(string_len < 2) return false;
          *bytes_written = 2;

          // u = 00000000 00000000 00000abc defghijk

          // 2 bytes
          // first byte:  110abcde
          string[0] = 0xC0 | ((u >> 6) & 0x1f);

          // second byte: 10fghijk
          string[1] = 0x80 | (u & 0x3f);
     }else if(u < 0x10000){
          if(string_len < 3) return false;
          *bytes_written = 3;

          // u = 00000000 00000000 abcdefgh ijklmnop

          // 3 bytes
          // first byte:  1110abcd
          string[0] = 0xE0 | ((u >> 12) & 0x0F);

          // second byte: 10efghij
          string[1] = 0x80 | ((u >> 6) & 0x3F);

          // third byte:  10klmnop
          string[2] = 0x80 | (u & 0x3F);
     }else if(u < 0x110000){
          if(string_len < 4) return false;
          *bytes_written = 4;

          // u = 00000000 000abcde fghijklm nopqrstu

          // 4 bytes
          // first byte:  11110abc
          string[0] = 0xF0 | ((u >> 18) & 0x07);
          // second byte: 10defghi
          string[1] = 0x80 | ((u >> 12) & 0x3F);
          // third byte:  10jklmno
          string[2] = 0x80 | ((u >> 6) & 0x3F);
          // fourth byte: 10pqrstu
          string[3] = 0x80 | (u & 0x3F);
     }

     return true;
}

// Assembly:
cmpl $0x7f, %edi
jg 0xf2b2
testq %rdx, %rdx
jle 0xf32b
movq $0x1, (%rcx)
movb %dil, (%rsi)
jmp 0xf318
cmpl $0x7ff, %edi            # imm = 0x7FF
jg 0xf2e0
cmpq $0x2, %rdx
jl 0xf32b
movq $0x2, (%rcx)
movl %edi, %eax
shrl $0x6, %eax
andb $0x1f, %al
orb $-0x40, %al
movb %al, (%rsi)
andb $0x3f, %dil
orb $-0x80, %dil
movb %dil, 0x1(%rsi)
jmp 0xf318
cmpl $0xffff, %edi           # imm = 0xFFFF
jg 0xf31b
cmpq $0x3, %rdx
jl 0xf32b
movq $0x3, (%rcx)
movl %edi, %eax
shrl $0xc, %eax
andb $0xf, %al
orb $-0x20, %al
movb %al, (%rsi)
movl %edi, %eax
shrl $0x6, %eax
andb $0x3f, %al
orb $-0x80, %al
movb %al, 0x1(%rsi)
andb $0x3f, %dil
orb $-0x80, %dil
movb %dil, 0x2(%rsi)
movb $0x1, %al
retq
movb $0x1, %al
cmpl $0x10ffff, %edi         # imm = 0x10FFFF
jg 0xf31a
cmpq $0x4, %rdx
jge 0xf32e
xorl %eax, %eax
retq
movq $0x4, (%rcx)
movl %edi, %ecx
shrl $0x12, %ecx
andb $0x7, %cl
orb $-0x10, %cl
movb %cl, (%rsi)
movl %edi, %ecx
shrl $0xc, %ecx
andb $0x3f, %cl
orb $-0x80, %cl
movb %cl, 0x1(%rsi)
movl %edi, %ecx
shrl $0x6, %ecx
andb $0x3f, %cl
orb $-0x80, %cl
movb %cl, 0x2(%rsi)
andb $0x3f, %dil
orb $-0x80, %dil
movb %dil, 0x3(%rsi)
retq
// File: /workspace/github_c_makefile_star2_O1/justy989[P]ce/ce.c
// Function: ce_buffer_remove_lines
bool ce_buffer_remove_lines(CeBuffer_t* buffer, int64_t line_start, int64_t lines_to_remove){
     // check invalid input
     if(line_start < 0) return false;
     if(line_start >= buffer->line_count) return false;
     if(lines_to_remove <= 0) return false;
     if(line_start + lines_to_remove > buffer->line_count) return false;

     // free lines we are going to remove and overwrite
     for(int64_t i = line_start; i < line_start + lines_to_remove; i++){
          free(buffer->lines[i]);
     }

     // shift lines down, overwriting lines we want to remove
     int64_t last_line_to_shift = buffer->line_count - lines_to_remove;
     for(int64_t dst = line_start; dst < last_line_to_shift; dst++){
          int64_t src = dst + lines_to_remove;
          buffer->lines[dst] = buffer->lines[src];
     }

     // update line count, and shrink our allocation
     buffer->line_count -= lines_to_remove;
     if(buffer->line_count > 0){
          buffer->lines = realloc(buffer->lines, buffer->line_count * sizeof(*buffer->lines));
     }else{
          ce_buffer_empty(buffer);
     }

     buffer->status = CE_BUFFER_STATUS_MODIFIED;
     return buffer->lines != NULL;
}

// Assembly:
testq %rsi, %rsi
js 0xf71a
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
movq %rdx, %r14
movq %rsi, %r15
movq %rdi, %rbx
movq 0x8(%rdi), %rax
cmpq %rsi, %rax
setle %cl
testq %rdx, %rdx
setle %dl
orb %cl, %dl
jne 0xf716
leaq (%r14,%r15), %r12
cmpq %rax, %r12
jle 0xf71d
xorl %eax, %eax
jmp 0xf790
xorl %eax, %eax
retq
testq %r14, %r14
jle 0xf739
movq %r15, %r13
movq (%rbx), %rax
movq (%rax,%r13,8), %rdi
callq 0xd090
incq %r13
cmpq %r12, %r13
jl 0xf725
movq 0x8(%rbx), %rsi
subq %r14, %rsi
cmpq %r15, %rsi
jle 0xf760
shlq $0x3, %r14
movq (%rbx), %rax
leaq (%rax,%r15,8), %rcx
movq (%r14,%rcx), %rcx
movq %rcx, (%rax,%r15,8)
incq %r15
cmpq %rsi, %r15
jl 0xf749
movq %rsi, 0x8(%rbx)
testq %rsi, %rsi
jle 0xf77a
movq (%rbx), %rdi
shlq $0x3, %rsi
callq 0xd520
movq %rax, (%rbx)
jmp 0xf782
movq %rbx, %rdi
callq 0xe3d9
movl $0x1, 0x18(%rbx)
cmpq $0x0, (%rbx)
setne %al
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
retq
// File: /workspace/github_c_makefile_star2_O1/justy989[P]ce/ce.c
// Function: ce_buffer_dupe
char* ce_buffer_dupe(CeBuffer_t* buffer){
     CePoint_t start = {0, 0};
     CePoint_t end = {0, buffer->line_count};
     if(end.y) end.y--;
     end.x = ce_utf8_last_index(buffer->lines[end.y]);
     int64_t len = ce_buffer_range_len(buffer, start, end);
     if(len > 0) return ce_buffer_dupe_string(buffer, start, len);
     return NULL;
}

// Assembly:
pushq %r14
pushq %rbx
pushq %rax
movq %rdi, %rbx
movq (%rdi), %rax
movq 0x8(%rdi), %r14
xorl %ecx, %ecx
subq $0x1, %r14
cmovbq %rcx, %r14
movq (%rax,%r14,8), %rdi
callq 0xe485
xorl %ecx, %ecx
testq %rax, %rax
setg %cl
subq %rcx, %rax
movq %rbx, %rdi
xorl %esi, %esi
xorl %edx, %edx
movq %rax, %rcx
movq %r14, %r8
callq 0xecb5
testq %rax, %rax
jle 0xfa39
movq %rbx, %rdi
xorl %esi, %esi
xorl %edx, %edx
movq %rax, %rcx
addq $0x8, %rsp
popq %rbx
popq %r14
jmp 0xf79a
xorl %eax, %eax
addq $0x8, %rsp
popq %rbx
popq %r14
retq
// File: /workspace/github_c_makefile_star2_O1/justy989[P]ce/ce.c
// Function: ce_buffer_insert_string_change
bool ce_buffer_insert_string_change(CeBuffer_t* buffer, char* alloced_string, CePoint_t point, CePoint_t* cursor_before,
                                    CePoint_t cursor_after, bool chain_undo){
     if(!ce_buffer_insert_string(buffer, alloced_string, point)) return false;

     CeBufferChange_t change = {};
     change.chain = chain_undo;
     change.insertion = true;
     change.string = alloced_string;
     change.location = point;
     change.cursor_before = *cursor_before;
     change.cursor_after = cursor_after;
     ce_buffer_change(buffer, &change);

     *cursor_before = cursor_after;
     return true;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x58, %rsp
movl %r9d, 0xc(%rsp)
movq %r8, %rbx
movq %rcx, %r15
movq %rdx, %r12
movq %rsi, %r13
movq %rdi, %r14
callq 0xda6e
movl %eax, %ebp
testb %al, %al
je 0xfac5
leaq 0x90(%rsp), %rcx
xorps %xmm0, %xmm0
leaq 0x10(%rsp), %rsi
movaps %xmm0, (%rsi)
movaps %xmm0, 0x10(%rsi)
movaps %xmm0, 0x30(%rsi)
movaps %xmm0, 0x20(%rsi)
movl 0xc(%rsp), %eax
movb %al, (%rsi)
movb $0x1, 0x1(%rsi)
movq %r13, 0x8(%rsi)
movq %r12, 0x10(%rsi)
movq %r15, 0x18(%rsi)
movups (%rbx), %xmm0
movaps %xmm0, 0x20(%rsi)
movq %rcx, %r15
movups (%rcx), %xmm0
movaps %xmm0, 0x30(%rsi)
movq %r14, %rdi
callq 0xfad6
movups (%r15), %xmm0
movups %xmm0, (%rbx)
movl %ebp, %eax
addq $0x58, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
// File: /workspace/github_c_makefile_star2_O1/justy989[P]ce/ce.c
// Function: ce_buffer_change
bool ce_buffer_change(CeBuffer_t* buffer, CeBufferChange_t* change){
     CeBufferChangeNode_t* node = calloc(1, sizeof(*node));
     node->change = *change;
     node->next = NULL;

     if(buffer->change_node){
          if(buffer->change_node->next){
               ce_buffer_change_node_free(&buffer->change_node->next);
          }

          node->prev = buffer->change_node;
          node->index = buffer->change_node->index + 1;
          buffer->change_node->next = node;
     }else{
          CeBufferChangeNode_t* first_empty_node = calloc(1, sizeof(*node));
          first_empty_node->next = node;
          node->prev = first_empty_node;
          if(buffer->save_at_change_node == NULL) buffer->save_at_change_node = first_empty_node;
     }

     buffer->change_node = node;
     return true;
}

// Assembly:
pushq %r15
pushq %r14
pushq %rbx
movq %rsi, %r15
movq %rdi, %rbx
movl $0x1, %edi
movl $0x58, %esi
callq 0xd380
movq %rax, %r14
movups (%r15), %xmm0
movups 0x10(%r15), %xmm1
movups 0x20(%r15), %xmm2
movups 0x30(%r15), %xmm3
movups %xmm0, (%rax)
movups %xmm1, 0x10(%rax)
movups %xmm2, 0x20(%rax)
movups %xmm3, 0x30(%rax)
movq $0x0, 0x40(%rax)
movq 0x40(%rbx), %rdi
testq %rdi, %rdi
je 0xfb4f
cmpq $0x0, 0x40(%rdi)
je 0xfb36
addq $0x40, %rdi
callq 0xdf24
movq 0x40(%rbx), %rax
movq %rax, 0x48(%r14)
movq 0x50(%rax), %rcx
incq %rcx
movq %rcx, 0x50(%r14)
movq %r14, 0x40(%rax)
jmp 0xfb71
movl $0x1, %edi
movl $0x58, %esi
callq 0xd380
movq %r14, 0x40(%rax)
movq %rax, 0x48(%r14)
cmpq $0x0, 0x48(%rbx)
jne 0xfb71
movq %rax, 0x48(%rbx)
movq %r14, 0x40(%rbx)
movb $0x1, %al
popq %rbx
popq %r14
popq %r15
retq
// File: /workspace/github_c_makefile_star2_O1/justy989[P]ce/ce.c
// Function: ce_buffer_insert_string_change_at_cursor
bool ce_buffer_insert_string_change_at_cursor(CeBuffer_t* buffer, char* alloced_string, CePoint_t* cursor, bool chain_undo){
     if(!ce_buffer_insert_string(buffer, alloced_string, *cursor)) return false;
     CePoint_t cursor_after = ce_buffer_advance_point(buffer, *cursor, strlen(alloced_string));

     CeBufferChange_t change = {};
     change.chain = chain_undo;
     change.insertion = true;
     change.string = alloced_string;
     change.location = *cursor;
     change.cursor_before = *cursor;
     change.cursor_after = cursor_after;
     ce_buffer_change(buffer, &change);

     *cursor = cursor_after;
     return true;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x48, %rsp
movl %ecx, %r12d
movq %rdx, %rbx
movq %rsi, %r15
movq %rdi, %r14
movq (%rdx), %rdx
movq 0x8(%rbx), %rcx
callq 0xda6e
movl %eax, %ebp
testb %al, %al
je 0xfc10
movq %r15, %rdi
callq 0xd210
movq (%rbx), %rsi
movq 0x8(%rbx), %rdx
movq %r14, %rdi
movq %rax, %rcx
callq 0xeffa
movq %rax, %r13
movl %r12d, %eax
movq %rdx, %r12
xorps %xmm0, %xmm0
movq %rsp, %rsi
movaps %xmm0, (%rsi)
movaps %xmm0, 0x30(%rsi)
movaps %xmm0, 0x20(%rsi)
movaps %xmm0, 0x10(%rsi)
movb %al, (%rsi)
movb $0x1, 0x1(%rsi)
movq %r15, 0x8(%rsi)
movups (%rbx), %xmm0
movaps %xmm0, 0x10(%rsi)
movups (%rbx), %xmm0
movaps %xmm0, 0x20(%rsi)
movq %r13, 0x30(%rsi)
movq %rdx, 0x38(%rsi)
movq %r14, %rdi
callq 0xfad6
movq %r13, (%rbx)
movq %r12, 0x8(%rbx)
movl %ebp, %eax
addq $0x48, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
// File: /workspace/github_c_makefile_star2_O1/justy989[P]ce/ce.c
// Function: ce_buffer_remove_string_change
bool ce_buffer_remove_string_change(CeBuffer_t* buffer, CePoint_t point, int64_t remove_len, CePoint_t* cursor_before,
                                    CePoint_t cursor_after, bool chain_undo){
     char* remove_string = ce_buffer_dupe_string(buffer, point, remove_len);
     if(!ce_buffer_remove_string(buffer, point, remove_len)){
          free(remove_string);
          return false;
     }

     CeBufferChange_t change = {};
     change.chain = chain_undo;
     change.insertion = false;
     change.string = remove_string;
     change.location = point;
     change.cursor_before = *cursor_before;
     change.cursor_after = cursor_after;
     ce_buffer_change(buffer, &change);

     *cursor_before = cursor_after;
     return true;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x58, %rsp
movl %r9d, 0xc(%rsp)
movq %r8, %rbx
movq %rcx, %rbp
movq %rdx, %r15
movq %rsi, %r13
movq %rdi, %r14
callq 0xf79a
movq %rax, %r12
movq %r14, %rdi
movq %r13, %rsi
movq %r15, %rdx
movq %rbp, %rcx
callq 0xf36b
movl %eax, %ebp
testb %al, %al
je 0xfcb9
leaq 0x90(%rsp), %rcx
xorps %xmm0, %xmm0
leaq 0x10(%rsp), %rsi
movaps %xmm0, (%rsi)
movaps %xmm0, 0x10(%rsi)
movaps %xmm0, 0x30(%rsi)
movaps %xmm0, 0x20(%rsi)
movl 0xc(%rsp), %eax
movb %al, (%rsi)
movb $0x0, 0x1(%rsi)
movq %r12, 0x8(%rsi)
movq %r13, 0x10(%rsi)
movq %r15, 0x18(%rsi)
movups (%rbx), %xmm0
movaps %xmm0, 0x20(%rsi)
movq %rcx, %r15
movups (%rcx), %xmm0
movaps %xmm0, 0x30(%rsi)
movq %r14, %rdi
callq 0xfad6
movups (%r15), %xmm0
movups %xmm0, (%rbx)
jmp 0xfcc1
movq %r12, %rdi
callq 0xd090
movl %ebp, %eax
addq $0x58, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
// File: /workspace/github_c_makefile_star2_O1/justy989[P]ce/ce.c
// Function: ce_buffer_undo
bool ce_buffer_undo(CeBuffer_t* buffer, CePoint_t* cursor){
     // nothing to undo
     if(!buffer->change_node) return true;
     if(!buffer->change_node->prev) return true;

     CeBufferChange_t* change = &buffer->change_node->change;
     if(change->insertion){
          ce_buffer_remove_string(buffer, change->location, ce_utf8_strlen(change->string));
     }else{
          ce_buffer_insert_string(buffer, change->string, change->location);
     }

     *cursor = change->cursor_before;
     buffer->change_node = buffer->change_node->prev;

     bool success = true;
     if(change->chain) success = ce_buffer_undo(buffer, cursor);

     if(buffer->status == CE_BUFFER_STATUS_MODIFIED && buffer->change_node == buffer->save_at_change_node){
          buffer->status = CE_BUFFER_STATUS_NONE;
     }

     return success;
}

// Assembly:
pushq %r15
pushq %r14
pushq %rbx
movq 0x40(%rdi), %r15
testq %r15, %r15
je 0xfd67
cmpq $0x0, 0x48(%r15)
je 0xfd67
movq %rsi, %r14
movq %rdi, %rbx
cmpb $0x1, 0x1(%r15)
jne 0xfd16
movq 0x8(%r15), %rdi
callq 0xe485
movq 0x10(%r15), %rsi
movq 0x18(%r15), %rdx
movq %rbx, %rdi
movq %rax, %rcx
callq 0xf36b
jmp 0xfd2a
movq 0x8(%r15), %rsi
movq 0x10(%r15), %rdx
movq 0x18(%r15), %rcx
movq %rbx, %rdi
callq 0xda6e
movups 0x20(%r15), %xmm0
movups %xmm0, (%r14)
movq 0x40(%rbx), %rax
movq 0x48(%rax), %rax
movq %rax, 0x40(%rbx)
cmpb $0x1, (%r15)
jne 0xfd50
movq %rbx, %rdi
movq %r14, %rsi
callq 0xfcd2
cmpl $0x1, 0x18(%rbx)
jne 0xfd67
movq 0x40(%rbx), %rax
cmpq 0x48(%rbx), %rax
jne 0xfd67
movl $0x0, 0x18(%rbx)
movb $0x1, %al
popq %rbx
popq %r14
popq %r15
retq
// File: /workspace/github_c_makefile_star2_O1/justy989[P]ce/ce.c
// Function: ce_buffer_redo
bool ce_buffer_redo(CeBuffer_t* buffer, CePoint_t* cursor){
     // nothing to redo
     if(!buffer->change_node) return false;
     if(!buffer->change_node->next) return false;

     buffer->change_node = buffer->change_node->next;

     CeBufferChange_t* change = &buffer->change_node->change;
     if(change->insertion){
          ce_buffer_insert_string(buffer, change->string, change->location);
     }else{
          ce_buffer_remove_string(buffer, change->location, ce_utf8_strlen(change->string));
     }

     *cursor = change->cursor_after;

     if(buffer->change_node->next && buffer->change_node->next->change.chain) return ce_buffer_redo(buffer, cursor);

     if(buffer->status == CE_BUFFER_STATUS_MODIFIED && buffer->change_node == buffer->save_at_change_node){
          buffer->status = CE_BUFFER_STATUS_NONE;
     }

     return true;
}

// Assembly:
pushq %r15
pushq %r14
pushq %rbx
movq %rsi, %r14
movq %rdi, %rbx
movq 0x40(%rbx), %rax
testq %rax, %rax
je 0xfdfb
movq 0x40(%rax), %r15
testq %r15, %r15
je 0xfdfb
movq %r15, 0x40(%rbx)
cmpb $0x1, 0x1(%r15)
jne 0xfdad
movq 0x8(%r15), %rsi
movq 0x10(%r15), %rdx
movq 0x18(%r15), %rcx
movq %rbx, %rdi
callq 0xda6e
jmp 0xfdc9
movq 0x8(%r15), %rdi
callq 0xe485
movq 0x10(%r15), %rsi
movq 0x18(%r15), %rdx
movq %rbx, %rdi
movq %rax, %rcx
callq 0xf36b
movups 0x30(%r15), %xmm0
movups %xmm0, (%r14)
movq 0x40(%rbx), %rcx
movq 0x40(%rcx), %rax
testq %rax, %rax
je 0xfde4
cmpb $0x0, (%rax)
jne 0xfd7a
movb $0x1, %al
cmpl $0x1, 0x18(%rbx)
jne 0xfdfd
cmpq 0x48(%rbx), %rcx
jne 0xfdfd
movl $0x0, 0x18(%rbx)
jmp 0xfdfd
xorl %eax, %eax
popq %rbx
popq %r14
popq %r15
retq
// File: /workspace/github_c_makefile_star2_O1/justy989[P]ce/ce.c
// Function: ce_move_point_based_on_buffer_changes
CePoint_t ce_move_point_based_on_buffer_changes(CeBuffer_t* buffer, CeBufferChangeNode_t* before, CePoint_t point){
     CeBufferChangeNode_t* itr = buffer->change_node;
     while(itr && itr != before){
          point = move_point_based_on_buffer_change(buffer, itr, point);
          itr = itr->prev;
     }
     return point;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x18, %rsp
movq %rcx, %r15
movq %rdx, %r12
movq %rdi, 0x10(%rsp)
movq 0x40(%rdi), %rbx
testq %rbx, %rbx
sete %al
cmpq %rsi, %rbx
sete %cl
orb %al, %cl
jne 0xfef0
movq %rsi, 0x8(%rsp)
movq 0x8(%rbx), %r14
testq %r14, %r14
je 0xfed0
movq 0x10(%rbx), %r13
movq 0x18(%rbx), %rbp
cmpq %r15, %rbp
jl 0xfe5a
jne 0xfed0
cmpq %r12, %r13
jge 0xfed0
movq %r14, %rdi
callq 0xe2bc
cmpq $0x1, %rax
jne 0xfe9b
cmpq %r15, %rbp
jne 0xfebd
movq %r14, %rdi
callq 0xe485
movq %rax, %rcx
negq %rcx
cmpb $0x0, 0x1(%rbx)
cmovneq %rax, %rcx
movq 0x10(%rsp), %rdi
movq %r12, %rsi
movq %r15, %rdx
callq 0xeffa
movq %rax, %r13
movq %rdx, %rbp
jmp 0xfec3
movq 0x8(%rsp), %rsi
jle 0xfed0
leaq (%rax,%rbp), %rcx
cmpq %r15, %rcx
jg 0xfed6
cmpb $0x1, 0x1(%rbx)
jne 0xfeca
leaq (%r15,%rax), %rbp
decq %rbp
movq %r12, %r13
jmp 0xfed6
movq %r12, %r13
movq %r15, %rbp
movq 0x8(%rsp), %rsi
jmp 0xfed6
subq %rax, %r15
incq %r15
movq %r12, %r13
movq %r15, %rbp
movq 0x48(%rbx), %rbx
testq %rbx, %rbx
je 0xfef6
movq %rbp, %r15
movq %r13, %r12
cmpq %rsi, %rbx
jne 0xfe39
jmp 0xfef6
movq %r12, %r13
movq %r15, %rbp
movq %r13, %rax
movq %rbp, %rdx
addq $0x18, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
// File: /workspace/github_c_makefile_star2_O1/justy989[P]ce/ce.c
// Function: ce_utf8_strlen_between
int64_t ce_utf8_strlen_between(const char* start, const char* end){
     int64_t len = 0;
     int64_t byte_count = 0;

     while(start <= end){
          if((*start & 0x80) == 0){
               byte_count = 1;
          }else if((*start & 0xE0) == 0xC0){
               byte_count = 2;
          }else if((*start & 0xF0) == 0xE0){
               byte_count = 3;
          }else if((*start & 0xF8) == 0xF0){
               byte_count = 4;
          }else{
               assert(!"unicode character claiming it has more than 4 bytes?!");
               return -1;
          }

          // validate string doesn't early terminate
          for(int64_t i = 0; i < byte_count; i++){
               if(*start == 0) return -1;
               start++;
          }

          len++;
     }

     return len;

}

// Assembly:
pushq %rax
xorl %eax, %eax
cmpq %rsi, %rdi
ja 0x10179
movzbl (%rdi), %edx
movl $0x1, %ecx
testb %dl, %dl
jns 0x1014f
movl %edx, %r8d
andl $-0x20, %r8d
movl $0x2, %ecx
cmpl $0xc0, %r8d
je 0x1014f
movl %edx, %r8d
andl $-0x10, %r8d
movl $0x3, %ecx
cmpl $0xe0, %r8d
je 0x1014f
andl $-0x8, %edx
movl $0x4, %ecx
cmpl $0xf0, %edx
jne 0x1017b
leaq (%rdi,%rcx), %rdx
xorl %r8d, %r8d
cmpb $0x0, (%rdi,%r8)
je 0x10172
incq %r8
cmpq %r8, %rcx
jne 0x10156
incq %rax
movq %rdx, %rdi
cmpq %rsi, %rdx
jbe 0x10109
jmp 0x10179
movq $-0x1, %rax
popq %rcx
retq
leaq 0x1e5a3(%rip), %rdi     # 0x2e725
leaq 0x1e4ef(%rip), %rsi     # 0x2e678
leaq 0x1e5f3(%rip), %rcx     # 0x2e783
movl $0x54f, %edx            # imm = 0x54F
callq 0xd280
// File: /workspace/github_c_makefile_star2_O1/justy989[P]ce/ce.c
// Function: ce_utf8_rune_len
int64_t ce_utf8_rune_len(CeRune_t u){
     // TODO: optimize based on st's bitmasking
     if(u < 0x80){
          return 1;
     }else if(u < 0x0800){
          return 2;
     }else if(u < 0x10000){
          return 3;
     }else if(u < 0x110000){
          return 4;
     }

     return true;
}

// Assembly:
movl $0x1, %eax
cmpl $0x80, %edi
jl 0x102c2
movl $0x2, %eax
cmpl $0x800, %edi            # imm = 0x800
jl 0x102c2
movl $0x3, %eax
cmpl $0x10000, %edi          # imm = 0x10000
jl 0x102c2
xorl %eax, %eax
cmpl $0x110000, %edi         # imm = 0x110000
setl %al
leaq (%rax,%rax,2), %rax
incq %rax
retq
// File: /workspace/github_c_makefile_star2_O1/justy989[P]ce/ce.c
// Function: ce_rune_node_insert
bool ce_rune_node_insert(CeRuneNode_t** head, CeRune_t rune){
     CeRuneNode_t* node = malloc(sizeof(*node));
     if(!node) return false;

     // always insert at head
     node->rune = rune;
     node->next = *head;
     *head = node;

     return true;
}

// Assembly:
pushq %rbp
pushq %rbx
pushq %rax
movl %esi, %ebp
movq %rdi, %rbx
movl $0x10, %edi
callq 0xd4c0
testq %rax, %rax
je 0x1030a
movl %ebp, (%rax)
movq (%rbx), %rcx
movq %rcx, 0x8(%rax)
movq %rax, (%rbx)
testq %rax, %rax
setne %al
addq $0x8, %rsp
popq %rbx
popq %rbp
retq
// File: /workspace/github_c_makefile_star2_O1/justy989[P]ce/ce.c
// Function: ce_rune_node_string
CeRune_t* ce_rune_node_string(CeRuneNode_t* head){
     // count nodes
     CeRuneNode_t* itr = head;
     int64_t len = 0;
     while(itr){
          itr = itr->next;
          len++;
     }

     CeRune_t* runes = malloc((len + 1) * sizeof(*runes));

     // copy into string
     int64_t save_len = len;
     itr = head;
     while(itr){
          runes[len - 1] = itr->rune;
          itr = itr->next;
          len--;
     }

     // null terminate
     runes[save_len] = 0;
     return runes;
}

// Assembly:
pushq %r14
pushq %rbx
pushq %rax
movq %rdi, %rbx
xorl %r14d, %r14d
testq %rdi, %rdi
je 0x10335
movq %rbx, %rax
movq 0x8(%rax), %rax
incq %r14
testq %rax, %rax
jne 0x10329
leaq 0x4(,%r14,4), %rdi
callq 0xd4c0
testq %rbx, %rbx
je 0x10360
leaq (%rax,%r14,4), %rcx
addq $-0x4, %rcx
movl (%rbx), %edx
movl %edx, (%rcx)
movq 0x8(%rbx), %rbx
addq $-0x4, %rcx
testq %rbx, %rbx
jne 0x1034f
movl $0x0, (%rax,%r14,4)
addq $0x8, %rsp
popq %rbx
popq %r14
retq
// File: /workspace/github_c_makefile_star2_O1/justy989[P]ce/ce.c
// Function: ce_rune_node_free
void ce_rune_node_free(CeRuneNode_t** head){
     CeRuneNode_t* itr = *head;
     while(itr){
          CeRuneNode_t* tmp = itr;
          itr = itr->next;
          free(tmp);
     }

     *head = NULL;
}

// Assembly:
pushq %r14
pushq %rbx
pushq %rax
movq %rdi, %rbx
movq (%rdi), %rdi
testq %rdi, %rdi
je 0x10390
movq 0x8(%rdi), %r14
callq 0xd090
movq %r14, %rdi
testq %r14, %r14
jne 0x1037f
movq $0x0, (%rbx)
addq $0x8, %rsp
popq %rbx
popq %r14
retq