// File: CMU-SAFARI[P]MQSim/src/ssd/Host_Interface_NVMe.cpp
// Function: SSD_Components::Input_Stream_Manager_NVMe::Handle_new_arrived_request(SSD_Components::User_Request*)
inline void Input_Stream_Manager_NVMe::Handle_new_arrived_request(User_Request *request)
{
	((Input_Stream_NVMe *)input_streams[request->Stream_id])->Submission_head_informed_to_host++;
	if (((Input_Stream_NVMe *)input_streams[request->Stream_id])->Submission_head_informed_to_host == ((Input_Stream_NVMe *)input_streams[request->Stream_id])->Submission_queue_size)
	{ //Circular queue implementation
		((Input_Stream_NVMe *)input_streams[request->Stream_id])->Submission_head_informed_to_host = 0;
	}
	if (request->Type == UserRequestType::READ)
	{
		((Input_Stream_NVMe *)input_streams[request->Stream_id])->Waiting_user_requests.push_back(request);
		((Input_Stream_NVMe *)input_streams[request->Stream_id])->STAT_number_of_read_requests++;
		segment_user_request(request);

		((Host_Interface_NVMe *)host_interface)->broadcast_user_request_arrival_signal(request);
	}
	else
	{ //This is a write request
		((Input_Stream_NVMe *)input_streams[request->Stream_id])->Waiting_user_requests.push_back(request);
		((Input_Stream_NVMe *)input_streams[request->Stream_id])->STAT_number_of_write_requests++;
		((Host_Interface_NVMe *)host_interface)->request_fetch_unit->Fetch_write_data(request);
	}
}

// Assembly:
subq $0x28, %rsp
movq %rdi, 0x20(%rsp)
movq %rsi, 0x18(%rsp)
movq 0x20(%rsp), %rdi
movq %rdi, 0x8(%rsp)
addq $0x10, %rdi
movq 0x18(%rsp), %rax
movzwl 0x68(%rax), %eax
movl %eax, %esi
callq 0x85300
movq 0x8(%rsp), %rdi
movq (%rax), %rax
movw 0x7c(%rax), %cx
addw $0x1, %cx
movw %cx, 0x7c(%rax)
addq $0x10, %rdi
movq 0x18(%rsp), %rax
movzwl 0x68(%rax), %eax
movl %eax, %esi
callq 0x85300
movq 0x8(%rsp), %rdi
movq (%rax), %rax
movzwl 0x7c(%rax), %eax
movl %eax, 0x14(%rsp)
addq $0x10, %rdi
movq 0x18(%rsp), %rax
movzwl 0x68(%rax), %eax
movl %eax, %esi
callq 0x85300
movq %rax, %rcx
movl 0x14(%rsp), %eax
movq (%rcx), %rcx
movzwl 0x68(%rcx), %ecx
cmpl %ecx, %eax
jne 0x87efc
movq 0x8(%rsp), %rdi
addq $0x10, %rdi
movq 0x18(%rsp), %rax
movzwl 0x68(%rax), %eax
movl %eax, %esi
callq 0x85300
movq (%rax), %rax
movw $0x0, 0x7c(%rax)
movq 0x18(%rsp), %rax
cmpl $0x0, 0x64(%rax)
jne 0x87f7e
movq 0x8(%rsp), %rdi
addq $0x10, %rdi
movq 0x18(%rsp), %rax
movzwl 0x68(%rax), %eax
movl %eax, %esi
callq 0x85300
movq (%rax), %rdi
addq $0x88, %rdi
leaq 0x18(%rsp), %rsi
callq 0x6c210
movq 0x8(%rsp), %rdi
addq $0x10, %rdi
movq 0x18(%rsp), %rax
movzwl 0x68(%rax), %eax
movl %eax, %esi
callq 0x85300
movq 0x8(%rsp), %rdi
movq (%rax), %rax
movl 0x8(%rax), %ecx
addl $0x1, %ecx
movl %ecx, 0x8(%rax)
movq 0x18(%rsp), %rsi
movq (%rdi), %rax
callq *0x28(%rax)
movq 0x8(%rsp), %rax
movq 0x8(%rax), %rdi
movq 0x18(%rsp), %rsi
callq 0x87ff0
jmp 0x87feb
movq 0x8(%rsp), %rdi
addq $0x10, %rdi
movq 0x18(%rsp), %rax
movzwl 0x68(%rax), %eax
movl %eax, %esi
callq 0x85300
movq (%rax), %rdi
addq $0x88, %rdi
leaq 0x18(%rsp), %rsi
callq 0x6c210
movq 0x8(%rsp), %rdi
addq $0x10, %rdi
movq 0x18(%rsp), %rax
movzwl 0x68(%rax), %eax
movl %eax, %esi
callq 0x85300
movq %rax, %rcx
movq 0x8(%rsp), %rax
movq (%rcx), %rcx
movl 0xc(%rcx), %edx
addl $0x1, %edx
movl %edx, 0xc(%rcx)
movq 0x8(%rax), %rax
movq 0x58(%rax), %rdi
movq 0x18(%rsp), %rsi
movq (%rdi), %rax
callq *0x18(%rax)
addq $0x28, %rsp
retq