// File: /workspace/github_cpp_makefile_star2_O3/CMU-SAFARI[P]ramulator/src/Memory.h
// Function: ramulator::Memory<ramulator::DDR3, ramulator::Controller>::init_mapping_with_file(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>)
void init_mapping_with_file(string filename){
        ifstream file(filename);
        assert(file.good() && "Bad mapping file");
        // possible line types are:
        // 0. Empty line
        // 1. Direct bit assignment   : component N   = x
        // 2. Direct range assignment : component N:M = x:y
        // 3. XOR bit assignment      : component N   = x y z ...
        // 4. Comment line            : # comment here
        string line;
        char delim[] = " \t";
        while (getline(file, line)) {
            short capture_flags = 0;
            int level = -1;
            int target_bit = -1, target_bit2 = -1;
            int source_bit = -1, source_bit2 = -1;
            // cout << "Processing: " << line << endl;
            bool is_range = false;
            while (true) { // process next word
                size_t start = line.find_first_not_of(delim);
                if (start == string::npos) // no more words
                    break;
                size_t end = line.find_first_of(delim, start);
                string word = line.substr(start, end - start);
                
                if (word.at(0) == '#')// starting a comment
                    break;
                
                size_t col_index;
                int source_min, target_min, target_max;
                switch (capture_flags){
                    case 0: // capturing the component name
                        // fetch component level from channel spec
                        for (int i = 0; i < int(T::Level::MAX); i++)
                            if (word.find(T::level_str[i]) != string::npos) {
                                level = i;
                                capture_flags ++;
                            }
                        break;

                    case 1: // capturing target bit(s)
                        col_index = word.find(":");
                        if ( col_index != string::npos ){
                            target_bit2 = stoi(word.substr(col_index+1));
                            word = word.substr(0,col_index);
                            is_range = true;
                        }
                        target_bit = stoi(word);
                        capture_flags ++;
                        break;

                    case 2: //this should be the delimiter
                        assert(word.find("=") != string::npos);
                        capture_flags ++;
                        break;

                    case 3:
                        if (is_range){
                            col_index = word.find(":");
                            source_bit  = stoi(word.substr(0,col_index));
                            source_bit2 = stoi(word.substr(col_index+1));
                            assert(source_bit2 - source_bit == target_bit2 - target_bit);
                            source_min = min(source_bit, source_bit2);
                            target_min = min(target_bit, target_bit2);
                            target_max = max(target_bit, target_bit2);
                            while (target_min <= target_max){
                                mapping_scheme[level][target_min].push_back(source_min);
                                // cout << target_min << " <- " << source_min << endl;
                                source_min ++;
                                target_min ++;
                            }
                        }
                        else {
                            source_bit = stoi(word);
                            mapping_scheme[level][target_bit].push_back(source_bit);
                        }
                }
                if (end == string::npos) { // this is the last word
                    break;
                }
                line = line.substr(end);
            }
        }
        if (dump_mapping)
            dump_mapping_scheme();
    }

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x2a8, %rsp            # imm = 0x2A8
movq %rdi, %r14
leaq 0xa0(%rsp), %rbx
movq %rbx, %rdi
movl $0x8, %edx
callq 0xb470
movq (%rbx), %rax
movq -0x18(%rax), %rax
cmpl $0x0, 0xc0(%rsp,%rax)
jne 0x2670b
leaq 0x80(%rsp), %rdx
movq %rdx, -0x10(%rdx)
movq $0x0, -0x8(%rdx)
xorl %ecx, %ecx
movb %cl, (%rdx)
leaq 0x4(%rsp), %r13
movb %cl, 0x2(%r13)
movw $0x920, (%r13)          # imm = 0x920
movq %r14, 0x90(%rsp)
leaq 0xb50(%r14), %rcx
movq %rcx, 0x68(%rsp)
leaq 0x70(%rsp), %r12
leaq 0x10(%rsp), %r14
leaq 0x17a4ab(%rip), %rcx    # 0x1a0450
addq $0x8, %rcx
movq %rcx, 0x98(%rsp)
leaq (%rsp,%rax), %rdi
addq $0xa0, %rdi
movl $0xa, %esi
callq 0xb2c0
movsbl %al, %edx
leaq 0xa0(%rsp), %rdi
movq %r12, %rsi
callq 0xb540
movq (%rax), %rcx
movq -0x18(%rcx), %rcx
testb $0x5, 0x20(%rax,%rcx)
jne 0x265ec
movl $0xffffffff, %eax       # imm = 0xFFFFFFFF
movq %rax, 0x38(%rsp)
movl $0x0, (%rsp)
movl $0xffffffff, %eax       # imm = 0xFFFFFFFF
movq %rax, 0x60(%rsp)
movl $0xffffffff, %ebp       # imm = 0xFFFFFFFF
xorl %r15d, %r15d
movq %r13, %rdi
callq 0xb180
movq %r12, %rdi
movq %r13, %rsi
xorl %edx, %edx
movq %rax, %rcx
callq 0xb4c0
cmpq $-0x1, %rax
je 0x265db
movq %rax, %rbx
movq %r13, %rdi
callq 0xb180
movq %r12, %rdi
movq %r13, %rsi
movq %rbx, %rdx
movq %rax, %rcx
callq 0xb400
movq %r12, %rsi
movq %rax, %r12
movq %rax, %rcx
subq %rbx, %rcx
leaq 0x40(%rsp), %rdi
movq %rbx, %rdx
callq 0xb310
cmpq $0x0, 0x48(%rsp)
je 0x26643
movq 0x40(%rsp), %r13
cmpb $0x23, (%r13)
jne 0x26089
xorl %ebx, %ebx
leaq 0x4(%rsp), %r13
jmp 0x26592
cmpw $0x3, %r15w
ja 0x2653d
movzwl %r15w, %eax
leaq 0x124031(%rip), %rcx    # 0x14a0d0
movslq (%rcx,%rax,4), %rax
addq %rcx, %rax
jmpq *%rax
movq 0x98(%rsp), %rbx
xorl %r13d, %r13d
leaq 0x40(%rsp), %r14
movq -0x8(%rbx), %rsi
movq (%rbx), %rcx
movq %r14, %rdi
xorl %edx, %edx
callq 0xb500
xorl %ecx, %ecx
cmpq $-0x1, %rax
setne %cl
cmovnel %r13d, %ebp
addl %ecx, %r15d
incq %r13
addq $0x20, %rbx
cmpq $0x5, %r13
jne 0x260b8
leaq 0x4(%rsp), %r13
jmp 0x26313
movl $0x1, %ecx
leaq 0x40(%rsp), %rdi
leaq 0x124266(%rip), %rsi    # 0x14a367
xorl %edx, %edx
callq 0xb500
movw $0x3, %r15w
cmpq $-0x1, %rax
leaq 0x4(%rsp), %r13
jne 0x26542
jmp 0x26655
testb $0x1, (%rsp)
je 0x26425
movl $0x1, %ecx
leaq 0x40(%rsp), %rbx
movq %rbx, %rdi
leaq 0x125a22(%rip), %rsi    # 0x14bb61
xorl %edx, %edx
callq 0xb500
movq %rax, %r13
movq %r14, %rdi
movq %rbx, %rsi
xorl %edx, %edx
movq %rax, %rcx
callq 0xb310
movq 0x10(%rsp), %r14
callq 0xb050
movq %rax, %r15
movl (%rax), %eax
movl %eax, (%rsp)
movl $0x0, (%r15)
movq %r14, %rdi
leaq 0x8(%rsp), %rsi
movl $0xa, %edx
callq 0xb3b0
cmpq %r14, 0x8(%rsp)
je 0x266f3
movq %rax, %rbx
addq $-0x80000000, %rax      # imm = 0x80000000
movabsq $-0x100000000, %rcx     # imm = 0xFFFFFFFF00000000
cmpq %rcx, %rax
jb 0x266ff
movl (%r15), %eax
cmpl $0x22, %eax
je 0x266ff
testl %eax, %eax
leaq 0x10(%rsp), %r14
jne 0x261c6
movl (%rsp), %eax
movl %eax, (%r15)
movq 0x10(%rsp), %rdi
leaq 0x20(%rsp), %rax
cmpq %rax, %rdi
je 0x261e2
movq 0x20(%rsp), %rsi
incq %rsi
callq 0xb2f0
incq %r13
movq %r14, %rdi
leaq 0x40(%rsp), %rsi
movq %r13, %rdx
movq $-0x1, %rcx
callq 0xb310
movq 0x10(%rsp), %r14
movl (%r15), %eax
movl %eax, (%rsp)
movl $0x0, (%r15)
movq %r14, %rdi
leaq 0x8(%rsp), %rsi
movl $0xa, %edx
callq 0xb3b0
cmpq %r14, 0x8(%rsp)
je 0x266db
movq %rax, %r13
addq $-0x80000000, %rax      # imm = 0x80000000
movabsq $-0x100000000, %rcx     # imm = 0xFFFFFFFF00000000
cmpq %rcx, %rax
jb 0x266e7
movl (%r15), %eax
cmpl $0x22, %eax
je 0x266e7
testl %eax, %eax
jne 0x2625d
movl (%rsp), %eax
movl %eax, (%r15)
movq 0x10(%rsp), %rdi
leaq 0x20(%rsp), %rax
cmpq %rax, %rdi
je 0x26279
movq 0x20(%rsp), %rsi
incq %rsi
callq 0xb2f0
movl %r13d, %eax
subl %ebx, %eax
movq 0x60(%rsp), %rdx
movl %edx, %ecx
movq 0x38(%rsp), %rsi
subl %esi, %ecx
cmpl %ecx, %eax
jne 0x266bc
cmpl %ebx, %r13d
cmovll %r13d, %ebx
cmpl %esi, %edx
movl %esi, %r14d
cmovll %edx, %r14d
movl %edx, %r15d
cmovll %esi, %r15d
incl %r15d
leaq 0x4(%rsp), %r13
movl %ebp, 0x10(%rsp)
movq 0x68(%rsp), %rdi
leaq 0x10(%rsp), %rsi
callq 0x274f8
movl %r14d, 0x8(%rsp)
movq %rax, %rdi
leaq 0x8(%rsp), %rsi
callq 0x2755e
movl %ebx, 0x34(%rsp)
movq 0x8(%rax), %rsi
cmpq 0x10(%rax), %rsi
je 0x262f2
movl %ebx, (%rsi)
addq $0x4, %rsi
movq %rsi, 0x8(%rax)
jmp 0x262ff
movq %rax, %rdi
leaq 0x34(%rsp), %rdx
callq 0x27c64
incl %ebx
incl %r14d
cmpl %r14d, %r15d
jne 0x262b3
movw $0x3, %r15w
movb $0x1, %al
movl %eax, (%rsp)
leaq 0x10(%rsp), %r14
jmp 0x26542
movl $0x1, %ecx
leaq 0x40(%rsp), %rbx
movq %rbx, %rdi
leaq 0x125830(%rip), %rsi    # 0x14bb61
xorl %edx, %edx
callq 0xb500
cmpq $-0x1, %rax
je 0x264d3
movq %rax, %r15
leaq 0x1(%rax), %rdx
movq %r14, %rdi
movq %rbx, %rsi
movq $-0x1, %rcx
callq 0xb310
movq 0x10(%rsp), %r13
callq 0xb050
movq %rax, %rbx
movl (%rax), %r14d
movl $0x0, (%rax)
movq %r13, %rdi
leaq 0x8(%rsp), %rsi
movl $0xa, %edx
callq 0xb3b0
cmpq %r13, 0x8(%rsp)
je 0x2668c
movq %rax, 0x60(%rsp)
addq $-0x80000000, %rax      # imm = 0x80000000
movabsq $-0x100000000, %rcx     # imm = 0xFFFFFFFF00000000
cmpq %rcx, %rax
jb 0x26698
movl (%rbx), %eax
cmpl $0x22, %eax
je 0x26698
testl %eax, %eax
leaq 0x40(%rsp), %r13
jne 0x263c3
movl %r14d, (%rbx)
movq 0x10(%rsp), %rdi
leaq 0x20(%rsp), %rax
cmpq %rax, %rdi
je 0x263df
movq 0x20(%rsp), %rsi
incq %rsi
callq 0xb2f0
leaq 0x10(%rsp), %r14
movq %r14, %rdi
movq %r13, %rsi
xorl %edx, %edx
movq %r15, %rcx
callq 0xb310
movq %r13, %rdi
movq %r14, %rsi
callq 0xb370
movq 0x10(%rsp), %rdi
leaq 0x20(%rsp), %rax
cmpq %rax, %rdi
je 0x2641b
movq 0x20(%rsp), %rsi
incq %rsi
callq 0xb2f0
movb $0x1, %al
movl %eax, (%rsp)
jmp 0x264db
callq 0xb050
movq %rax, %rbx
movq %r14, %rsi
movl (%rax), %r14d
movl $0x0, (%rax)
movq %r13, %rdi
movl $0xa, %edx
callq 0xb3b0
cmpq %r13, 0x10(%rsp)
je 0x266b0
movq %rax, %r15
addq $-0x80000000, %rax      # imm = 0x80000000
movabsq $-0x100000000, %rcx     # imm = 0xFFFFFFFF00000000
cmpq %rcx, %rax
leaq 0x4(%rsp), %r13
jb 0x266a4
movl (%rbx), %eax
cmpl $0x22, %eax
je 0x266a4
testl %eax, %eax
jne 0x26484
movl %r14d, (%rbx)
movl %ebp, 0x10(%rsp)
movq 0x68(%rsp), %rdi
leaq 0x10(%rsp), %r14
movq %r14, %rsi
callq 0x274f8
movq 0x38(%rsp), %rcx
movl %ecx, 0x8(%rsp)
movq %rax, %rdi
leaq 0x8(%rsp), %rsi
callq 0x2755e
movl %r15d, 0x34(%rsp)
movq 0x8(%rax), %rsi
cmpq 0x10(%rax), %rsi
je 0x265bd
movl %r15d, (%rsi)
addq $0x4, %rsi
movq %rsi, 0x8(%rax)
jmp 0x265ca
callq 0xb050
movq %rax, %rbx
movq 0x40(%rsp), %r15
movl (%rbx), %r13d
movl $0x0, (%rbx)
movq %r15, %rdi
movq %r14, %rsi
movl $0xa, %edx
callq 0xb3b0
cmpq %r15, 0x10(%rsp)
je 0x26680
leaq -0x80000000(%rax), %rdx
movabsq $-0x100000000, %rcx     # imm = 0xFFFFFFFF00000000
cmpq %rcx, %rdx
jb 0x26674
movq %rax, %rcx
movl (%rbx), %eax
cmpl $0x22, %eax
je 0x26674
movq %rcx, 0x38(%rsp)
testl %eax, %eax
jne 0x26538
movl %r13d, (%rbx)
movw $0x2, %r15w
leaq 0x4(%rsp), %r13
cmpq $-0x1, %r12
je 0x26590
movq %r14, %rdi
leaq 0x70(%rsp), %rbx
movq %rbx, %rsi
movq %r12, %rdx
movq $-0x1, %rcx
callq 0xb310
movq %rbx, %rdi
movq %r14, %rsi
callq 0xb370
movq 0x10(%rsp), %rdi
leaq 0x20(%rsp), %rax
cmpq %rax, %rdi
movq %rbx, %r12
je 0x2658c
movq 0x20(%rsp), %rsi
incq %rsi
callq 0xb2f0
movb $0x1, %bl
jmp 0x26597
xorl %ebx, %ebx
leaq 0x70(%rsp), %r12
movq 0x40(%rsp), %rdi
leaq 0x50(%rsp), %rax
cmpq %rax, %rdi
je 0x265b3
movq 0x50(%rsp), %rsi
incq %rsi
callq 0xb2f0
testb %bl, %bl
jne 0x2600e
jmp 0x265db
movq %rax, %rdi
leaq 0x34(%rsp), %rdx
callq 0x27c64
movw $0x3, %r15w
movl $0x0, (%rsp)
jmp 0x26542
movq 0xa0(%rsp), %rax
movq -0x18(%rax), %rax
jmp 0x25fb1
movq 0x90(%rsp), %rdi
cmpb $0x1, 0xc61(%rdi)
jne 0x26602
callq 0x275c4
movq 0x70(%rsp), %rdi
leaq 0x80(%rsp), %rax
cmpq %rax, %rdi
je 0x26624
movq 0x80(%rsp), %rsi
incq %rsi
callq 0xb2f0
leaq 0xa0(%rsp), %rdi
callq 0xb0d0
addq $0x2a8, %rsp            # imm = 0x2A8
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
leaq 0x125281(%rip), %rdi    # 0x14b8cb
xorl %esi, %esi
xorl %edx, %edx
xorl %eax, %eax
callq 0xb3f0
leaq 0x12521b(%rip), %rdi    # 0x14b877
leaq 0x124b8e(%rip), %rsi    # 0x14b1f1
leaq 0x12518b(%rip), %rcx    # 0x14b7f5
movl $0x194, %edx            # imm = 0x194
callq 0xb200
leaq 0x125294(%rip), %rdi    # 0x14b90f
callq 0xb3d0
leaq 0x125288(%rip), %rdi    # 0x14b90f
callq 0xb1f0
leaq 0x12527c(%rip), %rdi    # 0x14b90f
callq 0xb1f0
leaq 0x125270(%rip), %rdi    # 0x14b90f
callq 0xb3d0
leaq 0x125264(%rip), %rdi    # 0x14b90f
callq 0xb3d0
leaq 0x125258(%rip), %rdi    # 0x14b90f
callq 0xb1f0
leaq 0x1251d3(%rip), %rdi    # 0x14b896
leaq 0x124b27(%rip), %rsi    # 0x14b1f1
leaq 0x125124(%rip), %rcx    # 0x14b7f5
movl $0x19d, %edx            # imm = 0x19D
callq 0xb200
leaq 0x12522d(%rip), %rdi    # 0x14b90f
callq 0xb1f0
leaq 0x125221(%rip), %rdi    # 0x14b90f
callq 0xb3d0
leaq 0x125215(%rip), %rdi    # 0x14b90f
callq 0xb1f0
leaq 0x125209(%rip), %rdi    # 0x14b90f
callq 0xb3d0
leaq 0x1250c1(%rip), %rdi    # 0x14b7d3
leaq 0x124ad8(%rip), %rsi    # 0x14b1f1
leaq 0x1250d5(%rip), %rcx    # 0x14b7f5
movl $0x162, %edx            # imm = 0x162
callq 0xb200
jmp 0x26798
jmp 0x2679f
jmp 0x2679f
jmp 0x2679f
jmp 0x2679f
jmp 0x2679f
jmp 0x2679f
jmp 0x2679f
jmp 0x2673c
movq %rax, %r12
cmpl $0x0, (%r15)
jne 0x26765
movl (%rsp), %eax
movl %eax, (%r15)
jmp 0x26765
movq %rax, %r12
cmpl $0x0, (%rbx)
jne 0x267a2
movl %r14d, (%rbx)
jmp 0x267a2
movq %rax, %r12
cmpl $0x0, (%rbx)
jne 0x26765
movl %r14d, (%rbx)
movq 0x10(%rsp), %rdi
leaq 0x20(%rsp), %rax
cmpq %rax, %rdi
je 0x267a2
movq 0x20(%rsp), %rsi
incq %rsi
callq 0xb2f0
jmp 0x267a2
jmp 0x26798
movq %rax, %r12
cmpl $0x0, (%rbx)
jne 0x267a2
movl %r13d, (%rbx)
jmp 0x267a2
jmp 0x2679f
jmp 0x2679f
jmp 0x2679f
movq %rax, %r12
jmp 0x267be
jmp 0x2679f
movq %rax, %r12
movq 0x40(%rsp), %rdi
leaq 0x50(%rsp), %rax
cmpq %rax, %rdi
je 0x267be
movq 0x50(%rsp), %rsi
incq %rsi
callq 0xb2f0
movq 0x70(%rsp), %rdi
leaq 0x80(%rsp), %rax
cmpq %rax, %rdi
je 0x267e0
movq 0x80(%rsp), %rsi
incq %rsi
callq 0xb2f0
leaq 0xa0(%rsp), %rdi
callq 0xb0d0
movq %r12, %rdi
callq 0xb510
nop