// File: /workspace/github_cpp_makefile_star2_O2/derekzwy[P]an-optimal-tcam-encoding-algorithm-for-packet-classification/rulesutils.cc
// Function: extend_prefix(unsigned int, unsigned int)
struct prefix *extend_prefix(unsigned ai, unsigned aj)
{
  struct prefix *pf = new prefix();
  int i = 0;  

  if(ai == aj) {
    pf->value[i] = ai;
    pf->length[i] = 16;
    pf->fullpf = ai;
    pf->fpf_len = 16;
    pf->nvalid = 1;

    pf->cmplvalue[i] = ai;
    pf->cmpllength[i] = 16;
    pf->ninvalid = 1; 
    return pf;
  } 
 
  int k;
  bool flag = false;
  pf->ninvalid = 0;         
  while(1) {
    for(k = 0; (ai & (int)pow(2,k)) == 0 && k <= 15 ; k ++);
    if(ai + pow(2,k) - 1 == aj) {       
      pf->value[i] = ai>>k<<k;
      pf->length[i] = 16 - k;
      pf->nvalid = i + 1;

      if( i  == 0) {
        pf->fullpf = ai>>k<<k;
        pf->fpf_len = 16 - k;

        pf->cmplvalue[i] = ai>>k<<k;
        pf->cmpllength[i] = 16 - k;
        pf->ninvalid = 1;
      }
      else {
        pf->fullpf = ai>>(k + 1)<<(k + 1);
        pf->fpf_len = 16 - k - 1;
        
        int numcmpl = pf->length[i - 1] - pf->length[i] - 1;
        while(numcmpl > 0) {
            pf->cmplvalue[pf->ninvalid] = (ai - (int)pow(2,k))>>(k - numcmpl)<<(k - numcmpl);
            pf->cmpllength[pf->ninvalid] = 16 - k + numcmpl;
            numcmpl --;
            pf->ninvalid ++;
        }
      }
      return pf;
    }
    else if (ai + pow(2,k) - 1 < aj) {
      pf->value[i] = ai>>k<<k;
      pf->length[i] = 16 - k;
      if(i == 0) {
        pf->cmplvalue[pf->ninvalid] = (ai - (int)pow(2,k))>>k<<k;
        pf->cmpllength[pf->ninvalid] = 16 - k;
        pf->ninvalid ++;
      }
      else {
        int numcmpl = pf->length[i - 1] - pf->length[i] - 1;
        while(numcmpl > 0) {
            pf->cmplvalue[pf->ninvalid] = (ai - (int)pow(2,k))>>(k - numcmpl)<<(k - numcmpl);
            pf->cmpllength[pf->ninvalid] = 16 - k + numcmpl;
            numcmpl --;
            pf->ninvalid ++;
        }
      }
      ai = ai + (int)pow(2, k);
    }
    else{
        if(i != 0) {
            flag = true;
            pf->fullpf = ai>>(k + 1)<<(k + 1);
            pf->fpf_len = 16 - k - 1; 

            int numcmpl = pf->length[i - 1] - pf->fpf_len - 2;
            while(numcmpl > 0) {
                pf->cmplvalue[pf->ninvalid] = (ai - (int)pow(2,k))>>(k - numcmpl)<<(k - numcmpl);
                pf->cmpllength[pf->ninvalid] = 16 - k + numcmpl;
                numcmpl --;
                pf->ninvalid ++;
            }
        }
      break;
    }        
    i++;
  } 

  if(ai == aj){
    pf->value[i] = ai;
    pf->length[i] = 16;
    pf->nvalid = i + 1;

    pf->cmplvalue[pf->ninvalid] = ai + 1;
    pf->cmpllength[pf->ninvalid] = 16;
    pf->ninvalid ++; 
    return pf;
  } 

  while(ai < aj) {
    for(k = 15; ((ai ^ aj) & (int)pow(2,k)) == 0 ; k --);
    if(ai + pow(2,k + 1) - 1 == aj) {
      pf->value[i] = ai>>(k+1)<<(k+1);
      pf->length[i] = 15 - k;
      pf->nvalid = i + 1;

      if(!flag) {
        if(i == 0){
            pf->fullpf = ai>>(k+1)<<(k+1);
            pf->fpf_len = 15 - k;
        }
        else {
            pf->fullpf = pf->value[0]>>(15 - pf->length[0])<<(15 - pf->length[0]);
            pf->fpf_len = pf->length[0] - 1;
        }
      }

      pf->cmplvalue[pf->ninvalid] = (ai + (int)pow(2, k + 1))>>(k + 1)<<(k + 1);
      pf->cmpllength[pf->ninvalid] = 15 - k;
      pf->ninvalid ++;
      i--;
      while((pf->value[i] >> (16 - pf->length[i])) % 2 == 0 && i > 0) {
        int numcmpl = pf->length[i + 1] - pf->length[i] - 1;
        while(numcmpl > 0) {
            int move = 16 - pf->length[i] - numcmpl;
            pf->cmplvalue[pf->ninvalid] = (ai + (int)pow(2, move))>>move<<move;
            pf->cmpllength[pf->ninvalid] = pf->length[i] + numcmpl;
            numcmpl--;
            pf->ninvalid ++;
        }
        i--;
      }
      int numcmpl = pf->length[i + 1] - pf->fpf_len - 2;
      int tmp = 1;
      while(numcmpl >= tmp ) {
        int move = 16 - pf->length[i + 1] + tmp; 
        pf->cmplvalue[pf->ninvalid] = (ai + (int)pow(2, move))>>move<<move;
        pf->cmpllength[pf->ninvalid] = pf->length[i + 1] - tmp;
        tmp ++;
        pf->ninvalid ++;
      }
      return pf;
    } 
    else {
      pf->value[i]=ai>>k<<k;
      pf->length[i]=16 - k;
      ai = ai + (int)pow(2,k);
    }
    i++;        
  } 

  pf->value[i] = ai;
  pf->length[i] = 16;
  pf->nvalid = i + 1;
  
  if(!flag) {
    pf->fullpf = pf->value[0]>>(15 - pf->length[0])<<(15 - pf->length[0]);
    pf->fpf_len = pf->length[0] - 1;
  }

  pf->cmplvalue[pf->ninvalid] = ai + (int)pow(2, 0);
  pf->cmpllength[pf->ninvalid] = 16;
  pf->ninvalid ++;
  i--;
  while((pf->value[i] >> (16 - pf->length[i])) % 2 == 0 && i > 0) {
    int numcmpl = pf->length[i + 1] - pf->length[i] - 1;
    while(numcmpl > 0) {
        int move = 16 - pf->length[i] - numcmpl;
        pf->cmplvalue[pf->ninvalid] = (ai + (int)pow(2, move))>>move<<move;
        pf->cmpllength[pf->ninvalid] = pf->length[i] + numcmpl;
        numcmpl--;
        pf->ninvalid ++;
    }
    i--;
  }
  int numcmpl = pf->length[i + 1] - pf->fpf_len - 2;
  int tmp = 1;
  while(numcmpl >= tmp ) {
    int move = 16 - pf->length[i + 1] + tmp; 
    pf->cmplvalue[pf->ninvalid] = (ai + (int)pow(2, move))>>move<<move;
    pf->cmpllength[pf->ninvalid] = pf->length[i + 1] - tmp;
    tmp ++;
    pf->ninvalid ++;
  }

  return pf;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x38, %rsp
movl %esi, %r15d
movl %edi, %r14d
movl $0x110, %edi            # imm = 0x110
callq 0x2150
movq %rax, %rbx
movl $0x110, %edx            # imm = 0x110
movq %rax, %rdi
xorl %esi, %esi
callq 0x20b0
pushq $0x10
popq %rcx
cmpl %r15d, %r14d
jne 0x3917
movl %r14d, (%rbx)
movl %ecx, 0x40(%rbx)
movl %r14d, 0x100(%rbx)
movabsq $0x100000010, %rax      # imm = 0x100000010
movq %rax, 0x104(%rbx)
movl %r14d, 0x80(%rbx)
movl %ecx, 0xc0(%rbx)
movl $0x1, 0x10c(%rbx)
movq %rbx, %rax
addq $0x38, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
movl %r15d, -0x44(%rbp)
movl %r15d, %eax
cvtsi2sd %rax, %xmm0
movsd %xmm0, -0x50(%rbp)
movq $0x0, -0x40(%rbp)
pushq $0x11
popq %rax
movl %eax, -0x48(%rbp)
pushq $0x1
popq %rax
xorl %r13d, %r13d
movl %r13d, %r12d
movl %eax, %r15d
cvtsi2sd %r13d, %xmm0
movsd %xmm0, -0x30(%rbp)
callq 0x2110
leal 0x1(%r12), %r13d
cmpl $0xf, %r12d
ja 0x396b
cvttsd2si %xmm0, %ecx
andl %r14d, %ecx
leal 0x1(%r15), %eax
testl %ecx, %ecx
je 0x393c
movl %r14d, %eax
cvtsi2sd %rax, %xmm0
movsd %xmm0, -0x58(%rbp)
movsd -0x30(%rbp), %xmm0
callq 0x2110
addsd -0x58(%rbp), %xmm0
movsd 0x2759(%rip), %xmm1     # 0x60e8
addsd %xmm1, %xmm0
ucomisd -0x50(%rbp), %xmm0
pushq $-0x2
popq %r10
pushq $0xf
popq %r8
movabsq $-0x100000000, %r9      # imm = 0xFFFFFFFF00000000
movq %r14, -0x38(%rbp)
jne 0x39b6
jnp 0x3ad5
movl %r10d, %r15d
movl %r8d, %r14d
movsd -0x30(%rbp), %xmm0
callq 0x2110
addsd -0x58(%rbp), %xmm0
addsd 0x2715(%rip), %xmm0     # 0x60e8
movsd -0x50(%rbp), %xmm1
ucomisd %xmm0, %xmm1
jbe 0x3b9c
pushq $-0x1
popq %rax
movl %eax, %r14d
movl %r12d, %ecx
shll %cl, %r14d
movl %r14d, %eax
movq -0x38(%rbp), %rdx
andl %edx, %eax
movq -0x40(%rbp), %rcx
movl %eax, (%rbx,%rcx,4)
pushq $0x10
popq %r15
subl %r12d, %r15d
movl %r15d, 0x40(%rbx,%rcx,4)
testq %rcx, %rcx
je 0x3a7d
movl 0x3c(%rbx,%rcx,4), %r14d
pushq $0x11
popq %r12
subl %r14d, %r12d
decl %r14d
movsd -0x30(%rbp), %xmm0
leal (%r14,%r13), %eax
addl $-0x11, %eax
testl %eax, %eax
jle 0x3abc
movsd -0x30(%rbp), %xmm0
callq 0x2110
cvttsd2si %xmm0, %eax
movsd -0x30(%rbp), %xmm0
movq -0x38(%rbp), %rcx
movl %ecx, %edx
subl %eax, %edx
movl %r12d, %ecx
shrl %cl, %edx
shll %cl, %edx
movl 0x10c(%rbx), %eax
movl %edx, 0x80(%rbx,%rax,4)
movl 0x10c(%rbx), %eax
movl %r14d, 0xc0(%rbx,%rax,4)
incl 0x10c(%rbx)
incl %r12d
decl %r14d
jmp 0x3a23
movsd -0x30(%rbp), %xmm0
movq %rdx, %r12
callq 0x2110
cvttsd2si %xmm0, %eax
movsd -0x30(%rbp), %xmm0
movl %r12d, %ecx
subl %eax, %ecx
andl %r14d, %ecx
movl 0x10c(%rbx), %eax
movl %ecx, 0x80(%rbx,%rax,4)
movl 0x10c(%rbx), %eax
movl %r15d, 0xc0(%rbx,%rax,4)
incl 0x10c(%rbx)
callq 0x2110
cvttsd2si %xmm0, %eax
movq -0x38(%rbp), %r14
addl %eax, %r14d
incq -0x40(%rbp)
jmp 0x3936
movl %r14d, %edx
movl %r12d, %ecx
shrl %cl, %edx
shll %cl, %edx
movq -0x40(%rbp), %rsi
movl %esi, %eax
movl %edx, (%rbx,%rax,4)
pushq $0x10
popq %rdi
subl %r12d, %edi
movl %edi, 0x40(%rbx,%rax,4)
leal 0x1(%rsi), %ecx
movl %ecx, 0x108(%rbx)
testq %rsi, %rsi
je 0x3d34
movl %r12d, %ecx
shll %cl, %r10d
andl %r14d, %r10d
movl %r10d, 0x100(%rbx)
subl %r12d, %r8d
movl %r8d, 0x104(%rbx)
shlq $0x20, %rsi
addq %r9, %rsi
sarq $0x1e, %rsi
movl 0x40(%rbx,%rsi), %r14d
movl 0x40(%rbx,%rax,4), %eax
movl %eax, %r13d
notl %r13d
addl %r14d, %r13d
movl %eax, %r12d
subl %r14d, %r12d
addl %r15d, %r12d
subl %eax, %r14d
addl %r8d, %r14d
testl %r13d, %r13d
movsd -0x30(%rbp), %xmm0
jle 0x3905
callq 0x2110
cvttsd2si %xmm0, %eax
movq -0x38(%rbp), %rcx
movl %ecx, %edx
subl %eax, %edx
movl %r12d, %ecx
shrl %cl, %edx
shll %cl, %edx
movl 0x10c(%rbx), %eax
movl %edx, 0x80(%rbx,%rax,4)
movl 0x10c(%rbx), %eax
movl %r14d, 0xc0(%rbx,%rax,4)
incl 0x10c(%rbx)
decl %r13d
incl %r12d
decl %r14d
jmp 0x3b4a
cmpq $0x0, -0x40(%rbp)
je 0x3c3b
movl %r12d, %ecx
shll %cl, %r15d
andl -0x38(%rbp), %r15d
movl %r15d, 0x100(%rbx)
subl %r12d, %r14d
movl %r14d, 0x104(%rbx)
movq -0x40(%rbp), %rax
shlq $0x20, %rax
movabsq $-0x100000000, %rcx     # imm = 0xFFFFFFFF00000000
addq %rcx, %rax
sarq $0x1e, %rax
movl 0x40(%rbx,%rax), %r14d
pushq $0x11
popq %r12
subl %r14d, %r12d
decl %r14d
leal (%r14,%r13), %eax
addl $-0x11, %eax
testl %eax, %eax
jle 0x3c3b
movsd -0x30(%rbp), %xmm0
callq 0x2110
cvttsd2si %xmm0, %eax
movq -0x38(%rbp), %rcx
movl %ecx, %edx
subl %eax, %edx
movl %r12d, %ecx
shrl %cl, %edx
shll %cl, %edx
movl 0x10c(%rbx), %eax
movl %edx, 0x80(%rbx,%rax,4)
movl 0x10c(%rbx), %eax
movl %r14d, 0xc0(%rbx,%rax,4)
incl 0x10c(%rbx)
decl %r14d
incl %r12d
jmp 0x3bea
movq -0x38(%rbp), %r14
movl -0x44(%rbp), %edx
cmpl %edx, %r14d
jne 0x3c86
movq -0x40(%rbp), %rcx
movl %ecx, %eax
movl %edx, (%rbx,%rax,4)
pushq $0x10
popq %rsi
movl %esi, 0x40(%rbx,%rax,4)
incl %ecx
movl %ecx, 0x108(%rbx)
incl %edx
movl 0x10c(%rbx), %eax
movl %edx, 0x80(%rbx,%rax,4)
movl 0x10c(%rbx), %eax
movl %esi, 0xc0(%rbx,%rax,4)
incl 0x10c(%rbx)
jmp 0x3905
movq -0x40(%rbp), %r13
cmpl %edx, %r14d
movq %r14, -0x38(%rbp)
jae 0x3d53
xorl %edx, %r14d
xorl %r12d, %r12d
leal 0xf(%r12), %edi
movsd 0x2446(%rip), %xmm0     # 0x60f0
callq 0x21d0
cvttsd2si %xmm0, %eax
decl %r12d
testl %eax, %r14d
je 0x3c9d
movq -0x38(%rbp), %r14
movl %r14d, %eax
cvtsi2sd %rax, %xmm0
movsd %xmm0, -0x30(%rbp)
leal 0x11(%r12), %r15d
movsd 0x2417(%rip), %xmm0     # 0x60f0
movl %r15d, %edi
callq 0x21d0
addsd -0x30(%rbp), %xmm0
addsd 0x23fa(%rip), %xmm0     # 0x60e8
ucomisd -0x50(%rbp), %xmm0
jne 0x3cfb
jnp 0x3ed3
leal 0x10(%r12), %ecx
movl %r14d, %eax
shrl %cl, %eax
shll %cl, %eax
movl %eax, (%rbx,%r13,4)
negl %r12d
movl %r12d, 0x40(%rbx,%r13,4)
movsd 0x23d5(%rip), %xmm0     # 0x60f0
movl %ecx, %edi
callq 0x21d0
cvttsd2si %xmm0, %eax
addl %eax, %r14d
incq %r13
movl -0x44(%rbp), %edx
jmp 0x3c8a
movl %edx, 0x100(%rbx)
movl %edi, 0x104(%rbx)
movl %edx, 0x80(%rbx,%rax,4)
movl %edi, 0xc0(%rbx,%rax,4)
jmp 0x38fb
leal 0x1(%r13), %eax
movl %r13d, %ecx
movl %r14d, (%rbx,%rcx,4)
movl $0x10, 0x40(%rbx,%rcx,4)
movl %eax, 0x108(%rbx)
cmpq $0x0, -0x40(%rbp)
jne 0x3d8e
movl (%rbx), %eax
movl 0x40(%rbx), %edx
movb $0xf, %cl
subb %dl, %cl
shrl %cl, %eax
shll %cl, %eax
movl %eax, 0x100(%rbx)
decl %edx
movl %edx, 0x104(%rbx)
leal 0x1(%r14), %eax
movl 0x10c(%rbx), %ecx
movl %eax, 0x80(%rbx,%rcx,4)
movl 0x10c(%rbx), %eax
movl $0x10, 0xc0(%rbx,%rax,4)
incl 0x10c(%rbx)
movl 0x3c(%rbx,%r13,4), %r12d
movb $0x10, %cl
subb %r12b, %cl
pushq $0x1
popq %rax
shll %cl, %eax
cmpq $0x2, %r13
jl 0x3e45
andl -0x4(%rbx,%r13,4), %eax
jne 0x3e45
movl 0x40(%rbx,%r13,4), %eax
decq %r13
movl %r12d, %r14d
notl %r14d
addl %eax, %r14d
subl %eax, %r12d
addl $0x11, %r12d
testl %r14d, %r14d
jle 0x3db6
movl %r12d, %r15d
subl 0x40(%rbx,%r13,4), %r15d
movsd 0x22f1(%rip), %xmm0     # 0x60f0
movl %r15d, %edi
callq 0x21d0
cvttsd2si %xmm0, %eax
addl -0x38(%rbp), %eax
movl %r15d, %ecx
shrl %cl, %eax
shll %cl, %eax
movl 0x10c(%rbx), %ecx
movl %eax, 0x80(%rbx,%rcx,4)
movl 0x40(%rbx,%r13,4), %eax
addl %r14d, %eax
movl 0x10c(%rbx), %ecx
movl %eax, 0xc0(%rbx,%rcx,4)
decl %r14d
incl 0x10c(%rbx)
incl %r12d
jmp 0x3dea
movslq %r13d, %r12
movl 0x40(%rbx,%r12,4), %eax
subl 0x104(%rbx), %eax
addl $-0x2, %eax
xorl %ecx, %ecx
testl %eax, %eax
cmovgl %eax, %ecx
movq %rcx, -0x30(%rbp)
pushq $-0x1
popq %r14
movq -0x30(%rbp), %rax
addl %r14d, %eax
cmpl $-0x1, %eax
je 0x3905
movl -0x48(%rbp), %r13d
movl %r13d, %r15d
subl 0x40(%rbx,%r12,4), %r15d
movsd 0x2267(%rip), %xmm0     # 0x60f0
movl %r15d, %edi
callq 0x21d0
cvttsd2si %xmm0, %eax
addl -0x38(%rbp), %eax
movl %r15d, %ecx
shrl %cl, %eax
shll %cl, %eax
movl 0x10c(%rbx), %ecx
movl %eax, 0x80(%rbx,%rcx,4)
movl 0x40(%rbx,%r12,4), %eax
addl %r14d, %eax
movl 0x10c(%rbx), %ecx
movl %eax, 0xc0(%rbx,%rcx,4)
incl 0x10c(%rbx)
decl %r14d
incl %r13d
movl %r13d, -0x48(%rbp)
jmp 0x3e65
pushq $-0x1
popq %rax
movl %r15d, %edi
movl %eax, %r15d
movl %edi, %ecx
shll %cl, %r15d
movl %r15d, %eax
andl %r14d, %eax
movl %r13d, %ecx
movl %eax, (%rbx,%rcx,4)
notl %r12d
movl %r12d, 0x40(%rbx,%rcx,4)
leal 0x1(%r13), %ecx
movl %ecx, 0x108(%rbx)
cmpq $0x0, -0x40(%rbp)
jne 0x3f31
testq %r13, %r13
je 0x3f22
movl (%rbx), %edx
movl 0x40(%rbx), %eax
movb $0xf, %cl
subb %al, %cl
shrl %cl, %edx
shll %cl, %edx
movl %edx, 0x100(%rbx)
decl %eax
jmp 0x3f2b
movl %eax, 0x100(%rbx)
movl %r12d, %eax
movl %eax, 0x104(%rbx)
movsd 0x21b7(%rip), %xmm0     # 0x60f0
callq 0x21d0
cvttsd2si %xmm0, %eax
addl %r14d, %eax
andl %r15d, %eax
movl 0x10c(%rbx), %ecx
movl %eax, 0x80(%rbx,%rcx,4)
movl 0x10c(%rbx), %eax
movl %r12d, 0xc0(%rbx,%rax,4)
incl 0x10c(%rbx)
movl 0x3c(%rbx,%r13,4), %r14d
movb $0x10, %cl
subb %r14b, %cl
pushq $0x1
popq %rax
shll %cl, %eax
cmpq $0x2, %r13
jl 0x3ff8
andl -0x4(%rbx,%r13,4), %eax
jne 0x3ff8
movl 0x40(%rbx,%r13,4), %eax
decq %r13
movl %r14d, %r12d
notl %r12d
addl %eax, %r12d
subl %eax, %r14d
addl $0x11, %r14d
testl %r12d, %r12d
jle 0x3f69
movl %r14d, %r15d
subl 0x40(%rbx,%r13,4), %r15d
movsd 0x213e(%rip), %xmm0     # 0x60f0
movl %r15d, %edi
callq 0x21d0
cvttsd2si %xmm0, %eax
addl -0x38(%rbp), %eax
movl %r15d, %ecx
shrl %cl, %eax
shll %cl, %eax
movl 0x10c(%rbx), %ecx
movl %eax, 0x80(%rbx,%rcx,4)
movl 0x40(%rbx,%r13,4), %eax
addl %r12d, %eax
movl 0x10c(%rbx), %ecx
movl %eax, 0xc0(%rbx,%rcx,4)
decl %r12d
incl 0x10c(%rbx)
incl %r14d
jmp 0x3f9d
movslq %r13d, %r12
movl 0x40(%rbx,%r12,4), %eax
subl 0x104(%rbx), %eax
addl $-0x2, %eax
xorl %ecx, %ecx
testl %eax, %eax
cmovgl %eax, %ecx
movq %rcx, -0x30(%rbp)
pushq $0x11
popq %r14
pushq $-0x1
popq %r13
movq -0x30(%rbp), %rax
addl %r13d, %eax
cmpl $-0x1, %eax
je 0x3905
movl %r14d, %r15d
subl 0x40(%rbx,%r12,4), %r15d
movsd 0x20b4(%rip), %xmm0     # 0x60f0
movl %r15d, %edi
callq 0x21d0
cvttsd2si %xmm0, %eax
addl -0x38(%rbp), %eax
movl %r15d, %ecx
shrl %cl, %eax
shll %cl, %eax
movl 0x10c(%rbx), %ecx
movl %eax, 0x80(%rbx,%rcx,4)
movl 0x40(%rbx,%r12,4), %eax
addl %r13d, %eax
movl 0x10c(%rbx), %ecx
movl %eax, 0xc0(%rbx,%rcx,4)
incl 0x10c(%rbx)
decl %r13d
incl %r14d
jmp 0x401c