// File: sbingner[P]kerneldec/lzfse/src/lzvn_encode_base.c
// Function: emit
static inline unsigned char *emit(const unsigned char *p, unsigned char *q,
                                  unsigned char *q1, size_t L, size_t M,
                                  size_t D, size_t D_prev) {
  size_t x;
  while (L > 15) {
    x = L < 271 ? L : 271;
    if (q + x + 10 >= q1)
      goto OUT_FULL;
    store2(q, 0xE0 + ((x - 16) << 8));
    q += 2;
    L -= x;
    q = lzvn_copy64(q, p, x);
    p += x;
  }
  if (L > 3) {
    if (q + L + 10 >= q1)
      goto OUT_FULL;
    *q++ = 0xE0 + L; // 1110LLLL
    q = lzvn_copy64(q, p, L);
    p += L;
    L = 0;
  }
  x = M <= 10 - 2 * L ? M : 10 - 2 * L; // x = min(10-2*L,M)
  M -= x;
  x -= 3; // M = (x+3) + M'    max value for x is 7-2*L

  // Here L<4 literals remaining, we read them here
  uint32_t literal = load4(p);
  // P is not accessed after this point

  // Relaxed capacity test covering all cases
  if (q + 8 >= q1)
    goto OUT_FULL;

  if (D == D_prev) {
    if (L == 0) {
      *q++ = 0xF0 + (x + 3); // XM!
    } else {
      *q++ = (L << 6) + (x << 3) + 6; //  LLxxx110
    }
    store4(q, literal);
    q += L;
  } else if (D < 2048 - 2 * 256) {
    // Short dist    D>>8 in 0..5
    *q++ = (D >> 8) + (L << 6) + (x << 3); // LLxxxDDD
    *q++ = D & 0xFF;
    store4(q, literal);
    q += L;
  } else if (D >= (1 << 14) || M == 0 || (x + 3) + M > 34) {
    // Long dist
    *q++ = (L << 6) + (x << 3) + 7;
    store2(q, D);
    q += 2;
    store4(q, literal);
    q += L;
  } else {
    // Medium distance
    x += M;
    M = 0;
    *q++ = 0xA0 + (x >> 2) + (L << 3);
    store2(q, D << 2 | (x & 3));
    q += 2;
    store4(q, literal);
    q += L;
  }

  // Issue remaining match
  while (M > 15) {
    if (q + 2 >= q1)
      goto OUT_FULL;
    x = M < 271 ? M : 271;
    store2(q, 0xf0 + ((x - 16) << 8));
    q += 2;
    M -= x;
  }
  if (M > 0) {
    if (q + 1 >= q1)
      goto OUT_FULL;
    *q++ = 0xF0 + M; // M = 0..15
  }

  return q;

OUT_FULL:
  return q1;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0xf0, %rsp
movq 0x10(%rbp), %rax
movq %rdi, -0xa0(%rbp)
movq %rsi, -0xa8(%rbp)
movq %rdx, -0xb0(%rbp)
movq %rcx, -0xb8(%rbp)
movq %r8, -0xc0(%rbp)
movq %r9, -0xc8(%rbp)
cmpq $0xf, -0xb8(%rbp)
jbe 0xb5f4
cmpq $0x10f, -0xb8(%rbp) # imm = 0x10F
jae 0xb524
movq -0xb8(%rbp), %rax
movq %rax, -0xe0(%rbp)
jmp 0xb532
movl $0x10f, %eax            # imm = 0x10F
movq %rax, -0xe0(%rbp)
jmp 0xb532
movq -0xe0(%rbp), %rax
movq %rax, -0xd0(%rbp)
movq -0xa8(%rbp), %rax
addq -0xd0(%rbp), %rax
addq $0xa, %rax
cmpq -0xb0(%rbp), %rax
jb 0xb560
jmp 0xbb68
movq -0xa8(%rbp), %rcx
movq -0xd0(%rbp), %rax
subq $0x10, %rax
shlq $0x8, %rax
addq $0xe0, %rax
movq %rcx, -0x48(%rbp)
movw %ax, -0x4a(%rbp)
movq -0x48(%rbp), %rax
movw -0x4a(%rbp), %cx
movw %cx, (%rax)
movq -0xa8(%rbp), %rax
addq $0x2, %rax
movq %rax, -0xa8(%rbp)
movq -0xd0(%rbp), %rcx
movq -0xb8(%rbp), %rax
subq %rcx, %rax
movq %rax, -0xb8(%rbp)
movq -0xa8(%rbp), %rdi
movq -0xa0(%rbp), %rsi
movq -0xd0(%rbp), %rdx
callq 0xbb90
movq %rax, -0xa8(%rbp)
movq -0xd0(%rbp), %rax
addq -0xa0(%rbp), %rax
movq %rax, -0xa0(%rbp)
jmp 0xb4f9
cmpq $0x3, -0xb8(%rbp)
jbe 0xb689
movq -0xa8(%rbp), %rax
addq -0xb8(%rbp), %rax
addq $0xa, %rax
cmpq -0xb0(%rbp), %rax
jb 0xb622
jmp 0xbb68
movq -0xb8(%rbp), %rax
addq $0xe0, %rax
movb %al, %cl
movq -0xa8(%rbp), %rax
movq %rax, %rdx
addq $0x1, %rdx
movq %rdx, -0xa8(%rbp)
movb %cl, (%rax)
movq -0xa8(%rbp), %rdi
movq -0xa0(%rbp), %rsi
movq -0xb8(%rbp), %rdx
callq 0xbb90
movq %rax, -0xa8(%rbp)
movq -0xb8(%rbp), %rax
addq -0xa0(%rbp), %rax
movq %rax, -0xa0(%rbp)
movq $0x0, -0xb8(%rbp)
movq -0xc0(%rbp), %rax
movq -0xb8(%rbp), %rdx
shlq %rdx
movl $0xa, %ecx
subq %rdx, %rcx
cmpq %rcx, %rax
ja 0xb6b7
movq -0xc0(%rbp), %rax
movq %rax, -0xe8(%rbp)
jmp 0xb6d0
movq -0xb8(%rbp), %rcx
shlq %rcx
movl $0xa, %eax
subq %rcx, %rax
movq %rax, -0xe8(%rbp)
movq -0xe8(%rbp), %rax
movq %rax, -0xd0(%rbp)
movq -0xd0(%rbp), %rcx
movq -0xc0(%rbp), %rax
subq %rcx, %rax
movq %rax, -0xc0(%rbp)
movq -0xd0(%rbp), %rax
subq $0x3, %rax
movq %rax, -0xd0(%rbp)
movq -0xa0(%rbp), %rax
movq %rax, -0x88(%rbp)
movq -0x88(%rbp), %rax
movl (%rax), %eax
movl %eax, -0x8c(%rbp)
movl -0x8c(%rbp), %eax
movl %eax, -0xd4(%rbp)
movq -0xa8(%rbp), %rax
addq $0x8, %rax
cmpq -0xb0(%rbp), %rax
jb 0xb74a
jmp 0xbb68
movq -0xc8(%rbp), %rax
cmpq 0x10(%rbp), %rax
jne 0xb7fe
cmpq $0x0, -0xb8(%rbp)
jne 0xb791
movq -0xd0(%rbp), %rax
addq $0x3, %rax
addq $0xf0, %rax
movb %al, %cl
movq -0xa8(%rbp), %rax
movq %rax, %rdx
addq $0x1, %rdx
movq %rdx, -0xa8(%rbp)
movb %cl, (%rax)
jmp 0xb7c7
movq -0xb8(%rbp), %rax
shlq $0x6, %rax
movq -0xd0(%rbp), %rcx
shlq $0x3, %rcx
addq %rcx, %rax
addq $0x6, %rax
movb %al, %cl
movq -0xa8(%rbp), %rax
movq %rax, %rdx
addq $0x1, %rdx
movq %rdx, -0xa8(%rbp)
movb %cl, (%rax)
movq -0xa8(%rbp), %rcx
movl -0xd4(%rbp), %eax
movq %rcx, -0x8(%rbp)
movl %eax, -0xc(%rbp)
movq -0x8(%rbp), %rax
movl -0xc(%rbp), %ecx
movl %ecx, (%rax)
movq -0xb8(%rbp), %rax
addq -0xa8(%rbp), %rax
movq %rax, -0xa8(%rbp)
jmp 0xba52
cmpq $0x600, -0xc8(%rbp) # imm = 0x600
jae 0xb8ac
movq -0xc8(%rbp), %rax
shrq $0x8, %rax
movq -0xb8(%rbp), %rcx
shlq $0x6, %rcx
addq %rcx, %rax
movq -0xd0(%rbp), %rcx
shlq $0x3, %rcx
addq %rcx, %rax
movb %al, %cl
movq -0xa8(%rbp), %rax
movq %rax, %rdx
addq $0x1, %rdx
movq %rdx, -0xa8(%rbp)
movb %cl, (%rax)
movq -0xc8(%rbp), %rax
andq $0xff, %rax
movb %al, %cl
movq -0xa8(%rbp), %rax
movq %rax, %rdx
addq $0x1, %rdx
movq %rdx, -0xa8(%rbp)
movb %cl, (%rax)
movq -0xa8(%rbp), %rcx
movl -0xd4(%rbp), %eax
movq %rcx, -0x18(%rbp)
movl %eax, -0x1c(%rbp)
movq -0x18(%rbp), %rax
movl -0x1c(%rbp), %ecx
movl %ecx, (%rax)
movq -0xb8(%rbp), %rax
addq -0xa8(%rbp), %rax
movq %rax, -0xa8(%rbp)
jmp 0xba50
cmpq $0x4000, -0xc8(%rbp) # imm = 0x4000
jae 0xb8df
cmpq $0x0, -0xc0(%rbp)
je 0xb8df
movq -0xd0(%rbp), %rax
addq $0x3, %rax
addq -0xc0(%rbp), %rax
cmpq $0x22, %rax
jbe 0xb97f
movq -0xb8(%rbp), %rax
shlq $0x6, %rax
movq -0xd0(%rbp), %rcx
shlq $0x3, %rcx
addq %rcx, %rax
addq $0x7, %rax
movb %al, %cl
movq -0xa8(%rbp), %rax
movq %rax, %rdx
addq $0x1, %rdx
movq %rdx, -0xa8(%rbp)
movb %cl, (%rax)
movq -0xa8(%rbp), %rcx
movq -0xc8(%rbp), %rax
movq %rcx, -0x58(%rbp)
movw %ax, -0x5a(%rbp)
movq -0x58(%rbp), %rax
movw -0x5a(%rbp), %cx
movw %cx, (%rax)
movq -0xa8(%rbp), %rax
addq $0x2, %rax
movq %rax, -0xa8(%rbp)
movq -0xa8(%rbp), %rcx
movl -0xd4(%rbp), %eax
movq %rcx, -0x28(%rbp)
movl %eax, -0x2c(%rbp)
movq -0x28(%rbp), %rax
movl -0x2c(%rbp), %ecx
movl %ecx, (%rax)
movq -0xb8(%rbp), %rax
addq -0xa8(%rbp), %rax
movq %rax, -0xa8(%rbp)
jmp 0xba4e
movq -0xc0(%rbp), %rax
addq -0xd0(%rbp), %rax
movq %rax, -0xd0(%rbp)
movq $0x0, -0xc0(%rbp)
movq -0xd0(%rbp), %rax
shrq $0x2, %rax
addq $0xa0, %rax
movq -0xb8(%rbp), %rcx
shlq $0x3, %rcx
addq %rcx, %rax
movb %al, %cl
movq -0xa8(%rbp), %rax
movq %rax, %rdx
addq $0x1, %rdx
movq %rdx, -0xa8(%rbp)
movb %cl, (%rax)
movq -0xa8(%rbp), %rcx
movq -0xc8(%rbp), %rax
shlq $0x2, %rax
movq -0xd0(%rbp), %rdx
andq $0x3, %rdx
orq %rdx, %rax
movq %rcx, -0x68(%rbp)
movw %ax, -0x6a(%rbp)
movq -0x68(%rbp), %rax
movw -0x6a(%rbp), %cx
movw %cx, (%rax)
movq -0xa8(%rbp), %rax
addq $0x2, %rax
movq %rax, -0xa8(%rbp)
movq -0xa8(%rbp), %rcx
movl -0xd4(%rbp), %eax
movq %rcx, -0x38(%rbp)
movl %eax, -0x3c(%rbp)
movq -0x38(%rbp), %rax
movl -0x3c(%rbp), %ecx
movl %ecx, (%rax)
movq -0xb8(%rbp), %rax
addq -0xa8(%rbp), %rax
movq %rax, -0xa8(%rbp)
jmp 0xba50
jmp 0xba52
jmp 0xba54
cmpq $0xf, -0xc0(%rbp)
jbe 0xbb12
movq -0xa8(%rbp), %rax
addq $0x2, %rax
cmpq -0xb0(%rbp), %rax
jb 0xba7b
jmp 0xbb68
cmpq $0x10f, -0xc0(%rbp) # imm = 0x10F
jae 0xba98
movq -0xc0(%rbp), %rax
movq %rax, -0xf0(%rbp)
jmp 0xbaa6
movl $0x10f, %eax            # imm = 0x10F
movq %rax, -0xf0(%rbp)
jmp 0xbaa6
movq -0xf0(%rbp), %rax
movq %rax, -0xd0(%rbp)
movq -0xa8(%rbp), %rcx
movq -0xd0(%rbp), %rax
subq $0x10, %rax
shlq $0x8, %rax
addq $0xf0, %rax
movq %rcx, -0x78(%rbp)
movw %ax, -0x7a(%rbp)
movq -0x78(%rbp), %rax
movw -0x7a(%rbp), %cx
movw %cx, (%rax)
movq -0xa8(%rbp), %rax
addq $0x2, %rax
movq %rax, -0xa8(%rbp)
movq -0xd0(%rbp), %rcx
movq -0xc0(%rbp), %rax
subq %rcx, %rax
movq %rax, -0xc0(%rbp)
jmp 0xba54
cmpq $0x0, -0xc0(%rbp)
jbe 0xbb58
movq -0xa8(%rbp), %rax
addq $0x1, %rax
cmpq -0xb0(%rbp), %rax
jb 0xbb32
jmp 0xbb68
movq -0xc0(%rbp), %rax
addq $0xf0, %rax
movb %al, %cl
movq -0xa8(%rbp), %rax
movq %rax, %rdx
addq $0x1, %rdx
movq %rdx, -0xa8(%rbp)
movb %cl, (%rax)
movq -0xa8(%rbp), %rax
movq %rax, -0x98(%rbp)
jmp 0xbb76
movq -0xb0(%rbp), %rax
movq %rax, -0x98(%rbp)
movq -0x98(%rbp), %rax
addq $0xf0, %rsp
popq %rbp
retq
nopw %cs:(%rax,%rax)