// File: /workspace/github_c_makefile_star2_O2/neovim[P]libvterm/src/vterm.c
// Function: vterm_scroll_rect
void vterm_scroll_rect(VTermRect rect,
    int downward,
    int rightward,
    int (*moverect)(VTermRect src, VTermRect dest, void *user),
    int (*eraserect)(VTermRect rect, int selective, void *user),
    void *user)
{
  VTermRect src;
  VTermRect dest;

  if(abs(downward)  >= rect.end_row - rect.start_row ||
     abs(rightward) >= rect.end_col - rect.start_col) {
    /* Scroll more than area; just erase the lot */
    (*eraserect)(rect, 0, user);
    return;
  }

  if(rightward >= 0) {
    /* rect: [XXX................]
     * src:     [----------------]
     * dest: [----------------]
     */
    dest.start_col = rect.start_col;
    dest.end_col   = rect.end_col   - rightward;
    src.start_col  = rect.start_col + rightward;
    src.end_col    = rect.end_col;
  }
  else {
    /* rect: [................XXX]
     * src:  [----------------]
     * dest:    [----------------]
     */
    int leftward = -rightward;
    dest.start_col = rect.start_col + leftward;
    dest.end_col   = rect.end_col;
    src.start_col  = rect.start_col;
    src.end_col    = rect.end_col - leftward;
  }

  if(downward >= 0) {
    dest.start_row = rect.start_row;
    dest.end_row   = rect.end_row   - downward;
    src.start_row  = rect.start_row + downward;
    src.end_row    = rect.end_row;
  }
  else {
    int upward = -downward;
    dest.start_row = rect.start_row + upward;
    dest.end_row   = rect.end_row;
    src.start_row  = rect.start_row;
    src.end_row    = rect.end_row - upward;
  }

  if(moverect)
    (*moverect)(dest, src, user);

  if(downward > 0)
    rect.start_row = rect.end_row - downward;
  else if(downward < 0)
    rect.end_row = rect.start_row - downward;

  if(rightward > 0)
    rect.start_col = rect.end_col - rightward;
  else if(rightward < 0)
    rect.end_col = rect.start_col - rightward;

  (*eraserect)(rect, 0, user);
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x18, %rsp
movl %ecx, %r15d
movl %edx, %r13d
movq %rsi, %r14
movq %rdi, %r12
movq %rdi, %rbp
shrq $0x20, %rbp
movl %edx, %ecx
negl %ecx
cmovsl %edx, %ecx
movq 0x50(%rsp), %r10
movl %ebp, %edx
subl %r12d, %edx
cmpl %edx, %ecx
jge 0x9bab
movq %r14, %rbx
shrq $0x20, %rbx
movl %r15d, %ecx
negl %ecx
cmovsl %r15d, %ecx
movl %ebx, %edx
subl %r14d, %edx
cmpl %edx, %ecx
jge 0x9bab
movq %r8, %rax
movabsq $-0x100000000, %rdx     # imm = 0xFFFFFFFF00000000
testl %r15d, %r15d
js 0x9bb6
movl %r14d, %ecx
movl %ebx, %esi
subl %r15d, %esi
shlq $0x20, %rsi
orq %rcx, %rsi
leal (%r14,%r15), %edi
movq %r14, %rcx
andq %rdx, %rcx
jmp 0x9bd0
movq %r12, %rdi
movq %r14, %rsi
jmp 0x9c6a
movl %r14d, %ecx
subl %r15d, %ecx
movq %r14, %rsi
andq %rdx, %rsi
orq %rcx, %rsi
movl %r14d, %edi
leal (%rbx,%r15), %ecx
shlq $0x20, %rcx
orq %rdi, %rcx
testl %r13d, %r13d
js 0x9bf0
movl %r12d, %r8d
movl %ebp, %edi
subl %r13d, %edi
shlq $0x20, %rdi
orq %r8, %rdi
leal (%r12,%r13), %r8d
andq %r12, %rdx
jmp 0x9c0b
movl %r12d, %r8d
subl %r13d, %r8d
andq %r12, %rdx
movq %rdx, %rdi
orq %r8, %rdi
movl %r12d, %r8d
leal (%rbp,%r13), %edx
shlq $0x20, %rdx
orq %r8, %rdx
testq %rax, %rax
je 0x9c2c
movq %r10, %r8
movq %r9, 0x10(%rsp)
movq %r10, 0x8(%rsp)
callq *%rax
movq 0x8(%rsp), %r10
movq 0x10(%rsp), %r9
movl %ebp, %edi
subl %r13d, %edi
movl %r12d, %eax
subl %r13d, %eax
testl %r13d, %r13d
cmovnsl %ebp, %eax
cmovlel %r12d, %edi
cmovgl %ebp, %eax
movl %ebx, %esi
subl %r15d, %esi
movl %r14d, %ecx
subl %r15d, %ecx
testl %r15d, %r15d
cmovnsl %ebx, %ecx
cmovlel %r14d, %esi
cmovgl %ebx, %ecx
shlq $0x20, %rax
orq %rax, %rdi
shlq $0x20, %rcx
orq %rcx, %rsi
xorl %edx, %edx
movq %r10, %rcx
addq $0x18, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
jmpq *%r9