// File: /workspace/github_cpp_makefile_star2_O2/twekkel[P]mzpq/libzpaq.cpp
// Function: libzpaq::Compiler::compile_comp(libzpaq::ZPAQL&)
int Compiler::compile_comp(ZPAQL& z) {
  int op=0;
  const int comp_begin=z.hend;
  while (true) {
    op=rtoken(opcodelist);
    if (op==POST || op==PCOMP || op==END) break;
    int operand=-1; // 0...255 if 2 bytes
    int operand2=-1;  // 0...255 if 3 bytes
    if (op==IF) {
      op=JF;
      operand=0; // set later
      if_stack.push(z.hend+1); // save jump target location
    }
    else if (op==IFNOT) {
      op=JT;
      operand=0;
      if_stack.push(z.hend+1); // save jump target location
    }
    else if (op==IFL || op==IFNOTL) {  // long if
      if (op==IFL) z.header[z.hend++]=(JT);
      if (op==IFNOTL) z.header[z.hend++]=(JF);
      z.header[z.hend++]=(3);
      op=LJ;
      operand=operand2=0;
      if_stack.push(z.hend+1);
    }
    else if (op==ELSE || op==ELSEL) {
      if (op==ELSE) op=JMP, operand=0;
      if (op==ELSEL) op=LJ, operand=operand2=0;
      int a=if_stack.pop();  // conditional jump target location
      assert(a>comp_begin && a<int(z.hend));
      if (z.header[a-1]!=LJ) {  // IF, IFNOT
        assert(z.header[a-1]==JT || z.header[a-1]==JF || z.header[a-1]==JMP);
        int j=z.hend-a+1+(op==LJ); // offset at IF
        assert(j>=0);
        if (j>127) syntaxError("IF too big, try IFL, IFNOTL");
        z.header[a]=j;
      }
      else {  // IFL, IFNOTL
        int j=z.hend-comp_begin+2+(op==LJ);
        assert(j>=0);
        z.header[a]=j&255;
        z.header[a+1]=(j>>8)&255;
      }
      if_stack.push(z.hend+1);  // save JMP target location
    }
    else if (op==ENDIF) {
      int a=if_stack.pop();  // jump target address
      assert(a>comp_begin && a<int(z.hend));
      int j=z.hend-a-1;  // jump offset
      assert(j>=0);
      if (z.header[a-1]!=LJ) {
        assert(z.header[a-1]==JT || z.header[a-1]==JF || z.header[a-1]==JMP);
        if (j>127) syntaxError("IF too big, try IFL, IFNOTL, ELSEL\n");
        z.header[a]=j;
      }
      else {
        assert(a+1<int(z.hend));
        j=z.hend-comp_begin;
        z.header[a]=j&255;
        z.header[a+1]=(j>>8)&255;
      }
    }
    else if (op==DO) {
      do_stack.push(z.hend);
    }
    else if (op==WHILE || op==UNTIL || op==FOREVER) {
      int a=do_stack.pop();
      assert(a>=comp_begin && a<int(z.hend));
      int j=a-z.hend-2;
      assert(j<=-2);
      if (j>=-127) {  // backward short jump
        if (op==WHILE) op=JT;
        if (op==UNTIL) op=JF;
        if (op==FOREVER) op=JMP;
        operand=j&255;
      }
      else {  // backward long jump
        j=a-comp_begin;
        assert(j>=0 && j<int(z.hend)-comp_begin);
        if (op==WHILE) {
          z.header[z.hend++]=(JF);
          z.header[z.hend++]=(3);
        }
        if (op==UNTIL) {
          z.header[z.hend++]=(JT);
          z.header[z.hend++]=(3);
        }
        op=LJ;
        operand=j&255;
        operand2=j>>8;
      }
    }
    else if ((op&7)==7) { // 2 byte operand, read N
      if (op==LJ) {
        operand=rtoken(0, 65535);
        operand2=operand>>8;
        operand&=255;
      }
      else if (op==JT || op==JF || op==JMP) {
        operand=rtoken(-128, 127);
        operand&=255;
      }
      else
        operand=rtoken(0, 255);
    }
    if (op>=0 && op<=255)
      z.header[z.hend++]=(op);
    if (operand>=0)
      z.header[z.hend++]=(operand);
    if (operand2>=0)
      z.header[z.hend++]=(operand2);
    if (z.hend>=z.header.isize()-130 || z.hend-z.hbegin+z.cend-2>65535)
      syntaxError("program too big");
  }
  z.header[z.hend++]=(0); // END
  return op;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x28, %rsp
movq %rsi, %rbx
movq %rdi, %r14
movl 0x30(%rsi), %eax
movl %eax, 0x8(%rsp)
leaq 0x30(%rdi), %r15
leaq 0x50(%rdi), %rax
movq %rax, 0x18(%rsp)
leaq 0x1eda9(%rip), %r13     # 0x2ba00
movq %r14, %rdi
movq %r13, %rsi
callq 0xcae4
cmpl $0x103, %eax            # imm = 0x103
je 0xcce8
movl %eax, %ebp
cmpl $0x104, %eax            # imm = 0x104
je 0xcd05
leal -0x100(%rbp), %eax
cmpl $0x3, %eax
jb 0xd02e
leal -0x10b(%rbp), %eax
cmpl $0x1, %eax
ja 0xcd9d
cmpl $0x10b, %ebp            # imm = 0x10B
setne %al
movslq 0x30(%rbx), %rcx
leal 0x1(%rcx), %edx
movl %edx, 0x30(%rbx)
movq 0x10(%rbx), %rdx
shlb $0x3, %al
orb $0x27, %al
movb %al, (%rdx,%rcx)
movslq 0x30(%rbx), %rax
leal 0x1(%rax), %ecx
movl %ecx, 0x30(%rbx)
movq 0x10(%rbx), %rcx
movb $0x3, (%rcx,%rax)
movl 0x30(%rbx), %eax
incl %eax
movw %ax, 0x12(%rsp)
movq %r15, %rdi
leaq 0x12(%rsp), %rsi
callq 0x1c952
xorl %eax, %eax
movl $0xff, %ebp
xorl %r12d, %r12d
jmp 0xcd27
movl 0x30(%rbx), %eax
incl %eax
movw %ax, 0x16(%rsp)
movq %r15, %rdi
leaq 0x16(%rsp), %rsi
callq 0x1c952
xorl %eax, %eax
pushq $0x2f
jmp 0xcd20
movl 0x30(%rbx), %eax
incl %eax
movw %ax, 0x14(%rsp)
movq %r15, %rdi
leaq 0x14(%rsp), %rsi
callq 0x1c952
xorl %eax, %eax
pushq $0x27
popq %rcx
movl %ecx, %ebp
pushq $-0x1
popq %r12
movslq 0x30(%rbx), %rcx
leal 0x1(%rcx), %edx
movl %edx, 0x30(%rbx)
movq 0x10(%rbx), %rdx
movb %bpl, (%rdx,%rcx)
testl %eax, %eax
js 0xcd4e
movslq 0x30(%rbx), %rcx
leal 0x1(%rcx), %edx
movl %edx, 0x30(%rbx)
movq 0x10(%rbx), %rdx
movb %al, (%rdx,%rcx)
testl %r12d, %r12d
js 0xcd65
movslq 0x30(%rbx), %rax
leal 0x1(%rax), %ecx
movl %ecx, 0x30(%rbx)
movq 0x10(%rbx), %rcx
movb %r12b, (%rcx,%rax)
movl 0x30(%rbx), %eax
movl 0x18(%rbx), %ecx
movl $0xffffff7e, %edx       # imm = 0xFFFFFF7E
addl %edx, %ecx
cmpl %ecx, %eax
jge 0xcd87
subl 0x2c(%rbx), %eax
addl 0x28(%rbx), %eax
cmpl $0x10002, %eax          # imm = 0x10002
jl 0xcc57
movq %r14, %rdi
leaq 0x15834(%rip), %rsi     # 0x225c5
xorl %edx, %edx
callq 0xc98e
jmp 0xcc57
leal -0x105(%rbp), %eax
cmpl $0x8, %eax
ja 0xce95
leaq 0x11a6d(%rip), %rcx     # 0x1e820
movslq (%rcx,%rax,4), %rax
addq %rcx, %rax
jmpq *%rax
xorl %r13d, %r13d
pushq $-0x1
popq %r12
pushq $0x3f
popq %rax
movl %eax, %ebp
jmp 0xce3d
movzwl 0x30(%rbx), %eax
movw %ax, 0xe(%rsp)
movq 0x18(%rsp), %rdi
leaq 0xe(%rsp), %rsi
callq 0x1c952
jmp 0xcd65
movq %r15, %rdi
callq 0x1c992
movzwl %ax, %ebp
movl 0x30(%rbx), %edx
movq 0x10(%rbx), %rax
cmpb $-0x1, -0x1(%rax,%rbp)
je 0xcf74
movl %ebp, %ecx
notl %ecx
addl %ecx, %edx
cmpl $0x80, %edx
jl 0xce2a
movq %r14, %rdi
leaq 0x15788(%rip), %rsi     # 0x225a1
movl %edx, %r12d
xorl %edx, %edx
callq 0xc98e
movl %r12d, %edx
movq 0x10(%rbx), %rax
movb %dl, (%rax,%rbp)
jmp 0xcd65
movl $0xff, %ebp
xorl %r12d, %r12d
movb $0x1, %r13b
movq %r15, %rdi
callq 0x1c992
movq 0x10(%rbx), %rcx
movzwl %ax, %esi
cmpb $-0x1, -0x1(%rcx,%rsi)
movzbl %r13b, %eax
je 0xcef7
movl 0x30(%rbx), %edx
subl %esi, %eax
leal (%rax,%rdx), %r13d
incl %r13d
cmpl $0x80, %r13d
jl 0xce8f
movq %r14, %rdi
movq %rsi, 0x20(%rsp)
leaq 0x15706(%rip), %rsi     # 0x22585
xorl %edx, %edx
callq 0xc98e
movq 0x20(%rsp), %rsi
movq 0x10(%rbx), %rcx
movb %r13b, (%rcx,%rsi)
jmp 0xcf0e
leal -0x108(%rbp), %eax
cmpl $0x2, %eax
ja 0xcf33
movq 0x18(%rsp), %rdi
callq 0x1c992
movzwl %ax, %eax
movslq 0x30(%rbx), %rcx
movl %eax, %edx
subl %ecx, %edx
cmpl $-0x7d, %edx
jl 0xcf88
addl $0xfe, %edx
cmpl $0x108, %ebp            # imm = 0x108
pushq $0x27
popq %rax
cmovel %eax, %ebp
cmpl $0x109, %ebp            # imm = 0x109
pushq $0x2f
popq %rax
cmovel %eax, %ebp
cmpl $0x10a, %ebp            # imm = 0x10A
pushq $0x3f
popq %rax
cmovel %eax, %ebp
pushq $-0x1
popq %r12
movl %edx, %eax
jmp 0xcfd6
movl 0x30(%rbx), %edx
subl 0x8(%rsp), %eax
addl %edx, %eax
addl $0x2, %eax
movb %al, (%rcx,%rsi)
movq 0x10(%rbx), %rcx
movb %ah, 0x1(%rcx,%rsi)
movl 0x30(%rbx), %eax
incl %eax
movw %ax, 0x10(%rsp)
movq %r15, %rdi
leaq 0x10(%rsp), %rsi
callq 0x1c952
xorl %eax, %eax
leaq 0x1ead2(%rip), %r13     # 0x2ba00
jmp 0xcd27
movl %ebp, %eax
notl %eax
testb $0x7, %al
jne 0xcfdb
cmpl $0x3f, %ebp
ja 0xcff2
movl %ebp, %eax
movabsq $-0x7fff7f8000000000, %rcx # imm = 0x8000808000000000
btq %rax, %rcx
jae 0xcff2
movq %r14, %rdi
pushq $-0x80
popq %rsi
pushq $0x7f
popq %rdx
callq 0xcb70
movzbl %al, %eax
jmp 0xcd23
subl 0x8(%rsp), %edx
movb %dl, (%rax,%rbp)
movq 0x10(%rbx), %rax
movb %dh, 0x1(%rax,%rbp)
jmp 0xcd65
movl %ebp, %edx
andl $0x10a, %edx            # imm = 0x10A
cmpl $0x108, %edx            # imm = 0x108
jne 0xcfc6
cmpl $0x108, %ebp            # imm = 0x108
sete %dl
shlb $0x3, %dl
orb $0x27, %dl
leal 0x1(%rcx), %esi
movl %esi, 0x30(%rbx)
movq 0x10(%rbx), %rsi
movb %dl, (%rsi,%rcx)
movslq 0x30(%rbx), %rcx
leal 0x1(%rcx), %edx
movl %edx, 0x30(%rbx)
movq 0x10(%rbx), %rdx
movb $0x3, (%rdx,%rcx)
subl 0x8(%rsp), %eax
movl %eax, %r12d
sarl $0x8, %r12d
movl $0xff, %ebp
movzbl %al, %eax
jmp 0xcfe1
pushq $-0x1
popq %rax
movl %eax, %r12d
cmpl $0xff, %ebp
jbe 0xcd27
jmp 0xcd39
movq %r14, %rdi
xorl %esi, %esi
cmpl $0xff, %ebp
jne 0xd01e
movl $0xffff, %edx           # imm = 0xFFFF
callq 0xcb70
movl %eax, %r12d
movzbl %r12b, %eax
sarl $0x8, %r12d
movl $0xff, %ebp
jmp 0xcd27
movl $0xff, %edx
callq 0xcb70
pushq $-0x1
popq %r12
jmp 0xcfe1
movslq 0x30(%rbx), %rax
leal 0x1(%rax), %ecx
movl %ecx, 0x30(%rbx)
movq 0x10(%rbx), %rcx
movb $0x0, (%rcx,%rax)
movl %ebp, %eax
addq $0x28, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
nop