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

	if (!((argc == 3) && (strcmp(argv[1], "-F") == 0 || strcmp(argv[1], "-L") == 0))) {
		cerr << "Usage: ./a.out [-F|-L] [INPUT FILE]" << endl
			<< "\t-F, use FIFO page replacement policy" << endl
			<< "\t-L, use LRU page replacment policy" << endl;
		return -1;
	}

	// create page table
	PageTable T(strcmp(argv[1], "-F") == 0 ? "FIFO" : "LRU");

	// open input file
	ifstream input(argv[2]);
	if (!input) {
		cerr << "Unable to open input file\n";
		return -1;
	}



	// input line looks like
	// R(ead) Address, or W(rite) Address Argument, separated by spaces. e.g.
	// R 245
	// W 5421 132
	string line, op;
	int addr, arg, pnum, offset, fnum, memval;
	vector<string> fields;
	while (getline(input, line)) {
		istringstream iss(line);
		for (string s; iss >> s; )
			fields.push_back(s);
		op = fields[0];
		addr = stoi(fields[1]);

		pnum = addr >> FRAME_SIZE_BITS;	// page number
		offset = addr & FRAME_OFFSET_MASK;	// page offset

		// access the page and get its frame number
		fnum = T[pnum];

		if (op == "R") {
		}
		else if (op == "W") {
			T.setDirty(pnum, true);
			arg = stoi(fields[2]);
			Memory[fnum][offset] = arg;
		}
		else
			cerr << "Bad operation: " << op << endl;

		memval = Memory[fnum][offset];

		// output format: page #, offset, TLB hit, page fault, physical address, value (only for reads)
		cout << pnum << ' ' << offset << ' ' << (!T.tlbMiss ? 'H' : 'N') << ' '
			<< (T.pageFault ? 'F' : 'N') << ' ' << ((fnum << FRAME_SIZE_BITS) | offset);
		// print memory content for reads
		if (op == "R")
			cout << ' ' << memval;
		cout << endl;

		fields.clear();
	}
	cout << endl << "Page Table:" << endl << T << endl;
	cout << endl << T.numPageFaults << " Page Faults" << endl;
	input.close();
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x818, %rsp            # imm = 0x818
cmpl $0x3, %edi
jne 0x3c1d
movq %rsi, %rbx
movq 0x8(%rsi), %rax
cmpb $0x2d, (%rax)
jne 0x3c1d
cmpb $0x46, 0x1(%rax)
jne 0x3c11
cmpb $0x0, 0x2(%rax)
je 0x3c7d
cmpb $0x4c, 0x1(%rax)
jne 0x3c1d
cmpb $0x0, 0x2(%rax)
je 0x3c7d
movq 0x43c4(%rip), %rdi      # 0x7fe8
leaq 0x1494(%rip), %rsi      # 0x50bf
callq 0x2210
movq %rax, %rdi
callq 0x2130
leaq 0x14a4(%rip), %rsi      # 0x50e3
movq %rax, %rdi
callq 0x2210
movq %rax, %rdi
callq 0x2130
leaq 0x14b3(%rip), %rsi      # 0x5109
movq %rax, %rdi
callq 0x2210
movq %rax, %rdi
callq 0x2130
pushq $-0x1
popq %rbx
movl %ebx, %eax
addq $0x818, %rsp            # imm = 0x818
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
cmpb $0x46, 0x1(%rax)
jne 0x3c9b
cmpb $0x0, 0x2(%rax)
leaq 0x1377(%rip), %rax      # 0x5005
leaq 0x139d(%rip), %rsi      # 0x5032
cmoveq %rax, %rsi
jmp 0x3ca2
leaq 0x1390(%rip), %rsi      # 0x5032
leaq -0x2b8(%rbp), %rdi
leaq -0xb0(%rbp), %rdx
callq 0x20f0
leaq 0x1471(%rip), %rsi      # 0x512d
leaq -0x438(%rbp), %rdi
leaq -0x58(%rbp), %rdx
callq 0x20f0
leaq -0x838(%rbp), %rdi
leaq -0x2b8(%rbp), %rsi
leaq -0x438(%rbp), %rdx
callq 0x2bc4
leaq -0x438(%rbp), %rdi
callq 0x2110
leaq -0x2b8(%rbp), %rdi
callq 0x2110
movq 0x10(%rbx), %rsi
leaq -0x2b8(%rbp), %rdi
pushq $0x8
popq %rdx
callq 0x2390
movq -0x2b8(%rbp), %rax
movq -0x18(%rax), %rax
testb $0x5, -0x298(%rbp,%rax)
je 0x3d41
movq 0x42bb(%rip), %rdi      # 0x7fe8
leaq 0x140b(%rip), %rsi      # 0x513f
callq 0x2210
pushq $-0x1
popq %rbx
jmp 0x4062
leaq -0xa0(%rbp), %rax
movq %rax, -0x10(%rax)
andq $0x0, -0x8(%rax)
leaq -0x48(%rbp), %rcx
movq %rcx, -0x10(%rcx)
andq $0x0, -0x8(%rcx)
xorl %edx, %edx
movb %dl, (%rax)
movb %dl, (%rcx)
xorps %xmm0, %xmm0
leaq -0x70(%rbp), %rbx
andq $0x0, 0x10(%rbx)
movaps %xmm0, (%rbx)
leaq -0x438(%rbp), %r12
leaq -0x90(%rbp), %r13
leaq -0x2b8(%rbp), %rdi
leaq -0xb0(%rbp), %rsi
callq 0x2070
movq (%rax), %rcx
movq -0x18(%rcx), %rcx
testb $0x5, 0x20(%rax,%rcx)
jne 0x3fcb
movq %r12, %rdi
leaq -0xb0(%rbp), %rsi
pushq $0x8
popq %rdx
callq 0x2350
leaq -0x80(%rbp), %rax
movq %rax, -0x90(%rbp)
andq $0x0, -0x88(%rbp)
movb $0x0, -0x80(%rbp)
movq %r12, %rdi
movq %r13, %rsi
callq 0x2280
movq (%rax), %rcx
movq -0x18(%rcx), %rcx
testb $0x5, 0x20(%rax,%rcx)
jne 0x3df5
movq %rbx, %rdi
movq %r13, %rsi
callq 0x4118
jmp 0x3dcf
movq %r13, %rdi
callq 0x2110
movq -0x70(%rbp), %rsi
leaq -0x58(%rbp), %rdi
callq 0x2170
movq -0x70(%rbp), %rdi
addq $0x20, %rdi
xorl %esi, %esi
pushq $0xa
popq %rdx
callq 0x4153
movl %eax, %r15d
movl %eax, %r14d
sarl $0x8, %r14d
leaq -0x838(%rbp), %rdi
movl %r14d, %esi
callq 0x2e84
movl %eax, -0x30(%rbp)
movq %rbx, %r12
movzbl %r15b, %ebx
leaq -0x58(%rbp), %rdi
leaq 0x1310(%rip), %rsi      # 0x515a
callq 0x3191
movslq -0x30(%rbp), %r15
movl %ebx, -0x2c(%rbp)
movl %ebx, %ecx
movq %rcx, -0x38(%rbp)
movq %r12, %rbx
leaq -0x438(%rbp), %r12
testb %al, %al
jne 0x3ee0
leaq -0x58(%rbp), %rdi
leaq 0x12e7(%rip), %rsi      # 0x515c
callq 0x3191
testb %al, %al
je 0x3eb9
leaq -0x838(%rbp), %rdi
movl %r14d, %esi
pushq $0x1
popq %rdx
callq 0x327c
movq -0x70(%rbp), %rdi
addq $0x40, %rdi
xorl %esi, %esi
pushq $0xa
popq %rdx
callq 0x4153
movq %r15, %rcx
shlq $0x8, %rcx
addq 0x40e0(%rip), %rcx      # 0x7f90
movq -0x38(%rbp), %rdx
movb %al, (%rdx,%rcx)
jmp 0x3ee0
movq 0x4128(%rip), %rdi      # 0x7fe8
leaq 0x1297(%rip), %rsi      # 0x515e
callq 0x2210
movq %rax, %rdi
leaq -0x58(%rbp), %rsi
callq 0x21f0
movq %rax, %rdi
callq 0x2130
shlq $0x8, %r15
addq 0x40a5(%rip), %r15      # 0x7f90
movq -0x38(%rbp), %rax
movzbl (%rax,%r15), %r15d
movq 0x40b5(%rip), %rdi      # 0x7fb0
movl %r14d, %esi
callq 0x2370
movq %rax, %rdi
pushq $0x20
popq %rsi
callq 0x2250
movq %rax, %rdi
movl -0x2c(%rbp), %esi
callq 0x2370
movq %rax, %rdi
pushq $0x20
popq %rsi
callq 0x2250
cmpb $0x0, -0x440(%rbp)
pushq $0x48
popq %rsi
pushq $0x4e
popq %rcx
cmovnel %ecx, %esi
movq %rax, %rdi
callq 0x2250
movq %rax, %rdi
pushq $0x20
popq %rsi
callq 0x2250
movzbl -0x448(%rbp), %ecx
xorl $0x1, %ecx
leal 0x46(,%rcx,8), %esi
movq %rax, %rdi
callq 0x2250
movq %rax, %rdi
pushq $0x20
popq %rsi
callq 0x2250
movl -0x30(%rbp), %esi
shll $0x8, %esi
addl -0x2c(%rbp), %esi
movq %rax, %rdi
callq 0x2370
leaq -0x58(%rbp), %rdi
leaq 0x11d3(%rip), %rsi      # 0x515a
callq 0x3191
testb %al, %al
je 0x3faa
movq 0x4019(%rip), %rdi      # 0x7fb0
pushq $0x20
popq %rsi
callq 0x2250
movq %rax, %rdi
movl %r15d, %esi
callq 0x2370
movq 0x3fff(%rip), %rdi      # 0x7fb0
callq 0x2130
movq %rbx, %rdi
callq 0x4174
movq %r12, %rdi
callq 0x2120
jmp 0x3d81
movq 0x3fde(%rip), %rdi      # 0x7fb0
callq 0x2130
leaq 0x1190(%rip), %rsi      # 0x516e
movq %rax, %rdi
callq 0x2210
movq %rax, %rdi
callq 0x2130
leaq -0x838(%rbp), %rsi
movq %rax, %rdi
callq 0x3063
movq %rax, %rdi
callq 0x2130
movq 0x3fa4(%rip), %rdi      # 0x7fb0
callq 0x2130
movl -0x444(%rbp), %esi
movq %rax, %rdi
callq 0x2370
leaq 0x1154(%rip), %rsi      # 0x517a
movq %rax, %rdi
callq 0x2210
movq %rax, %rdi
callq 0x2130
leaq -0x2b8(%rbp), %rdi
callq 0x2080
leaq -0x70(%rbp), %rdi
callq 0x4182
leaq -0x58(%rbp), %rdi
callq 0x2110
leaq -0xb0(%rbp), %rdi
callq 0x2110
xorl %ebx, %ebx
leaq -0x2b8(%rbp), %rdi
callq 0x20a0
leaq -0x838(%rbp), %rdi
callq 0x2db6
jmp 0x3c69
movq %rax, %rbx
jmp 0x40f7
movq %rax, %rbx
jmp 0x4103
movq %rax, %rbx
leaq -0x438(%rbp), %rdi
callq 0x2110
jmp 0x409d
movq %rax, %rbx
leaq -0x2b8(%rbp), %rdi
callq 0x2110
jmp 0x410f
movq %rax, %rbx
jmp 0x410f
jmp 0x40b4
jmp 0x40b4
movq %rax, %rbx
jmp 0x40d9
movq %rax, %rbx
jmp 0x40cd
movq %rax, %rbx
leaq -0x90(%rbp), %rdi
callq 0x2110
leaq -0x438(%rbp), %rdi
callq 0x2120
leaq -0x70(%rbp), %rdi
callq 0x4182
leaq -0x58(%rbp), %rdi
callq 0x2110
leaq -0xb0(%rbp), %rdi
callq 0x2110
leaq -0x2b8(%rbp), %rdi
callq 0x20a0
leaq -0x838(%rbp), %rdi
callq 0x2db6
movq %rbx, %rdi
callq 0x2380
nop