// File: ctz[P]openssl-bench/bench.cc
// Function: main
int main(int argc, char **argv) {
  Context server_ctx = Context::server();
  Context client_ctx = Context::client();

  argv += 1;
  argc -= 1;

  if (argc < 2) {
    return usage();
  }

  unsigned n_threads = 1;
  if (strcmp(argv[0], "--threads") == 0) {
    n_threads = unsigned(atoi(argv[1]));
    argv += 2;
    argc -= 2;
    if (n_threads == 0) {
      puts("bad --threads count");
      return usage();
    }
  }

  KeyType key_type;
  if (strcmp(argv[0], "--rsa") == 0) {
    key_type = KeyType::RSA2048;
    argv += 1;
    argc -= 1;
  } else if (strcmp(argv[0], "--ecdsa") == 0) {
    key_type = KeyType::ECDSAP256;
    argv += 1;
    argc -= 1;
  } else {
    key_type = KeyType::RSA2048;
  }

  if (argc < 2) {
    return usage();
  }

  server_ctx.set_ciphers(argv[1]);
  client_ctx.set_ciphers(argv[1]);
  server_ctx.load_server_creds(key_type);
  client_ctx.load_client_creds(key_type);

  if (!strcmp(argv[0], "bulk") && argc == 3) {
    test_bulk(n_threads, server_ctx, client_ctx, atoi(argv[2]));
  } else if (!strcmp(argv[0], "handshake")) {
    test_handshake(n_threads, server_ctx, client_ctx);
  } else if (!strcmp(argv[0], "handshake-resume")) {
    test_handshake_resume(n_threads, server_ctx, client_ctx, false);
  } else if (!strcmp(argv[0], "handshake-ticket")) {
    test_handshake_resume(n_threads, server_ctx, client_ctx, true);
  } else if (!strcmp(argv[0], "memory")) {
    test_memory(server_ctx, client_ctx, atoi(argv[2]));
  } else {
    return usage();
  }

  return 0;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x50, %rsp
movl $0x0, -0x4(%rbp)
movl %edi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
leaq -0x18(%rbp), %rdi
callq 0x5eb0
leaq -0x20(%rbp), %rdi
callq 0x5ef0
jmp 0x376a
movq -0x10(%rbp), %rax
addq $0x8, %rax
movq %rax, -0x10(%rbp)
movl -0x8(%rbp), %eax
subl $0x1, %eax
movl %eax, -0x8(%rbp)
cmpl $0x2, -0x8(%rbp)
jge 0x37cc
callq 0x3a90
movl %eax, -0x3c(%rbp)
jmp 0x378f
movl -0x3c(%rbp), %eax
movl %eax, -0x4(%rbp)
movl $0x1, -0x30(%rbp)
jmp 0x3a5f
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x28(%rbp)
movl %eax, -0x2c(%rbp)
jmp 0x3a7a
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x28(%rbp)
movl %eax, -0x2c(%rbp)
leaq -0x20(%rbp), %rdi
callq 0x61a0
jmp 0x3a7a
movl $0x1, -0x34(%rbp)
movq -0x10(%rbp), %rax
movq (%rax), %rdi
leaq 0xa867(%rip), %rsi      # 0xe048
callq 0x3490
cmpl $0x0, %eax
jne 0x3842
movq -0x10(%rbp), %rax
movq 0x8(%rax), %rdi
callq 0x3510
movl %eax, -0x34(%rbp)
movq -0x10(%rbp), %rax
addq $0x10, %rax
movq %rax, -0x10(%rbp)
movl -0x8(%rbp), %eax
subl $0x2, %eax
movl %eax, -0x8(%rbp)
cmpl $0x0, -0x34(%rbp)
jne 0x3840
leaq 0xa835(%rip), %rdi      # 0xe052
callq 0x34f0
jmp 0x3824
callq 0x3a90
movl %eax, -0x40(%rbp)
jmp 0x382e
movl -0x40(%rbp), %eax
movl %eax, -0x4(%rbp)
movl $0x1, -0x30(%rbp)
jmp 0x3a5f
jmp 0x3842
movq -0x10(%rbp), %rax
movq (%rax), %rdi
leaq 0xa816(%rip), %rsi      # 0xe066
callq 0x3490
cmpl $0x0, %eax
jne 0x3878
movl $0x0, -0x38(%rbp)
movq -0x10(%rbp), %rax
addq $0x8, %rax
movq %rax, -0x10(%rbp)
movl -0x8(%rbp), %eax
subl $0x1, %eax
movl %eax, -0x8(%rbp)
jmp 0x38b7
movq -0x10(%rbp), %rax
movq (%rax), %rdi
leaq 0xa7e6(%rip), %rsi      # 0xe06c
callq 0x3490
cmpl $0x0, %eax
jne 0x38ae
movl $0x1, -0x38(%rbp)
movq -0x10(%rbp), %rax
addq $0x8, %rax
movq %rax, -0x10(%rbp)
movl -0x8(%rbp), %eax
subl $0x1, %eax
movl %eax, -0x8(%rbp)
jmp 0x38b5
movl $0x0, -0x38(%rbp)
jmp 0x38b7
cmpl $0x2, -0x8(%rbp)
jge 0x38d9
callq 0x3a90
movl %eax, -0x44(%rbp)
jmp 0x38c7
movl -0x44(%rbp), %eax
movl %eax, -0x4(%rbp)
movl $0x1, -0x30(%rbp)
jmp 0x3a5f
movq -0x10(%rbp), %rax
movq 0x8(%rax), %rsi
leaq -0x18(%rbp), %rdi
callq 0x5f30
jmp 0x38ec
movq -0x10(%rbp), %rax
movq 0x8(%rax), %rsi
leaq -0x20(%rbp), %rdi
callq 0x5f30
jmp 0x38ff
movl -0x38(%rbp), %esi
leaq -0x18(%rbp), %rdi
callq 0x5fd0
jmp 0x390d
movl -0x38(%rbp), %esi
leaq -0x20(%rbp), %rdi
callq 0x6110
jmp 0x391b
movq -0x10(%rbp), %rax
movq (%rax), %rdi
leaq 0xa74b(%rip), %rsi      # 0xe074
callq 0x3490
cmpl $0x0, %eax
jne 0x3966
cmpl $0x3, -0x8(%rbp)
jne 0x3966
movl -0x34(%rbp), %eax
movl %eax, -0x48(%rbp)
movq -0x10(%rbp), %rax
movq 0x10(%rax), %rdi
callq 0x3510
movl -0x48(%rbp), %edi
movslq %eax, %rcx
leaq -0x18(%rbp), %rsi
leaq -0x20(%rbp), %rdx
callq 0x3ac0
jmp 0x3961
jmp 0x3a51
movq -0x10(%rbp), %rax
movq (%rax), %rdi
leaq 0xa705(%rip), %rsi      # 0xe079
callq 0x3490
cmpl $0x0, %eax
jne 0x3995
movl -0x34(%rbp), %edi
leaq -0x18(%rbp), %rsi
leaq -0x20(%rbp), %rdx
callq 0x3f80
jmp 0x3990
jmp 0x3a4f
movq -0x10(%rbp), %rax
movq (%rax), %rdi
leaq 0xa6e0(%rip), %rsi      # 0xe083
callq 0x3490
cmpl $0x0, %eax
jne 0x39c6
movl -0x34(%rbp), %edi
leaq -0x18(%rbp), %rsi
leaq -0x20(%rbp), %rdx
xorl %ecx, %ecx
callq 0x43f0
jmp 0x39c1
jmp 0x3a4d
movq -0x10(%rbp), %rax
movq (%rax), %rdi
leaq 0xa6c0(%rip), %rsi      # 0xe094
callq 0x3490
cmpl $0x0, %eax
jne 0x39f7
movl -0x34(%rbp), %edi
leaq -0x18(%rbp), %rsi
leaq -0x20(%rbp), %rdx
movl $0x1, %ecx
callq 0x43f0
jmp 0x39f5
jmp 0x3a4b
movq -0x10(%rbp), %rax
movq (%rax), %rdi
leaq 0xa6a0(%rip), %rsi      # 0xe0a5
callq 0x3490
cmpl $0x0, %eax
jne 0x3a30
movq -0x10(%rbp), %rax
movq 0x10(%rax), %rdi
callq 0x3510
movslq %eax, %rdx
leaq -0x18(%rbp), %rdi
leaq -0x20(%rbp), %rsi
callq 0x4970
jmp 0x3a2e
jmp 0x3a49
callq 0x3a90
movl %eax, -0x4c(%rbp)
jmp 0x3a3a
movl -0x4c(%rbp), %eax
movl %eax, -0x4(%rbp)
movl $0x1, -0x30(%rbp)
jmp 0x3a5f
jmp 0x3a4b
jmp 0x3a4d
jmp 0x3a4f
jmp 0x3a51
movl $0x0, -0x4(%rbp)
movl $0x1, -0x30(%rbp)
leaq -0x20(%rbp), %rdi
callq 0x61a0
leaq -0x18(%rbp), %rdi
callq 0x61a0
movl -0x4(%rbp), %eax
addq $0x50, %rsp
popq %rbp
retq
leaq -0x18(%rbp), %rdi
callq 0x61a0
movq -0x28(%rbp), %rdi
callq 0x3590
nopl (%rax)