// File: /workspace/github_cpp_makefile_star2_O3/CMU-SAFARI[P]MQSim/src/ssd/Host_Interface_SATA.cpp
// Function: SSD_Components::Input_Stream_Manager_SATA::segment_user_request(SSD_Components::User_Request*)
void Input_Stream_Manager_SATA::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_SATA*)input_streams[SATA_STREAM_ID])->Start_logical_sector_address || lsa >((Input_Stream_SATA*)input_streams[SATA_STREAM_ID])->End_logical_sector_address) {
				lsa = ((Input_Stream_SATA*)input_streams[SATA_STREAM_ID])->Start_logical_sector_address
				+ (lsa % (((Input_Stream_SATA*)input_streams[SATA_STREAM_ID])->End_logical_sector_address - (((Input_Stream_SATA*)input_streams[SATA_STREAM_ID])->Start_logical_sector_address)));
			}
			LHA_type internal_lsa = lsa - ((Input_Stream_SATA*)input_streams[SATA_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, SATA_STREAM_ID,
					transaction_size * SECTOR_SIZE_IN_BYTE, lpa, NO_PPA, user_request, 0, access_status_bitmap, CurrentTimeStamp);
				user_request->Transaction_list.push_back(transaction);
				input_streams[SATA_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, SATA_STREAM_ID,
					transaction_size * SECTOR_SIZE_IN_BYTE, lpa, user_request, 0, access_status_bitmap, CurrentTimeStamp);
				user_request->Transaction_list.push_back(transaction);
				input_streams[SATA_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 $0x28, %rsp
movq %rsi, (%rsp)
movl 0x60(%rsi), %r8d
testl %r8d, %r8d
je 0x436a9
movq (%rsp), %rax
movq 0x28(%rax), %r12
addq $0x40, %rax
movq %rax, 0x10(%rsp)
movq 0x10(%rdi), %rax
movq (%rax), %rax
xorl %ebx, %ebx
movq %rdi, 0x18(%rsp)
movl %r8d, 0xc(%rsp)
movq 0x48(%rax), %rcx
movq 0x50(%rax), %rsi
cmpq %rcx, %r12
jb 0x4353f
cmpq %rsi, %r12
jbe 0x43550
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), %edi
movq %r12, %rax
xorl %edx, %edx
divq %rdi
movl %edi, %eax
subl %edx, %eax
leal (%rax,%rbx), %ecx
movl %r8d, %r13d
subl %ebx, %r13d
cmpl %r8d, %ecx
cmovbl %eax, %r13d
movq $-0x1, %r15
movl %r13d, %ecx
shlq %cl, %r15
movq %rsi, %rax
xorl %edx, %edx
divq %rdi
movq %rax, 0x20(%rsp)
movq %rdx, %rcx
notq %r15
shlq %cl, %r15
movl %r13d, %r14d
shll $0x9, %r14d
movq (%rsp), %rax
cmpl $0x0, 0x64(%rax)
je 0x43621
movl $0xb0, %edi
callq 0x73a0
movq %rax, %rbp
callq 0x28018
movq %rax, %rdi
callq 0x2841a
subq $0x8, %rsp
movq %rbp, %rdi
xorl %esi, %esi
xorl %edx, %edx
movl %r14d, %ecx
movq 0x28(%rsp), %r8
movq 0x8(%rsp), %r9
pushq %rax
pushq %r15
pushq $0x0
callq 0x4827c
addq $0x20, %rsp
movl $0x18, %edi
callq 0x73a0
movq %rbp, 0x10(%rax)
movq %rax, %rdi
movq 0x10(%rsp), %rsi
callq 0x7060
movq (%rsp), %rax
incq 0x50(%rax)
movq 0x18(%rsp), %rdi
movq 0x10(%rdi), %rax
movq (%rax), %rax
incl 0x14(%rax)
jmp 0x43695
movl $0xa0, %edi
callq 0x73a0
movq %rax, %rbp
callq 0x28018
movq %rax, %rdi
callq 0x2841a
movq %rbp, %rdi
xorl %esi, %esi
xorl %edx, %edx
movl %r14d, %ecx
movq 0x20(%rsp), %r8
movq $-0x1, %r9
pushq %rax
pushq %r15
pushq $0x0
pushq 0x18(%rsp)
callq 0x48114
addq $0x20, %rsp
movl $0x18, %edi
callq 0x73a0
movq %rbp, 0x10(%rax)
movq %rax, %rdi
movq 0x10(%rsp), %rsi
callq 0x7060
movq (%rsp), %rax
incq 0x50(%rax)
movq 0x18(%rsp), %rdi
movq 0x10(%rdi), %rax
movq (%rax), %rax
incl 0x10(%rax)
addq %r13, %r12
addl %r13d, %ebx
movl 0xc(%rsp), %r8d
cmpl %r8d, %ebx
jb 0x4352d
addq $0x28, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
jmp 0x436ba
movq %rax, %rbx
movq %rbp, %rdi
callq 0x7370
movq %rbx, %rdi
callq 0x7620
nop