// File: /workspace/github_cpp_makefile_star2_O2/twekkel[P]mzpq/libzpaq.cpp
// Function: libzpaq::Predictor::update0(int)
void Predictor::update0(int y) {
  assert(initTables);
  assert(y==0 || y==1);
  assert(c8>=1 && c8<=255);
  assert(hmap4>=1 && hmap4<=511);

  // Update components
  const U8* cp=&z.header[7];
  int n=z.header[6];
  assert(n>=1 && n<=255);
  assert(cp[-1]==n);
  for (int i=0; i<n; ++i) {
    Component& cr=comp[i];
    switch(cp[0]) {
      case CONS:  // c
        break;
      case CM:  // sizebits limit
        train(cr, y);
        break;
      case ICM: { // sizebits: cxt=ht[b]=bh, ht[c][0..15]=bh row, cxt=bh
        cr.ht[cr.c+(hmap4&15)]=st.next(cr.ht[cr.c+(hmap4&15)], y);
        U32& pn=cr.cm(cr.cxt);
        pn+=int(y*32767-(pn>>8))>>2;
      }
        break;
      case MATCH: // sizebits bufbits:
                  //   a=len, b=offset, c=bit, cm=index, cxt=bitpos
                  //   ht=buf, limit=pos
      {
        assert(cr.a<=255);
        assert(cr.c==0 || cr.c==1);
        assert(cr.cxt<8);
        assert(cr.cm.size()==(size_t(1)<<cp[1]));
        assert(cr.ht.size()==(size_t(1)<<cp[2]));
        assert(cr.limit<cr.ht.size());
        if (int(cr.c)!=y) cr.a=0;  // mismatch?
        cr.ht(cr.limit)+=cr.ht(cr.limit)+y;
        if (++cr.cxt==8) {
          cr.cxt=0;
          ++cr.limit;
          cr.limit&=(1<<cp[2])-1;
          if (cr.a==0) {  // look for a match
            cr.b=cr.limit-cr.cm(h[i]);
            if (cr.b&(cr.ht.size()-1))
              while (cr.a<255
                     && cr.ht(cr.limit-cr.a-1)==cr.ht(cr.limit-cr.a-cr.b-1))
                ++cr.a;
          }
          else cr.a+=cr.a<255;
          cr.cm(h[i])=cr.limit;
        }
      }
        break;
      case AVG:  // j k wt
        break;
      case MIX2: { // sizebits j k rate mask
                   // cm=wt[size], cxt=input
        assert(cr.a16.size()==cr.c);
        assert(cr.cxt<cr.a16.size());
        int err=(y*32767-squash(p[i]))*cp[4]>>5;
        int w=cr.a16[cr.cxt];
        w+=(err*(p[cp[2]]-p[cp[3]])+(1<<12))>>13;
        if (w<0) w=0;
        if (w>65535) w=65535;
        cr.a16[cr.cxt]=w;
      }
        break;
      case MIX: {   // sizebits j m rate mask
                    // cm=wt[size][m], cxt=input
        int m=cp[3];
        assert(m>0 && m<=i);
        assert(cr.cm.size()==m*cr.c);
        assert(cr.cxt+m<=cr.cm.size());
        int err=(y*32767-squash(p[i]))*cp[4]>>4;
        int* wt=(int*)&cr.cm[cr.cxt];
        for (int j=0; j<m; ++j)
          wt[j]=clamp512k(wt[j]+((err*p[cp[2]+j]+(1<<12))>>13));
      }
        break;
      case ISSE: { // sizebits j  -- c=hi, cxt=bh
        assert(cr.cxt==cr.ht[cr.c+(hmap4&15)]);
        int err=y*32767-squash(p[i]);
        int *wt=(int*)&cr.cm[cr.cxt*2];
        wt[0]=clamp512k(wt[0]+((err*p[cp[2]]+(1<<12))>>13));
        wt[1]=clamp512k(wt[1]+((err+16)>>5));
        cr.ht[cr.c+(hmap4&15)]=st.next(cr.cxt, y);
      }
        break;
      case SSE:  // sizebits j start limit
        train(cr, y);
        break;
      default:
        assert(0);
    }
    cp+=compsize[cp[0]];
    assert(cp>=&z.header[7] && cp<&z.header[z.cend] 
           && cp<&z.header[z.header.isize()-8]);
  }
  assert(cp[0]==NONE);

  // Save bit y in c8, hmap4
  c8+=c8+y;
  if (c8>=256) {
    z.run(c8-256);
    hmap4=1;
    c8=1;
    for (int i=0; i<n; ++i) h[i]=z.H(i);
  }
  else if (c8>=16 && c8<32)
    hmap4=(hmap4&0xf)<<5|y<<4|1;
  else
    hmap4=(hmap4&0x1f0)|(((hmap4&0xf)*2+y)&0xf);
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x28, %rsp
movl %esi, %r12d
movq %rdi, %rbx
movq 0x808(%rdi), %rax
movq 0x10(%rax), %r13
movzbl 0x6(%r13), %r15d
addq $0x7, %r13
leaq 0x810(%rdi), %rbp
imull $0x7fff, %esi, %r10d    # imm = 0x7FFF
leaq 0x133fb(%rip), %r11     # 0x1eaf0
movslq %esi, %rax
movq %rax, 0x20(%rsp)
xorl %r14d, %r14d
movl %r10d, 0xc(%rsp)
cmpq %r15, %r14
je 0xba66
movzbl (%r13), %eax
addl $-0x2, %eax
cmpl $0x7, %eax
ja 0xba52
imulq $0x70, %r14, %rsi
addq %rbp, %rsi
leaq 0x130ab(%rip), %rcx     # 0x1e7d8
movslq (%rcx,%rax,4), %rax
addq %rcx, %rax
jmpq *%rax
movq %rbx, %rdi
movl %r12d, %edx
callq 0x1c830
leaq 0x133a8(%rip), %r11     # 0x1eaf0
movl 0xc(%rsp), %r10d
jmp 0xba52
cmpl %r12d, 0x20(%rsi)
je 0xb75d
andq $0x0, 0x10(%rsi)
movq 0x40(%rsi), %rax
movq 0x48(%rsi), %rcx
decq %rcx
andq (%rsi), %rcx
movb (%rax,%rcx), %dl
addb %dl, %dl
addb %r12b, %dl
movb %dl, (%rax,%rcx)
movq 0x8(%rsi), %rax
incq %rax
movq %rax, 0x8(%rsi)
cmpq $0x8, %rax
jne 0xba52
andq $0x0, 0x8(%rsi)
movq (%rsi), %rax
movq 0x10(%rsi), %rdx
incq %rax
movq %rax, (%rsi)
movb 0x2(%r13), %cl
pushq $-0x1
popq %rdi
shll %cl, %edi
notl %edi
andl %edi, %eax
movq %rax, (%rsi)
testq %rdx, %rdx
je 0xb9a9
cmpq $0xff, %rdx
adcq $0x0, %rdx
movq %rdx, 0x10(%rsi)
movq 0x28(%rsi), %rdi
movl 0x30(%rsi), %edx
movl $0xffffffff, %ecx       # imm = 0xFFFFFFFF
addl %ecx, %edx
andl 0x408(%rbx,%r14,4), %edx
jmp 0xba4f
movl 0x4(%rbx), %eax
andl $0xf, %eax
movq 0x40(%rsi), %rcx
addq 0x20(%rsi), %rcx
movzbl (%rax,%rcx), %edx
movq 0x20(%rsp), %rdi
leaq (%rdi,%rdx,4), %rdx
movb 0x1ac14(%rbx,%rdx), %dl
movb %dl, (%rax,%rcx)
movq 0x28(%rsi), %rax
movq 0x30(%rsi), %rcx
decq %rcx
andq 0x8(%rsi), %rcx
movl (%rax,%rcx,4), %edx
movl %edx, %esi
shrl $0x8, %esi
movl %r10d, %edi
subl %esi, %edi
sarl $0x2, %edi
addl %edx, %edi
movl %edi, (%rax,%rcx,4)
jmp 0xba52
movslq 0x8(%rbx,%r14,4), %rax
movzwl 0x9c14(%rbx,%rax,2), %eax
movl %r10d, %ecx
subl %eax, %ecx
movzbl 0x4(%r13), %eax
imull %ecx, %eax
sarl $0x5, %eax
movq 0x8(%rsi), %rcx
movq 0x58(%rsi), %rdx
movzbl 0x2(%r13), %esi
movl 0x8(%rbx,%rsi,4), %esi
movzbl 0x3(%r13), %edi
subl 0x8(%rbx,%rdi,4), %esi
movzwl (%rdx,%rcx,2), %edi
imull %eax, %esi
addl $0x1000, %esi           # imm = 0x1000
sarl $0xd, %esi
addl %edi, %esi
testl %esi, %esi
movl $0x0, %eax
cmovlel %eax, %esi
movl $0xffff, %eax           # imm = 0xFFFF
cmpl %eax, %esi
cmovgel %eax, %esi
movw %si, (%rdx,%rcx,2)
jmp 0xba52
movzbl 0x3(%r13), %eax
movslq 0x8(%rbx,%r14,4), %rcx
movzwl 0x9c14(%rbx,%rcx,2), %ecx
movl %r10d, %edx
subl %ecx, %edx
movzbl 0x4(%r13), %ecx
imull %edx, %ecx
sarl $0x4, %ecx
movq 0x8(%rsi), %rdx
shlq $0x2, %rdx
addq 0x28(%rsi), %rdx
xorl %esi, %esi
cmpq %rsi, %rax
je 0xba52
movzbl 0x2(%r13), %edi
addq %rsi, %rdi
movl 0x8(%rbx,%rdi,4), %edi
imull %ecx, %edi
addl $0x1000, %edi           # imm = 0x1000
sarl $0xd, %edi
addl (%rdx,%rsi,4), %edi
movl $0x7ffff, %r8d          # imm = 0x7FFFF
cmpl %r8d, %edi
jl 0xb8f8
movl $0x7ffff, %edi          # imm = 0x7FFFF
cmpl $0xfff80001, %edi       # imm = 0xFFF80001
jge 0xb905
movl $0xfff80000, %edi       # imm = 0xFFF80000
movl %edi, (%rdx,%rsi,4)
incq %rsi
jmp 0xb8c4
movslq 0x8(%rbx,%r14,4), %rax
movzwl 0x9c14(%rbx,%rax,2), %eax
movl %r10d, %ecx
subl %eax, %ecx
movq 0x8(%rsi), %rax
movq 0x28(%rsi), %rdx
movzbl 0x2(%r13), %edi
movl 0x8(%rbx,%rdi,4), %edi
imull %ecx, %edi
addl $0x1000, %edi           # imm = 0x1000
sarl $0xd, %edi
addl (%rdx,%rax,8), %edi
movl $0x7ffff, %r8d          # imm = 0x7FFFF
cmpl %r8d, %edi
cmovgel %r8d, %edi
movl $0xfff80001, %r9d       # imm = 0xFFF80001
cmpl %r9d, %edi
movl $0xfff80000, %r9d       # imm = 0xFFF80000
cmovll %r9d, %edi
movl %edi, (%rdx,%rax,8)
addl $0x10, %ecx
sarl $0x5, %ecx
addl 0x4(%rdx,%rax,8), %ecx
cmpl %r8d, %ecx
cmovgel %r8d, %ecx
movl $0xfff80001, %edi       # imm = 0xFFF80001
cmpl %edi, %ecx
cmovll %r9d, %ecx
movl %ecx, 0x4(%rdx,%rax,8)
movq 0x20(%rsp), %rcx
leal (%rcx,%rax,4), %eax
cltq
movb 0x1ac14(%rbx,%rax), %al
movl 0x4(%rbx), %ecx
andl $0xf, %ecx
movq 0x40(%rsi), %rdx
addq 0x20(%rsi), %rdx
movb %al, (%rcx,%rdx)
jmp 0xba52
movq %r12, 0x18(%rsp)
movq 0x28(%rsi), %r8
movq 0x48(%rsi), %rdi
movl 0x30(%rsi), %edx
movl $0xffffffff, %ecx       # imm = 0xFFFFFFFF
addl %ecx, %edx
andl 0x408(%rbx,%r14,4), %edx
movq %r8, 0x10(%rsp)
movl (%r8,%rdx,4), %r12d
movq %rax, %r9
subq %r12, %r9
movq %r9, 0x18(%rsi)
decq %rdi
testq %r9, %rdi
je 0xba26
leaq -0x1(%rax), %rcx
decq %r12
xorl %r10d, %r10d
cmpq $0xfe, %r10
ja 0xba2d
movq 0x40(%rsi), %r11
movq %rcx, %r9
andq %rdi, %r9
movb (%r11,%r9), %r9b
movq %r12, %r8
andq %rdi, %r8
cmpb (%r11,%r8), %r9b
jne 0xba39
incq %r10
movq %r10, 0x10(%rsi)
decq %rcx
decq %r12
leaq 0x130cc(%rip), %r11     # 0x1eaf0
jmp 0xb9ed
movq 0x18(%rsp), %r12
jmp 0xba4a
movq 0x18(%rsp), %r12
movl 0xc(%rsp), %r10d
jmp 0xba4a
movq 0x18(%rsp), %r12
movl 0xc(%rsp), %r10d
leaq 0x130a6(%rip), %r11     # 0x1eaf0
movq 0x10(%rsp), %rdi
movl %eax, (%rdi,%rdx,4)
movzbl (%r13), %eax
movslq (%r11,%rax,4), %rax
addq %rax, %r13
incq %r14
jmp 0xb705
movl (%rbx), %eax
leal (%r12,%rax,2), %esi
movl %esi, (%rbx)
cmpl $0xff, %esi
jle 0xbac5
movq 0x808(%rbx), %rdi
addl $0xffffff00, %esi       # imm = 0xFFFFFF00
callq 0xbb08
movabsq $0x100000001, %rax      # imm = 0x100000001
movq %rax, (%rbx)
movq 0x808(%rbx), %rax
xorl %ecx, %ecx
movl $0x7fffffff, %edx       # imm = 0x7FFFFFFF
cmpq %rcx, %r15
je 0xbaf9
movq 0x50(%rax), %rsi
movq 0x58(%rax), %rdi
addq %rdx, %rdi
andq %rcx, %rdi
movl (%rsi,%rdi,4), %esi
movl %esi, 0x408(%rbx,%rcx,4)
incq %rcx
jmp 0xbaa3
andl $-0x10, %esi
movl 0x4(%rbx), %eax
cmpl $0x10, %esi
jne 0xbae2
andl $0xf, %eax
shll $0x5, %eax
shll $0x4, %r12d
orl %eax, %r12d
incl %r12d
jmp 0xbaf5
movl %eax, %ecx
andl $0x1f0, %ecx            # imm = 0x1F0
leal (%r12,%rax,2), %r12d
andl $0xf, %r12d
orl %ecx, %r12d
movl %r12d, 0x4(%rbx)
addq $0x28, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq