// File: derekzwy[P]an-optimal-tcam-encoding-algorithm-for-packet-classification/rulesutils.cc
// Function: IP2Range(unsigned int, unsigned int, unsigned int, unsigned int, unsigned int, pc_rule*, int)
void IP2Range(unsigned ip1,unsigned ip2,unsigned ip3,unsigned ip4,unsigned iplen,pc_rule *rule,int index)
{
    unsigned tmp;
    unsigned Lo,Hi;

    if(iplen == 0){
        Lo = 0;
        Hi = 0xFFFFFFFF;

    }else if(iplen > 0 && iplen <= 8) {
        tmp = ip1 << 24;
        tmp &= (0xffffffff << (32-iplen));

        Lo = tmp;
        Hi = Lo + (1<<(32-iplen)) - 1;
    }else if(iplen > 8 && iplen <= 16){
        tmp =  ip1 << 24; 
        tmp += ip2 << 16;
        tmp &= (0xffffffff << (32-iplen));

        Lo = tmp;
        Hi = Lo + (1<<(32-iplen)) - 1;
    }else if(iplen > 16 && iplen <= 24){
        tmp = ip1 << 24; 
        tmp += ip2 << 16; 
        tmp += ip3 << 8; 
        tmp &= (0xffffffff << (32-iplen));

        Lo = tmp;
        Hi = Lo + (1<<(32-iplen)) - 1;
    }else if(iplen > 24 && iplen <= 32){
        tmp = ip1 << 24; 
        tmp += ip2 << 16; 
        tmp += ip3 << 8; 
        tmp += ip4;
        tmp &= (0xffffffff << (32-iplen));

        Lo = tmp;
        Hi = Lo + (1<<(32-iplen)) - 1;
    }else{
        printf("Error: Src IP length exceeds 32\n");
        exit(1);
    }

    rule->field[index].low  = Lo;
    rule->field[index].high = Hi;

    if (CheckIPBounds(rule->field[index]))
    {
        printf("Error: IP2Range bounds check for %d failed\n",index);
        exit(1);
    }

}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x40, %rsp
movl 0x10(%rbp), %eax
movl %edi, -0x4(%rbp)
movl %esi, -0x8(%rbp)
movl %edx, -0xc(%rbp)
movl %ecx, -0x10(%rbp)
movl %r8d, -0x14(%rbp)
movq %r9, -0x20(%rbp)
cmpl $0x0, -0x14(%rbp)
jne 0x6128
movl $0x0, -0x28(%rbp)
movl $0xffffffff, -0x2c(%rbp) # imm = 0xFFFFFFFF
jmp 0x62ce
cmpl $0x0, -0x14(%rbp)
jbe 0x6179
cmpl $0x8, -0x14(%rbp)
ja 0x6179
movl -0x4(%rbp), %eax
shll $0x18, %eax
movl %eax, -0x24(%rbp)
movl $0x20, %ecx
subl -0x14(%rbp), %ecx
movl $0xffffffff, %eax       # imm = 0xFFFFFFFF
shll %cl, %eax
andl -0x24(%rbp), %eax
movl %eax, -0x24(%rbp)
movl -0x24(%rbp), %eax
movl %eax, -0x28(%rbp)
movl -0x28(%rbp), %eax
movl $0x20, %ecx
subl -0x14(%rbp), %ecx
movl $0x1, %edx
shll %cl, %edx
movl %edx, %ecx
addl %ecx, %eax
subl $0x1, %eax
movl %eax, -0x2c(%rbp)
jmp 0x62cc
cmpl $0x8, -0x14(%rbp)
jbe 0x61d6
cmpl $0x10, -0x14(%rbp)
ja 0x61d6
movl -0x4(%rbp), %eax
shll $0x18, %eax
movl %eax, -0x24(%rbp)
movl -0x8(%rbp), %eax
shll $0x10, %eax
addl -0x24(%rbp), %eax
movl %eax, -0x24(%rbp)
movl $0x20, %ecx
subl -0x14(%rbp), %ecx
movl $0xffffffff, %eax       # imm = 0xFFFFFFFF
shll %cl, %eax
andl -0x24(%rbp), %eax
movl %eax, -0x24(%rbp)
movl -0x24(%rbp), %eax
movl %eax, -0x28(%rbp)
movl -0x28(%rbp), %eax
movl $0x20, %ecx
subl -0x14(%rbp), %ecx
movl $0x1, %edx
shll %cl, %edx
movl %edx, %ecx
addl %ecx, %eax
subl $0x1, %eax
movl %eax, -0x2c(%rbp)
jmp 0x62ca
cmpl $0x10, -0x14(%rbp)
jbe 0x623f
cmpl $0x18, -0x14(%rbp)
ja 0x623f
movl -0x4(%rbp), %eax
shll $0x18, %eax
movl %eax, -0x24(%rbp)
movl -0x8(%rbp), %eax
shll $0x10, %eax
addl -0x24(%rbp), %eax
movl %eax, -0x24(%rbp)
movl -0xc(%rbp), %eax
shll $0x8, %eax
addl -0x24(%rbp), %eax
movl %eax, -0x24(%rbp)
movl $0x20, %ecx
subl -0x14(%rbp), %ecx
movl $0xffffffff, %eax       # imm = 0xFFFFFFFF
shll %cl, %eax
andl -0x24(%rbp), %eax
movl %eax, -0x24(%rbp)
movl -0x24(%rbp), %eax
movl %eax, -0x28(%rbp)
movl -0x28(%rbp), %eax
movl $0x20, %ecx
subl -0x14(%rbp), %ecx
movl $0x1, %edx
shll %cl, %edx
movl %edx, %ecx
addl %ecx, %eax
subl $0x1, %eax
movl %eax, -0x2c(%rbp)
jmp 0x62c8
cmpl $0x18, -0x14(%rbp)
jbe 0x62ae
cmpl $0x20, -0x14(%rbp)
ja 0x62ae
movl -0x4(%rbp), %eax
shll $0x18, %eax
movl %eax, -0x24(%rbp)
movl -0x8(%rbp), %eax
shll $0x10, %eax
addl -0x24(%rbp), %eax
movl %eax, -0x24(%rbp)
movl -0xc(%rbp), %eax
shll $0x8, %eax
addl -0x24(%rbp), %eax
movl %eax, -0x24(%rbp)
movl -0x10(%rbp), %eax
addl -0x24(%rbp), %eax
movl %eax, -0x24(%rbp)
movl $0x20, %ecx
subl -0x14(%rbp), %ecx
movl $0xffffffff, %eax       # imm = 0xFFFFFFFF
shll %cl, %eax
andl -0x24(%rbp), %eax
movl %eax, -0x24(%rbp)
movl -0x24(%rbp), %eax
movl %eax, -0x28(%rbp)
movl -0x28(%rbp), %eax
movl $0x20, %ecx
subl -0x14(%rbp), %ecx
movl $0x1, %edx
shll %cl, %edx
movl %edx, %ecx
addl %ecx, %eax
subl $0x1, %eax
movl %eax, -0x2c(%rbp)
jmp 0x62c6
leaq 0x6e62(%rip), %rdi      # 0xd117
movb $0x0, %al
callq 0x2030
movl $0x1, %edi
callq 0x2190
jmp 0x62c8
jmp 0x62ca
jmp 0x62cc
jmp 0x62ce
movl -0x28(%rbp), %eax
movl %eax, %ecx
movq -0x20(%rbp), %rax
addq $0x8, %rax
movslq 0x10(%rbp), %rdx
shlq $0x4, %rdx
addq %rdx, %rax
movq %rcx, (%rax)
movl -0x2c(%rbp), %eax
movl %eax, %ecx
movq -0x20(%rbp), %rax
addq $0x8, %rax
movslq 0x10(%rbp), %rdx
shlq $0x4, %rdx
addq %rdx, %rax
movq %rcx, 0x8(%rax)
movq -0x20(%rbp), %rax
addq $0x8, %rax
movslq 0x10(%rbp), %rcx
shlq $0x4, %rcx
addq %rcx, %rax
movq (%rax), %rcx
movq %rcx, -0x40(%rbp)
movq 0x8(%rax), %rax
movq %rax, -0x38(%rbp)
movq -0x40(%rbp), %rdi
movq -0x38(%rbp), %rsi
callq 0x6050
cmpl $0x0, %eax
je 0x6354
movl 0x10(%rbp), %esi
leaq 0x6df5(%rip), %rdi      # 0xd138
movb $0x0, %al
callq 0x2030
movl $0x1, %edi
callq 0x2190
addq $0x40, %rsp
popq %rbp
retq
nopw (%rax,%rax)