// File: /workspace/github_cpp_makefile_star2_O2/DavieV[P]virtual-usb-printer/main.cc
// Function: main
int main() {
  const USB_DEVICE_DESCRIPTOR device = {
      0x12,                   // Size of this descriptor in bytes
      USB_DESCRIPTOR_DEVICE,  // descriptor type
      0x0110,                 // USB Spec Release Number in BCD format
      0x00,                   // Class Code
      0x00,                   // Subclass code
      0x00,                   // Protocol code
      0x08,                   // Max packet size for EP0, see usb_config.h
      0x04a9,                 // Vendor ID
      0x27e8,                 // Product ID
      0x0000,                 // Device release number in BCD format
      0x01,                   // Manufacturer string descriptor index
      0x02,                   // Product string descriptor index
      0x01,                   // Device serial number string descriptor index
      0x01,                   // Number of possible configurations
  };

  const USB_CONFIGURATION_DESCRIPTOR configuration = {
      0x09,                          // Size of this descriptor in bytes.
      USB_DESCRIPTOR_CONFIGURATION,  // descriptor type.
      0x20,  // Total length of data for this configuration.
      0x01,  // Number of interfaces in this configuration.
      0x01,  // Index value for this configuration.
      0x00,  // Configuration string descriptor index.
      0x80,  // Configuration characteristics (bmAttributes).
      0x00,  // Max power consumption (2X mA).
  };

  std::vector<char> str1 = {
      0x04, USB_DESCRIPTOR_STRING, // bLength, bDscType
      0x09, 0x04
  };

  std::vector<char> str2 = {
      0x0E, USB_DESCRIPTOR_STRING, // bLength, bDscType
      'D', 0x00,
      'a', 0x00,
      'v', 0x00,
      'i', 0x00,
      'e', 0x00,
      'V', 0x00,
  };

  std::vector<char> str3 = {
      0x28, USB_DESCRIPTOR_STRING, // bLength, bDscType
      'V', 0x00,
      'i', 0x00,
      'r', 0x00,
      't', 0x00,
      'u', 0x00,
      'a', 0x00,
      'l', 0x00,
      ' ', 0x00,
      'U', 0x00,
      'S', 0x00,
      'B', 0x00,
      ' ', 0x00,
      'P', 0x00,
      'r', 0x00,
      'i', 0x00,
      'n', 0x00,
      't', 0x00,
      'e', 0x00,
      'r', 0x00,
  };

  const std::vector<std::vector<char>> strings = {str1, str2, str3};

  const std::vector<char> ieee_device_id = {
    0x00, 0x1A,  // Length (26 bytes)
    'M', 'F', 'G', ':', 'D', 'V', '3', ';',
    'C', 'M', 'D', ':', 'P', 'D', 'F', ';',
    'M', 'D', 'L', ':', 'V', 'T', 'L', ';',
  };

  const std::vector<USB_INTERFACE_DESCRIPTOR> interfaces = {
      {
          0x09,                      // Size of this descriptor in bytes
          USB_DESCRIPTOR_INTERFACE,  // descriptor type.
          0x00,                      // Interface Number.
          0x00,                      // Alternate Setting Number.
          0x02,                      // Number of endpoints in this interface.
          0x07,                      // Class code.
          0x01,                      // Subclass code.
          0x02,                      // Protocol code.
          0x00,                      // Interface string index.
      },
      /*
      {
          0x09,                      // Size of this descriptor in bytes
          USB_DESCRIPTOR_INTERFACE,  // descriptor type.
          0x01,                      // Interface Number.
          0x00,                      // Alternate Setting Number.
          0x02,                      // Number of endpoints in this interface.
          0x07,                      // Class code.
          0x01,                      // Subclass code.
          0x02,                      // Protocol code.
          0x00,                      // Interface string index.
      }*/};

  const std::vector<USB_ENDPOINT_DESCRIPTOR> endpoints = {
      {
          0x07,                     // Size of this descriptor in bytes.
          USB_DESCRIPTOR_ENDPOINT,  // descriptor type.
          0x01,                     // Endpoint Address.
          0x02,                     // Attributes (Bulk Endpoint).
          512,                      // Max transfer size.
          0x00,                     // Interval.
      },
      {
          0x07,                     // Size of this descriptor in bytes.
          USB_DESCRIPTOR_ENDPOINT,  // descriptor type.
          0x81,                     // Endpoint Address.
          0x02,                     // Attributes (Bulk Endpoint).
          512,                      // Max transfer size.
          0x00,                     // Interval.
      },
      /*
      {
          0x07,                     // Size of this descriptor in bytes.
          USB_DESCRIPTOR_ENDPOINT,  // descriptor type.
          0x03,                     // Endpoint Address.
          0x02,                     // Attributes (Bulk Endpoint).
          0x08,                     // Max transfer size.
          0x00,                     // Interval.
      },
      {
          0x07,                     // Size of this descriptor in bytes.
          USB_DESCRIPTOR_ENDPOINT,  // descriptor type.
          0x84,                     // Endpoint Address.
          0x02,                     // Attributes (Bulk Endpoint).
          0x08,                     // Max transfer size.
          0x00,                     // Interval.
      }*/};

  UsbPrinter printer(device, configuration, strings, ieee_device_id, interfaces,
                     endpoints);
  run_server(printer);
}

// Assembly:
pushq %r15
pushq %r14
pushq %rbx
subq $0x200, %rsp            # imm = 0x200
movups 0xd61(%rip), %xmm0      # 0x34f4
movaps %xmm0, 0xa0(%rsp)
movw $0x101, 0xb0(%rsp)      # imm = 0x101
movabsq $-0x7ffffefeffdffdf7, %rax # imm = 0x8000010100200209
movq %rax, 0x18(%rsp)
movb $0x0, 0x20(%rsp)
leaq 0x100(%rsp), %rbx
movl $0x4090304, (%rbx)      # imm = 0x4090304
leaq 0xe8(%rsp), %rdi
pushq $0x4
popq %rdx
leaq 0x88(%rsp), %rcx
movq %rbx, %rsi
callq 0x2b40
movabsq $0x7600610044030e, %rax # imm = 0x7600610044030E
movq %rax, (%rbx)
movl $0x650069, 0x8(%rbx)    # imm = 0x650069
movw $0x56, 0xc(%rbx)
leaq 0x88(%rsp), %rdi
leaq 0x100(%rsp), %rsi
pushq $0xe
popq %rdx
leaq 0x70(%rsp), %rcx
callq 0x2b40
movups 0xcff(%rip), %xmm0      # 0x351f
leaq 0x100(%rsp), %rsi
movaps %xmm0, 0x10(%rsi)
movups 0xcdc(%rip), %xmm0      # 0x350f
movaps %xmm0, (%rsi)
movabsq $0x7200650074006e, %rax # imm = 0x7200650074006E
movq %rax, 0x20(%rsi)
leaq 0x70(%rsp), %rdi
pushq $0x28
popq %rdx
leaq 0x58(%rsp), %rcx
callq 0x2b40
leaq 0x100(%rsp), %r14
leaq 0xe8(%rsp), %rsi
movq %r14, %rdi
callq 0x2118
leaq 0x118(%rsp), %r15
leaq 0x88(%rsp), %rsi
movq %r15, %rdi
callq 0x2118
leaq 0x130(%rsp), %r15
leaq 0x70(%rsp), %rsi
movq %r15, %rdi
callq 0x2118
leaq 0x58(%rsp), %rdi
leaq 0x100(%rsp), %rsi
pushq $0x3
popq %rdx
leaq 0x40(%rsp), %rcx
callq 0x2b76
pushq $0x30
popq %rbx
leaq (%rsp,%rbx), %rdi
addq $0x100, %rdi            # imm = 0x100
callq 0x23a6
addq $-0x18, %rbx
cmpq $-0x18, %rbx
jne 0x28b8
movups 0xc68(%rip), %xmm0      # 0x3541
leaq 0x100(%rsp), %rsi
movups %xmm0, 0xa(%rsi)
movups 0xc4b(%rip), %xmm0      # 0x3537
movaps %xmm0, (%rsi)
leaq 0x40(%rsp), %rdi
pushq $0x1a
popq %rdx
leaq 0x28(%rsp), %rcx
callq 0x2b40
movabsq $0x201070200000409, %rax # imm = 0x201070200000409
leaq 0x100(%rsp), %rsi
movq %rax, (%rsi)
movb $0x0, 0x8(%rsi)
leaq 0x28(%rsp), %rdi
pushq $0x1
popq %rdx
leaq 0xd0(%rsp), %rcx
callq 0x2bb0
leaq 0x100(%rsp), %rsi
movl $0x2010507, (%rsi)      # imm = 0x2010507
movw $0x200, %ax             # imm = 0x200
movw %ax, 0x4(%rsi)
movl $0x81050700, 0x6(%rsi)  # imm = 0x81050700
movb $0x2, 0xa(%rsi)
movw %ax, 0xb(%rsi)
movb $0x0, 0xd(%rsi)
leaq 0xd0(%rsp), %rbx
pushq $0x2
popq %rdx
leaq 0x17(%rsp), %rcx
movq %rbx, %rdi
callq 0x2bea
leaq 0xb8(%rsp), %rdi
leaq 0x40(%rsp), %rsi
callq 0x2118
movq %rbx, (%rsp)
leaq 0x100(%rsp), %rdi
leaq 0xa0(%rsp), %rsi
leaq 0x18(%rsp), %rdx
leaq 0x58(%rsp), %rcx
leaq 0xb8(%rsp), %r8
leaq 0x28(%rsp), %r9
callq 0x1adc
leaq 0xb8(%rsp), %rdi
callq 0x23a6
leaq 0x180(%rsp), %rdi
leaq 0x100(%rsp), %rsi
callq 0x2c24
leaq 0x180(%rsp), %rdi
callq 0x2560
leaq 0x180(%rsp), %rdi
callq 0x2cbe
leaq 0x100(%rsp), %rdi
callq 0x2cbe
leaq 0xd0(%rsp), %rdi
callq 0x2cea
leaq 0x28(%rsp), %rdi
callq 0x1a24
leaq 0x40(%rsp), %rdi
callq 0x23a6
leaq 0x58(%rsp), %rdi
callq 0x21b6
leaq 0x70(%rsp), %rdi
callq 0x23a6
leaq 0x88(%rsp), %rdi
callq 0x23a6
leaq 0xe8(%rsp), %rdi
callq 0x23a6
xorl %eax, %eax
addq $0x200, %rsp            # imm = 0x200
popq %rbx
popq %r14
popq %r15
retq
movq %rax, %rbx
leaq 0x180(%rsp), %rdi
callq 0x2cbe
jmp 0x2a6e
movq %rax, %rbx
leaq 0x100(%rsp), %rdi
callq 0x2cbe
jmp 0x2a92
movq %rax, %rbx
leaq 0xb8(%rsp), %rdi
callq 0x23a6
jmp 0x2a92
movq %rax, %rbx
leaq 0xd0(%rsp), %rdi
callq 0x2cea
jmp 0x2aa4
movq %rax, %rbx
leaq 0x28(%rsp), %rdi
callq 0x1a24
leaq 0x40(%rsp), %rdi
callq 0x23a6
leaq 0x58(%rsp), %rdi
callq 0x21b6
jmp 0x2b14
movq %rax, %rbx
jmp 0x2aae
movq %rax, %rbx
jmp 0x2ab8
movq %rax, %rbx
pushq $0x30
popq %r14
leaq (%rsp,%r14), %rdi
addq $0x100, %rdi            # imm = 0x100
callq 0x23a6
addq $-0x18, %r14
cmpq $-0x18, %r14
jne 0x2ad5
jmp 0x2b14
movq %rax, %rbx
jmp 0x2b14
movq %rax, %rbx
jmp 0x2b1e
movq %rax, %rbx
jmp 0x2b2b
movq %rax, %rbx
addq $-0x18, %r15
movq %r15, %rdi
callq 0x23a6
cmpq %r14, %r15
jne 0x2b03
leaq 0x70(%rsp), %rdi
callq 0x23a6
leaq 0x88(%rsp), %rdi
callq 0x23a6
leaq 0xe8(%rsp), %rdi
callq 0x23a6
movq %rbx, %rdi
callq 0x1210