// File: /workspace/github_cpp_makefile_star2_O2/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:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x48, %rsp
movq %rsi, %r15
movq 0x28(%rsi), %r12
movl 0x60(%rsi), %r10d
leaq 0x40(%rsi), %rax
movq %rax, 0x28(%rsp)
xorl %r11d, %r11d
movq %rsi, 0x10(%rsp)
movq %rdi, 0x30(%rsp)
movl %r10d, 0x24(%rsp)
movl %r10d, %ebp
subl %r11d, %ebp
jbe 0x34bce
movzwl 0x68(%r15), %r9d
movq 0x10(%rdi), %rax
movq (%rax,%r9,8), %rax
movq 0x50(%rax), %rcx
movq 0x58(%rax), %rsi
cmpq %rcx, %r12
jb 0x34a61
cmpq %rsi, %r12
jbe 0x34a72
subq %rcx, %rsi
movq %r12, %rax
xorl %edx, %edx
divq %rsi
movq %rdx, %r12
addq %rcx, %r12
movq %r12, %rsi
subq %rcx, %rsi
movq 0x8(%rdi), %rax
movl 0x48(%rax), %r8d
movq %r12, %rax
xorl %edx, %edx
divq %r8
movl %r8d, %eax
subl %edx, %eax
movq %r11, 0x40(%rsp)
leal (%rax,%r11), %ecx
cmpl %r10d, %ecx
cmovbl %eax, %ebp
pushq $-0x1
popq %rbx
movl %ebp, %ecx
shlq %cl, %rbx
movq %rsi, %rax
xorl %edx, %edx
divq %r8
movq %rax, 0x38(%rsp)
movq %rdx, %rcx
notq %rbx
shlq %cl, %rbx
movl %ebp, %r14d
shll $0x9, %r14d
cmpl $0x0, 0x64(%r15)
movzwl %r9w, %eax
movl %eax, 0xc(%rsp)
je 0x34b42
movl $0xb0, %edi
callq 0x7370
movq %rax, %r13
movl (%r15), %r15d
callq 0x1f784
movq %rax, %rdi
callq 0x1fafc
movq %r13, %rdi
xorl %esi, %esi
movl 0xc(%rsp), %edx
movl %r14d, %ecx
movq 0x38(%rsp), %r8
movq 0x10(%rsp), %r9
pushq %rax
pushq %rbx
pushq $0x0
pushq %r15
callq 0x3a310
addq $0x20, %rsp
movq %r13, 0x18(%rsp)
movq 0x28(%rsp), %rdi
leaq 0x18(%rsp), %rsi
callq 0x2ab40
movq 0x10(%rsp), %r15
movzwl 0x68(%r15), %eax
movq 0x30(%rsp), %rdi
movq 0x10(%rdi), %rcx
movq (%rcx,%rax,8), %rax
incl 0x14(%rax)
jmp 0x34bb9
movl $0xa0, %edi
callq 0x7370
movq %rax, %r13
movl (%r15), %r15d
callq 0x1f784
movq %rax, %rdi
callq 0x1fafc
subq $0x8, %rsp
movq %r13, %rdi
xorl %esi, %esi
movl 0x14(%rsp), %edx
movl %r14d, %ecx
movq 0x40(%rsp), %r8
pushq $-0x1
popq %r9
pushq %rax
pushq %rbx
pushq $0x0
pushq %r15
pushq 0x38(%rsp)
callq 0x3a1c4
addq $0x30, %rsp
movq %r13, 0x18(%rsp)
movq 0x28(%rsp), %rdi
leaq 0x18(%rsp), %rsi
callq 0x2ab40
movq 0x10(%rsp), %r15
movzwl 0x68(%r15), %eax
movq 0x30(%rsp), %rdi
movq 0x10(%rdi), %rcx
movq (%rcx,%rax,8), %rax
incl 0x10(%rax)
addq %rbp, %r12
movq 0x40(%rsp), %r11
addl %ebp, %r11d
movl 0x24(%rsp), %r10d
jmp 0x34a36
addq $0x48, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
jmp 0x34bdf
movq %rax, %rbx
movq %r13, %rdi
callq 0x7340
movq %rbx, %rdi
callq 0x75d0