// File: /workspace/github_c_makefile_star2_O0/lukexi[P]eglstreams-mini/src/edid.c
// Function: edid_parse
int edid_parse(drm_edid* edid, const uint8_t* data, size_t length) {
   char* tmp;
   int i;
   int rc = 0;
   uint32_t serial;

   /* check header */
   if (length < 128) {
       rc = -1;
       goto out;
   }
   if (data[0] != 0x00 || data[1] != 0xff) {
       rc = -1;
       goto out;
   }

   /* decode the PNP ID from three 5 bit words packed into 2 bytes
    * /--08--\/--09--\
    * 7654321076543210
    * |\---/\---/\---/
    * R  C1   C2   C3 */
   edid->PNPID = malloc(4);
   edid->PNPID[0] = 'A' + ((data[EDID_OFFSET_PNPID+0] & 0x7c) / 4) - 1;
   edid->PNPID[1] = 'A' + ((data[EDID_OFFSET_PNPID+0] & 0x3) * 8) + ((data[EDID_OFFSET_PNPID+1] & 0xe0) / 32) - 1;
   edid->PNPID[2] = 'A' + (data[EDID_OFFSET_PNPID+1] & 0x1f) - 1;
   edid->PNPID[3] = '\0';;

   /* maybe there isn't a ASCII serial number descriptor, so use this instead */
   serial = (int32_t) data[EDID_OFFSET_SERIAL+0];
   serial += (int32_t) data[EDID_OFFSET_SERIAL+1] * 0x100;
   serial += (int32_t) data[EDID_OFFSET_SERIAL+2] * 0x10000;
   serial += (int32_t) data[EDID_OFFSET_SERIAL+3] * 0x1000000;
   if (serial > 0) {
       edid->SerialNumber = malloc(9);
       sprintf (edid->SerialNumber, "%li", (long int) serial);
   }

   /* parse EDID data */
   for (i = EDID_OFFSET_DATA_BLOCKS;
        i <= EDID_OFFSET_LAST_BLOCK;
        i += 18) {
       /* ignore pixel clock data */
       if (data[i] != 0)
           continue;
       if (data[i+2] != 0)
           continue;

       /* any useful blocks? */
       if (data[i+3] == EDID_DESCRIPTOR_DISPLAY_PRODUCT_NAME) {
           tmp = edid_parse_string (&data[i+5]);
           if (tmp != NULL) {
               free (edid->MonitorName);
               edid->MonitorName = tmp;
           }
       } else if (data[i+3] == EDID_DESCRIPTOR_DISPLAY_PRODUCT_SERIAL_NUMBER) {
           tmp = edid_parse_string (&data[i+5]);
           if (tmp != NULL) {
               free (edid->SerialNumber);
               edid->SerialNumber = tmp;
           }
       } else if (data[i+3] == EDID_DESCRIPTOR_ALPHANUMERIC_DATA_STRING) {
           tmp = edid_parse_string (&data[i+5]);
           if (tmp != NULL) {
               free (edid->EISAID);
               edid->EISAID = tmp;
           }
       }
   }
out:
   return rc;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x30, %rsp
movq %rdi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
movq %rdx, -0x18(%rbp)
movl $0x0, -0x28(%rbp)
cmpq $0x80, -0x18(%rbp)
jae 0x2931
movl $0xffffffff, -0x28(%rbp) # imm = 0xFFFFFFFF
jmp 0x2bbf
movq -0x10(%rbp), %rax
movzbl (%rax), %eax
cmpl $0x0, %eax
jne 0x294c
movq -0x10(%rbp), %rax
movzbl 0x1(%rax), %eax
cmpl $0xff, %eax
je 0x2958
movl $0xffffffff, -0x28(%rbp) # imm = 0xFFFFFFFF
jmp 0x2bbf
movl $0x4, %edi
callq 0x2120
movq %rax, %rcx
movq -0x8(%rbp), %rax
movq %rcx, 0x18(%rax)
movq -0x10(%rbp), %rax
movzbl 0x8(%rax), %eax
andl $0x7c, %eax
movl $0x4, %ecx
cltd
idivl %ecx
addl $0x41, %eax
subl $0x1, %eax
movb %al, %cl
movq -0x8(%rbp), %rax
movq 0x18(%rax), %rax
movb %cl, (%rax)
movq -0x10(%rbp), %rax
movzbl 0x8(%rax), %eax
andl $0x3, %eax
shll $0x3, %eax
addl $0x41, %eax
movl %eax, -0x30(%rbp)
movq -0x10(%rbp), %rax
movzbl 0x9(%rax), %eax
andl $0xe0, %eax
movl $0x20, %ecx
cltd
idivl %ecx
movl %eax, %ecx
movl -0x30(%rbp), %eax
addl %ecx, %eax
subl $0x1, %eax
movb %al, %cl
movq -0x8(%rbp), %rax
movq 0x18(%rax), %rax
movb %cl, 0x1(%rax)
movq -0x10(%rbp), %rax
movzbl 0x9(%rax), %eax
andl $0x1f, %eax
addl $0x41, %eax
subl $0x1, %eax
movb %al, %cl
movq -0x8(%rbp), %rax
movq 0x18(%rax), %rax
movb %cl, 0x2(%rax)
movq -0x8(%rbp), %rax
movq 0x18(%rax), %rax
movb $0x0, 0x3(%rax)
movq -0x10(%rbp), %rax
movzbl 0xc(%rax), %eax
movl %eax, -0x2c(%rbp)
movq -0x10(%rbp), %rax
movzbl 0xd(%rax), %eax
shll $0x8, %eax
addl -0x2c(%rbp), %eax
movl %eax, -0x2c(%rbp)
movq -0x10(%rbp), %rax
movzbl 0xe(%rax), %eax
shll $0x10, %eax
addl -0x2c(%rbp), %eax
movl %eax, -0x2c(%rbp)
movq -0x10(%rbp), %rax
movzbl 0xf(%rax), %eax
shll $0x18, %eax
addl -0x2c(%rbp), %eax
movl %eax, -0x2c(%rbp)
cmpl $0x0, -0x2c(%rbp)
jbe 0x2a70
movl $0x9, %edi
callq 0x2120
movq %rax, %rcx
movq -0x8(%rbp), %rax
movq %rcx, 0x8(%rax)
movq -0x8(%rbp), %rax
movq 0x8(%rax), %rdi
movl -0x2c(%rbp), %eax
movl %eax, %edx
leaq 0x3610(%rip), %rsi      # 0x6079
movb $0x0, %al
callq 0x2290
movl $0x36, -0x24(%rbp)
cmpl $0x6c, -0x24(%rbp)
jg 0x2bbd
movq -0x10(%rbp), %rax
movslq -0x24(%rbp), %rcx
movzbl (%rax,%rcx), %eax
cmpl $0x0, %eax
je 0x2a97
jmp 0x2baf
movq -0x10(%rbp), %rax
movl -0x24(%rbp), %ecx
addl $0x2, %ecx
movslq %ecx, %rcx
movzbl (%rax,%rcx), %eax
cmpl $0x0, %eax
je 0x2ab2
jmp 0x2baf
movq -0x10(%rbp), %rax
movl -0x24(%rbp), %ecx
addl $0x3, %ecx
movslq %ecx, %rcx
movzbl (%rax,%rcx), %eax
cmpl $0xfc, %eax
jne 0x2b05
movq -0x10(%rbp), %rdi
movl -0x24(%rbp), %eax
addl $0x5, %eax
cltq
addq %rax, %rdi
callq 0x2bd0
movq %rax, -0x20(%rbp)
cmpq $0x0, -0x20(%rbp)
je 0x2b00
movq -0x8(%rbp), %rax
movq (%rax), %rdi
callq 0x21f0
movq -0x20(%rbp), %rcx
movq -0x8(%rbp), %rax
movq %rcx, (%rax)
jmp 0x2bad
movq -0x10(%rbp), %rax
movl -0x24(%rbp), %ecx
addl $0x3, %ecx
movslq %ecx, %rcx
movzbl (%rax,%rcx), %eax
cmpl $0xff, %eax
jne 0x2b57
movq -0x10(%rbp), %rdi
movl -0x24(%rbp), %eax
addl $0x5, %eax
cltq
addq %rax, %rdi
callq 0x2bd0
movq %rax, -0x20(%rbp)
cmpq $0x0, -0x20(%rbp)
je 0x2b55
movq -0x8(%rbp), %rax
movq 0x8(%rax), %rdi
callq 0x21f0
movq -0x20(%rbp), %rcx
movq -0x8(%rbp), %rax
movq %rcx, 0x8(%rax)
jmp 0x2bab
movq -0x10(%rbp), %rax
movl -0x24(%rbp), %ecx
addl $0x3, %ecx
movslq %ecx, %rcx
movzbl (%rax,%rcx), %eax
cmpl $0xfe, %eax
jne 0x2ba9
movq -0x10(%rbp), %rdi
movl -0x24(%rbp), %eax
addl $0x5, %eax
cltq
addq %rax, %rdi
callq 0x2bd0
movq %rax, -0x20(%rbp)
cmpq $0x0, -0x20(%rbp)
je 0x2ba7
movq -0x8(%rbp), %rax
movq 0x10(%rax), %rdi
callq 0x21f0
movq -0x20(%rbp), %rcx
movq -0x8(%rbp), %rax
movq %rcx, 0x10(%rax)
jmp 0x2ba9
jmp 0x2bab
jmp 0x2bad
jmp 0x2baf
movl -0x24(%rbp), %eax
addl $0x12, %eax
movl %eax, -0x24(%rbp)
jmp 0x2a77
jmp 0x2bbf
movl -0x28(%rbp), %eax
addq $0x30, %rsp
popq %rbp
retq
nopl (%rax,%rax)