// File: /workspace/github_cpp_makefile_star2_O2/twekkel[P]mzpq/libzpaq.cpp
// Function: libzpaq::Predictor::predict0()
int Predictor::predict0() {
  assert(initTables);
  assert(c8>=1 && c8<=255);

  // Predict next bit
  int n=z.header[6];
  assert(n>0 && n<=255);
  const U8* cp=&z.header[7];
  assert(cp[-1]==n);
  for (int i=0; i<n; ++i) {
    assert(cp>&z.header[0] && cp<&z.header[z.header.isize()-8]);
    Component& cr=comp[i];
    switch(cp[0]) {
      case CONS:  // c
        break;
      case CM:  // sizebits limit
        cr.cxt=h[i]^hmap4;
        p[i]=stretch(cr.cm(cr.cxt)>>17);
        break;
      case ICM: // sizebits
        assert((hmap4&15)>0);
        if (c8==1 || (c8&0xf0)==16) cr.c=find(cr.ht, cp[1]+2, h[i]+16*c8);
        cr.cxt=cr.ht[cr.c+(hmap4&15)];
        p[i]=stretch(cr.cm(cr.cxt)>>8);
        break;
      case MATCH: // sizebits bufbits: a=len, b=offset, c=bit, cxt=bitpos,
                  //                   ht=buf, limit=pos
        assert(cr.cm.size()==(size_t(1)<<cp[1]));
        assert(cr.ht.size()==(size_t(1)<<cp[2]));
        assert(cr.a<=255);
        assert(cr.c==0 || cr.c==1);
        assert(cr.cxt<8);
        assert(cr.limit<cr.ht.size());
        if (cr.a==0) p[i]=0;
        else {
          cr.c=(cr.ht(cr.limit-cr.b)>>(7-cr.cxt))&1; // predicted bit
          p[i]=stretch(dt2k[cr.a]*(cr.c*-2+1)&32767);
        }
        break;
      case AVG: // j k wt
        p[i]=(p[cp[1]]*cp[3]+p[cp[2]]*(256-cp[3]))>>8;
        break;
      case MIX2: { // sizebits j k rate mask
                   // c=size cm=wt[size] cxt=input
        cr.cxt=((h[i]+(c8&cp[5]))&(cr.c-1));
        assert(cr.cxt<cr.a16.size());
        int w=cr.a16[cr.cxt];
        assert(w>=0 && w<65536);
        p[i]=(w*p[cp[2]]+(65536-w)*p[cp[3]])>>16;
        assert(p[i]>=-2048 && p[i]<2048);
      }
        break;
      case MIX: {  // sizebits j m rate mask
                   // c=size cm=wt[size][m] cxt=index of wt in cm
        int m=cp[3];
        assert(m>=1 && m<=i);
        cr.cxt=h[i]+(c8&cp[5]);
        cr.cxt=(cr.cxt&(cr.c-1))*m; // pointer to row of weights
        assert(cr.cxt<=cr.cm.size()-m);
        int* wt=(int*)&cr.cm[cr.cxt];
        p[i]=0;
        for (int j=0; j<m; ++j)
          p[i]+=(wt[j]>>8)*p[cp[2]+j];
        p[i]=clamp2k(p[i]>>8);
      }
        break;
      case ISSE: { // sizebits j -- c=hi, cxt=bh
        assert((hmap4&15)>0);
        if (c8==1 || (c8&0xf0)==16)
          cr.c=find(cr.ht, cp[1]+2, h[i]+16*c8);
        cr.cxt=cr.ht[cr.c+(hmap4&15)];  // bit history
        int *wt=(int*)&cr.cm[cr.cxt*2];
        p[i]=clamp2k((wt[0]*p[cp[2]]+wt[1]*64)>>16);
      }
        break;
      case SSE: { // sizebits j start limit
        cr.cxt=(h[i]+c8)*32;
        int pq=p[cp[2]]+992;
        if (pq<0) pq=0;
        if (pq>1983) pq=1983;
        int wt=pq&63;
        pq>>=6;
        assert(pq>=0 && pq<=30);
        cr.cxt+=pq;
        p[i]=stretch(((cr.cm(cr.cxt)>>10)*(64-wt)+(cr.cm(cr.cxt+1)>>10)*wt)>>13);
        cr.cxt+=wt>>5;
      }
        break;
      default:
        error("component predict not implemented");
    }
    cp+=compsize[cp[0]];
    assert(cp<&z.header[z.cend]);
    assert(p[i]>=-2048 && p[i]<2048);
  }
  assert(cp[0]==NONE);
  return squash(p[n-1]);
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
pushq %rax
movq %rdi, %rbx
movq 0x808(%rdi), %rax
movq 0x10(%rax), %r13
movzbl 0x6(%r13), %r12d
addq $0x7, %r13
leaq 0x810(%rdi), %rbp
xorl %r14d, %r14d
leaq 0x138a3(%rip), %r10     # 0x1eaf0
leaq 0x13560(%rip), %r11     # 0x1e7b4
cmpq %r12, %r14
je 0xb616
movzbl (%r13), %eax
decl %eax
cmpl $0x8, %eax
ja 0xb55a
imulq $0x70, %r14, %r15
addq %rbp, %r15
movslq (%r11,%rax,4), %rax
addq %r11, %rax
jmpq *%rax
movl 0x4(%rbx), %eax
xorl 0x408(%rbx,%r14,4), %eax
movq %rax, 0x8(%r15)
movq 0x28(%r15), %rcx
movl 0x30(%r15), %edx
movl $0xffffffff, %esi       # imm = 0xFFFFFFFF
addl %esi, %edx
andl %eax, %edx
movzwl 0x2(%rcx,%rdx,4), %eax
andl $-0x2, %eax
movswl 0xac14(%rbx,%rax), %eax
jmp 0xb5f5
movzbl 0x1(%r13), %eax
movzbl 0x3(%r13), %ecx
movl 0x8(%rbx,%rax,4), %eax
movzbl 0x2(%r13), %edx
movl $0x100, %esi            # imm = 0x100
subl %ecx, %esi
imull 0x8(%rbx,%rdx,4), %esi
imull %ecx, %eax
addl %eax, %esi
sarl $0x8, %esi
movl %esi, 0x8(%rbx,%r14,4)
jmp 0xb5fa
movl (%rbx), %ecx
cmpl $0x1, %ecx
sete %al
movl %ecx, %edx
andl $0xf0, %edx
cmpl $0x10, %edx
sete %dl
orb %al, %dl
je 0xb579
leaq 0x40(%r15), %rsi
movzbl 0x1(%r13), %edx
addl $0x2, %edx
shll $0x4, %ecx
addl 0x408(%rbx,%r14,4), %ecx
callq 0xb632
leaq 0x13490(%rip), %r11     # 0x1e7b4
leaq 0x137c5(%rip), %r10     # 0x1eaf0
movq %rax, 0x20(%r15)
jmp 0xb57d
movq 0x10(%r15), %rax
testq %rax, %rax
je 0xb60e
movq (%r15), %rcx
movq 0x40(%r15), %rdx
subq 0x18(%r15), %rcx
movq 0x48(%r15), %rsi
decq %rsi
andq %rcx, %rsi
movzbl (%rdx,%rsi), %ecx
movb $0x7, %dl
subb 0x8(%r15), %dl
movzbl %dl, %edx
xorl %esi, %esi
btl %edx, %ecx
setb %sil
movq %rsi, 0x20(%r15)
imull $0x7ffe, %esi, %ecx     # imm = 0x7FFE
incl %ecx
imull 0x7814(%rbx,%rax,4), %ecx
andl $0x7fff, %ecx           # imm = 0x7FFF
movswl 0xac14(%rbx,%rcx,2), %eax
jmp 0xb5f5
movl (%rbx), %ecx
cmpl $0x1, %ecx
sete %al
movl %ecx, %edx
andl $0xf0, %edx
cmpl $0x10, %edx
sete %dl
orb %al, %dl
je 0xb5ab
leaq 0x40(%r15), %rsi
movzbl 0x1(%r13), %edx
addl $0x2, %edx
shll $0x4, %ecx
addl 0x408(%rbx,%r14,4), %ecx
callq 0xb632
leaq 0x133e0(%rip), %r11     # 0x1e7b4
leaq 0x13715(%rip), %r10     # 0x1eaf0
movq %rax, 0x20(%r15)
jmp 0xb5af
movzbl 0x5(%r13), %eax
andl (%rbx), %eax
addl 0x408(%rbx,%r14,4), %eax
movl 0x20(%r15), %ecx
movl $0xffffffff, %edx       # imm = 0xFFFFFFFF
addl %edx, %ecx
andl %eax, %ecx
movq %rcx, 0x8(%r15)
movq 0x58(%r15), %rax
movzwl (%rax,%rcx,2), %eax
movzbl 0x2(%r13), %ecx
movl $0x10000, %edx          # imm = 0x10000
subl %eax, %edx
imull 0x8(%rbx,%rcx,4), %eax
movzbl 0x3(%r13), %ecx
imull 0x8(%rbx,%rcx,4), %edx
addl %eax, %edx
sarl $0x10, %edx
movl %edx, 0x8(%rbx,%r14,4)
jmp 0xb5fa
movzbl 0x3(%r13), %eax
movzbl 0x5(%r13), %edx
andl (%rbx), %edx
addl 0x408(%rbx,%r14,4), %edx
movl 0x20(%r15), %ecx
movl $0xffffffff, %esi       # imm = 0xFFFFFFFF
addl %esi, %ecx
andl %edx, %ecx
imulq %rax, %rcx
movq %rcx, 0x8(%r15)
shlq $0x2, %rcx
addq 0x28(%r15), %rcx
andl $0x0, 0x8(%rbx,%r14,4)
xorl %edx, %edx
xorl %esi, %esi
cmpq %rsi, %rax
je 0xb496
movl (%rcx,%rsi,4), %edi
sarl $0x8, %edi
movzbl 0x2(%r13), %r8d
addq %rsi, %r8
imull 0x8(%rbx,%r8,4), %edi
addl %edi, %edx
movl %edx, 0x8(%rbx,%r14,4)
incq %rsi
jmp 0xb471
sarl $0x8, %edx
movl $0x7ff, %eax            # imm = 0x7FF
cmpl %eax, %edx
cmovgel %eax, %edx
cmpl $0xfffff801, %edx       # imm = 0xFFFFF801
movl $0xfffff800, %eax       # imm = 0xFFFFF800
cmovll %eax, %edx
movl %edx, 0x8(%rbx,%r14,4)
jmp 0xb5fa
movl (%rbx), %ecx
addl 0x408(%rbx,%r14,4), %ecx
shll $0x5, %ecx
movq %rcx, 0x8(%r15)
movzbl 0x2(%r13), %eax
movl 0x8(%rbx,%rax,4), %r8d
cmpl $0xfffffc21, %r8d       # imm = 0xFFFFFC21
movl $0xfffffc20, %eax       # imm = 0xFFFFFC20
cmovll %eax, %r8d
movl $0x3df, %eax            # imm = 0x3DF
cmpl %eax, %r8d
cmovgel %eax, %r8d
addl $0x3e0, %r8d            # imm = 0x3E0
movl %r8d, %eax
andl $0x3f, %eax
shrl $0x6, %r8d
leaq (%r8,%rcx), %rsi
movq 0x28(%r15), %rdx
movq 0x30(%r15), %rdi
decq %rdi
pushq $0x40
popq %r9
subl %eax, %r9d
addq %r8, %rcx
incq %rcx
andq %rdi, %rcx
movl (%rdx,%rcx,4), %ecx
shrl $0xa, %ecx
imull %eax, %ecx
shrl $0x5, %eax
addq %rsi, %rax
andq %rdi, %rsi
movl (%rdx,%rsi,4), %edx
shrl $0xa, %edx
imull %edx, %r9d
addl %r9d, %ecx
shrl $0xd, %ecx
movswl 0xac14(%rbx,%rcx,2), %ecx
movl %ecx, 0x8(%rbx,%r14,4)
movq %rax, 0x8(%r15)
jmp 0xb5fa
leaq 0x16a5d(%rip), %rdi     # 0x21fbe
callq 0x44dc
leaq 0x13247(%rip), %r11     # 0x1e7b4
leaq 0x1357c(%rip), %r10     # 0x1eaf0
jmp 0xb5fa
movq 0x20(%r15), %rax
movl 0x4(%rbx), %ecx
andl $0xf, %ecx
addq 0x40(%r15), %rax
movzbl (%rcx,%rax), %eax
movq %rax, 0x8(%r15)
movq 0x28(%r15), %rcx
movl 0x30(%r15), %edx
decl %edx
andl %eax, %edx
movl (%rcx,%rdx,4), %eax
shrl $0x8, %eax
movswl 0xac14(%rbx,%rax,2), %eax
jmp 0xb5f5
movq 0x20(%r15), %rax
movl 0x4(%rbx), %ecx
addq 0x40(%r15), %rax
andl $0xf, %ecx
movzbl (%rcx,%rax), %eax
movq %rax, 0x8(%r15)
movq 0x28(%r15), %rcx
movzbl 0x2(%r13), %edx
movl 0x8(%rbx,%rdx,4), %edx
imull (%rcx,%rax,8), %edx
movl 0x4(%rcx,%rax,8), %eax
shll $0x6, %eax
addl %edx, %eax
sarl $0x10, %eax
movl $0x7ff, %ecx            # imm = 0x7FF
cmpl %ecx, %eax
cmovgel %ecx, %eax
cmpl $0xfffff801, %eax       # imm = 0xFFFFF801
movl $0xfffff800, %ecx       # imm = 0xFFFFF800
cmovll %ecx, %eax
movl %eax, 0x8(%rbx,%r14,4)
movzbl (%r13), %eax
movslq (%r10,%rax,4), %rax
addq %rax, %r13
incq %r14
jmp 0xb254
andl $0x0, 0x8(%rbx,%r14,4)
jmp 0xb5fa
movslq 0x4(%rbx,%r12,4), %rax
movzwl 0x9c14(%rbx,%rax,2), %eax
addq $0x8, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq