// File: /workspace/github_cpp_makefile_star2_O1/yiboyang[P]VirtualMemory/PageTable.cpp
// Function: PageTable::operator[](int)
int PageTable::operator[](const int pnum) {
	/*
	Get the number (index) of the frame in physical memory corresponding to given page number (pnum) in logical memory;
	this is done prior to every access to Memory. Page faults are resolved automatically.
	*/
	int fnum;
	pageFault = tlbMiss = false;
	if (tlb.contains(pnum)) // look in TLB first
		fnum = tlb[pnum];
	else { // TLB miss; look in page table
		tlbMiss = true;
		fnum = pt[pnum].first;

		if (fnum == -1) {
			// page fault!
			pageFault = true;
			numPageFaults++;
			// read the requested page from backing store into a free frame
			fnum = getFreeFrameNum();	// somehow find a free frame
			bs.read(pnum);		// read the page at pnum on backing store
			copy(bs.getBuff(), bs.getBuff() + FRAME_SIZE, Memory[fnum]);	// copy into the frame at fnum of physical memory
			pt[pnum].first = fnum;	// point the pnum enty to fnum in page table
		}

		tlb[pnum] = fnum;	// update TLB
	}


	if (pageFault) {
		// with either FIFO or LRU, if a page is newly brought into memory, its index is inserted at tail of queue
		q.push_back(pnum);
	}
	else {
		// in the case of no page fault, FIFO does nothing;
		// LRU will move the recently accessed page number to the tail of queue
		if (pageReplacementPolicy == "LRU") {
			q.remove(pnum);
			q.push_back(pnum);
		}
	}


	return fnum;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
pushq %rax
movq %rdi, %rbx
movl %esi, -0x2c(%rbp)
xorl %eax, %eax
movb %al, 0x3f8(%rdi)
movb %al, 0x3f0(%rdi)
movq 0x3b8(%rdi), %rdx
leaq 0x3b0(%rdi), %rax
movq %rax, %rcx
testq %rdx, %rdx
je 0x2dc8
movq %rax, %rcx
xorl %edi, %edi
cmpl %esi, 0x20(%rdx)
setl %dil
cmovgeq %rdx, %rcx
movq 0x10(%rdx,%rdi,8), %rdx
testq %rdx, %rdx
jne 0x2db1
movq %rax, %rdx
cmpq %rax, %rcx
je 0x2dda
cmpl %esi, 0x20(%rcx)
cmovgq %rax, %rcx
movq %rcx, %rdx
leaq 0x3a8(%rbx), %r15
cmpq %rax, %rdx
je 0x2df6
movq %r15, %rdi
callq 0x258c
movl (%rax), %r14d
jmp 0x2e7f
movb $0x1, 0x3f8(%rbx)
leaq -0x2c(%rbp), %rsi
movq %rbx, %rdi
callq 0x3106
movl (%rax), %r14d
cmpl $-0x1, %r14d
jne 0x2e71
movb $0x1, 0x3f0(%rbx)
incl 0x3f4(%rbx)
movq %rbx, %rdi
callq 0x2efe
movl %eax, %r14d
leaq 0x98(%rbx), %rdi
leaq -0x2c(%rbp), %r12
movl (%r12), %esi
callq 0x38e4
leaq 0x2a8(%rbx), %rsi
movslq %r14d, %r13
movq %r13, %rax
shlq $0x8, %rax
leaq 0x53da(%rip), %rdi      # 0x8230
addq %rax, %rdi
movl $0x100, %edx            # imm = 0x100
callq 0x2330
movq %rbx, %rdi
movq %r12, %rsi
callq 0x3106
movl %r13d, (%rax)
movl -0x2c(%rbp), %esi
movq %r15, %rdi
callq 0x258c
movl %r14d, (%rax)
cmpb $0x1, 0x3f0(%rbx)
jne 0x2e9e
leaq 0x80(%rbx), %r15
movl $0x18, %edi
callq 0x2220
movl -0x2c(%rbp), %ecx
jmp 0x2ed6
leaq 0x60(%rbx), %rdi
leaq 0x2189(%rip), %rsi      # 0x5032
callq 0x20c0
testl %eax, %eax
jne 0x2eeb
leaq 0x80(%rbx), %r15
leaq -0x2c(%rbp), %r12
movq %r15, %rdi
movq %r12, %rsi
callq 0x268a
movl $0x18, %edi
callq 0x2220
movl (%r12), %ecx
movl %ecx, 0x10(%rax)
movq %rax, %rdi
movq %r15, %rsi
callq 0x2060
incq 0x90(%rbx)
movl %r14d, %eax
addq $0x8, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
nop