// File: /workspace/github_cpp_makefile_star2_O1/twekkel[P]mzpq/libzpaq.cpp
// Function: libzpaq::Predictor::init()
void Predictor::init() {

  // Clear old JIT code if any
  allocx(pcode, pcode_size, 0);

  // Initialize context hash function
  z.inith();

  // Initialize model independent tables
  if (!initTables && isModeled()) {
    initTables=true;
    memcpy(dt2k, sdt2k, sizeof(dt2k));
    memcpy(dt, sdt, sizeof(dt));

    // ssquasht[i]=int(32768.0/(1+exp((i-2048)*(-1.0/64))));
    // Copy middle 1344 of 4096 entries.
    memset(squasht, 0, 1376*2);
    memcpy(squasht+1376, ssquasht, 1344*2);
    for (int i=2720; i<4096; ++i) squasht[i]=32767;

    // sstretcht[i]=int(log((i+0.5)/(32767.5-i))*64+0.5+100000)-100000;
    int k=16384;
    for (int i=0; i<712; ++i)
      for (int j=stdt[i]; j>0; --j)
        stretcht[k++]=i;
    assert(k==32768);
    for (int i=0; i<16384; ++i)
      stretcht[i]=-stretcht[32767-i];

#ifndef NDEBUG
    // Verify floating point math for squash() and stretch()
    U32 sqsum=0, stsum=0;
    for (int i=32767; i>=0; --i)
      stsum=stsum*3+stretch(i);
    for (int i=4095; i>=0; --i)
      sqsum=sqsum*3+squash(i-2048);
    assert(stsum==3887533746u);
    assert(sqsum==2278286169u);
#endif
  }

  // Initialize predictions
  for (int i=0; i<256; ++i) h[i]=p[i]=0;

  // Initialize components
  for (int i=0; i<256; ++i)  // clear old model
    comp[i].init();
  int n=z.header[6]; // hsize[0..1] hh hm ph pm n (comp)[n] END 0[128] (hcomp) END
  const U8* cp=&z.header[7];  // start of component list
  for (int i=0; i<n; ++i) {
    assert(cp<&z.header[z.cend]);
    assert(cp>&z.header[0] && cp<&z.header[z.header.isize()-8]);
    Component& cr=comp[i];
    switch(cp[0]) {
      case CONS:  // c
        p[i]=(cp[1]-128)*4;
        break;
      case CM: // sizebits limit
        if (cp[1]>32) error("max size for CM is 32");
        cr.cm.resize(1, cp[1]);  // packed CM (22 bits) + CMCOUNT (10 bits)
        cr.limit=cp[2]*4;
        for (size_t j=0; j<cr.cm.size(); ++j)
          cr.cm[j]=0x80000000;
        break;
      case ICM: // sizebits
        if (cp[1]>26) error("max size for ICM is 26");
        cr.limit=1023;
        cr.cm.resize(256);
        cr.ht.resize(64, cp[1]);
        for (size_t j=0; j<cr.cm.size(); ++j)
          cr.cm[j]=st.cminit(j);
        break;
      case MATCH:  // sizebits
        if (cp[1]>32 || cp[2]>32) error("max size for MATCH is 32 32");
        cr.cm.resize(1, cp[1]);  // index
        cr.ht.resize(1, cp[2]);  // buf
        cr.ht(0)=1;
        break;
      case AVG: // j k wt
        if (cp[1]>=i) error("AVG j >= i");
        if (cp[2]>=i) error("AVG k >= i");
        break;
      case MIX2:  // sizebits j k rate mask
        if (cp[1]>32) error("max size for MIX2 is 32");
        if (cp[3]>=i) error("MIX2 k >= i");
        if (cp[2]>=i) error("MIX2 j >= i");
        cr.c=(size_t(1)<<cp[1]); // size (number of contexts)
        cr.a16.resize(1, cp[1]);  // wt[size][m]
        for (size_t j=0; j<cr.a16.size(); ++j)
          cr.a16[j]=32768;
        break;
      case MIX: {  // sizebits j m rate mask
        if (cp[1]>32) error("max size for MIX is 32");
        if (cp[2]>=i) error("MIX j >= i");
        if (cp[3]<1 || cp[3]>i-cp[2]) error("MIX m not in 1..i-j");
        int m=cp[3];  // number of inputs
        assert(m>=1);
        cr.c=(size_t(1)<<cp[1]); // size (number of contexts)
        cr.cm.resize(m, cp[1]);  // wt[size][m]
        for (size_t j=0; j<cr.cm.size(); ++j)
          cr.cm[j]=65536/m;
        break;
      }
      case ISSE:  // sizebits j
        if (cp[1]>32) error("max size for ISSE is 32");
        if (cp[2]>=i) error("ISSE j >= i");
        cr.ht.resize(64, cp[1]);
        cr.cm.resize(512);
        for (int j=0; j<256; ++j) {
          cr.cm[j*2]=1<<15;
          cr.cm[j*2+1]=clamp512k(stretch(st.cminit(j)>>8)*1024);
        }
        break;
      case SSE: // sizebits j start limit
        if (cp[1]>32) error("max size for SSE is 32");
        if (cp[2]>=i) error("SSE j >= i");
        if (cp[3]>cp[4]*4) error("SSE start > limit*4");
        cr.cm.resize(32, cp[1]);
        cr.limit=cp[4]*4;
        for (size_t j=0; j<cr.cm.size(); ++j)
          cr.cm[j]=squash((j&31)*64-992)<<17|cp[3];
        break;
      default: error("unknown component type");
    }
    assert(compsize[*cp]>0);
    cp+=compsize[*cp];
    assert(cp>=&z.header[7] && cp<&z.header[z.cend]);
  }
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x18, %rsp
movq %rdi, %rbx
movq 0x1b018(%rdi), %rdi
testq %rdi, %rdi
sete %cl
movl 0x1b020(%rbx), %eax
testl %eax, %eax
sete %dl
testb %dl, %cl
jne 0xb287
testq %rdi, %rdi
je 0xb272
movslq %eax, %rsi
callq 0x40f0
movq $0x0, 0x1b018(%rbx)
movl $0x0, 0x1b020(%rbx)
movq 0x808(%rbx), %rdi
movq 0x10(%rdi), %rax
movzbl 0x2(%rax), %esi
movzbl 0x3(%rax), %edx
callq 0x9dc8
cmpb $0x0, 0x7810(%rbx)
jne 0xb3a6
movq 0x808(%rbx), %rax
movq 0x10(%rax), %rax
cmpb $0x0, 0x6(%rax)
je 0xb3a6
movb $0x1, 0x7810(%rbx)
leaq 0x7814(%rbx), %rdi
leaq 0x40fea(%rip), %rsi     # 0x4c2c0
movl $0x400, %edx            # imm = 0x400
callq 0x4140
leaq 0x7c14(%rbx), %rdi
leaq 0x413d2(%rip), %rsi     # 0x4c6c0
movl $0x1000, %edx           # imm = 0x1000
callq 0x4140
leaq 0x8c14(%rbx), %rdi
xorl %r14d, %r14d
movl $0xac0, %edx            # imm = 0xAC0
xorl %esi, %esi
callq 0x40e0
leaq 0x96d4(%rbx), %rdi
leaq 0x423a4(%rip), %rsi     # 0x4d6c0
movl $0xa80, %edx            # imm = 0xA80
callq 0x4140
movw $0x7fff, 0xa154(%rbx,%r14,2) # imm = 0x7FFF
incq %r14
cmpq $0x560, %r14            # imm = 0x560
jne 0xb326
leaq 0xac14(%rbx), %rax
movl $0x4000, %ecx           # imm = 0x4000
xorl %edx, %edx
leaq 0x42dee(%rip), %rsi     # 0x4e140
movzbl (%rdx,%rsi), %edi
testl %edi, %edi
je 0xb374
movslq %ecx, %rcx
leaq (%rax,%rcx,2), %r8
addl %edi, %ecx
incl %edi
movw %dx, (%r8)
addq $0x2, %r8
decl %edi
cmpl $0x1, %edi
jg 0xb365
incq %rdx
cmpq $0x2c8, %rdx            # imm = 0x2C8
jne 0xb352
leaq 0x1ac12(%rbx), %rax
xorl %ecx, %ecx
xorl %edx, %edx
subw (%rax), %dx
movw %dx, 0xac14(%rbx,%rcx,2)
incq %rcx
addq $-0x2, %rax
cmpq $0x4000, %rcx           # imm = 0x4000
jne 0xb389
leaq 0x8(%rbx), %rdi
movl $0x800, %edx            # imm = 0x800
xorl %esi, %esi
callq 0x40e0
movl $0x810, %r14d           # imm = 0x810
leaq (%rbx,%r14), %rdi
callq 0x9806
addq $0x70, %r14
cmpq $0x7810, %r14           # imm = 0x7810
jne 0xb3bc
movq 0x808(%rbx), %rax
movq 0x10(%rax), %rbp
movzbl 0x6(%rbp), %eax
movq %rax, 0x10(%rsp)
testq %rax, %rax
je 0xb849
addq $0x7, %rbp
leaq 0x810(%rbx), %rax
movq %rax, 0x8(%rsp)
xorl %r14d, %r14d
movzbl (%rbp), %eax
decl %eax
cmpl $0x8, %eax
ja 0xb81d
imulq $0x70, %r14, %r13
addq 0x8(%rsp), %r13
leaq 0x4033f(%rip), %rcx     # 0x4b760
movslq (%rcx,%rax,4), %rax
addq %rcx, %rax
jmpq *%rax
movzbl 0x1(%rbp), %eax
leal -0x200(,%rax,4), %eax
movl %eax, 0x8(%rbx,%r14,4)
jmp 0xb829
movzbl 0x1(%rbp), %eax
cmpq %rax, %r14
ja 0xb454
leaq 0x43a5d(%rip), %rdi     # 0x4eeac
callq 0x455c
movzbl 0x2(%rbp), %eax
cmpq %rax, %r14
ja 0xb829
leaq 0x43a4f(%rip), %rdi     # 0x4eeb7
jmp 0xb824
cmpb $0x1b, 0x1(%rbp)
jb 0xb47f
leaq 0x439ff(%rip), %rdi     # 0x4ee79
callq 0x455c
movq $0x3ff, (%r13)          # imm = 0x3FF
leaq 0x28(%r13), %r15
movl $0x100, %esi            # imm = 0x100
movq %r15, %rdi
xorl %edx, %edx
callq 0x4a048
leaq 0x40(%r13), %rdi
movzbl 0x1(%rbp), %edx
movl $0x40, %esi
callq 0x4a126
movq 0x30(%r13), %rcx
testq %rcx, %rcx
je 0xb829
movq (%r15), %rsi
movl $0x2, %edi
xorl %r8d, %r8d
leal 0x1(%rdi), %eax
cltq
movzbl 0x1ac14(%rbx,%rax), %eax
movslq %edi, %rdi
movzbl 0x1ac14(%rbx,%rdi), %edx
leal (%rax,%rdx), %r9d
incl %r9d
shll $0x17, %eax
orl $0x400000, %eax         # imm = 0x400000
xorl %edx, %edx
divl %r9d
movl %eax, (%rsi,%r8,4)
incq %r8
addl $0x4, %edi
cmpq %r8, %rcx
jne 0xb4c4
jmp 0xb829
cmpb $0x20, 0x1(%rbp)
ja 0xb510
cmpb $0x21, 0x2(%rbp)
jb 0xb51c
leaq 0x43979(%rip), %rdi     # 0x4ee90
callq 0x455c
leaq 0x28(%r13), %rdi
movzbl 0x1(%rbp), %edx
movl $0x1, %esi
callq 0x4a048
leaq 0x40(%r13), %rdi
movzbl 0x2(%rbp), %edx
movl $0x1, %esi
callq 0x4a126
movq 0x40(%r13), %rax
movb $0x1, (%rax)
jmp 0xb829
cmpb $0x21, 0x1(%rbp)
jb 0xb55e
leaq 0x439cf(%rip), %rdi     # 0x4ef28
callq 0x455c
movzbl 0x2(%rbp), %eax
cmpq %rax, %r14
ja 0xb573
leaq 0x439d2(%rip), %rdi     # 0x4ef40
callq 0x455c
leaq 0x40(%r13), %rdi
movzbl 0x1(%rbp), %edx
movl $0x40, %esi
callq 0x4a126
leaq 0x28(%r13), %rdi
movl $0x200, %esi            # imm = 0x200
xorl %edx, %edx
callq 0x4a048
movq 0x28(%r13), %rcx
xorl %esi, %esi
movl $0x7ffff, %r8d          # imm = 0x7FFFF
movl $0xfff80000, %r9d       # imm = 0xFFF80000
movl $0x8000, (%rcx,%rsi,8)  # imm = 0x8000
movzbl 0x1ac17(%rbx,%rsi,4), %eax
movzbl 0x1ac16(%rbx,%rsi,4), %edx
leal (%rax,%rdx), %edi
incl %edi
shll $0x17, %eax
orl $0x400000, %eax         # imm = 0x400000
xorl %edx, %edx
divl %edi
shrl $0x7, %eax
andl $0xfffffe, %eax         # imm = 0xFFFFFE
movswl 0xac14(%rbx,%rax), %eax
shll $0xa, %eax
cmpl %r8d, %eax
cmovgel %r8d, %eax
cmpl $0xfff80001, %eax       # imm = 0xFFF80001
cmovll %r9d, %eax
movl %eax, 0x4(%rcx,%rsi,8)
incq %rsi
cmpq $0x100, %rsi            # imm = 0x100
jne 0xb5a7
jmp 0xb829
cmpb $0x21, 0x1(%rbp)
jb 0xb619
leaq 0x4384f(%rip), %rdi     # 0x4ee63
callq 0x455c
leaq 0x28(%r13), %r15
movzbl 0x1(%rbp), %edx
movl $0x1, %esi
movq %r15, %rdi
callq 0x4a048
movzbl 0x2(%rbp), %eax
shll $0x2, %eax
movq %rax, (%r13)
movq 0x30(%r13), %rax
testq %rax, %rax
je 0xb829
movq (%r15), %rcx
xorl %edx, %edx
movl $0x80000000, (%rcx,%rdx,4) # imm = 0x80000000
incq %rdx
cmpq %rdx, %rax
jne 0xb64b
jmp 0xb829
cmpb $0x21, 0x1(%rbp)
jb 0xb671
leaq 0x43856(%rip), %rdi     # 0x4eec2
callq 0x455c
movzbl 0x3(%rbp), %eax
cmpq %rax, %r14
ja 0xb686
leaq 0x43859(%rip), %rdi     # 0x4eeda
callq 0x455c
movzbl 0x2(%rbp), %eax
cmpq %rax, %r14
ja 0xb69b
leaq 0x43850(%rip), %rdi     # 0x4eee6
callq 0x455c
movb 0x1(%rbp), %cl
movl $0x1, %eax
shlq %cl, %rax
movq %rax, 0x20(%r13)
leaq 0x58(%r13), %r15
movzbl 0x1(%rbp), %edx
movl $0x1, %esi
movq %r15, %rdi
callq 0x4a1f4
movq 0x60(%r13), %rax
testq %rax, %rax
je 0xb829
movq (%r15), %rcx
xorl %edx, %edx
movw $0x8000, (%rcx,%rdx,2)  # imm = 0x8000
incq %rdx
cmpq %rdx, %rax
jne 0xb6d1
jmp 0xb829
cmpb $0x21, 0x1(%rbp)
jb 0xb6f6
leaq 0x43801(%rip), %rdi     # 0x4eef2
callq 0x455c
movzbl 0x2(%rbp), %eax
cmpq %rax, %r14
ja 0xb70b
leaq 0x43803(%rip), %rdi     # 0x4ef09
callq 0x455c
movzbl 0x3(%rbp), %eax
testl %eax, %eax
je 0xb720
movzbl 0x2(%rbp), %ecx
movl %r14d, %edx
subl %ecx, %edx
cmpl %eax, %edx
jge 0xb72c
leaq 0x437ed(%rip), %rdi     # 0x4ef14
callq 0x455c
movb 0x1(%rbp), %cl
movl $0x1, %eax
shlq %cl, %rax
movzbl 0x3(%rbp), %r12d
movq %rax, 0x20(%r13)
leaq 0x28(%r13), %r15
movzbl 0x1(%rbp), %edx
movq %r15, %rdi
movq %r12, %rsi
callq 0x4a048
movq 0x30(%r13), %rcx
testq %rcx, %rcx
je 0xb829
movl $0x10000, %eax          # imm = 0x10000
xorl %edx, %edx
divl %r12d
movq (%r15), %rdx
xorl %esi, %esi
movl %eax, (%rdx,%rsi,4)
incq %rsi
cmpq %rsi, %rcx
jne 0xb76f
jmp 0xb829
cmpb $0x21, 0x1(%rbp)
jb 0xb791
leaq 0x437c0(%rip), %rdi     # 0x4ef4c
callq 0x455c
movzbl 0x2(%rbp), %eax
cmpq %rax, %r14
ja 0xb7a6
leaq 0x437a0(%rip), %rdi     # 0x4ef41
callq 0x455c
movzbl 0x3(%rbp), %eax
movzbl 0x4(%rbp), %ecx
shll $0x2, %ecx
cmpl %eax, %ecx
jae 0xb7c1
leaq 0x437a7(%rip), %rdi     # 0x4ef63
callq 0x455c
leaq 0x28(%r13), %r15
movzbl 0x1(%rbp), %edx
movl $0x20, %esi
movq %r15, %rdi
callq 0x4a048
movzbl 0x4(%rbp), %eax
shll $0x2, %eax
movq %rax, (%r13)
movq 0x30(%r13), %rax
testq %rax, %rax
je 0xb829
movq (%r15), %rcx
xorl %edx, %edx
xorl %esi, %esi
movl %edx, %edi
andl $0x7c0, %edi            # imm = 0x7C0
movl 0x9454(%rbx,%rdi,2), %edi
shll $0x11, %edi
movzbl 0x3(%rbp), %r8d
orl %edi, %r8d
movl %r8d, (%rcx,%rsi,4)
incq %rsi
addq $0x40, %rdx
cmpq %rsi, %rax
jne 0xb7f1
jmp 0xb829
leaq 0x43753(%rip), %rdi     # 0x4ef77
callq 0x455c
movzbl (%rbp), %eax
leaq 0x4028c(%rip), %rcx     # 0x4bac0
movslq (%rcx,%rax,4), %rax
addq %rax, %rbp
incq %r14
cmpq 0x10(%rsp), %r14
jne 0xb402
addq $0x18, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq