// File: /workspace/github_c_makefile_star2_O2/FH0[P]tun_direct/lwip-2.1.2/src/core/tcp_out.c
// Function: tcp_create_segment
static struct tcp_seg *
tcp_create_segment(const struct tcp_pcb *pcb, struct pbuf *p, u8_t hdrflags, u32_t seqno, u8_t optflags)
{
  struct tcp_seg *seg;
  u8_t optlen;

  LWIP_ASSERT("tcp_create_segment: invalid pcb", pcb != NULL);
  LWIP_ASSERT("tcp_create_segment: invalid pbuf", p != NULL);

  optlen = LWIP_TCP_OPT_LENGTH_SEGMENT(optflags, pcb);

  if ((seg = (struct tcp_seg *)memp_malloc(MEMP_TCP_SEG)) == NULL) {
    LWIP_DEBUGF(TCP_OUTPUT_DEBUG | LWIP_DBG_LEVEL_SERIOUS, ("tcp_create_segment: no memory.\n"));
    pbuf_free(p);
    return NULL;
  }
  seg->flags = optflags;
  seg->next = NULL;
  seg->p = p;
  LWIP_ASSERT("p->tot_len >= optlen", p->tot_len >= optlen);
  seg->len = p->tot_len - optlen;
#if TCP_OVERSIZE_DBGCHECK
  seg->oversize_left = 0;
#endif /* TCP_OVERSIZE_DBGCHECK */
#if TCP_CHECKSUM_ON_COPY
  seg->chksum = 0;
  seg->chksum_swapped = 0;
  /* check optflags */
  LWIP_ASSERT("invalid optflags passed: TF_SEG_DATA_CHECKSUMMED",
              (optflags & TF_SEG_DATA_CHECKSUMMED) == 0);
#endif /* TCP_CHECKSUM_ON_COPY */

  /* build TCP header */
  if (pbuf_add_header(p, TCP_HLEN)) {
    LWIP_DEBUGF(TCP_OUTPUT_DEBUG | LWIP_DBG_LEVEL_SERIOUS, ("tcp_create_segment: no room for TCP header in pbuf.\n"));
    TCP_STATS_INC(tcp.err);
    tcp_seg_free(seg);
    return NULL;
  }
  seg->tcphdr = (struct tcp_hdr *)seg->p->payload;
  seg->tcphdr->src = lwip_htons(pcb->local_port);
  seg->tcphdr->dest = lwip_htons(pcb->remote_port);
  seg->tcphdr->seqno = lwip_htonl(seqno);
  /* ackno is set in tcp_output */
  TCPH_HDRLEN_FLAGS_SET(seg->tcphdr, (5 + optlen / 4), hdrflags);
  /* wnd and chksum are set in tcp_output */
  seg->tcphdr->urgp = 0;
  return seg;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
pushq %rax
testq %rsi, %rsi
je 0xb249
movl %r8d, %r13d
movl %ecx, %r14d
movl %edx, %ebp
movq %rsi, %r12
movq %rdi, %r15
pushq $0x4
popq %rdi
callq 0x3b4a
testq %rax, %rax
je 0xb1c2
movq %rax, %rbx
movl %ebp, 0x4(%rsp)
leal (,%r13,4), %ecx
andb $0x4, %cl
movb %r13b, 0x17(%rax)
andq $0x0, (%rax)
movq %r12, 0x8(%rax)
movzwl 0x10(%r12), %eax
movzbl %cl, %ebp
cmpw %bp, %ax
jb 0xb265
movzwl %bp, %ecx
subl %ecx, %eax
movw %ax, 0x10(%rbx)
andl $0x0, 0x12(%rbx)
movb $0x0, 0x16(%rbx)
testb $0x4, %r13b
jne 0xb281
pushq $0x14
popq %rsi
movq %r12, %rdi
callq 0x504c
testb %al, %al
je 0xb1ce
movq %rbx, %rdi
callq 0x7e33
jmp 0xb1ca
movq %r12, %rdi
callq 0x4e16
xorl %ebx, %ebx
jmp 0xb237
movq 0x8(%rbx), %rax
movq 0x8(%rax), %rax
movq %rax, 0x18(%rbx)
movzwl 0x4e(%r15), %edi
callq 0x12ed0
movq 0x18(%rbx), %rcx
movw %ax, (%rcx)
movzwl 0x50(%r15), %edi
callq 0x12ed0
movq 0x18(%rbx), %rcx
movw %ax, 0x2(%rcx)
movl %r14d, %edi
callq 0x12ed7
movq 0x18(%rbx), %rcx
movl %eax, 0x4(%rcx)
shrb $0x2, %bpl
addb $0x5, %bpl
movzbl %bpl, %eax
shll $0xc, %eax
movzbl 0x4(%rsp), %ecx
orl %eax, %ecx
movzwl %cx, %edi
callq 0x12ed0
movq 0x18(%rbx), %rcx
movw %ax, 0xc(%rcx)
andw $0x0, 0x12(%rcx)
movq %rbx, %rax
addq $0x8, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
leaq 0x907c(%rip), %rdi      # 0x142cc
leaq 0xab3e(%rip), %rsi      # 0x15d95
leaq 0xa539(%rip), %rcx      # 0x15797
movl $0xa4, %edx
jmp 0xb29b
leaq 0x9060(%rip), %rdi      # 0x142cc
leaq 0xab43(%rip), %rsi      # 0x15db6
leaq 0xa51d(%rip), %rcx      # 0x15797
movl $0xb0, %edx
jmp 0xb29b
leaq 0x9044(%rip), %rdi      # 0x142cc
leaq 0xab3c(%rip), %rsi      # 0x15dcb
leaq 0xa501(%rip), %rcx      # 0x15797
movl $0xba, %edx
xorl %eax, %eax
callq 0x20d0
xorl %edi, %edi
callq 0x21b0
callq 0x2050