// File: /workspace/github_c_makefile_star2_O3/TeaInside[P]teavpn/src/teavpn/server/tcp.c
// Function: teavpn_tcp_server
__attribute__((force_align_arg_pointer)) uint8_t teavpn_tcp_server(server_config *config)
{
	fd_set rd_set;
	int  fd_ret, max_fd;
	ssize_t nwrite, nread;
	int16_t bufchan_index;
	pthread_t accept_worker;
	struct sockaddr_in server_addr;
	struct teavpn_tcp_queue _queues[QUEUE_AMOUNT];
	struct buffer_channel _bufchan[BUFCHAN_ALLOC];
	struct connection_entry _connections[CONNECTION_ALLOC];

	/**
	 * To store config file buffer (parsing).
	 *
	 * Avoid to use heap as long as it
	 * is still eligible to use stack.
	 *
	 * (heap is slower than stack)
	 */
	char config_buffer[4096];

	/** 
	 * Assign internal stack allocation to global vars
	 * in order to make other threads can access them.
	 */
	queues = _queues;
	bufchan = _bufchan;
	connections = _connections;

	/**
	 * Initialize TeaVPN server (vars, socket, iface, etc.)
	 */
	if (teavpn_tcp_server_init(config_buffer, config)) {
		return 1;
	}

	thread_amount = config->threads;

	/**
	 * Prepare worker threads.
	 * (Threads which transmit data to client).
	 *
	 * Use stack allocation as long as possible.
	 */
	struct worker_thread _workers[thread_amount];
	workers = _workers;

	if (thread_amount < 3) {
		debug_log(0, "Minimal threads amount is 3, but %d given", thread_amount);
		goto close_server;
	}


	/**
	 * Create the worker threads.
	 */
	for (register uint8_t i = 0; i < config->threads; ++i) {
		workers[i].busy = false;
		workers[i].num = i;
		pthread_cond_init(&(workers[i].cond), NULL);
		pthread_mutex_init(&(workers[i].mutex), NULL);
		pthread_create(
			&(workers[i].thread),
			NULL,
			(void * (*)(void *))teavpn_tcp_worker_thread,
			(void *)&(workers[i])
		);
		pthread_detach(workers[i].thread);

		#define thread_name (bufchan[0].buffer)
		sprintf(thread_name, "teavpn-worker-%d", i);
		pthread_setname_np(workers[i].thread, thread_name);
		#undef thread_name
	}
	memset(bufchan[0].buffer, 0, sizeof("teavpn-worker-xxx"));

	/**
	 * Prepare server bind address data.
	 */
	memset(&server_addr, 0, sizeof(server_addr));
	server_addr.sin_family = AF_INET;
	server_addr.sin_port = htons(config->bind_port);
	server_addr.sin_addr.s_addr = inet_addr(config->bind_addr);

	/**
	 * Bind socket to address.
	 */
	if (bind(net_fd, (struct sockaddr *)&server_addr, sizeof(server_addr)) < 0) {
		debug_log(0, "Bind socket failed");
		perror("Bind failed");
		goto close_server;
	}

	/**
	 * Listen
	 */
	if (listen(net_fd, 3) < 0) {
		debug_log(0, "Listen socket failed");
		perror("Listen failed");
		goto close_server;
	}

	/**
	 * Ignore SIGPIPE
	 */
	signal(SIGPIPE, SIG_IGN);

	/**
	 * Create accept worker thread.
	 * (Thread which accepts new connection).
	 */
	pthread_create(
		&accept_worker,
		NULL,
		(void * (*)(void *))teavpn_tcp_accept_worker_thread,
		(void *)config
	);
	pthread_setname_np(accept_worker, "accept-worker");
	pthread_detach(accept_worker);

	debug_log(0, "Listening on %s:%d...", config->bind_addr, config->bind_port);

	/**
	 * TeaVPN server event loop.
	 */
	while (true) {

		/**
		 * Calculate maximum value between tap_fd, net_fd and m_pie_fd[0].
		 */
		max_fd = (((tap_fd > net_fd) && (tap_fd > m_pipe_fd[0])) ? tap_fd :
				(net_fd > m_pipe_fd[0]) ? net_fd : m_pipe_fd[0]);

		/**
		 * Set rd_set to zero.
		 *
		 * This is a compulsory step in using
		 * select(2) inside of an event loop.
		 */
		FD_ZERO(&rd_set);

		/**
		 * Add file descriptors to rd_set.
		 */
		FD_SET(net_fd, &rd_set);
		FD_SET(tap_fd, &rd_set);
		FD_SET(m_pipe_fd[0], &rd_set);


		/**
		 * Add all connected clients file descriptor to rd_set.
		 */
		for (register uint16_t i = 0; i < CONNECTION_ALLOC; i++) {
			if (connections[i].connected) {

				/**
				 * Recalculate max fd to make sure that max_fd
				 * has the maximum value from the entire involved
				 * file descriptors.
				 */
				if (connections[i].fd > max_fd) {
					max_fd = connections[i].fd;
				}

				/**
				 * Add file descriptors to rd_set.
				 */
				FD_SET(connections[i].fd, &rd_set);
			}
		}


		/**
		 * Get buffer channel index.
		 */
		do {
			bufchan_index = get_bufchan_index();
		} while (bufchan_index == -1);


		/**
		 * Block main process until there is one or more ready fd.
		 * Read `man 2 select_tut` for details.
		 */
		fd_ret = select(max_fd + 1, &rd_set, NULL, NULL, NULL);

		/**
		 * Got interrupt signal.
		 */
		if ((fd_ret < 0) && (errno == EINTR)) {
			debug_log(2, "select(2) got interrupt signal");
			continue;
		}

		/**
		 * Got an error.
		 */
		if (fd_ret < 0) {
			debug_log(0, "select(2) got an error");
			perror("select()");
			continue;
		}

		/**
		 * Create a macro to manage buffer channel as other data type.
		 *
		 * Don't make a new variable as long as we can use the available
		 * resources in safely way.
		 */
		#define packet ((teavpn_packet *)(bufchan[bufchan_index].buffer))


		/**
		 * Read data from server TUN/TAP.
		 */
		if (FD_ISSET(tap_fd, &rd_set)) {
			/**
			 * Read from TUN/TAP.
			 */
			nread = read(tap_fd, packet->data.data, TEAVPN_TAP_READ_SIZE);
			if (nread < 0) {
				debug_log(0, "Error read from tap_fd");
				perror("Error read from tap_fd");
				goto next_1;
			}

			packet->info.type = TEAVPN_PACKET_DATA;
			packet->info.len = TEAVPN_PACK(nread);
			for (register uint16_t i = 0; i < CONNECTION_ALLOC; i++) {
				if (connections[i].connected) {
					/**
					 * Insert write queue.
					 *
					 * Send bufchan_index to connection i.
					 */
					bufchan[bufchan_index].ref_count++;
					// printf("i = %d;  r = %d\n", bufchan_index, bufchan[bufchan_index].ref_count);
					enqueue_packet(i, bufchan_index);
					thread_job_broadcast();
				}
			}
		}


		next_1:
		/**
		 * Traverse clients fd and read data from clients.
		 */
		for (register uint16_t i = 0; i < CONNECTION_ALLOC; i++) {
			if (connections[i].connected) {
				if (FD_ISSET(connections[i].fd, &rd_set)) {

					/**
					 * Get buffer channel index.
					 */
					do {
						bufchan_index = get_bufchan_index();
					} while (bufchan_index == -1);

					nread = read(connections[i].fd, packet, TEAVPN_PACKET_BUFFER);

					/**
					 * Connection closed by client.
					 */
					if (nread == 0) {
						FD_CLR(connections[i].fd, &rd_set);
						close(connections[i].fd);
						debug_log(1, "(%s:%d) connection closed",
							inet_ntoa(connections[i].addr.sin_addr),
							ntohs(connections[i].addr.sin_port)
						);
						connection_zero(i);
						continue;
					}

					/**
					 * Error read from client fd.
					 */
					if (nread < 0) {
						char *remote_addr = inet_ntoa(connections[i].addr.sin_addr);
						uint16_t remote_port = ntohs(connections[i].addr.sin_port);

						debug_log(0, "Error read from (%s:%d)", remote_addr, remote_port);
						perror("Error read from connection fd");

						/**
						 * Increment the error counter.
						 */
						connections[i].error++;

						/**
						 * Force disconnect client if it has
						 * reached the max number of errors.
						 */
						if (connections[i].error > MAX_CLIENT_ERR) {
							debug_log(0,
								"Client %s:%d has been disconnected because it has reached the max number of errors",
								remote_port,
								remote_port
							);
							FD_CLR(connections[i].fd, &rd_set);
							close(connections[i].fd);
							connection_zero(i);
						}

						continue;
					}


					/**
					 * Write to TUN/TAP server.
					 */
					if (packet->info.type == TEAVPN_PACKET_DATA) {

						while (nread < (packet->info.len)) {
							register ssize_t tmp_nread;
							debug_log(3, "Read extra %ld/%ld bytes", nread, packet->info.len);
							tmp_nread = read(
								connections[i].fd,
								&(((char *)packet)[nread]),
								packet->info.len - nread
							);

							if (tmp_nread < 0) {
								connections[i].error++;
								perror("Error read extra");
							} else {
								nread += tmp_nread;
							}
						}

						connections[i].seq++;
						debug_log(3, "[%ld] Read from client %s:%d (server_seq: %ld) (client_seq: %ld) (seq %s)",
							connections[i].seq,
							inet_ntoa(connections[i].addr.sin_addr),
							ntohs(connections[i].addr.sin_port),
							connections[i].seq,
							packet->info.seq,
							(connections[i].seq == packet->info.seq) ? "match" : "invalid"
						);

						nwrite = write(tap_fd, &(packet->data.data), nread - TEAVPN_PACK(0));
						if (nwrite < 0) {
							connections[i].error++;
							perror("Error write to tap_fd");
							continue;
						}

						debug_log(3, "Write to tap_fd %ld bytes", nwrite);

					} else {
						connections[i].error++;
					}
				}
			}
		}


		/**
		 * Deal with new connection.
		 */
		if (FD_ISSET(m_pipe_fd[0], &rd_set)) {
			uint8_t sig_x;

			nread = read(m_pipe_fd[0], &sig_x, sizeof(sig_x));
			if (nread < 0) {
				debug_log(0, "Error read from m_pipe_fd[0]");
				perror("Error read from m_pipe_fd[0]");
			}
		}

		if (FD_ISSET(net_fd, &rd_set)) {
			pthread_cond_signal(&accept_worker_cond);
		}

		/**
		 * Since macro doesn't have scope limit, we have to undef here
		 * so that it doesn't distrub the outer scope of variable usage.
		 */
		#undef packet
	}

	close_server:
	close(m_pipe_fd[0]);
	close(m_pipe_fd[1]);
	close(net_fd);
	close(tap_fd);
	return 1;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
andq $-0x10, %rsp
subq $0x1a1a0, %rsp          # imm = 0x1A1A0
movq %rsp, %rbx
movq %rdi, %r13
movq %fs:0x28, %rax
movq %rax, 0x1a190(%rbx)
leaq 0x19c20(%rbx), %rax
movq %rax, 0x6d98(%rip)      # 0xb368
leaq 0x17a0(%rbx), %rax
movq %rax, 0x6d92(%rip)      # 0xb370
leaq 0x1020(%rbx), %rax
movq %rax, 0x6d8c(%rip)      # 0xb378
xorl %eax, %eax
movw $0x0, 0x17a0(%rbx,%rax)
addq $0x1030, %rax           # imm = 0x1030
cmpq $0x18480, %rax          # imm = 0x18480
jne 0x45ee
movl $0x12, %eax
movb $0x0, 0x19c0e(%rbx,%rax)
movq $-0x1, 0x19c16(%rbx,%rax)
movl $0xffffffff, 0x19c1e(%rbx,%rax) # imm = 0xFFFFFFFF
addq $0x18, %rax
cmpq $0x492, %rax            # imm = 0x492
jne 0x460b
xorl %r15d, %r15d
movzwl %r15w, %r15d
movl %r15d, %edi
callq 0x5d87
incl %r15d
cmpw $0x18, %r15w
jne 0x4639
cmpq $0x0, 0x8(%r13)
je 0x466a
leaq 0x20(%rbx), %rdi
movq %r13, %rsi
callq 0x2b90
testb %al, %al
je 0x47cd
movb 0x3c(%r13), %al
leaq 0x6daf(%rip), %rcx      # 0xb424
movb %al, (%rcx)
cmpq $0x0, 0x18(%r13)
je 0x47d6
leaq 0x6d0f(%rip), %rdi      # 0xb398
callq 0x21b0
testl %eax, %eax
js 0x4957
leaq 0x6d87(%rip), %rax      # 0xb424
cmpb $0x2, (%rax)
jb 0x46b0
leaq 0x3153(%rip), %rdi      # 0x77fc
xorl %eax, %eax
callq 0x5fb8
movq 0x20(%r13), %rdi
movl $0x1, %esi
callq 0x60d4
movl %eax, 0x6cd0(%rip)      # 0xb394
movq 0x20(%r13), %rsi
testl %eax, %eax
js 0x47e6
leaq 0x316f(%rip), %rdi      # 0x7846
xorl %eax, %eax
callq 0x5fb8
movq 0x20(%r13), %rdi
callq 0x2a80
movq %rax, %r12
movq 0x28(%r13), %rdi
callq 0x2a80
movq %rax, %r14
movq 0x30(%r13), %rdi
callq 0x2a80
movq %rax, %r15
movzwl 0x38(%r13), %ecx
leaq 0x3227(%rip), %rsi      # 0x7935
leaq 0x1a0a0(%rbx), %rdi
movq %r12, %rdx
xorl %eax, %eax
callq 0x2390
leaq 0x3241(%rip), %rsi      # 0x7967
leaq 0x1a120(%rbx), %rdi
movq %r12, %rdx
movq %r14, %rcx
movq %r15, %r8
xorl %eax, %eax
callq 0x2390
movq %r12, %rdi
callq 0x2030
movq %r14, %rdi
callq 0x2030
movq %r15, %rdi
callq 0x2030
leaq 0x3234(%rip), %rdi      # 0x7990
leaq 0x1a0a0(%rbx), %r14
movq %r14, %rsi
xorl %eax, %eax
callq 0x5fb8
movq %r14, %rdi
callq 0x2140
testl %eax, %eax
jne 0x47a1
leaq 0x3210(%rip), %rdi      # 0x7990
leaq 0x1a120(%rbx), %r15
movq %r15, %rsi
xorl %eax, %eax
callq 0x5fb8
movq %r15, %rdi
callq 0x2140
testl %eax, %eax
je 0x4831
leaq 0x3ab0(%rip), %rdi      # 0x8258
xorl %eax, %eax
callq 0x5fb8
movl 0x6be3(%rip), %edi      # 0xb398
callq 0x21a0
movl 0x6bdc(%rip), %edi      # 0xb39c
callq 0x21a0
movl 0x6bc9(%rip), %edi      # 0xb394
jmp 0x4805
leaq 0x2f9b(%rip), %rdi      # 0x776f
jmp 0x47dd
leaq 0x3a16(%rip), %rdi      # 0x81f3
xorl %eax, %eax
callq 0x5fb8
jmp 0x480a
leaq 0x3a3f(%rip), %rdi      # 0x822c
xorl %eax, %eax
callq 0x5fb8
movl 0x6b9e(%rip), %edi      # 0xb398
callq 0x21a0
movl 0x6b97(%rip), %edi      # 0xb39c
callq 0x21a0
movq %fs:0x28, %rax
cmpq 0x1a190(%rbx), %rax
jne 0x50fc
movb $0x1, %al
leaq -0x28(%rbp), %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
leaq 0x6bec(%rip), %rax      # 0xb424
cmpb $0x0, (%rax)
je 0x484b
leaq 0x302d(%rip), %rdi      # 0x7871
xorl %eax, %eax
callq 0x5fb8
movl $0x2, %edi
movl $0x1, %esi
xorl %edx, %edx
callq 0x2410
movl %eax, 0x6b2e(%rip)      # 0xb390
testl %eax, %eax
js 0x50cc
leaq 0x6bb3(%rip), %rax      # 0xb424
cmpb $0x0, (%rax)
je 0x489e
leaq 0x3022(%rip), %rdi      # 0x789f
xorl %eax, %eax
callq 0x5fb8
leaq 0x6b99(%rip), %rax      # 0xb424
cmpb $0x0, (%rax)
je 0x489e
leaq 0x39f0(%rip), %rdi      # 0x8287
xorl %eax, %eax
callq 0x5fb8
movl 0x6aec(%rip), %edi      # 0xb390
leaq 0x1a0a0(%rbx), %rcx
movl $0x1, (%rcx)
movl $0x1, %esi
movl $0x2, %edx
movl $0x4, %r8d
callq 0x20b0
testl %eax, %eax
js 0x50d6
leaq 0x6b4f(%rip), %rax      # 0xb424
cmpb $0x0, (%rax)
je 0x48e8
leaq 0x39df(%rip), %rdi      # 0x82c0
xorl %eax, %eax
callq 0x5fb8
movq %rsp, %r14
movzbl 0x3d(%r13), %esi
movb %sil, 0x6a89(%rip)      # 0xb380
movq %rsp, %rax
imull $0x68, %esi, %ecx
addl $0xf, %ecx
andl $-0x10, %ecx
subq %rcx, %rax
movq %rax, %rsp
movq %rax, 0x6a78(%rip)      # 0xb388
cmpl $0x3, %esi
jae 0x4961
leaq 0x3174(%rip), %rdi      # 0x7a90
xorl %eax, %eax
callq 0x5fb8
movl 0x6a6f(%rip), %edi      # 0xb398
callq 0x21a0
movl 0x6a68(%rip), %edi      # 0xb39c
callq 0x21a0
movl 0x6a51(%rip), %edi      # 0xb390
callq 0x21a0
movl 0x6a4a(%rip), %edi      # 0xb394
callq 0x21a0
movq %r14, %rsp
jmp 0x480a
callq 0x27f3
jmp 0x480a
movq %r14, 0x8(%rbx)
cmpb $0x0, 0x3d(%r13)
movq %r13, %r12
je 0x4a2f
leaq 0x3140(%rip), %r14      # 0x7aba
xorl %r13d, %r13d
xorl %r15d, %r15d
movq 0x6a01(%rip), %rax      # 0xb388
leaq (%rax,%r13), %rdi
addq $0x38, %rdi
movb $0x0, -0x38(%rdi)
movb %r15b, -0x37(%rdi)
xorl %esi, %esi
callq 0x22a0
movq 0x69e3(%rip), %rax      # 0xb388
leaq (%rax,%r13), %rdi
addq $0x10, %rdi
xorl %esi, %esi
callq 0x23d0
movq 0x69cd(%rip), %rcx      # 0xb388
leaq (%rcx,%r13), %rdi
addq $0x8, %rdi
addq %r13, %rcx
xorl %esi, %esi
leaq 0x732(%rip), %rdx       # 0x5101
callq 0x2310
movq 0x69ad(%rip), %rax      # 0xb388
movq 0x8(%rax,%r13), %rdi
callq 0x22e0
movq 0x6984(%rip), %rdi      # 0xb370
addq $0x10, %rdi
movq %r14, %rsi
movl %r15d, %edx
xorl %eax, %eax
callq 0x2390
movq 0x6984(%rip), %rax      # 0xb388
movq 0x8(%rax,%r13), %rdi
movq 0x6960(%rip), %rsi      # 0xb370
addq $0x10, %rsi
callq 0x2170
incq %r15
movzbl 0x3d(%r12), %eax
addq $0x68, %r13
cmpq %rax, %r15
jb 0x4980
movq 0x693a(%rip), %rax      # 0xb370
xorps %xmm0, %xmm0
movups %xmm0, 0x10(%rax)
movw $0x0, 0x20(%rax)
leaq 0x1a120(%rbx), %r15
movq $0x0, 0x8(%r15)
movw $0x2, (%r15)
movzwl 0x3a(%r12), %eax
rolw $0x8, %ax
movw %ax, 0x2(%r15)
movq (%r12), %rdi
callq 0x2210
movl %eax, 0x4(%r15)
movl 0x6916(%rip), %edi      # 0xb390
movq %r15, %rsi
movl $0x10, %edx
callq 0x2300
testl %eax, %eax
js 0x50e7
movl 0x68fb(%rip), %edi      # 0xb390
movl $0x3, %esi
callq 0x22f0
testl %eax, %eax
js 0x50ee
movl $0x1, %esi
movl $0xd, %edi
callq 0x2230
leaq 0x9b5(%rip), %rdx       # 0x5472
leaq 0x18(%rbx), %r15
movq %r15, %rdi
xorl %esi, %esi
movq %r12, %rcx
callq 0x2310
movq (%r15), %rdi
leaq 0x3035(%rip), %rsi      # 0x7b0d
callq 0x2170
movq (%r15), %rdi
callq 0x22e0
movq (%r12), %rsi
movzwl 0x3a(%r12), %edx
leaq 0x3025(%rip), %rdi      # 0x7b1b
xorl %eax, %eax
callq 0x5fb8
movl 0x6891(%rip), %edx      # 0xb394
movl 0x6887(%rip), %ecx      # 0xb390
movl 0x6889(%rip), %eax      # 0xb398
cmpl %eax, %ecx
movl %eax, %esi
cmovgl %ecx, %esi
cmpl %eax, %edx
xorps %xmm0, %xmm0
movaps %xmm0, 0x1a0a0(%rbx)
movaps %xmm0, 0x1a0b0(%rbx)
movaps %xmm0, 0x1a0c0(%rbx)
movaps %xmm0, 0x1a0d0(%rbx)
movaps %xmm0, 0x1a0e0(%rbx)
movaps %xmm0, 0x1a0f0(%rbx)
movaps %xmm0, 0x1a100(%rbx)
movaps %xmm0, 0x1a110(%rbx)
movl %esi, %r12d
cmovgl %edx, %r12d
cmpl %ecx, %edx
cmovlel %esi, %r12d
leal 0x3f(%rcx), %esi
testl %ecx, %ecx
cmovnsl %ecx, %esi
movl %esi, %edi
andl $-0x40, %edi
subl %edi, %ecx
movl $0x1, %edi
shlq %cl, %rdi
sarl $0x6, %esi
movslq %esi, %rcx
orq %rdi, 0x1a0a0(%rbx,%rcx,8)
leal 0x3f(%rdx), %esi
testl %edx, %edx
cmovnsl %edx, %esi
movl %esi, %ecx
andl $-0x40, %ecx
subl %ecx, %edx
movl $0x1, %edi
movl %edx, %ecx
shlq %cl, %rdi
sarl $0x6, %esi
movslq %esi, %rcx
orq %rdi, 0x1a0a0(%rbx,%rcx,8)
leal 0x3f(%rax), %edx
testl %eax, %eax
cmovnsl %eax, %edx
movl %edx, %ecx
andl $-0x40, %ecx
subl %ecx, %eax
movl $0x1, %esi
movl %eax, %ecx
shlq %cl, %rsi
sarl $0x6, %edx
movslq %edx, %rax
orq %rsi, 0x1a0a0(%rbx,%rax,8)
movl $0x4, %eax
movq 0x6799(%rip), %rdx      # 0xb378
cmpb $0x1, (%rdx,%rax)
jne 0x4c15
movl -0x4(%rdx,%rax), %ecx
cmpl %r12d, %ecx
cmovgl %ecx, %r12d
leal 0x3f(%rcx), %esi
testl %ecx, %ecx
cmovnsl %ecx, %esi
movl %esi, %edi
andl $-0x40, %edi
subl %edi, %ecx
movl $0x1, %edi
shlq %cl, %rdi
sarl $0x6, %esi
movslq %esi, %rcx
orq %rdi, 0x1a0a0(%rbx,%rcx,8)
addq $0x50, %rax
cmpq $0x784, %rax            # imm = 0x784
jne 0x4bdf
callq 0x5dd7
cmpw $-0x1, %ax
je 0x4c21
movl %eax, %r14d
incl %r12d
movl %r12d, %edi
leaq 0x1a0a0(%rbx), %rsi
xorl %edx, %edx
xorl %ecx, %ecx
xorl %r8d, %r8d
callq 0x2290
testl %eax, %eax
js 0x5084
movl 0x673e(%rip), %edi      # 0xb394
leal 0x3f(%rdi), %eax
testl %edi, %edi
cmovnsl %edi, %eax
sarl $0x6, %eax
cltq
movq 0x1a0a0(%rbx,%rax,8), %rax
btq %rdi, %rax
jae 0x4d58
movq 0x66f4(%rip), %rax      # 0xb370
movswq %r14w, %rcx
imulq $0x1030, %rcx, %r15     # imm = 0x1030
leaq (%rax,%r15), %rsi
addq $0x20, %rsi
movl $0xbb8, %edx            # imm = 0xBB8
callq 0x21d0
testq %rax, %rax
js 0x50b1
movq 0x66c7(%rip), %rcx      # 0xb370
movl $0x2, 0x10(%rcx,%r15)
addl $0x10, %eax
movw %ax, 0x14(%rcx,%r15)
xorl %r12d, %r12d
movq 0x66b3(%rip), %rax      # 0xb378
leaq (%r12,%r12,4), %rcx
shlq $0x4, %rcx
cmpb $0x1, 0x4(%rax,%rcx)
jne 0x4d4b
movq 0x6695(%rip), %rax      # 0xb370
incw (%rax,%r15)
movq 0x6681(%rip), %rax      # 0xb368
xorl %ecx, %ecx
cmpb $0x0, (%rax,%rcx)
je 0x4d0c
addq $0x18, %rcx
cmpq $0x480, %rcx            # imm = 0x480
jne 0x4ce9
leaq 0x2f4e(%rip), %rdi      # 0x7c51
xorl %eax, %eax
callq 0x5fb8
jmp 0x4ce0
movw $0x1, (%rax,%rcx)
movw %r12w, 0x10(%rax,%rcx)
movw %r14w, 0x12(%rax,%rcx)
movzbl 0x665b(%rip), %eax      # 0xb380
testq %rax, %rax
je 0x4d4b
movq 0x6657(%rip), %rdi      # 0xb388
addq $0x38, %rdi
cmpb $0x0, -0x38(%rdi)
je 0x4d46
addq $0x68, %rdi
decq %rax
jne 0x4d35
jmp 0x4d4b
callq 0x21f0
incq %r12
cmpq $0x18, %r12
jne 0x4cbe
xorl %r14d, %r14d
movq 0x6616(%rip), %rax      # 0xb378
leaq (%r14,%r14,4), %r15
shlq $0x4, %r15
cmpb $0x1, 0x4(%rax,%r15)
jne 0x500c
addq %r15, %rax
movl (%rax), %eax
leal 0x3f(%rax), %ecx
testl %eax, %eax
cmovnsl %eax, %ecx
sarl $0x6, %ecx
movslq %ecx, %rcx
movq 0x1a0a0(%rbx,%rcx,8), %rcx
btq %rax, %rcx
jae 0x500c
callq 0x5dd7
cmpw $-0x1, %ax
je 0x4d9b
movq 0x65cb(%rip), %rcx      # 0xb378
movl (%rcx,%r15), %edi
movq 0x65b8(%rip), %rcx      # 0xb370
movswq %ax, %rax
imulq $0x1030, %rax, %r13     # imm = 0x1030
leaq (%rcx,%r13), %rsi
addq $0x10, %rsi
movl $0xfa0, %edx            # imm = 0xFA0
callq 0x21d0
testq %rax, %rax
je 0x4e7e
js 0x4ff3
movq %rax, %r12
movq 0x6582(%rip), %rax      # 0xb370
cmpl $0x2, 0x10(%rax,%r13)
jne 0x4f0b
movzwl 0x14(%rax,%r13), %ecx
cmpq %rcx, %r12
jae 0x4f1c
leaq 0x6614(%rip), %rdx      # 0xb424
cmpb $0x3, (%rdx)
jb 0x4e30
movzwl %cx, %edx
leaq 0x28b9(%rip), %rdi      # 0x76d8
movq %r12, %rsi
xorl %eax, %eax
callq 0x5fb8
movq 0x6540(%rip), %rax      # 0xb370
movq 0x6541(%rip), %rcx      # 0xb378
movl (%rcx,%r15), %edi
leaq (%rax,%r13), %rcx
leaq (%r12,%rcx), %rsi
addq $0x10, %rsi
movzwl 0x14(%rax,%r13), %edx
subq %r12, %rdx
callq 0x21d0
testq %rax, %rax
js 0x4e74
addq %rax, %r12
movq 0x650c(%rip), %rax      # 0xb370
movzwl 0x14(%rax,%r13), %ecx
cmpq %rcx, %r12
jl 0x4e09
jmp 0x4f1c
movq %r14, %rdi
callq 0x25f3
jmp 0x4e5d
movq 0x64f3(%rip), %rax      # 0xb378
movl (%rax,%r15), %ecx
movq $-0x2, %rax
rolq %cl, %rax
leal 0x3f(%rcx), %edx
testl %ecx, %ecx
cmovnsl %ecx, %edx
sarl $0x6, %edx
movslq %edx, %rdx
andq %rax, 0x1a0a0(%rbx,%rdx,8)
movl %ecx, %edi
callq 0x21a0
leaq 0x656d(%rip), %rax      # 0xb424
cmpb $0x0, (%rax)
je 0x4efd
movq 0x64b5(%rip), %rax      # 0xb378
movq %r14, %rcx
shlq $0x4, %rcx
leaq (%rcx,%rcx,4), %r15
movl 0x44(%rax,%r15), %edi
callq 0x20d0
movq 0x6499(%rip), %rcx      # 0xb378
movzwl 0x42(%rcx,%r15), %ecx
rolw $0x8, %cx
movzwl %cx, %edx
leaq 0x2c3e(%rip), %rdi      # 0x7b31
movq %rax, %rsi
xorl %eax, %eax
callq 0x5fb8
movzwl %r14w, %edi
callq 0x5d87
jmp 0x500c
movq 0x6466(%rip), %rax      # 0xb378
incb 0x5(%rax,%r15)
jmp 0x500c
movq 0x6455(%rip), %rcx      # 0xb378
movq 0x8(%rcx,%r15), %rsi
incq %rsi
movq %rsi, 0x8(%rcx,%r15)
leaq 0x64ed(%rip), %rdx      # 0xb424
cmpb $0x3, (%rdx)
jb 0x4fb5
movq %r14, %rax
shlq $0x4, %rax
leaq (%rax,%rax,4), %r15
movl 0x44(%rcx,%r15), %edi
movq %rsi, 0x8(%rbx)
callq 0x20d0
movq 0x641c(%rip), %rdx      # 0xb378
movzwl 0x42(%rdx,%r15), %ecx
rolw $0x8, %cx
movzwl %cx, %ecx
movq 0x8(%rdx,%r15), %r8
movq 0x63fb(%rip), %rdx      # 0xb370
movq 0x18(%rdx,%r13), %r9
cmpq %r9, %r8
leaq 0x25aa(%rip), %r10      # 0x752e
leaq 0x259d(%rip), %rdx      # 0x7528
cmoveq %rdx, %r10
subq $0x8, %rsp
leaq 0x2c3a(%rip), %rdi      # 0x7bd4
movq 0x8(%rbx), %rsi
movq %rax, %rdx
xorl %eax, %eax
pushq %r10
callq 0x5fb8
addq $0x10, %rsp
movq 0x63bb(%rip), %rax      # 0xb370
movl 0x63d9(%rip), %edi      # 0xb394
leaq (%rax,%r13), %rsi
addq $0x20, %rsi
addq $-0x10, %r12
movq %r12, %rdx
callq 0x20c0
testq %rax, %rax
js 0x5004
leaq 0x6449(%rip), %rcx      # 0xb424
cmpb $0x3, (%rcx)
jb 0x500c
leaq 0x276e(%rip), %rdi      # 0x7755
movq %rax, %rsi
xorl %eax, %eax
callq 0x5fb8
jmp 0x500c
movq %r14, %rdi
leaq 0x1a0a0(%rbx), %rsi
callq 0x2643
jmp 0x500c
movq %r14, %rdi
callq 0x261b
incq %r14
cmpq $0x18, %r14
jne 0x4d5b
movl 0x6379(%rip), %edi      # 0xb398
leal 0x3f(%rdi), %eax
testl %edi, %edi
cmovnsl %edi, %eax
sarl $0x6, %eax
cltq
movq 0x1a0a0(%rbx,%rax,8), %rax
btq %rdi, %rax
jae 0x504d
movl $0x1, %edx
leaq 0x17(%rbx), %rsi
callq 0x21d0
testq %rax, %rax
js 0x50bb
movl 0x633d(%rip), %eax      # 0xb390
leal 0x3f(%rax), %ecx
testl %eax, %eax
cmovnsl %eax, %ecx
sarl $0x6, %ecx
movslq %ecx, %rcx
movq 0x1a0a0(%rbx,%rcx,8), %rcx
btq %rax, %rcx
jae 0x4afd
leaq 0x6326(%rip), %rdi      # 0xb3a0
callq 0x21f0
jmp 0x4afd
callq 0x2050
cmpl $0x4, (%rax)
jne 0x50c2
leaq 0x638f(%rip), %rax      # 0xb424
cmpb $0x2, (%rax)
jb 0x4afd
leaq 0x2586(%rip), %rdi      # 0x762b
xorl %eax, %eax
callq 0x5fb8
jmp 0x4afd
callq 0x25c6
jmp 0x4d58
callq 0x2709
jmp 0x504d
callq 0x2736
jmp 0x4afd
callq 0x27ab
jmp 0x480a
leaq 0x1a0a0(%rbx), %rdi
callq 0x2573
jmp 0x480a
callq 0x2784
jmp 0x50f3
callq 0x275d
movq 0x8(%rbx), %r14
jmp 0x4923
callq 0x2110