// File: /workspace/github_cpp_makefile_star2_O2/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
addq $0x1b018, %rdi          # imm = 0x1B018
leaq 0x1b020(%rbx), %rsi
xorl %edx, %edx
callq 0x4c24
movq 0x808(%rbx), %rdi
callq 0x9898
cmpb $0x0, 0x7810(%rbx)
jne 0xad90
movq 0x808(%rbx), %rax
movq 0x10(%rax), %rax
cmpb $0x0, 0x6(%rax)
je 0xad90
movb $0x1, 0x7810(%rbx)
leaq 0x7814(%rbx), %rdi
leaq 0x1462d(%rip), %rsi     # 0x1f2f0
movl $0x400, %edx            # imm = 0x400
callq 0x4140
leaq 0x7c14(%rbx), %rdi
leaq 0x14a15(%rip), %rsi     # 0x1f6f0
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 0x159e7(%rip), %rsi     # 0x206f0
movl $0xa80, %edx            # imm = 0xA80
callq 0x4140
cmpq $0x560, %r14            # imm = 0x560
je 0xad2c
movw $0x7fff, 0xa154(%rbx,%r14,2) # imm = 0x7FFF
incq %r14
jmp 0xad13
movl $0x4000, %edx           # imm = 0x4000
xorl %eax, %eax
leaq 0x16436(%rip), %rcx     # 0x21170
cmpq $0x2c8, %rax            # imm = 0x2C8
je 0xad65
movslq %edx, %rsi
movzbl (%rax,%rcx), %edx
addl %esi, %edx
movslq %edx, %rdi
cmpq %rsi, %rdi
je 0xad60
movw %ax, 0xac14(%rbx,%rsi,2)
incq %rsi
jmp 0xad4e
incq %rax
jmp 0xad3a
leaq 0x1ac12(%rbx), %rax
xorl %ecx, %ecx
cmpq $0x4000, %rcx           # imm = 0x4000
je 0xad90
movzwl (%rax), %edx
xorl %esi, %esi
subw %dx, %si
movw %si, 0xac14(%rbx,%rcx,2)
incq %rcx
addq $-0x2, %rax
jmp 0xad6e
movq $-0x400, %rax           # imm = 0xFC00
testq %rax, %rax
je 0xadb2
andl $0x0, 0x408(%rbx,%rax)
andl $0x0, 0x808(%rbx,%rax)
addq $0x4, %rax
jmp 0xad97
leaq 0x810(%rbx), %rax
movq %rax, (%rsp)
movl $0x810, %r14d           # imm = 0x810
cmpq $0x7810, %r14           # imm = 0x7810
je 0xaddb
leaq (%rbx,%r14), %rdi
callq 0x93f2
addq $0x70, %r14
jmp 0xadc3
movq 0x808(%rbx), %rax
movq 0x10(%rax), %r13
movzbl 0x6(%r13), %eax
movq %rax, 0x8(%rsp)
addq $0x7, %r13
leaq 0x1ac14(%rbx), %r14
xorl %ebp, %ebp
cmpq 0x8(%rsp), %rbp
je 0xb20b
movzbl (%r13), %eax
decl %eax
cmpl $0x8, %eax
movq %rbp, 0x10(%rsp)
ja 0xb1df
imulq $0x70, %rbp, %r15
addq (%rsp), %r15
leaq 0x13964(%rip), %rcx     # 0x1e790
movslq (%rcx,%rax,4), %rax
addq %rcx, %rax
jmpq *%rax
movzbl 0x1(%r13), %eax
leal -0x200(,%rax,4), %eax
movl %eax, 0x8(%rbx,%rbp,4)
jmp 0xb1eb
movzbl 0x1(%r13), %eax
cmpq %rax, %rbp
ja 0xae60
leaq 0x17081(%rip), %rdi     # 0x21edc
callq 0x44dc
movzbl 0x2(%r13), %eax
cmpq %rax, %rbp
ja 0xb1eb
leaq 0x17072(%rip), %rdi     # 0x21ee7
jmp 0xb1e6
cmpb $0x1b, 0x1(%r13)
jb 0xae8d
leaq 0x17021(%rip), %rdi     # 0x21ea9
callq 0x44dc
movq $0x3ff, (%r15)          # imm = 0x3FF
leaq 0x28(%r15), %rbp
movl $0x100, %esi            # imm = 0x100
movq %rbp, %rdi
xorl %edx, %edx
callq 0x1c3a4
leaq 0x40(%r15), %rdi
movzbl 0x1(%r13), %edx
pushq $0x40
popq %rsi
callq 0x1c46e
xorl %r12d, %r12d
cmpq 0x30(%r15), %r12
jae 0xb1eb
movq %r14, %rdi
movl %r12d, %esi
callq 0x1c80c
movq (%rbp), %rcx
movl %eax, (%rcx,%r12,4)
incq %r12
jmp 0xaebb
movb 0x1(%r13), %al
cmpb $0x20, %al
ja 0xaeec
cmpb $0x21, 0x2(%r13)
jb 0xaefc
leaq 0x16fcd(%rip), %rdi     # 0x21ec0
callq 0x44dc
movb 0x1(%r13), %al
leaq 0x28(%r15), %rdi
movzbl %al, %edx
pushq $0x1
popq %r12
movq %r12, %rsi
callq 0x1c3a4
leaq 0x40(%r15), %rdi
movzbl 0x2(%r13), %edx
movq %r12, %rsi
callq 0x1c46e
movq 0x40(%r15), %rax
movb $0x1, (%rax)
jmp 0xb1eb
cmpb $0x21, 0x1(%r13)
jb 0xaf3f
leaq 0x1701e(%rip), %rdi     # 0x21f58
callq 0x44dc
movzbl 0x2(%r13), %eax
cmpq %rax, %rbp
ja 0xaf55
leaq 0x17020(%rip), %rdi     # 0x21f70
callq 0x44dc
leaq 0x40(%r15), %rdi
movzbl 0x1(%r13), %edx
pushq $0x40
popq %rsi
callq 0x1c46e
addq $0x28, %r15
movl $0x200, %esi            # imm = 0x200
movq %r15, %rdi
xorl %edx, %edx
callq 0x1c3a4
xorl %ebp, %ebp
cmpq $0x100, %rbp            # imm = 0x100
je 0xb1eb
movq (%r15), %rax
movl $0x8000, (%rax,%rbp,8)  # imm = 0x8000
movq %r14, %rdi
movl %ebp, %esi
callq 0x1c80c
sarl $0x8, %eax
cltq
movswl 0xac14(%rbx,%rax,2), %eax
shll $0xa, %eax
movl $0x7ffff, %ecx          # imm = 0x7FFFF
cmpl %ecx, %eax
jl 0xafba
movl $0x7ffff, %eax          # imm = 0x7FFFF
cmpl $0xfff80001, %eax       # imm = 0xFFF80001
jge 0xafc6
movl $0xfff80000, %eax       # imm = 0xFFF80000
movq (%r15), %rcx
movl %eax, 0x4(%rcx,%rbp,8)
incq %rbp
jmp 0xaf7b
movb 0x1(%r13), %al
cmpb $0x21, %al
jb 0xafea
leaq 0x16eb2(%rip), %rdi     # 0x21e93
callq 0x44dc
movb 0x1(%r13), %al
leaq 0x28(%r15), %rbp
movzbl %al, %edx
movq %rbp, %rdi
pushq $0x1
popq %rsi
callq 0x1c3a4
movzbl 0x2(%r13), %eax
shll $0x2, %eax
movq %rax, (%r15)
movq 0x30(%r15), %rax
xorl %ecx, %ecx
cmpq %rcx, %rax
je 0xb1eb
movq (%rbp), %rdx
movl $0x80000000, (%rdx,%rcx,4) # imm = 0x80000000
incq %rcx
jmp 0xb00d
cmpb $0x21, 0x1(%r13)
jb 0xb039
leaq 0x16ebe(%rip), %rdi     # 0x21ef2
callq 0x44dc
movzbl 0x3(%r13), %eax
cmpq %rax, %rbp
ja 0xb04f
leaq 0x16ec0(%rip), %rdi     # 0x21f0a
callq 0x44dc
movzbl 0x2(%r13), %eax
cmpq %rax, %rbp
ja 0xb065
leaq 0x16eb6(%rip), %rdi     # 0x21f16
callq 0x44dc
movb 0x1(%r13), %cl
pushq $0x1
popq %rsi
movq %rsi, %rax
shlq %cl, %rax
movq %rax, 0x20(%r15)
leaq 0x58(%r15), %rbp
movzbl 0x1(%r13), %edx
movq %rbp, %rdi
callq 0x1c528
movq 0x60(%r15), %rax
xorl %ecx, %ecx
cmpq %rcx, %rax
je 0xb1eb
movq (%rbp), %rdx
movw $0x8000, (%rdx,%rcx,2)  # imm = 0x8000
incq %rcx
jmp 0xb08d
cmpb $0x21, 0x1(%r13)
jb 0xb0b8
leaq 0x16e6f(%rip), %rdi     # 0x21f22
callq 0x44dc
movzbl 0x2(%r13), %eax
cmpq %rax, %rbp
ja 0xb0ce
leaq 0x16e70(%rip), %rdi     # 0x21f39
callq 0x44dc
movzbl 0x3(%r13), %r12d
testl %r12d, %r12d
je 0xb0e9
movzbl 0x2(%r13), %eax
movl %ebp, %ecx
subl %eax, %ecx
movl %r12d, %eax
cmpl %r12d, %ecx
jge 0xb0fd
leaq 0x16e54(%rip), %rdi     # 0x21f44
callq 0x44dc
movb 0x3(%r13), %al
movzbl %al, %r12d
movb 0x1(%r13), %cl
pushq $0x1
popq %rdx
shlq %cl, %rdx
movq %rdx, 0x20(%r15)
leaq 0x28(%r15), %rbp
movzbl %al, %esi
movzbl 0x1(%r13), %edx
movq %rbp, %rdi
callq 0x1c3a4
movq 0x30(%r15), %rcx
xorl %esi, %esi
cmpq %rsi, %rcx
je 0xb1eb
movl $0x10000, %eax          # imm = 0x10000
xorl %edx, %edx
divl %r12d
movq (%rbp), %rdx
movl %eax, (%rdx,%rsi,4)
incq %rsi
jmp 0xb125
cmpb $0x21, 0x1(%r13)
jb 0xb157
leaq 0x16e2a(%rip), %rdi     # 0x21f7c
callq 0x44dc
movzbl 0x2(%r13), %eax
cmpq %rax, %rbp
ja 0xb16d
leaq 0x16e09(%rip), %rdi     # 0x21f71
callq 0x44dc
movzbl 0x3(%r13), %eax
movzbl 0x4(%r13), %ecx
shll $0x2, %ecx
cmpl %eax, %ecx
jae 0xb18a
leaq 0x16e0e(%rip), %rdi     # 0x21f93
callq 0x44dc
leaq 0x28(%r15), %rbp
movzbl 0x1(%r13), %edx
movq %rbp, %rdi
pushq $0x20
popq %rsi
callq 0x1c3a4
movzbl 0x4(%r13), %eax
shll $0x2, %eax
movq %rax, (%r15)
movq 0x30(%r15), %rax
xorl %ecx, %ecx
xorl %edx, %edx
cmpq %rdx, %rax
je 0xb1eb
movl %ecx, %esi
andl $0x7c0, %esi            # imm = 0x7C0
movl 0x9454(%rbx,%rsi,2), %esi
shll $0x11, %esi
movzbl 0x3(%r13), %edi
orl %esi, %edi
movq (%rbp), %rsi
movl %edi, (%rsi,%rdx,4)
incq %rdx
addq $0x40, %rcx
jmp 0xb1b1
leaq 0x16dc1(%rip), %rdi     # 0x21fa7
callq 0x44dc
movzbl (%r13), %eax
leaq 0x138f9(%rip), %rcx     # 0x1eaf0
movslq (%rcx,%rax,4), %rax
addq %rax, %r13
movq 0x10(%rsp), %rbp
incq %rbp
jmp 0xadfd
addq $0x18, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq