// File: 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
subq $0x980, %rsp            # imm = 0x980
movl $0x0, -0x4(%rbp)
movl %edi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
cmpl $0x3, -0x8(%rbp)
jne 0x9675
movq -0x10(%rbp), %rax
movq 0x8(%rax), %rdi
leaq 0x1a71(%rip), %rsi      # 0xb0bf
callq 0x3350
cmpl $0x0, %eax
je 0x96df
movq -0x10(%rbp), %rax
movq 0x8(%rax), %rdi
leaq 0x1a57(%rip), %rsi      # 0xb0c2
callq 0x3350
cmpl $0x0, %eax
je 0x96df
movq 0x796c(%rip), %rdi      # 0x10fe8
leaq 0x1a42(%rip), %rsi      # 0xb0c5
callq 0x3240
movq %rax, %rdi
movq 0x7906(%rip), %rsi      # 0x10f98
callq 0x3270
movq %rax, %rdi
leaq 0x1a48(%rip), %rsi      # 0xb0e9
callq 0x3240
movq %rax, %rdi
movq 0x78e8(%rip), %rsi      # 0x10f98
callq 0x3270
movq %rax, %rdi
leaq 0x1a50(%rip), %rsi      # 0xb10f
callq 0x3240
movq %rax, %rdi
movq 0x78ca(%rip), %rsi      # 0x10f98
callq 0x3270
movl $0xffffffff, -0x4(%rbp) # imm = 0xFFFFFFFF
jmp 0x9ee6
movq -0x10(%rbp), %rax
movq 0x8(%rax), %rdi
leaq 0x19d1(%rip), %rsi      # 0xb0bf
callq 0x3350
testl %eax, %eax
leaq 0x1909(%rip), %rcx      # 0xb005
leaq 0x192f(%rip), %rax      # 0xb032
cmoveq %rcx, %rax
movq %rax, -0x8a0(%rbp)
leaq -0x431(%rbp), %rdi
movq %rdi, -0x898(%rbp)
callq 0x3400
movq -0x8a0(%rbp), %rsi
movq -0x898(%rbp), %rdx
leaq -0x430(%rbp), %rdi
callq 0x3320
jmp 0x973d
leaq -0x469(%rbp), %rdi
movq %rdi, -0x8a8(%rbp)
callq 0x3400
movq -0x8a8(%rbp), %rdx
leaq 0x19d5(%rip), %rsi      # 0xb133
leaq -0x468(%rbp), %rdi
callq 0x3320
jmp 0x976c
leaq -0x410(%rbp), %rdi
leaq -0x430(%rbp), %rsi
leaq -0x468(%rbp), %rdx
callq 0x5b20
jmp 0x9788
leaq -0x468(%rbp), %rdi
callq 0x31c0
leaq -0x469(%rbp), %rdi
callq 0x3280
leaq -0x430(%rbp), %rdi
callq 0x31c0
leaq -0x431(%rbp), %rdi
callq 0x3280
movq -0x10(%rbp), %rax
movq 0x10(%rax), %rsi
leaq -0x678(%rbp), %rdi
movl $0x8, %edx
callq 0x3410
jmp 0x97d3
movq -0x678(%rbp), %rax
movq -0x18(%rax), %rax
leaq -0x678(%rbp,%rax), %rdi
callq 0x3130
movb %al, -0x8a9(%rbp)
jmp 0x97f3
movb -0x8a9(%rbp), %al
testb $0x1, %al
jne 0x9802
jmp 0x98ca
movq 0x77df(%rip), %rdi      # 0x10fe8
leaq 0x1935(%rip), %rsi      # 0xb145
callq 0x3240
jmp 0x9817
movl $0xffffffff, -0x4(%rbp) # imm = 0xFFFFFFFF
movl $0x1, -0x67c(%rbp)
jmp 0x9ece
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x440(%rbp)
movl %eax, -0x444(%rbp)
jmp 0x988b
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x440(%rbp)
movl %eax, -0x444(%rbp)
jmp 0x9873
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x440(%rbp)
movl %eax, -0x444(%rbp)
leaq -0x468(%rbp), %rdi
callq 0x31c0
leaq -0x469(%rbp), %rdi
callq 0x3280
leaq -0x430(%rbp), %rdi
callq 0x31c0
leaq -0x431(%rbp), %rdi
callq 0x3280
jmp 0x9f2e
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x440(%rbp)
movl %eax, -0x444(%rbp)
jmp 0x9f22
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x440(%rbp)
movl %eax, -0x444(%rbp)
jmp 0x9f16
leaq -0x6a0(%rbp), %rdi
callq 0x3340
leaq -0x6c0(%rbp), %rdi
callq 0x3340
leaq -0x6f0(%rbp), %rdi
callq 0x9f40
leaq -0x678(%rbp), %rdi
leaq -0x6a0(%rbp), %rsi
callq 0x3080
movq %rax, -0x8b8(%rbp)
jmp 0x990a
movq -0x8b8(%rbp), %rdi
movq (%rdi), %rax
movq -0x18(%rax), %rax
addq %rax, %rdi
callq 0x32c0
movb %al, -0x8b9(%rbp)
jmp 0x9928
movb -0x8b9(%rbp), %al
testb $0x1, %al
jne 0x9937
jmp 0x9da8
leaq -0x870(%rbp), %rdi
leaq -0x6a0(%rbp), %rsi
movl $0x8, %edx
callq 0x33c0
jmp 0x9951
leaq -0x890(%rbp), %rdi
callq 0x3340
leaq -0x870(%rbp), %rdi
leaq -0x890(%rbp), %rsi
callq 0x32e0
movq %rax, -0x8c8(%rbp)
jmp 0x9979
movq -0x8c8(%rbp), %rdi
movq (%rdi), %rax
movq -0x18(%rax), %rax
addq %rax, %rdi
callq 0x32c0
movb %al, -0x8c9(%rbp)
jmp 0x9997
movb -0x8c9(%rbp), %al
testb $0x1, %al
jne 0x99f5
jmp 0x99a3
movl $0x4, -0x67c(%rbp)
leaq -0x890(%rbp), %rdi
callq 0x31c0
jmp 0x9a0f
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x440(%rbp)
movl %eax, -0x444(%rbp)
jmp 0x9ef2
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x440(%rbp)
movl %eax, -0x444(%rbp)
leaq -0x890(%rbp), %rdi
callq 0x31c0
jmp 0x9d97
leaq -0x6f0(%rbp), %rdi
leaq -0x890(%rbp), %rsi
callq 0x9f60
jmp 0x9a0a
jmp 0x995d
xorl %eax, %eax
movl %eax, %esi
leaq -0x6f0(%rbp), %rdi
callq 0x9fd0
movq %rax, %rsi
leaq -0x6c0(%rbp), %rdi
callq 0x3030
jmp 0x9a30
leaq -0x6f0(%rbp), %rdi
movl $0x1, %esi
callq 0x9fd0
movq %rax, %rdi
xorl %eax, %eax
movl %eax, %esi
movl $0xa, %edx
callq 0x9ff0
movl %eax, -0x8d0(%rbp)
jmp 0x9a5a
movl -0x8d0(%rbp), %eax
movl %eax, -0x6c4(%rbp)
movl -0x6c4(%rbp), %eax
sarl $0x8, %eax
movl %eax, -0x6cc(%rbp)
movzbl -0x6c4(%rbp), %eax
movl %eax, -0x6d0(%rbp)
movl -0x6cc(%rbp), %esi
leaq -0x410(%rbp), %rdi
callq 0x5f90
movl %eax, -0x8d4(%rbp)
jmp 0x9a9c
movl -0x8d4(%rbp), %eax
movl %eax, -0x6d4(%rbp)
leaq 0x16b1(%rip), %rsi      # 0xb160
leaq -0x6c0(%rbp), %rdi
callq 0x6450
movb %al, -0x8d5(%rbp)
jmp 0x9ac3
movb -0x8d5(%rbp), %al
testb $0x1, %al
jne 0x9acf
jmp 0x9aeb
jmp 0x9bdb
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x440(%rbp)
movl %eax, -0x444(%rbp)
jmp 0x9d97
leaq 0x1670(%rip), %rsi      # 0xb162
leaq -0x6c0(%rbp), %rdi
callq 0x6450
movb %al, -0x8d6(%rbp)
jmp 0x9b06
movb -0x8d6(%rbp), %al
testb $0x1, %al
jne 0x9b12
jmp 0x9b8a
movl -0x6cc(%rbp), %esi
leaq -0x410(%rbp), %rdi
movl $0x1, %edx
callq 0x6910
jmp 0x9b2b
leaq -0x6f0(%rbp), %rdi
movl $0x2, %esi
callq 0x9fd0
movq %rax, %rdi
xorl %eax, %eax
movl %eax, %esi
movl $0xa, %edx
callq 0x9ff0
movl %eax, -0x8dc(%rbp)
jmp 0x9b55
movl -0x8dc(%rbp), %eax
movl %eax, -0x6c8(%rbp)
movl -0x6c8(%rbp), %eax
movb %al, %dl
movslq -0x6d4(%rbp), %rcx
leaq 0x76e9(%rip), %rax      # 0x11260
shlq $0x8, %rcx
addq %rcx, %rax
movslq -0x6d0(%rbp), %rcx
movb %dl, (%rax,%rcx)
jmp 0x9bd9
movq 0x7457(%rip), %rdi      # 0x10fe8
leaq 0x15cc(%rip), %rsi      # 0xb164
callq 0x3240
movq %rax, -0x8e8(%rbp)
jmp 0x9ba6
movq -0x8e8(%rbp), %rdi
leaq -0x6c0(%rbp), %rsi
callq 0x3220
movq %rax, -0x8f0(%rbp)
jmp 0x9bc2
movq -0x8f0(%rbp), %rdi
movq 0x73c8(%rip), %rsi      # 0x10f98
callq 0x3270
jmp 0x9bd7
jmp 0x9bd9
jmp 0x9bdb
movslq -0x6d4(%rbp), %rax
shlq $0x8, %rax
leaq 0x7673(%rip), %rcx      # 0x11260
addq %rax, %rcx
movslq -0x6d0(%rbp), %rax
movzbl (%rax,%rcx), %eax
movl %eax, -0x6d8(%rbp)
movl -0x6cc(%rbp), %esi
movq 0x73a2(%rip), %rdi      # 0x10fb0
callq 0x33e0
movq %rax, -0x8f8(%rbp)
jmp 0x9c1c
movq -0x8f8(%rbp), %rdi
movl $0x20, %esi
callq 0x32a0
movq %rax, -0x900(%rbp)
jmp 0x9c36
movq -0x900(%rbp), %rdi
movl -0x6d0(%rbp), %esi
callq 0x33e0
movq %rax, -0x908(%rbp)
jmp 0x9c51
movq -0x908(%rbp), %rdi
movl $0x20, %esi
callq 0x32a0
movq %rax, -0x910(%rbp)
jmp 0x9c6b
movq -0x910(%rbp), %rdi
movb -0x18(%rbp), %al
testb $0x1, %al
movl $0x4e, %eax
movl $0x48, %esi
cmovnel %eax, %esi
callq 0x32a0
movq %rax, -0x918(%rbp)
jmp 0x9c92
movq -0x918(%rbp), %rdi
movl $0x20, %esi
callq 0x32a0
movq %rax, -0x920(%rbp)
jmp 0x9cac
movq -0x920(%rbp), %rdi
movb -0x20(%rbp), %al
notb %al
movzbl %al, %ecx
andl $0x1, %ecx
movl %ecx, %eax
leal 0x46(,%rax,8), %esi
callq 0x32a0
movq %rax, -0x928(%rbp)
jmp 0x9cd5
movq -0x928(%rbp), %rdi
movl $0x20, %esi
callq 0x32a0
movq %rax, -0x930(%rbp)
jmp 0x9cef
movq -0x930(%rbp), %rdi
movl -0x6d4(%rbp), %esi
shll $0x8, %esi
movl -0x6d0(%rbp), %eax
orl %eax, %esi
callq 0x33e0
jmp 0x9d0e
leaq 0x144b(%rip), %rsi      # 0xb160
leaq -0x6c0(%rbp), %rdi
callq 0x6450
movb %al, -0x931(%rbp)
jmp 0x9d29
movb -0x931(%rbp), %al
testb $0x1, %al
jne 0x9d35
jmp 0x9d65
movq 0x7274(%rip), %rdi      # 0x10fb0
movl $0x20, %esi
callq 0x32a0
movq %rax, -0x940(%rbp)
jmp 0x9d4f
movq -0x940(%rbp), %rdi
movl -0x6d8(%rbp), %esi
callq 0x33e0
jmp 0x9d63
jmp 0x9d65
movq 0x7244(%rip), %rdi      # 0x10fb0
movq 0x7225(%rip), %rsi      # 0x10f98
callq 0x3270
jmp 0x9d7a
leaq -0x6f0(%rbp), %rdi
callq 0xa030
leaq -0x870(%rbp), %rdi
callq 0x3140
jmp 0x98ee
leaq -0x870(%rbp), %rdi
callq 0x3140
jmp 0x9ef2
movq 0x7201(%rip), %rdi      # 0x10fb0
movq 0x71e2(%rip), %rsi      # 0x10f98
callq 0x3270
movq %rax, -0x948(%rbp)
jmp 0x9dc4
movq -0x948(%rbp), %rdi
leaq 0x13a2(%rip), %rsi      # 0xb174
callq 0x3240
movq %rax, -0x950(%rbp)
jmp 0x9de0
movq -0x950(%rbp), %rdi
movq 0x71aa(%rip), %rsi      # 0x10f98
callq 0x3270
movq %rax, -0x958(%rbp)
jmp 0x9dfc
movq -0x958(%rbp), %rdi
leaq -0x410(%rbp), %rsi
callq 0x6210
movq %rax, -0x960(%rbp)
jmp 0x9e18
movq -0x960(%rbp), %rdi
movq 0x7172(%rip), %rsi      # 0x10f98
callq 0x3270
jmp 0x9e2d
movq 0x717c(%rip), %rdi      # 0x10fb0
movq 0x715d(%rip), %rsi      # 0x10f98
callq 0x3270
movq %rax, -0x968(%rbp)
jmp 0x9e49
movq -0x968(%rbp), %rdi
movl -0x1c(%rbp), %esi
callq 0x33e0
movq %rax, -0x970(%rbp)
jmp 0x9e61
movq -0x970(%rbp), %rdi
leaq 0x1311(%rip), %rsi      # 0xb180
callq 0x3240
movq %rax, -0x978(%rbp)
jmp 0x9e7d
movq -0x978(%rbp), %rdi
movq 0x710d(%rip), %rsi      # 0x10f98
callq 0x3270
jmp 0x9e92
leaq -0x678(%rbp), %rdi
callq 0x3090
jmp 0x9ea0
leaq -0x6f0(%rbp), %rdi
callq 0xa050
leaq -0x6c0(%rbp), %rdi
callq 0x31c0
leaq -0x6a0(%rbp), %rdi
callq 0x31c0
movl $0x0, -0x67c(%rbp)
leaq -0x678(%rbp), %rdi
callq 0x30b0
leaq -0x410(%rbp), %rdi
callq 0x5e30
movl -0x4(%rbp), %eax
addq $0x980, %rsp            # imm = 0x980
popq %rbp
retq
leaq -0x6f0(%rbp), %rdi
callq 0xa050
leaq -0x6c0(%rbp), %rdi
callq 0x31c0
leaq -0x6a0(%rbp), %rdi
callq 0x31c0
leaq -0x678(%rbp), %rdi
callq 0x30b0
leaq -0x410(%rbp), %rdi
callq 0x5e30
movq -0x440(%rbp), %rdi
callq 0x33f0
nopw (%rax,%rax)