// File: /workspace/github_c_makefile_star2_O0/snej[P]zdelta/deflate.c
// Function: reference_longest_match
local void reference_longest_match(s, cur_match, rw)
     deflate_state *s;
     IPos cur_match;
     int rw;
{
  register Bytef *scan = s->window + s->strstart; /* current string */
  register Bytef *match;                          /* matched string */
  register uInt len;                              /* length of current match */
  register int  benefit;
  register int  strategy = s->strategy; /* expected length for literal codes */
  /* max hash chain length, we want to search in the reference data
   * no longer than in the target data
   */
  register uInt chain_length = s->max_chain_length;

  uInt cur_distance;	       /* the shortest distance to the current match */
  int  cur_ptr;  

  long min;                    /* value of the smaller ref pointer */ 
  long max;                    /* value of the greater ref pointer */ 
  long mid;                   
 
  int min_ptr;
  int max_ptr;

  uInt best_len      = s->match_length;   /* best match length so far   */
  uInt best_distance = s->match_distance; /* best match distance so far */
  int best_benefit   = s->match_benefit;

  uInt nice_match    = s->nice_match;     /* stop if match long enough */
  int best_ptr       = NO_PTR;
  Pos best_match     = 0;

  Pos limit;
    
  Pos *prev  = s->ref_prev[rw];
  uInt wmask = s->rw_mask;
  ulg  wsize =  s->ref_window_size[rw];  

  register Bytef *strend   = s->window + s->strstart + MAX_MATCH;
  register Byte scan_end1  = scan[best_len-1];

  /* The code is optimized for HASH_BITS >= 8 and MAX_MATCH-2 multiple of 16.
   * It is easy to get rid of this optimization if necessary.
   */

  /* set the search boundaries in the reference data window */
  if(s->rwptr[2*rw] < s->rwptr[2*rw+1]){
    min = s->rwptr[2*rw], max = s->rwptr[2*rw+1];
    min_ptr = 2*rw, max_ptr = 2*rw+1;
  }
  else{
    min = s->rwptr[2*rw+1], max = s->rwptr[2*rw];
    min_ptr = 2*rw+1, max_ptr = 2*rw;
  }
  mid = min >= 0 ? (max + min) / 2 : 0;
  
  limit = min >  ZD_UNREACHABLE ? (Pos) (min - ZD_UNREACHABLE) : NIL;
  while(cur_match > (IPos) max + ZD_UNREACHABLE) 
    cur_match = prev[cur_match & wmask];
  if(cur_match == NIL) return;
  
  /* Do not waste too much time if we already have a good match: */
  if (best_len >= s->good_match) {
    chain_length >>= 2;
  }
  /* Do not look for matches beyond the end of the input. This is necessary
   * to make deflate deterministic.
   */
  if ((uInt)nice_match > s->lookahead) nice_match = s->lookahead;

  do {
    match = s->ref_window[rw] + cur_match; 
    
    /* Skip to next match if the match length cannot increase
     * or if the match length is less than 2:
     */
    if ( match[best_len-1] != scan_end1 ||
	 *match            != *scan     ||
	 *++match          != scan[1])      continue;
    
    /* check if the potential match is accessible */
    if((IPos) mid <= cur_match){
      cur_ptr = max_ptr;
      cur_distance = ZD_DISTANCE((IPos)max,cur_match);
    }
    else{ /* min_ptr is closer */
      cur_ptr = min_ptr;
      cur_distance = ZD_DISTANCE((IPos)min,cur_match);
    }
    if(cur_distance >= ZD_UNREACHABLE) continue;
    
    /* The check at best_len-1 can be removed because it will be made
     * again later. (This heuristic is not always a win.)
     * It is not necessary to compare scan[2] and match[2] since they
     * are always equal when the other bytes match, given that
     * the hash keys are equal and that HASH_BITS >= 8.
     */
    scan += 2, match++;
    Assert(*scan == *match, "ref. match[2]?");

    /* We check for insufficient lookahead only every 8th comparison;
     * the 256th check will be made at strstart+258.
     */
    do {
    } while (*++scan == *++match && *++scan == *++match &&
	     *++scan == *++match && *++scan == *++match &&
	     *++scan == *++match && *++scan == *++match &&
	     *++scan == *++match && *++scan == *++match &&
	     scan < strend);
    
    Assert(scan <= s->window+(unsigned)(s->window_size-1), "wild scan");

    len     = MAX_MATCH - (int)(strend - scan);
    scan    = strend - MAX_MATCH;

    /* Do not look for matches beyond the end of the input. This is necessary
     * to make deflate deterministic.
     */
    if (len > s->lookahead) { len = s->lookahead; }
    if (len > wsize - cur_match) { len = wsize - cur_match; }
    GetBenefit(len, cur_distance);

    if( (benefit > best_benefit) || \
	(benefit == best_benefit && cur_distance < best_distance) ){

      best_match    = cur_match;
      best_distance = cur_distance; 
      best_ptr      = cur_ptr;
      best_len      = len;
      best_benefit  = benefit;
      if (len >= nice_match) break;
      scan_end1     = scan[best_len-1];

    }
    
  } while ((cur_match = prev[cur_match & wmask]) > limit &&
	   --chain_length);
  
  if(best_ptr != NO_PTR){
    s->match_ptr      = best_ptr;
    s->match_length   = best_len;
    s->match_distance = best_distance;
    s->match_start    = best_match;
    s->match_sign     = (best_match < s->rwptr[best_ptr] ? ZD_MINUS:ZD_PLUS);
    s->match_benefit  = best_benefit;
  }
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x38, %rsp
movq %rdi, -0x8(%rbp)
movl %esi, -0xc(%rbp)
movl %edx, -0x10(%rbp)
movq -0x8(%rbp), %rax
movq 0x48(%rax), %rax
movq -0x8(%rbp), %rcx
movl 0xb4(%rcx), %ecx
addq %rcx, %rax
movq %rax, -0x18(%rbp)
movq -0x8(%rbp), %rax
movl 0xf8(%rax), %eax
movl %eax, -0x2c(%rbp)
movq -0x8(%rbp), %rax
movl 0xec(%rax), %eax
movl %eax, -0x30(%rbp)
movq -0x8(%rbp), %rax
movl 0xa8(%rax), %eax
movl %eax, -0x5c(%rbp)
movq -0x8(%rbp), %rax
movq 0xd0(%rax), %rax
movl %eax, -0x60(%rbp)
movq -0x8(%rbp), %rax
movl 0xe0(%rax), %eax
movl %eax, -0x64(%rbp)
movq -0x8(%rbp), %rax
movl 0x100(%rax), %eax
movl %eax, -0x68(%rbp)
movl $0x3, -0x6c(%rbp)
movw $0x0, -0x6e(%rbp)
movq -0x8(%rbp), %rax
movslq -0x10(%rbp), %rcx
movq 0x70(%rax,%rcx,8), %rax
movq %rax, -0x78(%rbp)
movq -0x8(%rbp), %rax
movl 0x44(%rax), %eax
movl %eax, -0x7c(%rbp)
movq -0x8(%rbp), %rax
movslq -0x10(%rbp), %rcx
movq 0x60(%rax,%rcx,8), %rax
movq %rax, -0x88(%rbp)
movq -0x8(%rbp), %rax
movq 0x48(%rax), %rax
movq -0x8(%rbp), %rcx
movl 0xb4(%rcx), %ecx
addq %rcx, %rax
addq $0x1002, %rax           # imm = 0x1002
movq %rax, -0x90(%rbp)
movq -0x18(%rbp), %rax
movl -0x5c(%rbp), %ecx
subl $0x1, %ecx
movl %ecx, %ecx
movb (%rax,%rcx), %al
movb %al, -0x91(%rbp)
movq -0x8(%rbp), %rax
movl -0x10(%rbp), %ecx
shll %ecx
movslq %ecx, %rcx
movq 0x1a78(%rax,%rcx,8), %rax
movq -0x8(%rbp), %rcx
movl -0x10(%rbp), %edx
shll %edx
addl $0x1, %edx
movslq %edx, %rdx
cmpq 0x1a78(%rcx,%rdx,8), %rax
jge 0x5672
movq -0x8(%rbp), %rax
movl -0x10(%rbp), %ecx
shll %ecx
movslq %ecx, %rcx
movq 0x1a78(%rax,%rcx,8), %rax
movq %rax, -0x40(%rbp)
movq -0x8(%rbp), %rax
movl -0x10(%rbp), %ecx
shll %ecx
addl $0x1, %ecx
movslq %ecx, %rcx
movq 0x1a78(%rax,%rcx,8), %rax
movq %rax, -0x48(%rbp)
movl -0x10(%rbp), %eax
shll %eax
movl %eax, -0x54(%rbp)
movl -0x10(%rbp), %eax
shll %eax
addl $0x1, %eax
movl %eax, -0x58(%rbp)
jmp 0x56b8
movq -0x8(%rbp), %rax
movl -0x10(%rbp), %ecx
shll %ecx
addl $0x1, %ecx
movslq %ecx, %rcx
movq 0x1a78(%rax,%rcx,8), %rax
movq %rax, -0x40(%rbp)
movq -0x8(%rbp), %rax
movl -0x10(%rbp), %ecx
shll %ecx
movslq %ecx, %rcx
movq 0x1a78(%rax,%rcx,8), %rax
movq %rax, -0x48(%rbp)
movl -0x10(%rbp), %eax
shll %eax
addl $0x1, %eax
movl %eax, -0x54(%rbp)
movl -0x10(%rbp), %eax
shll %eax
movl %eax, -0x58(%rbp)
cmpq $0x0, -0x40(%rbp)
jl 0x56da
movq -0x48(%rbp), %rax
addq -0x40(%rbp), %rax
movl $0x2, %ecx
cqto
idivq %rcx
movq %rax, -0xa8(%rbp)
jmp 0x56e5
xorl %eax, %eax
movq %rax, -0xa8(%rbp)
jmp 0x56e5
movq -0xa8(%rbp), %rax
movq %rax, -0x50(%rbp)
cmpq $0x8000, -0x40(%rbp)    # imm = 0x8000
jle 0x570f
movq -0x40(%rbp), %rax
subq $0x8000, %rax           # imm = 0x8000
movzwl %ax, %eax
movl %eax, -0xac(%rbp)
jmp 0x5719
xorl %eax, %eax
movl %eax, -0xac(%rbp)
jmp 0x5719
movl -0xac(%rbp), %eax
movw %ax, -0x70(%rbp)
movl -0xc(%rbp), %eax
movq -0x48(%rbp), %rcx
addl $0x8000, %ecx           # imm = 0x8000
cmpl %ecx, %eax
jbe 0x5749
movq -0x78(%rbp), %rax
movl -0xc(%rbp), %ecx
andl -0x7c(%rbp), %ecx
movl %ecx, %ecx
movzwl (%rax,%rcx,2), %eax
movl %eax, -0xc(%rbp)
jmp 0x5723
cmpl $0x0, -0xc(%rbp)
jne 0x5754
jmp 0x5c23
movl -0x5c(%rbp), %eax
movq -0x8(%rbp), %rcx
cmpl 0xfc(%rcx), %eax
jb 0x576c
movl -0x30(%rbp), %eax
shrl $0x2, %eax
movl %eax, -0x30(%rbp)
movl -0x68(%rbp), %eax
movq -0x8(%rbp), %rcx
cmpl 0xbc(%rcx), %eax
jbe 0x5788
movq -0x8(%rbp), %rax
movl 0xbc(%rax), %eax
movl %eax, -0x68(%rbp)
jmp 0x578a
movq -0x8(%rbp), %rax
movslq -0x10(%rbp), %rcx
movq 0x50(%rax,%rcx,8), %rax
movl -0xc(%rbp), %ecx
addq %rcx, %rax
movq %rax, -0x20(%rbp)
movq -0x20(%rbp), %rax
movl -0x5c(%rbp), %ecx
subl $0x1, %ecx
movl %ecx, %ecx
movzbl (%rax,%rcx), %eax
movzbl -0x91(%rbp), %ecx
cmpl %ecx, %eax
jne 0x57ed
movq -0x20(%rbp), %rax
movzbl (%rax), %eax
movq -0x18(%rbp), %rcx
movzbl (%rcx), %ecx
cmpl %ecx, %eax
jne 0x57ed
movq -0x20(%rbp), %rax
movq %rax, %rcx
addq $0x1, %rcx
movq %rcx, -0x20(%rbp)
movzbl 0x1(%rax), %eax
movq -0x18(%rbp), %rcx
movzbl 0x1(%rcx), %ecx
cmpl %ecx, %eax
je 0x57f2
jmp 0x5b65
movq -0x50(%rbp), %rax
cmpl -0xc(%rbp), %eax
ja 0x5833
movl -0x58(%rbp), %eax
movl %eax, -0x38(%rbp)
movq -0x48(%rbp), %rax
cmpl -0xc(%rbp), %eax
jbe 0x5819
movq -0x48(%rbp), %rax
subl -0xc(%rbp), %eax
movl %eax, -0xb0(%rbp)
jmp 0x5828
movl -0xc(%rbp), %eax
movq -0x48(%rbp), %rcx
subl %ecx, %eax
movl %eax, -0xb0(%rbp)
movl -0xb0(%rbp), %eax
movl %eax, -0x34(%rbp)
jmp 0x5869
movl -0x54(%rbp), %eax
movl %eax, -0x38(%rbp)
movq -0x40(%rbp), %rax
cmpl -0xc(%rbp), %eax
jbe 0x5851
movq -0x40(%rbp), %rax
subl -0xc(%rbp), %eax
movl %eax, -0xb4(%rbp)
jmp 0x5860
movl -0xc(%rbp), %eax
movq -0x40(%rbp), %rcx
subl %ecx, %eax
movl %eax, -0xb4(%rbp)
movl -0xb4(%rbp), %eax
movl %eax, -0x34(%rbp)
cmpl $0x8000, -0x34(%rbp)    # imm = 0x8000
jb 0x5877
jmp 0x5b65
movq -0x18(%rbp), %rax
addq $0x2, %rax
movq %rax, -0x18(%rbp)
movq -0x20(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x20(%rbp)
jmp 0x5891
movq -0x18(%rbp), %rax
movq %rax, %rcx
addq $0x1, %rcx
movq %rcx, -0x18(%rbp)
movzbl 0x1(%rax), %ecx
movq -0x20(%rbp), %rax
movq %rax, %rdx
addq $0x1, %rdx
movq %rdx, -0x20(%rbp)
movzbl 0x1(%rax), %edx
xorl %eax, %eax
cmpl %edx, %ecx
movb %al, -0xb5(%rbp)
jne 0x5a49
movq -0x18(%rbp), %rax
movq %rax, %rcx
addq $0x1, %rcx
movq %rcx, -0x18(%rbp)
movzbl 0x1(%rax), %ecx
movq -0x20(%rbp), %rax
movq %rax, %rdx
addq $0x1, %rdx
movq %rdx, -0x20(%rbp)
movzbl 0x1(%rax), %edx
xorl %eax, %eax
cmpl %edx, %ecx
movb %al, -0xb5(%rbp)
jne 0x5a49
movq -0x18(%rbp), %rax
movq %rax, %rcx
addq $0x1, %rcx
movq %rcx, -0x18(%rbp)
movzbl 0x1(%rax), %ecx
movq -0x20(%rbp), %rax
movq %rax, %rdx
addq $0x1, %rdx
movq %rdx, -0x20(%rbp)
movzbl 0x1(%rax), %edx
xorl %eax, %eax
cmpl %edx, %ecx
movb %al, -0xb5(%rbp)
jne 0x5a49
movq -0x18(%rbp), %rax
movq %rax, %rcx
addq $0x1, %rcx
movq %rcx, -0x18(%rbp)
movzbl 0x1(%rax), %ecx
movq -0x20(%rbp), %rax
movq %rax, %rdx
addq $0x1, %rdx
movq %rdx, -0x20(%rbp)
movzbl 0x1(%rax), %edx
xorl %eax, %eax
cmpl %edx, %ecx
movb %al, -0xb5(%rbp)
jne 0x5a49
movq -0x18(%rbp), %rax
movq %rax, %rcx
addq $0x1, %rcx
movq %rcx, -0x18(%rbp)
movzbl 0x1(%rax), %ecx
movq -0x20(%rbp), %rax
movq %rax, %rdx
addq $0x1, %rdx
movq %rdx, -0x20(%rbp)
movzbl 0x1(%rax), %edx
xorl %eax, %eax
cmpl %edx, %ecx
movb %al, -0xb5(%rbp)
jne 0x5a49
movq -0x18(%rbp), %rax
movq %rax, %rcx
addq $0x1, %rcx
movq %rcx, -0x18(%rbp)
movzbl 0x1(%rax), %ecx
movq -0x20(%rbp), %rax
movq %rax, %rdx
addq $0x1, %rdx
movq %rdx, -0x20(%rbp)
movzbl 0x1(%rax), %edx
xorl %eax, %eax
cmpl %edx, %ecx
movb %al, -0xb5(%rbp)
jne 0x5a49
movq -0x18(%rbp), %rax
movq %rax, %rcx
addq $0x1, %rcx
movq %rcx, -0x18(%rbp)
movzbl 0x1(%rax), %ecx
movq -0x20(%rbp), %rax
movq %rax, %rdx
addq $0x1, %rdx
movq %rdx, -0x20(%rbp)
movzbl 0x1(%rax), %edx
xorl %eax, %eax
cmpl %edx, %ecx
movb %al, -0xb5(%rbp)
jne 0x5a49
movq -0x18(%rbp), %rax
movq %rax, %rcx
addq $0x1, %rcx
movq %rcx, -0x18(%rbp)
movzbl 0x1(%rax), %ecx
movq -0x20(%rbp), %rax
movq %rax, %rdx
addq $0x1, %rdx
movq %rdx, -0x20(%rbp)
movzbl 0x1(%rax), %edx
xorl %eax, %eax
cmpl %edx, %ecx
movb %al, -0xb5(%rbp)
jne 0x5a49
movq -0x18(%rbp), %rax
cmpq -0x90(%rbp), %rax
setb %al
movb %al, -0xb5(%rbp)
movb -0xb5(%rbp), %al
testb $0x1, %al
jne 0x588f
movq -0x90(%rbp), %rax
movq -0x18(%rbp), %rcx
subq %rcx, %rax
movl %eax, %ecx
movl $0x1002, %eax           # imm = 0x1002
subl %ecx, %eax
movl %eax, -0x24(%rbp)
movq -0x90(%rbp), %rax
addq $-0x1002, %rax          # imm = 0xEFFE
movq %rax, -0x18(%rbp)
movl -0x24(%rbp), %eax
movq -0x8(%rbp), %rcx
cmpl 0xbc(%rcx), %eax
jbe 0x5a9e
movq -0x8(%rbp), %rax
movl 0xbc(%rax), %eax
movl %eax, -0x24(%rbp)
movl -0x24(%rbp), %eax
movq -0x88(%rbp), %rcx
movl -0xc(%rbp), %edx
subq %rdx, %rcx
cmpq %rcx, %rax
jbe 0x5ac3
movq -0x88(%rbp), %rax
movl -0xc(%rbp), %ecx
subq %rcx, %rax
movl %eax, -0x24(%rbp)
movl $0x0, -0x98(%rbp)
movl -0x34(%rbp), %eax
movl %eax, -0x9c(%rbp)
movl -0x9c(%rbp), %eax
shrl %eax
movl %eax, -0x9c(%rbp)
cmpl $0x0, %eax
je 0x5afa
movl -0x98(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x98(%rbp)
jmp 0x5ad6
movl -0x2c(%rbp), %eax
imull -0x24(%rbp), %eax
subl $0xb, %eax
subl -0x98(%rbp), %eax
movl %eax, -0x28(%rbp)
movl -0x28(%rbp), %eax
cmpl -0x64(%rbp), %eax
jg 0x5b25
movl -0x28(%rbp), %eax
cmpl -0x64(%rbp), %eax
jne 0x5b63
movl -0x34(%rbp), %eax
cmpl -0x60(%rbp), %eax
jae 0x5b63
movl -0xc(%rbp), %eax
movw %ax, -0x6e(%rbp)
movl -0x34(%rbp), %eax
movl %eax, -0x60(%rbp)
movl -0x38(%rbp), %eax
movl %eax, -0x6c(%rbp)
movl -0x24(%rbp), %eax
movl %eax, -0x5c(%rbp)
movl -0x28(%rbp), %eax
movl %eax, -0x64(%rbp)
movl -0x24(%rbp), %eax
cmpl -0x68(%rbp), %eax
jb 0x5b4e
jmp 0x5bab
movq -0x18(%rbp), %rax
movl -0x5c(%rbp), %ecx
subl $0x1, %ecx
movl %ecx, %ecx
movb (%rax,%rcx), %al
movb %al, -0x91(%rbp)
jmp 0x5b65
movq -0x78(%rbp), %rax
movl -0xc(%rbp), %ecx
andl -0x7c(%rbp), %ecx
movl %ecx, %ecx
movzwl (%rax,%rcx,2), %ecx
movl %ecx, -0xc(%rbp)
movzwl -0x70(%rbp), %edx
xorl %eax, %eax
cmpl %edx, %ecx
movb %al, -0xb6(%rbp)
jbe 0x5b9d
movl -0x30(%rbp), %eax
addl $-0x1, %eax
movl %eax, -0x30(%rbp)
cmpl $0x0, %eax
setne %al
movb %al, -0xb6(%rbp)
movb -0xb6(%rbp), %al
testb $0x1, %al
jne 0x578a
cmpl $0x3, -0x6c(%rbp)
je 0x5c23
movl -0x6c(%rbp), %ecx
movq -0x8(%rbp), %rax
movl %ecx, 0xc0(%rax)
movl -0x5c(%rbp), %ecx
movq -0x8(%rbp), %rax
movl %ecx, 0xa8(%rax)
movl -0x60(%rbp), %eax
movl %eax, %ecx
movq -0x8(%rbp), %rax
movq %rcx, 0xd0(%rax)
movzwl -0x6e(%rbp), %ecx
movq -0x8(%rbp), %rax
movl %ecx, 0xb8(%rax)
movzwl -0x6e(%rbp), %eax
movl %eax, %edx
movq -0x8(%rbp), %rax
movslq -0x6c(%rbp), %rcx
movq 0x1a78(%rax,%rcx,8), %rsi
xorl %ecx, %ecx
movl $0x80, %eax
cmpq %rsi, %rdx
cmovll %eax, %ecx
movq -0x8(%rbp), %rax
movl %ecx, 0xc8(%rax)
movl -0x64(%rbp), %ecx
movq -0x8(%rbp), %rax
movl %ecx, 0xe0(%rax)
addq $0x38, %rsp
popq %rbp
retq
nopl (%rax)