// File: CMU-SAFARI[P]ramulator/src/Memory.h
// Function: ramulator::Memory<ramulator::DDR3, ramulator::Controller>::apply_mapping(long, std::vector<int, std::allocator<int>>&)
void apply_mapping(long addr, std::vector<int>& addr_vec){
        int *sz = spec->org_entry.count;
        int addr_total_bits = sizeof(addr_vec)*8;
        int addr_bits [int(T::Level::MAX)];
        for (int i = 0 ; i < int(T::Level::MAX) ; i ++)
        {
            if ( i != int(T::Level::Row))
            {
                addr_bits[i] = calc_log2(sz[i]);
                addr_total_bits -= addr_bits[i];
            }
        }
        // Row address is an integer.
        addr_bits[int(T::Level::Row)] = min((int)sizeof(int)*8, max(addr_total_bits, calc_log2(sz[int(T::Level::Row)])));

        // printf("Address: %lx => ",addr);
        for (unsigned int lvl = 0; lvl < int(T::Level::MAX); lvl++)
        {
            unsigned int lvl_bits = addr_bits[lvl];
            addr_vec[lvl] = 0;
            for (unsigned int bitindex = 0 ; bitindex < lvl_bits ; bitindex++){
                bool bitvalue = false;
                for (MapSrcVector::iterator it = mapping_scheme[lvl][bitindex].begin() ;
                    it != mapping_scheme[lvl][bitindex].end(); it ++)
                {
                    bitvalue = bitvalue xor get_bit_at(addr, *it);
                }
                addr_vec[lvl] |= (bitvalue << bitindex);
            }
            // printf("%s: %x, ",T::level_str[lvl].c_str(),addr_vec[lvl]);
        }
        // printf("\n");
    }

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0xa0, %rsp
movq %rdi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
movq %rdx, -0x18(%rbp)
movq -0x8(%rbp), %rax
movq %rax, -0x80(%rbp)
movq 0xc20(%rax), %rax
addq $0x2724, %rax           # imm = 0x2724
addq $0x8, %rax
movq %rax, -0x20(%rbp)
movl $0xc0, -0x24(%rbp)
movl $0x0, -0x44(%rbp)
cmpl $0x5, -0x44(%rbp)
jge 0x477c9
cmpl $0x3, -0x44(%rbp)
je 0x477bc
movq -0x80(%rbp), %rdi
movq -0x20(%rbp), %rax
movslq -0x44(%rbp), %rcx
movl (%rax,%rcx,4), %esi
callq 0x37c20
movl %eax, %ecx
movslq -0x44(%rbp), %rax
movl %ecx, -0x40(%rbp,%rax,4)
movslq -0x44(%rbp), %rax
movl -0x40(%rbp,%rax,4), %ecx
movl -0x24(%rbp), %eax
subl %ecx, %eax
movl %eax, -0x24(%rbp)
jmp 0x477be
movl -0x44(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x44(%rbp)
jmp 0x47782
movq -0x80(%rbp), %rdi
movl $0x20, -0x48(%rbp)
movq -0x20(%rbp), %rax
movl 0xc(%rax), %esi
callq 0x37c20
movl %eax, -0x4c(%rbp)
leaq -0x24(%rbp), %rdi
leaq -0x4c(%rbp), %rsi
callq 0x26070
movq %rax, %rsi
leaq -0x48(%rbp), %rdi
callq 0x3a960
movl (%rax), %eax
movl %eax, -0x34(%rbp)
movl $0x0, -0x50(%rbp)
cmpl $0x5, -0x50(%rbp)
jae 0x4795e
movl -0x50(%rbp), %eax
movl -0x40(%rbp,%rax,4), %eax
movl %eax, -0x54(%rbp)
movq -0x18(%rbp), %rdi
movl -0x50(%rbp), %eax
movl %eax, %esi
callq 0x384f0
movl $0x0, (%rax)
movl $0x0, -0x58(%rbp)
movl -0x58(%rbp), %eax
cmpl -0x54(%rbp), %eax
jae 0x4794e
movq -0x80(%rbp), %rdi
movb $0x0, -0x59(%rbp)
addq $0xb50, %rdi            # imm = 0xB50
leaq -0x50(%rbp), %rsi
callq 0x47bf0
movq %rax, %rdi
leaq -0x58(%rbp), %rsi
callq 0x47cd0
movq %rax, %rdi
callq 0x3da10
movq %rax, -0x68(%rbp)
movq -0x80(%rbp), %rdi
addq $0xb50, %rdi            # imm = 0xB50
leaq -0x50(%rbp), %rsi
callq 0x47bf0
movq %rax, %rdi
leaq -0x58(%rbp), %rsi
callq 0x47cd0
movq %rax, %rdi
callq 0x3d860
movq %rax, -0x70(%rbp)
leaq -0x68(%rbp), %rdi
leaq -0x70(%rbp), %rsi
callq 0x3dfb0
testb $0x1, %al
jne 0x478b2
jmp 0x47915
movb -0x59(%rbp), %al
andb $0x1, %al
movzbl %al, %eax
movl %eax, -0x84(%rbp)
movq -0x10(%rbp), %rax
movq %rax, -0x90(%rbp)
leaq -0x68(%rbp), %rdi
callq 0x3dde0
movq -0x80(%rbp), %rdi
movq -0x90(%rbp), %rsi
movl (%rax), %edx
callq 0x47db0
movb %al, %cl
movl -0x84(%rbp), %eax
andb $0x1, %cl
movzbl %cl, %ecx
xorl %ecx, %eax
cmpl $0x0, %eax
setne %al
andb $0x1, %al
movb %al, -0x59(%rbp)
leaq -0x68(%rbp), %rdi
xorl %esi, %esi
callq 0x3dff0
movq %rax, -0x78(%rbp)
jmp 0x47873
movb -0x59(%rbp), %al
andb $0x1, %al
movzbl %al, %eax
movl -0x58(%rbp), %ecx
shll %cl, %eax
movl %eax, -0x94(%rbp)
movq -0x18(%rbp), %rdi
movl -0x50(%rbp), %eax
movl %eax, %esi
callq 0x384f0
movl -0x94(%rbp), %ecx
orl (%rax), %ecx
movl %ecx, (%rax)
movl -0x58(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x58(%rbp)
jmp 0x47837
jmp 0x47950
movl -0x50(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x50(%rbp)
jmp 0x47808
addq $0xa0, %rsp
popq %rbp
retq
nopw (%rax,%rax)