// File: /workspace/github_cpp_makefile_star2_O2/helchr[P]reMap/main.cpp
// Function: main
int main(int argc, char *argv[])
{

    int opt;
    bool verbose = false;
    bool considerTadRegions = false;
    unsigned int sizeGb = 20;
    size_t numAddressTotal = 1000;
    size_t numAccess = 2000;
    while ((opt = getopt(argc, argv, "vrs:n:a:")) != -1)
    {
        switch (opt)
        {
        case 'v': verbose=true; break;
        case 'r': considerTadRegions = true; break;
        case 's': sizeGb = atoi(optarg); break;
        case 'n': numAddressTotal = atoi(optarg); break;
        case 'a': numAccess = atoi(optarg); break;

        default:
            std::cout <<"Usage: " << argv[0] <<"\n"
                     << "[-v] Verbose output\n"
                     << "[-r] Resolve addressing function assuming multiple TAD regions\n"
                     << "[-s <memPoolSize>]\n"
                     << "[-n <number of samples collected>]\n"
                     << "[-a <number of accesses for one component test>]\n"
                     << "Must be run as root to resolve physical addresses\n"
                     << "Must be pinned to one socket and its local memory\n";
            exit(EXIT_FAILURE);
        }
    }

    unsigned int nodeid;
    unsigned int cpuid;
    auto status = syscall(SYS_getcpu, &cpuid, &nodeid, nullptr);
    if(status == -1)
    {
        cout << "Can not determine node id" << endl;
        return EXIT_FAILURE;
    }
    if(verbose) cout << "Running on socket " << nodeid << endl;

    initPagemap();
    const uint64_t size = sizeGb * 1024 * 1024 * 1024ULL;
    auto space = (uint64_t) allocate(size);
    if(space == 0)
    {
        return EXIT_FAILURE;
    }
    srand(3344);

    std::set<uint64_t> usedAddresses;
    std::map<size_t,std::vector<uint64_t>>channelAddresses;
    std::map<size_t,std::vector<uint64_t>>rankAddresses;
    std::map<size_t,std::vector<uint64_t>>bankAddresses;
    std::map<size_t,std::vector<uint64_t>>bankGroupAddresses;



    cout << "Collecting address samples ..." << endl;
    auto adr=space;
    while(usedAddresses.size() < numAddressTotal)
    {
        adr = getNextAddress(adr,space,size);
        auto physicalAddress = getPhysicalAddr(adr);
        if(verbose) cout << bitset<64>(physicalAddress);
        if(usedAddresses.count(physicalAddress) > 0)
        {
            continue;
        }
        usedAddresses.insert(physicalAddress);
        int identifiedChannel = -1;
        int identifiedRank = -1;
        int identifiedBank = -1;
        int identifiedBankGroup = -1;
        bool found = false;
        for(unsigned int channel = 0; channel < 4 && !found; channel++)
        {
            for(unsigned int rank = 0; rank < 8 && !found; rank++)
            {

                for(unsigned int bank = 0; bank < 16 && !found; bank++)
                {
                    usleep(1);
                    auto fd = setupMeasure(cpuid,channel,rank,bank);
                    startMeasure(fd);
                    access(adr,numAccess);
                    auto count = stopMeasure(fd);
                    if (count >= 0.9*numAccess)
                    {
                        identifiedChannel = channel;
                        identifiedRank = rank;
                        identifiedBank = bank;
                        found = true;
                    }
                }

                for(unsigned int bankGroup = 0; bankGroup < 4; bankGroup++)
                {
                    auto fd = setupMeasure(cpuid,channel,rank,bankGroup,true);
                    startMeasure(fd);
                    access(adr,numAccess);
                    auto count = stopMeasure(fd);
                    if (count >= 0.9*numAccess)
                    {
                        identifiedBankGroup = bankGroup;
                        break;
                    }
                }
            }
        }
        if(found)
        {
            channelAddresses[identifiedChannel].push_back(physicalAddress);
            rankAddresses[identifiedRank].push_back(physicalAddress);
            bankAddresses[identifiedBank].push_back(physicalAddress);
            bankGroupAddresses[identifiedBankGroup].push_back(physicalAddress);
            if(verbose) cout << " Channel " << identifiedChannel << " Rank " << identifiedRank << " Bank " << identifiedBank << " BankGroup" << identifiedBankGroup << endl;
        }
        else
        {
            if(verbose) std::cout  << " No set found" << endl;
        }
    }

    for (size_t i = 0 ;i < 4; i++)
    {
        std::cout << "Caputured " << channelAddresses[i].size() << " addresses on channel " << i << endl;
    }
    for (size_t j = 0 ;j < 8; j++)
    {
        std::cout << "Caputured " << rankAddresses[j].size() << " addresses on rank " << j << endl;
    }
    for(size_t k = 0; k < 16; k++)
    {
        std::cout << "Caputured " << bankAddresses[k].size() << " addresses on bank " << k << endl;
    }
    for(size_t k = 0; k < 4; k++)
    {
        std::cout << "Caputured " << bankGroupAddresses[k].size() << " addresses on bankGroup " << k << endl;
    }
    cout << endl;

    uint64_t andAll = std::numeric_limits<uint64_t>::max();
    uint64_t orAll = 0;
    for(auto a : usedAddresses)
    {
        orAll |= a;
        andAll &= a;
    }
    // bits with value 0 in orAll are 0 in all addresses
    // bits with value 1 in andAll are 1 in all addresses
    std::bitset<64> orAllBits(orAll);
    std::bitset<64> andAllBits(andAll);
    if(verbose) std::cout << "And all bits: " << andAllBits  << endl;
    if(verbose) std::cout << "Or all bits:  " << orAllBits  << endl;
    std::bitset<64> unknownBits = 0;
    for(size_t i = 0; i < 64; i++)
    {
        if(orAllBits[i] == 0 || andAllBits[i] == 1)
        {
            unknownBits[i] = 1;
        }
    }
    if(verbose) std::cout << "Unknown bits: " << unknownBits  << endl;


    uint64_t removeFront = 0;
    for(size_t i = 0; i < 64; i++)
    {
        if(unknownBits[i] == 0)
        {
            removeFront = i;
            break;
        }
    }
    if(verbose) std::cout << "Remove " << removeFront << " from front" << endl;

    uint64_t removeBack = 0;
    for(size_t i = 64; i-- > 0;)
    {
        if(unknownBits[i] == 0)
        {
            removeBack = 63 - i ;
            break;
        }
    }
    if(verbose) std::cout << "Remove " << removeBack << " from back" << endl;
    if(verbose) cout << endl;


    if(considerTadRegions)
    {
        auto tadRegions = SysInfo::getTadRegions(nodeid);
        std::map<size_t,AddressSet> regionControllerAddresses;
        std::map<size_t,std::map<size_t,AddressSet>> regionControllerChannelAddresses;

        //build zones
        for(size_t c = 0; c < channelAddresses.size(); c++)
        {
            auto adrList = channelAddresses.at(c);
            for(auto a : adrList)
            {
                for(auto rIt = tadRegions.begin(); rIt != tadRegions.end(); rIt++)
                {
                    auto limitAddress = rIt->first;
                    auto controllerList = rIt->second;
                    if(a <= limitAddress) //found a region that matches
                    {
                        if(controllerList.size() > 1) // this region has controller interleaving on
                        {
                            auto contr = SysInfo::channelToController(c);
                            regionControllerAddresses[limitAddress][contr].push_back(a);
                        }
                        for(size_t contr = 0; contr < controllerList.size(); contr++)
                        {
                            if(controllerList.at(contr).channelInterleaving > 1)
                            {
                                auto contrRef = SysInfo::channelToController(c);
                                if(contrRef == contr)
                                {
                                    regionControllerChannelAddresses[limitAddress][contr][c].push_back(a);
                                }
                            }
                        }
                        break; // regions are sorted. break after first match
                    }
                }
            }
        }


        cout << "Channels" << endl;
        unsigned int regionIndex = 0;
        size_t lastLimitAddress = 0;
        const size_t REGION_UNIT = 1024*1024;
        for(auto tadRegion : tadRegions)
        {
            auto limitAddress = tadRegion.first;
            cout << "Region " << regionIndex << " from " << lastLimitAddress/REGION_UNIT << "M to " << limitAddress/REGION_UNIT << "M:" << endl;
            auto controllerAddrSetIt = regionControllerAddresses.find(limitAddress);
            if(controllerAddrSetIt != regionControllerAddresses.end() && !controllerAddrSetIt->second.empty() )
            {
                cout << "Controller Interleaving:" << endl;
                prepareSolvePrint(controllerAddrSetIt->second,removeFront,removeBack);
            }
            else
            {
                if(tadRegion.second.size()==0)
                {
                    cout << "No addresses captured in this region" << endl;
                    lastLimitAddress = limitAddress;
                    regionIndex++;
                    continue;
                }
                else if(tadRegion.second.size() == 1)
                {
                    cout << "Single controller" << endl;
                }
            }
            auto controllerChannelAddrSetIt = regionControllerChannelAddresses.find(limitAddress);
            if(controllerChannelAddrSetIt != regionControllerChannelAddresses.end())
            {
                unsigned int contrIndex = 0;
                auto controllerChannelAddrSet = controllerChannelAddrSetIt->second;
                for(auto contr : controllerChannelAddrSet)
                {
                    cout << "Channel interleaving in controller " << contrIndex << ":" << endl;
                    prepareSolvePrint(contr.second,removeFront,removeBack);
                    contrIndex++;
                }
            }
            lastLimitAddress = limitAddress;
            regionIndex++;
        }
        cout << endl;
    }
    else // Assume there is only one TAD region
    {
        cout << "Channels" << endl;
        prepareSolvePrint(channelAddresses,removeFront,removeBack);
        cout << endl;
    }

    cout << "Ranks" << endl;
    auto setNums = getUsedSets(rankAddresses);
    cout << "Used ranks: ";
    for(auto s : setNums)
    {
        cout << s << " ";
    }
    cout << endl;
    prepareSolvePrint(rankAddresses,removeFront,removeBack);
    cout << endl;

    cout << "Banks" << endl;
    prepareSolvePrint(bankAddresses,removeFront,removeBack);
    cout << endl;

    cout << "Bank Groups" << endl;
    prepareSolvePrint(bankGroupAddresses,removeFront,removeBack);
    cout << endl;

    return 0;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x3f8, %rsp            # imm = 0x3F8
movq %rsi, %rbx
movl %edi, %ebp
pushq $0x14
popq %r13
movl $0x3e8, %eax            # imm = 0x3E8
movq %rax, 0x50(%rsp)
movl $0x7d0, %eax            # imm = 0x7D0
movq %rax, 0x10(%rsp)
movl $0x0, 0x44(%rsp)
leaq 0x18d68(%rip), %r15     # 0x211de
movq 0x23afb(%rip), %r14     # 0x2bf78
leaq 0x18bcc(%rip), %r12     # 0x21050
movl $0x0, 0xc(%rsp)
movl 0xc(%rsp), %eax
movl %eax, 0xc(%rsp)
movl %ebp, %edi
movq %rbx, %rsi
movq %r15, %rdx
callq 0x50f0
leal -0x6e(%rax), %ecx
cmpl $0x8, %ecx
ja 0x84c5
movb $0x1, %al
movslq (%r12,%rcx,4), %rcx
addq %r12, %rcx
jmpq *%rcx
movq (%r14), %rdi
callq 0x56d0
cltq
movq %rax, 0x50(%rsp)
jmp 0x848c
cmpl $-0x1, %eax
je 0x84f9
cmpl $0x61, %eax
jne 0x954e
movq (%r14), %rdi
callq 0x56d0
cltq
movq %rax, 0x10(%rsp)
jmp 0x848c
movb $0x1, %al
movl %eax, 0x44(%rsp)
jmp 0x848c
movq (%r14), %rdi
callq 0x56d0
movl %eax, %r13d
jmp 0x848c
pushq $0x1
popq %rbx
leaq 0x48(%rsp), %rsi
leaq 0x4c(%rsp), %rdx
movl $0x135, %edi            # imm = 0x135
xorl %ecx, %ecx
xorl %eax, %eax
callq 0x5070
cmpq $-0x1, %rax
je 0x898f
movl 0xc(%rsp), %ebp
testb $0x1, %bpl
je 0x854f
movq 0x23a81(%rip), %rdi     # 0x2bfb0
leaq 0x18df8(%rip), %rsi     # 0x2132e
callq 0x5450
movl 0x4c(%rsp), %esi
movq %rax, %rdi
callq 0x5340
movq %rax, %rdi
callq 0x5230
callq 0x7b51
shll $0x14, %r13d
shlq $0xa, %r13
movq %r13, %rdi
callq 0x79b7
movq %rax, 0xc0(%rsp)
testq %rax, %rax
movq 0x50(%rsp), %r12
je 0x953a
movl $0xd10, %edi            # imm = 0xD10
callq 0x5440
leaq 0x190(%rsp), %rax
andl $0x0, (%rax)
andq $0x0, 0x8(%rax)
movq %rax, 0x10(%rax)
movq %rax, 0x18(%rax)
andq $0x0, 0x20(%rax)
leaq 0x160(%rsp), %rax
andl $0x0, (%rax)
andq $0x0, 0x8(%rax)
movq %rax, 0x10(%rax)
movq %rax, 0x18(%rax)
andq $0x0, 0x20(%rax)
leaq 0x1c0(%rsp), %rax
andl $0x0, (%rax)
andq $0x0, 0x8(%rax)
movq %rax, 0x10(%rax)
movq %rax, 0x18(%rax)
andq $0x0, 0x20(%rax)
leaq 0x280(%rsp), %rax
andl $0x0, (%rax)
andq $0x0, 0x8(%rax)
movq %rax, 0x10(%rax)
movq %rax, 0x18(%rax)
andq $0x0, 0x20(%rax)
leaq 0x250(%rsp), %rax
andl $0x0, (%rax)
andq $0x0, 0x8(%rax)
movq %rax, 0x10(%rax)
movq %rax, 0x18(%rax)
andq $0x0, 0x20(%rax)
movq 0x23994(%rip), %rdi     # 0x2bfb0
leaq 0x18d1e(%rip), %rsi     # 0x21341
callq 0x5450
movq %rax, %rdi
callq 0x5230
movsd 0x10(%rsp), %xmm0
unpcklps 0x189e3(%rip), %xmm0    # xmm0 = xmm0[0],mem[0],xmm0[1],mem[1]
subpd 0x189eb(%rip), %xmm0    # 0x21030
movapd %xmm0, %xmm1
unpckhpd %xmm0, %xmm1            # xmm1 = xmm1[1],xmm0[1]
addsd %xmm0, %xmm1
mulsd 0x189ef(%rip), %xmm1    # 0x21048
movapd %xmm1, 0xa0(%rsp)
leaq 0xf8(%rsp), %rbx
movq 0xc0(%rsp), %r15
movq %r13, 0xb8(%rsp)
cmpq %r12, 0x1b0(%rsp)
jae 0x89af
movq %r15, %rdi
movq 0xc0(%rsp), %rsi
movq %r13, %rdx
callq 0x7e3f
movq %rax, %r15
movq %rax, %rdi
callq 0x7b8b
movq %rax, 0x58(%rsp)
testb $0x1, %bpl
je 0x86c8
movq %rax, 0xf8(%rsp)
movq 0x238f0(%rip), %rdi     # 0x2bfb0
movq %rbx, %rsi
callq 0x9918
leaq 0x188(%rsp), %rdi
leaq 0x58(%rsp), %rsi
callq 0x99e0
testq %rax, %rax
jne 0x867a
leaq 0x188(%rsp), %rdi
leaq 0x58(%rsp), %rsi
callq 0xad76
xorl %r12d, %r12d
xorl %r14d, %r14d
pushq $-0x1
popq %rax
movl %eax, 0x28(%rsp)
movl %eax, 0x18(%rsp)
movl %eax, 0x30(%rsp)
movl %eax, 0x2c(%rsp)
cmpl $0x3, %r12d
ja 0x8805
testb $0x1, %r14b
jne 0x8805
xorl %ebx, %ebx
cmpl $0x7, %ebx
ja 0x87fd
testb $0x1, %r14b
jne 0x87fd
xorl %r13d, %r13d
cmpl $0xf, %r13d
ja 0x87a1
testb $0x1, %r14b
jne 0x87a1
pushq $0x1
popq %rdi
callq 0x55f0
movl 0x48(%rsp), %edi
movl %r12d, %esi
movl %ebx, %edx
movl %r13d, %ecx
xorl %r8d, %r8d
callq 0x7c2c
movl %eax, %ebp
movl %eax, %edi
callq 0x7da8
movq %r15, %rdi
movq 0x10(%rsp), %rsi
callq 0x7c12
movl %ebp, %edi
callq 0x7dcd
cvtsi2sd %rax, %xmm0
ucomisd 0xa0(%rsp), %xmm0
jb 0x879c
movb $0x1, %r14b
movl %r13d, 0x18(%rsp)
movl %ebx, 0x30(%rsp)
movl %r12d, 0x2c(%rsp)
incl %r13d
jmp 0x8736
xorl %r13d, %r13d
cmpl $0x4, %r13d
je 0x87f6
movl 0x48(%rsp), %edi
movl %r12d, %esi
movl %ebx, %edx
movl %r13d, %ecx
pushq $0x1
popq %r8
callq 0x7c2c
movl %eax, %ebp
movl %eax, %edi
callq 0x7da8
movq %r15, %rdi
movq 0x10(%rsp), %rsi
callq 0x7c12
movl %ebp, %edi
callq 0x7dcd
cvtsi2sd %rax, %xmm0
ucomisd 0xa0(%rsp), %xmm0
jae 0x87f1
incl %r13d
jmp 0x87a4
movl %r13d, 0x28(%rsp)
incl %ebx
jmp 0x8720
incl %r12d
jmp 0x870a
testb $0x1, %r14b
je 0x894c
movslq 0x2c(%rsp), %rax
movq %rax, 0xf8(%rsp)
leaq 0x158(%rsp), %rdi
leaq 0xf8(%rsp), %rbx
movq %rbx, %rsi
callq 0x99fa
movl 0xc(%rsp), %ebp
movq 0xb8(%rsp), %r13
movq 0x50(%rsp), %r12
movq %rax, %rdi
leaq 0x58(%rsp), %rsi
callq 0x97de
movslq 0x30(%rsp), %rax
movq %rax, 0xf8(%rsp)
leaq 0x1b8(%rsp), %rdi
movq %rbx, %rsi
callq 0x99fa
movq %rax, %rdi
leaq 0x58(%rsp), %rsi
callq 0x97de
movslq 0x18(%rsp), %rax
movq %rax, 0xf8(%rsp)
leaq 0x278(%rsp), %rdi
movq %rbx, %rsi
callq 0x99fa
movq %rax, %rdi
leaq 0x58(%rsp), %rsi
callq 0x97de
movslq 0x28(%rsp), %rax
movq %rax, 0xf8(%rsp)
leaq 0x248(%rsp), %rdi
movq %rbx, %rsi
callq 0x99fa
movq %rax, %rdi
leaq 0x58(%rsp), %rsi
callq 0x97de
testb $0x1, %bpl
je 0x867a
movq 0x236cf(%rip), %rdi     # 0x2bfb0
leaq 0x18a78(%rip), %rsi     # 0x21360
callq 0x5450
movq %rax, %rdi
movl 0x2c(%rsp), %esi
callq 0x5760
movq %rax, %rdi
leaq 0x18a67(%rip), %rsi     # 0x2136a
callq 0x5450
movq %rax, %rdi
movl 0x30(%rsp), %esi
callq 0x5760
movq %rax, %rdi
leaq 0x18a53(%rip), %rsi     # 0x21371
callq 0x5450
movq %rax, %rdi
movl 0x18(%rsp), %esi
callq 0x5760
movq %rax, %rdi
leaq 0x18a3f(%rip), %rsi     # 0x21378
callq 0x5450
movq %rax, %rdi
movl 0x28(%rsp), %esi
callq 0x5760
jmp 0x8982
movl 0xc(%rsp), %ebp
testb $0x1, %bpl
movq 0xb8(%rsp), %r13
movq 0x50(%rsp), %r12
leaq 0xf8(%rsp), %rbx
je 0x867a
movq 0x2363a(%rip), %rdi     # 0x2bfb0
leaq 0x18a06(%rip), %rsi     # 0x21383
callq 0x5450
movq %rax, %rdi
callq 0x5230
jmp 0x867a
movq 0x2361a(%rip), %rdi     # 0x2bfb0
leaq 0x18977(%rip), %rsi     # 0x21314
callq 0x5450
movq %rax, %rdi
callq 0x5230
jmp 0x953a
xorl %eax, %eax
movq 0x235f8(%rip), %rbx     # 0x2bfb0
leaq 0x189d2(%rip), %r14     # 0x21391
leaq 0x158(%rsp), %r15
leaq 0x58(%rsp), %r12
leaq 0x189c9(%rip), %r13     # 0x2139c
movq %rax, 0x58(%rsp)
cmpq $0x4, %rax
jae 0x8a34
movq %rbx, %rdi
movq %r14, %rsi
callq 0x5450
movq %rax, %rbp
movq %r15, %rdi
movq %r12, %rsi
callq 0x9a4a
movq 0x8(%rax), %rsi
subq (%rax), %rsi
sarq $0x3, %rsi
movq %rbp, %rdi
callq 0x5340
movq %rax, %rdi
movq %r13, %rsi
callq 0x5450
movq 0x58(%rsp), %rsi
movq %rax, %rdi
callq 0x5340
movq %rax, %rdi
callq 0x5230
movq 0x58(%rsp), %rax
incq %rax
jmp 0x89d3
xorl %eax, %eax
movq 0x23573(%rip), %rbx     # 0x2bfb0
leaq 0x1894d(%rip), %r14     # 0x21391
leaq 0x1b8(%rsp), %r15
leaq 0x58(%rsp), %r12
leaq 0x1895b(%rip), %r13     # 0x213b3
movq %rax, 0x58(%rsp)
cmpq $0x8, %rax
jae 0x8ab9
movq %rbx, %rdi
movq %r14, %rsi
callq 0x5450
movq %rax, %rbp
movq %r15, %rdi
movq %r12, %rsi
callq 0x9a4a
movq 0x8(%rax), %rsi
subq (%rax), %rsi
sarq $0x3, %rsi
movq %rbp, %rdi
callq 0x5340
movq %rax, %rdi
movq %r13, %rsi
callq 0x5450
movq 0x58(%rsp), %rsi
movq %rax, %rdi
callq 0x5340
movq %rax, %rdi
callq 0x5230
movq 0x58(%rsp), %rax
incq %rax
jmp 0x8a58
xorl %eax, %eax
movq 0x234ee(%rip), %rbx     # 0x2bfb0
leaq 0x188c8(%rip), %r14     # 0x21391
leaq 0x278(%rsp), %r15
leaq 0x58(%rsp), %r12
leaq 0x188ea(%rip), %r13     # 0x213c7
movq %rax, 0x58(%rsp)
cmpq $0x10, %rax
jae 0x8b3e
movq %rbx, %rdi
movq %r14, %rsi
callq 0x5450
movq %rax, %rbp
movq %r15, %rdi
movq %r12, %rsi
callq 0x9a4a
movq 0x8(%rax), %rsi
subq (%rax), %rsi
sarq $0x3, %rsi
movq %rbp, %rdi
callq 0x5340
movq %rax, %rdi
movq %r13, %rsi
callq 0x5450
movq 0x58(%rsp), %rsi
movq %rax, %rdi
callq 0x5340
movq %rax, %rdi
callq 0x5230
movq 0x58(%rsp), %rax
incq %rax
jmp 0x8add
xorl %eax, %eax
movq 0x23469(%rip), %rbx     # 0x2bfb0
leaq 0x18843(%rip), %r14     # 0x21391
leaq 0x248(%rsp), %r15
leaq 0x58(%rsp), %r12
leaq 0x18879(%rip), %r13     # 0x213db
movq %rax, 0x58(%rsp)
cmpq $0x4, %rax
jae 0x8bc3
movq %rbx, %rdi
movq %r14, %rsi
callq 0x5450
movq %rax, %rbp
movq %r15, %rdi
movq %r12, %rsi
callq 0x9a4a
movq 0x8(%rax), %rsi
subq (%rax), %rsi
sarq $0x3, %rsi
movq %rbp, %rdi
callq 0x5340
movq %rax, %rdi
movq %r13, %rsi
callq 0x5450
movq 0x58(%rsp), %rsi
movq %rax, %rdi
callq 0x5340
movq %rax, %rdi
callq 0x5230
movq 0x58(%rsp), %rax
incq %rax
jmp 0x8b62
movq 0x233e6(%rip), %rdi     # 0x2bfb0
callq 0x5230
pushq $-0x1
popq %rbx
movq 0x1a0(%rsp), %rax
xorl %r14d, %r14d
leaq 0x190(%rsp), %rcx
cmpq %rcx, %rax
je 0x8bfe
movq 0x20(%rax), %rcx
orq %rcx, %r14
andq %rcx, %rbx
movq %rax, %rdi
callq 0x54c0
jmp 0x8bdd
movq %r14, 0xd0(%rsp)
movq %rbx, 0xc8(%rsp)
testb $0x1, 0xc(%rsp)
je 0x8c7b
movq 0x23394(%rip), %rdi     # 0x2bfb0
leaq 0x187d1(%rip), %rsi     # 0x213f4
callq 0x5450
leaq 0xc8(%rsp), %rsi
movq %rax, %rdi
callq 0x9918
movq %rax, %rdi
callq 0x5230
movq 0x23369(%rip), %rdi     # 0x2bfb0
leaq 0x187b5(%rip), %rsi     # 0x21403
callq 0x5450
leaq 0xd0(%rsp), %rsi
movq %rax, %rdi
callq 0x9918
movq %rax, %rdi
callq 0x5230
movq 0xd0(%rsp), %r14
movq 0xc8(%rsp), %rbx
andq $0x0, 0x90(%rsp)
xorl %eax, %eax
pushq $0x1
popq %rdx
xorl %ecx, %ecx
cmpq $0x40, %rcx
je 0x8cb5
movq %rdx, %rsi
shlq %cl, %rsi
btq %rcx, %r14
jae 0x8ca5
movq %rbx, %rdi
andq %rsi, %rdi
je 0x8cb0
orq %rsi, %rax
movq %rax, 0x90(%rsp)
incq %rcx
jmp 0x8c8b
movl 0xc(%rsp), %ebx
testb $0x1, %bl
je 0x8cf1
movq 0x232eb(%rip), %rdi     # 0x2bfb0
leaq 0x184eb(%rip), %rsi     # 0x211b7
callq 0x5450
leaq 0x90(%rsp), %rsi
movq %rax, %rdi
callq 0x9918
movq %rax, %rdi
callq 0x5230
movq 0x90(%rsp), %rax
xorl %r13d, %r13d
cmpq $0x40, %r13
je 0x8d05
btq %r13, %rax
jae 0x8d08
incq %r13
jmp 0x8cf4
xorl %r13d, %r13d
testb $0x1, %bl
je 0x8d4a
movq 0x2329c(%rip), %rdi     # 0x2bfb0
leaq 0x186f7(%rip), %rsi     # 0x21412
callq 0x5450
movq %rax, %rdi
movq %r13, %rsi
callq 0x5340
leaq 0x186e8(%rip), %rsi     # 0x2141a
movq %rax, %rdi
callq 0x5450
movq %rax, %rdi
callq 0x5230
movq 0x90(%rsp), %rax
pushq $-0x1
popq %rbp
pushq $0x3f
popq %rcx
cmpq $0x3f, %rbp
je 0x8d65
incq %rbp
btq %rcx, %rax
leaq -0x1(%rcx), %rcx
jb 0x8d50
jmp 0x8d67
xorl %ebp, %ebp
testb $0x1, %bl
je 0x8dad
movq 0x2323d(%rip), %rdi     # 0x2bfb0
leaq 0x18698(%rip), %rsi     # 0x21412
callq 0x5450
movq %rax, %rdi
movq %rbp, %rsi
callq 0x5340
leaq 0x18695(%rip), %rsi     # 0x21426
movq %rax, %rdi
callq 0x5450
movq %rax, %rdi
callq 0x5230
movq 0x23208(%rip), %rdi     # 0x2bfb0
callq 0x5230
testb $0x1, 0x44(%rsp)
je 0x8feb
movq %rbp, 0x18(%rsp)
movq %r13, 0xa0(%rsp)
movl 0x4c(%rsp), %esi
leaq 0xf8(%rsp), %rdi
callq 0xca78
leaq 0x220(%rsp), %rax
andl $0x0, (%rax)
andq $0x0, 0x8(%rax)
movq %rax, 0x10(%rax)
movq %rax, 0x18(%rax)
andq $0x0, 0x20(%rax)
leaq 0x1f0(%rsp), %rax
andl $0x0, (%rax)
andq $0x0, 0x8(%rax)
movq %rax, 0x10(%rax)
movq %rax, 0x18(%rax)
andq $0x0, 0x20(%rax)
leaq 0x100(%rsp), %rbx
xorl %eax, %eax
leaq 0xd8(%rsp), %r12
leaq 0x58(%rsp), %r14
leaq 0x128(%rsp), %r13
leaq 0x20(%rsp), %rbp
movq %rax, 0xd8(%rsp)
cmpq 0x180(%rsp), %rax
jae 0x904c
leaq 0x158(%rsp), %rdi
movq %r12, %rsi
callq 0x9a9a
movq %r14, %rdi
movq %rax, %rsi
callq 0x9ad4
movq 0x58(%rsp), %r14
movq 0x60(%rsp), %rax
movq %rax, 0x10(%rsp)
cmpq 0x10(%rsp), %r14
je 0x8fce
movq (%r14), %rax
movq %rax, 0x20(%rsp)
movq 0x110(%rsp), %r15
cmpq %rbx, %r15
je 0x8fc5
movq 0x20(%r15), %rax
movq %rax, 0x98(%rsp)
leaq 0x28(%r15), %rsi
movq %r13, %rdi
callq 0x9b22
movq 0x20(%rsp), %rax
cmpq 0x98(%rsp), %rax
jbe 0x8ed4
movq %r13, %rdi
callq 0xb0b6
movq %r15, %rdi
callq 0x5350
movq %rax, %r15
jmp 0x8e8f
movq 0x130(%rsp), %rax
subq 0x128(%rsp), %rax
cmpq $0x11, %rax
jb 0x8f30
movzbl 0xd8(%rsp), %edi
callq 0xcb62
movl %eax, %r15d
leaq 0x218(%rsp), %rdi
leaq 0x98(%rsp), %rsi
callq 0x9b70
movzbl %r15b, %ecx
movq %rcx, 0x38(%rsp)
movq %rax, %rdi
leaq 0x38(%rsp), %rsi
callq 0x99fa
movq %rax, %rdi
movq %rbp, %rsi
callq 0x97de
xorl %esi, %esi
movq %r12, %r15
movq %rsi, 0x38(%rsp)
movq 0x130(%rsp), %rax
subq 0x128(%rsp), %rax
sarq $0x4, %rax
cmpq %rax, %rsi
jae 0x8fbd
movq %r13, %rdi
callq 0x9bc0
cmpb $0x2, 0x9(%rax)
jb 0x8fb0
movzbl 0xd8(%rsp), %edi
callq 0xcb62
movzbl %al, %eax
cmpq %rax, 0x38(%rsp)
jne 0x8fb0
leaq 0x1e8(%rsp), %rdi
leaq 0x98(%rsp), %rsi
callq 0x9be2
movq %rax, %rdi
leaq 0x38(%rsp), %rsi
callq 0x9b70
movq %rax, %rdi
movq %r15, %rsi
callq 0x9a4a
movq %rax, %rdi
movq %rbp, %rsi
callq 0x97de
movq 0x38(%rsp), %rsi
incq %rsi
jmp 0x8f35
movq %r13, %rdi
callq 0xb0b6
addq $0x8, %r14
jmp 0x8e74
leaq 0x58(%rsp), %r14
movq %r14, %rdi
callq 0xa3b0
movq 0xd8(%rsp), %rax
incq %rax
jmp 0x8e34
movq 0x22fbe(%rip), %rdi     # 0x2bfb0
leaq 0x18438(%rip), %rsi     # 0x21431
callq 0x5450
movq %rax, %rdi
callq 0x5230
leaq 0x368(%rsp), %rdi
leaq 0x158(%rsp), %rsi
callq 0x9d78
leaq 0x368(%rsp), %rdi
movq %r13, %rsi
movq %rbp, %rdx
callq 0x8361
leaq 0x368(%rsp), %rdi
callq 0x9c64
movq 0x22f6e(%rip), %rdi     # 0x2bfb0
callq 0x5230
jmp 0x934d
movq 0x22f5d(%rip), %rdi     # 0x2bfb0
leaq 0x183d7(%rip), %rsi     # 0x21431
callq 0x5450
movq %rax, %rdi
callq 0x5230
movq 0x110(%rsp), %r13
movq $0x0, 0x10(%rsp)
leaq 0x60(%rsp), %r12
movq 0x22f2c(%rip), %r15     # 0x2bfb0
leaq 0x3c8(%rsp), %rbp
xorl %r14d, %r14d
cmpq %rbx, %r13
je 0x930d
leaq 0x20(%r13), %rsi
leaq 0xd8(%rsp), %rdi
callq 0x9c32
movq 0xd8(%rsp), %rax
movq %rax, 0x20(%rsp)
movq %r15, %rdi
leaq 0x1837a(%rip), %rsi     # 0x2143a
callq 0x5450
movl 0x10(%rsp), %esi
movq %rax, %rdi
callq 0x5340
movq %rax, %rdi
leaq 0x18367(%rip), %rsi     # 0x21442
callq 0x5450
shrq $0x14, %r14
movq %rax, %rdi
movq %r14, %rsi
callq 0x5340
movq %rax, %rdi
leaq 0x18350(%rip), %rsi     # 0x21449
callq 0x5450
movq 0x20(%rsp), %rsi
shrq $0x14, %rsi
movq %rax, %rdi
callq 0x5340
movq %rax, %rdi
leaq 0x18336(%rip), %rsi     # 0x2144f
callq 0x5450
movq %rax, %rdi
callq 0x5230
leaq 0x218(%rsp), %rdi
leaq 0x20(%rsp), %rsi
callq 0xb660
movq %rax, %r14
leaq 0x220(%rsp), %rax
cmpq %rax, %r14
je 0x91a1
cmpq $0x0, 0x50(%r14)
je 0x91a1
movq %r15, %rdi
leaq 0x182f9(%rip), %rsi     # 0x21452
callq 0x5450
movq %rax, %rdi
callq 0x5230
addq $0x28, %r14
leaq 0x398(%rsp), %rdi
movq %r14, %rsi
callq 0x9d78
leaq 0x398(%rsp), %r14
movq %r14, %rdi
movq 0xa0(%rsp), %rsi
movq 0x18(%rsp), %rdx
callq 0x8361
movq %r14, %rdi
callq 0x9c64
jmp 0x91f3
movq 0xe8(%rsp), %rax
subq 0xe0(%rsp), %rax
sarq $0x4, %rax
cmpq $0x1, %rax
je 0x91dc
testq %rax, %rax
jne 0x91f3
movq %r15, %rdi
leaq 0x182a1(%rip), %rsi     # 0x2146b
callq 0x5450
movq %rax, %rdi
callq 0x5230
jmp 0x92df
movq %r15, %rdi
leaq 0x182aa(%rip), %rsi     # 0x21490
callq 0x5450
movq %rax, %rdi
callq 0x5230
leaq 0x1e8(%rsp), %rdi
leaq 0x20(%rsp), %rsi
callq 0xb696
leaq 0x1f0(%rsp), %rcx
cmpq %rcx, %rax
je 0x92df
movq %r13, 0x30(%rsp)
addq $0x28, %rax
leaq 0x128(%rsp), %rdi
movq %rax, %rsi
callq 0x9fbc
xorl %r13d, %r13d
movq 0x140(%rsp), %r14
leaq 0x130(%rsp), %rax
cmpq %rax, %r14
je 0x92cd
leaq 0x20(%r14), %rsi
leaq 0x58(%rsp), %rdi
callq 0x9c46
movq %r15, %rdi
leaq 0x1823f(%rip), %rsi     # 0x214a2
callq 0x5450
movl %r13d, %esi
movq %rax, %rdi
callq 0x5340
movq %rax, %rdi
leaq 0x181d3(%rip), %rsi     # 0x21450
callq 0x5450
movq %rax, %rdi
callq 0x5230
movq %rbp, %rdi
movq %r12, %rsi
callq 0x9d78
movq %rbp, %rdi
movq 0xa0(%rsp), %rsi
movq 0x18(%rsp), %rdx
callq 0x8361
movq %rbp, %rdi
callq 0x9c64
incl %r13d
movq %r12, %rdi
callq 0x9c64
movq %r14, %rdi
callq 0x5350
movq %rax, %r14
jmp 0x923a
leaq 0x128(%rsp), %rdi
callq 0xa240
movq 0x30(%rsp), %r13
movq 0x20(%rsp), %r14
movq 0x10(%rsp), %rax
incl %eax
movq %rax, 0x10(%rsp)
leaq 0xe0(%rsp), %rdi
callq 0xb0b6
movq %r13, %rdi
callq 0x5350
movq %rax, %r13
jmp 0x908f
movq 0x22c9c(%rip), %rdi     # 0x2bfb0
callq 0x5230
leaq 0x1e8(%rsp), %rdi
callq 0xa254
leaq 0x218(%rsp), %rdi
callq 0xa240
leaq 0xf8(%rsp), %rdi
callq 0xa2b8
movq 0xa0(%rsp), %r13
movq 0x18(%rsp), %rbp
movq 0x22c5c(%rip), %rdi     # 0x2bfb0
leaq 0x1816b(%rip), %rsi     # 0x214c6
callq 0x5450
movq %rax, %rdi
callq 0x5230
leaq 0x338(%rsp), %rdi
leaq 0x1b8(%rsp), %rsi
callq 0x9d78
leaq 0x58(%rsp), %rdi
leaq 0x338(%rsp), %rsi
callq 0x7aa6
leaq 0x338(%rsp), %rdi
callq 0x9c64
movq 0x22c0d(%rip), %rdi     # 0x2bfb0
leaq 0x18122(%rip), %rsi     # 0x214cc
callq 0x5450
movq 0x58(%rsp), %r15
movq 0x60(%rsp), %r12
movq 0x22bf0(%rip), %rbx     # 0x2bfb0
leaq 0x18049(%rip), %r14     # 0x21410
cmpq %r12, %r15
je 0x93e8
movq (%r15), %rsi
movq %rbx, %rdi
callq 0x5340
movq %rax, %rdi
movq %r14, %rsi
callq 0x5450
addq $0x8, %r15
jmp 0x93c7
movq 0x22bc1(%rip), %rdi     # 0x2bfb0
callq 0x5230
leaq 0x308(%rsp), %rdi
leaq 0x1b8(%rsp), %rsi
callq 0x9d78
leaq 0x308(%rsp), %rdi
movq %r13, %rsi
movq %rbp, %rdx
callq 0x8361
leaq 0x308(%rsp), %rdi
callq 0x9c64
movq 0x22b80(%rip), %rdi     # 0x2bfb0
callq 0x5230
movq 0x22b74(%rip), %rdi     # 0x2bfb0
leaq 0x18096(%rip), %rsi     # 0x214d9
callq 0x5450
movq %rax, %rdi
callq 0x5230
leaq 0x2d8(%rsp), %rdi
leaq 0x278(%rsp), %rsi
callq 0x9d78
leaq 0x2d8(%rsp), %rdi
movq %r13, %rsi
movq %rbp, %rdx
callq 0x8361
leaq 0x2d8(%rsp), %rdi
callq 0x9c64
movq 0x22b24(%rip), %rdi     # 0x2bfb0
callq 0x5230
movq 0x22b18(%rip), %rdi     # 0x2bfb0
leaq 0x18040(%rip), %rsi     # 0x214df
callq 0x5450
movq %rax, %rdi
callq 0x5230
leaq 0x2a8(%rsp), %rdi
leaq 0x248(%rsp), %rsi
callq 0x9d78
leaq 0x2a8(%rsp), %rdi
movq %r13, %rsi
movq %rbp, %rdx
callq 0x8361
leaq 0x2a8(%rsp), %rdi
callq 0x9c64
movq 0x22ac8(%rip), %rdi     # 0x2bfb0
callq 0x5230
leaq 0x58(%rsp), %rdi
callq 0xa3b0
leaq 0x248(%rsp), %rdi
callq 0x9c64
leaq 0x278(%rsp), %rdi
callq 0x9c64
leaq 0x1b8(%rsp), %rdi
callq 0x9c64
leaq 0x158(%rsp), %rdi
callq 0x9c64
leaq 0x188(%rsp), %rdi
callq 0xa31c
xorl %ebx, %ebx
movl %ebx, %eax
addq $0x3f8, %rsp            # imm = 0x3F8
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
movq 0x22a5b(%rip), %rdi     # 0x2bfb0
leaq 0x17c8b(%rip), %rsi     # 0x211e7
callq 0x5450
movq (%rbx), %rsi
movq %rax, %rdi
callq 0x5450
leaq 0x17d07(%rip), %rsi     # 0x2127a
movq %rax, %rdi
callq 0x5450
leaq 0x17c6d(%rip), %rsi     # 0x211ef
movq %rax, %rdi
callq 0x5450
leaq 0x17c73(%rip), %rsi     # 0x21204
movq %rax, %rdi
callq 0x5450
leaq 0x17ca4(%rip), %rsi     # 0x21244
movq %rax, %rdi
callq 0x5450
leaq 0x17ca9(%rip), %rsi     # 0x21258
movq %rax, %rdi
callq 0x5450
leaq 0x17cbe(%rip), %rsi     # 0x2127c
movq %rax, %rdi
callq 0x5450
leaq 0x17ce1(%rip), %rsi     # 0x212ae
movq %rax, %rdi
callq 0x5450
leaq 0x17d05(%rip), %rsi     # 0x212e1
movq %rax, %rdi
callq 0x5450
pushq $0x1
popq %rdi
callq 0x54f0
jmp 0x96aa
movq %rax, %rbx
leaq 0x368(%rsp), %rdi
jmp 0x9642
jmp 0x977d
jmp 0x96aa
movq %rax, %rbx
leaq 0x2a8(%rsp), %rdi
jmp 0x962d
movq %rax, %rbx
leaq 0x2d8(%rsp), %rdi
jmp 0x962d
movq %rax, %rbx
leaq 0x308(%rsp), %rdi
callq 0x9c64
jmp 0x96bc
movq %rax, %rbx
leaq 0x338(%rsp), %rdi
callq 0x9c64
jmp 0x9780
jmp 0x977d
jmp 0x977d
jmp 0x977d
jmp 0x977d
jmp 0x977d
jmp 0x977d
movq %rax, %rbx
leaq 0x398(%rsp), %rdi
callq 0x9c64
jmp 0x971c
jmp 0x977d
jmp 0x96d0
jmp 0x977d
jmp 0x977d
jmp 0x977d
jmp 0x977d
jmp 0x96b9
jmp 0x96d0
jmp 0x96aa
jmp 0x977d
jmp 0x977d
movq %rax, %rbx
jmp 0x974c
jmp 0x977d
jmp 0x96d0
movq %rax, %rbx
leaq 0x58(%rsp), %rdi
callq 0xa3b0
jmp 0x9780
jmp 0x977d
movq %rax, %rbx
jmp 0x971c
jmp 0x977d
jmp 0x977d
jmp 0x977d
jmp 0x977d
jmp 0x9732
jmp 0x9732
movq %rax, %rbx
leaq 0x3c8(%rsp), %rdi
callq 0x9c64
jmp 0x9707
movq %rax, %rbx
jmp 0x970f
movq %rax, %rbx
movq %r12, %rdi
callq 0x9c64
leaq 0x128(%rsp), %rdi
callq 0xa240
leaq 0xe0(%rsp), %rdi
callq 0xb0b6
jmp 0x974c
jmp 0x9732
movq %rax, %rbx
jmp 0x9742
movq %rax, %rbx
leaq 0x128(%rsp), %rdi
callq 0xb0b6
leaq 0x58(%rsp), %rdi
callq 0xa3b0
leaq 0x1e8(%rsp), %rdi
callq 0xa254
leaq 0x218(%rsp), %rdi
callq 0xa240
leaq 0xf8(%rsp), %rdi
callq 0xa2b8
jmp 0x9780
jmp 0x977d
jmp 0x977d
jmp 0x977d
jmp 0x977d
movq %rax, %rbx
leaq 0x248(%rsp), %rdi
callq 0x9c64
leaq 0x278(%rsp), %rdi
callq 0x9c64
leaq 0x1b8(%rsp), %rdi
callq 0x9c64
leaq 0x158(%rsp), %rdi
callq 0x9c64
leaq 0x188(%rsp), %rdi
callq 0xa31c
movq %rbx, %rdi
callq 0x5790
nop