// File: CMU-SAFARI[P]MQSim/src/ssd/Host_Interface_NVMe.cpp
// Function: SSD_Components::Input_Stream_Manager_NVMe::segment_user_request(SSD_Components::User_Request*)
void Input_Stream_Manager_NVMe::segment_user_request(User_Request *user_request)
{
	LHA_type lsa = user_request->Start_LBA;
	LHA_type lsa2 = user_request->Start_LBA;
	unsigned int req_size = user_request->SizeInSectors;

	page_status_type access_status_bitmap = 0;
	unsigned int handled_sectors_count = 0;
	unsigned int transaction_size = 0;
	while (handled_sectors_count < req_size)
	{
		//Check if LSA is in the correct range allocted to the stream
		if (lsa < ((Input_Stream_NVMe *)input_streams[user_request->Stream_id])->Start_logical_sector_address || lsa > ((Input_Stream_NVMe *)input_streams[user_request->Stream_id])->End_logical_sector_address)
		{
			lsa = ((Input_Stream_NVMe *)input_streams[user_request->Stream_id])->Start_logical_sector_address + (lsa % (((Input_Stream_NVMe *)input_streams[user_request->Stream_id])->End_logical_sector_address - (((Input_Stream_NVMe *)input_streams[user_request->Stream_id])->Start_logical_sector_address)));
		}
		LHA_type internal_lsa = lsa - ((Input_Stream_NVMe *)input_streams[user_request->Stream_id])->Start_logical_sector_address; //For each flow, all lsa's should be translated into a range starting from zero

		transaction_size = host_interface->sectors_per_page - (unsigned int)(lsa % host_interface->sectors_per_page);
		if (handled_sectors_count + transaction_size >= req_size)
		{
			transaction_size = req_size - handled_sectors_count;
		}
		LPA_type lpa = internal_lsa / host_interface->sectors_per_page;

		page_status_type temp = ~(0xffffffffffffffff << (int)transaction_size);
		access_status_bitmap = temp << (int)(internal_lsa % host_interface->sectors_per_page);

		if (user_request->Type == UserRequestType::READ)
		{
			NVM_Transaction_Flash_RD *transaction = new NVM_Transaction_Flash_RD(Transaction_Source_Type::USERIO, user_request->Stream_id,
																				 transaction_size * SECTOR_SIZE_IN_BYTE, lpa, NO_PPA, user_request, user_request->Priority_class, 0, access_status_bitmap, CurrentTimeStamp);
			user_request->Transaction_list.push_back(transaction);
			input_streams[user_request->Stream_id]->STAT_number_of_read_transactions++;
		}
		else
		{ //user_request->Type == UserRequestType::WRITE
			NVM_Transaction_Flash_WR *transaction = new NVM_Transaction_Flash_WR(Transaction_Source_Type::USERIO, user_request->Stream_id,
																				 transaction_size * SECTOR_SIZE_IN_BYTE, lpa, user_request, user_request->Priority_class, 0, access_status_bitmap, CurrentTimeStamp);
			user_request->Transaction_list.push_back(transaction);
			input_streams[user_request->Stream_id]->STAT_number_of_write_transactions++;
		}

		lsa = lsa + transaction_size;
		handled_sectors_count += transaction_size;
	}
}

// Assembly:
subq $0x178, %rsp            # imm = 0x178
movq %rdi, 0x170(%rsp)
movq %rsi, 0x168(%rsp)
movq 0x170(%rsp), %rax
movq %rax, 0xf0(%rsp)
movq 0x168(%rsp), %rax
movq 0x28(%rax), %rax
movq %rax, 0x160(%rsp)
movq 0x168(%rsp), %rax
movq 0x28(%rax), %rax
movq %rax, 0x158(%rsp)
movq 0x168(%rsp), %rax
movl 0x60(%rax), %eax
movl %eax, 0x154(%rsp)
movq $0x0, 0x148(%rsp)
movl $0x0, 0x144(%rsp)
movl $0x0, 0x140(%rsp)
movl 0x144(%rsp), %eax
cmpl 0x154(%rsp), %eax
jae 0x8623c
movq 0xf0(%rsp), %rdi
movq 0x160(%rsp), %rax
movq %rax, 0xe8(%rsp)
addq $0x10, %rdi
movq 0x168(%rsp), %rax
movzwl 0x68(%rax), %eax
movl %eax, %esi
callq 0x85300
movq %rax, %rcx
movq 0xe8(%rsp), %rax
movq (%rcx), %rcx
cmpq 0x50(%rcx), %rax
jb 0x85d51
movq 0xf0(%rsp), %rdi
movq 0x160(%rsp), %rax
movq %rax, 0xe0(%rsp)
addq $0x10, %rdi
movq 0x168(%rsp), %rax
movzwl 0x68(%rax), %eax
movl %eax, %esi
callq 0x85300
movq %rax, %rcx
movq 0xe0(%rsp), %rax
movq (%rcx), %rcx
cmpq 0x58(%rcx), %rax
jbe 0x85e0e
movq 0xf0(%rsp), %rdi
addq $0x10, %rdi
movq 0x168(%rsp), %rax
movzwl 0x68(%rax), %eax
movl %eax, %esi
callq 0x85300
movq 0xf0(%rsp), %rdi
movq (%rax), %rax
movq 0x50(%rax), %rax
movq %rax, 0xd8(%rsp)
movq 0x160(%rsp), %rax
movq %rax, 0xd0(%rsp)
addq $0x10, %rdi
movq 0x168(%rsp), %rax
movzwl 0x68(%rax), %eax
movl %eax, %esi
callq 0x85300
movq 0xf0(%rsp), %rdi
movq (%rax), %rax
movq 0x58(%rax), %rax
movq %rax, 0xc8(%rsp)
addq $0x10, %rdi
movq 0x168(%rsp), %rax
movzwl 0x68(%rax), %eax
movl %eax, %esi
callq 0x85300
movq 0xc8(%rsp), %rcx
movq %rax, %rdx
movq 0xd0(%rsp), %rax
movq (%rdx), %rdx
subq 0x50(%rdx), %rcx
xorl %edx, %edx
divq %rcx
movq 0xd8(%rsp), %rax
addq %rdx, %rax
movq %rax, 0x160(%rsp)
movq 0xf0(%rsp), %rdi
movq 0x160(%rsp), %rax
movq %rax, 0xb8(%rsp)
addq $0x10, %rdi
movq 0x168(%rsp), %rax
movzwl 0x68(%rax), %eax
movl %eax, %esi
callq 0x85300
movq 0xf0(%rsp), %rcx
movq %rax, %rdx
movq 0xb8(%rsp), %rax
movq (%rdx), %rdx
subq 0x50(%rdx), %rax
movq %rax, 0x138(%rsp)
movq 0x8(%rcx), %rax
movl 0x48(%rax), %eax
movl %eax, 0xc4(%rsp)
movq 0x160(%rsp), %rax
movq 0x8(%rcx), %rcx
movl 0x48(%rcx), %ecx
xorl %edx, %edx
divq %rcx
movl 0xc4(%rsp), %eax
movl %edx, %ecx
subl %ecx, %eax
movl %eax, 0x140(%rsp)
movl 0x144(%rsp), %eax
addl 0x140(%rsp), %eax
cmpl 0x154(%rsp), %eax
jb 0x85ebf
movl 0x154(%rsp), %eax
subl 0x144(%rsp), %eax
movl %eax, 0x140(%rsp)
movq 0xf0(%rsp), %rcx
movq 0x138(%rsp), %rax
movq 0x8(%rcx), %rcx
movl 0x48(%rcx), %ecx
xorl %edx, %edx
divq %rcx
movq %rax, 0x130(%rsp)
movl 0x140(%rsp), %eax
movl %eax, %ecx
movq $-0x1, %rax
shlq %cl, %rax
movq 0xf0(%rsp), %rcx
xorq $-0x1, %rax
movq %rax, 0x128(%rsp)
movq 0x128(%rsp), %rax
movq %rax, 0xb0(%rsp)
movq 0x138(%rsp), %rax
movq 0x8(%rcx), %rcx
movl 0x48(%rcx), %ecx
xorl %edx, %edx
divq %rcx
movq 0xb0(%rsp), %rax
movl %edx, %ecx
movl %ecx, %ecx
shlq %cl, %rax
movq %rax, 0x148(%rsp)
movq 0x168(%rsp), %rax
cmpl $0x0, 0x64(%rax)
jne 0x860ce
movl $0xa0, %edi
callq 0x8450
movq %rax, 0x78(%rsp)
movq 0x168(%rsp), %rax
movq %rax, 0x80(%rsp)
movw 0x68(%rax), %cx
movw %cx, 0x8a(%rsp)
movl 0x140(%rsp), %ecx
shll $0x9, %ecx
movl %ecx, 0x8c(%rsp)
movq 0x130(%rsp), %rcx
movq %rcx, 0x90(%rsp)
movl (%rax), %eax
movl %eax, 0x9c(%rsp)
movq 0x148(%rsp), %rax
movq %rax, 0xa0(%rsp)
callq 0x46500
movq %rax, 0xa8(%rsp)
jmp 0x85fcb
movq 0xa8(%rsp), %rdi
callq 0x46c50
movq %rax, 0x70(%rsp)
jmp 0x85fdf
movq 0x90(%rsp), %r8
movl 0x8c(%rsp), %ecx
movq 0x78(%rsp), %rdi
movw 0x8a(%rsp), %ax
movq 0x80(%rsp), %rsi
movl 0x9c(%rsp), %r9d
movq 0xa0(%rsp), %r10
movq 0x70(%rsp), %r11
movq %rsp, %rdx
movq %r11, 0x20(%rdx)
movq %r10, 0x18(%rdx)
movl %r9d, 0x8(%rdx)
movq %rsi, (%rdx)
movq $0x0, 0x10(%rdx)
movzwl %ax, %edx
xorl %esi, %esi
movq $-0x1, %r9
callq 0x960c0
jmp 0x86045
movq 0x78(%rsp), %rax
movq %rax, 0x120(%rsp)
movq 0x168(%rsp), %rdi
addq $0x40, %rdi
movq 0x120(%rsp), %rax
movq %rax, 0x108(%rsp)
leaq 0x108(%rsp), %rsi
callq 0x6c260
movq 0xf0(%rsp), %rdi
addq $0x10, %rdi
movq 0x168(%rsp), %rax
movzwl 0x68(%rax), %eax
movl %eax, %esi
callq 0x85300
movq (%rax), %rax
movl 0x10(%rax), %ecx
addl $0x1, %ecx
movl %ecx, 0x10(%rax)
jmp 0x86208
movq 0x78(%rsp), %rdi
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x118(%rsp)
movl %eax, 0x114(%rsp)
callq 0x8410
jmp 0x86244
movl $0xb0, %edi
callq 0x8450
movq %rax, 0x38(%rsp)
movq 0x168(%rsp), %rax
movq %rax, 0x40(%rsp)
movw 0x68(%rax), %cx
movw %cx, 0x4a(%rsp)
movl 0x140(%rsp), %ecx
shll $0x9, %ecx
movl %ecx, 0x4c(%rsp)
movq 0x130(%rsp), %rcx
movq %rcx, 0x50(%rsp)
movl (%rax), %eax
movl %eax, 0x5c(%rsp)
movq 0x148(%rsp), %rax
movq %rax, 0x60(%rsp)
callq 0x46500
movq %rax, 0x68(%rsp)
jmp 0x8612d
movq 0x68(%rsp), %rdi
callq 0x46c50
movq %rax, 0x30(%rsp)
jmp 0x8613e
movq 0x40(%rsp), %r9
movq 0x50(%rsp), %r8
movl 0x4c(%rsp), %ecx
movq 0x38(%rsp), %rdi
movw 0x4a(%rsp), %ax
movl 0x5c(%rsp), %esi
movq 0x60(%rsp), %r10
movq 0x30(%rsp), %r11
movq %rsp, %rdx
movq %r11, 0x18(%rdx)
movq %r10, 0x10(%rdx)
movl %esi, (%rdx)
movq $0x0, 0x8(%rdx)
movzwl %ax, %edx
xorl %esi, %esi
callq 0x963f0
jmp 0x86185
movq 0x38(%rsp), %rax
movq %rax, 0x100(%rsp)
movq 0x168(%rsp), %rdi
addq $0x40, %rdi
movq 0x100(%rsp), %rax
movq %rax, 0xf8(%rsp)
leaq 0xf8(%rsp), %rsi
callq 0x6c260
movq 0xf0(%rsp), %rdi
addq $0x10, %rdi
movq 0x168(%rsp), %rax
movzwl 0x68(%rax), %eax
movl %eax, %esi
callq 0x85300
movq (%rax), %rax
movl 0x14(%rax), %ecx
addl $0x1, %ecx
movl %ecx, 0x14(%rax)
jmp 0x86208
movq 0x38(%rsp), %rdi
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x118(%rsp)
movl %eax, 0x114(%rsp)
callq 0x8410
jmp 0x86244
movq 0x160(%rsp), %rax
movl 0x140(%rsp), %ecx
addq %rcx, %rax
movq %rax, 0x160(%rsp)
movl 0x140(%rsp), %eax
addl 0x144(%rsp), %eax
movl %eax, 0x144(%rsp)
jmp 0x85cb3
addq $0x178, %rsp            # imm = 0x178
retq
movq 0x118(%rsp), %rdi
callq 0x8770
nopw %cs:(%rax,%rax)