// File: /workspace/github_c_makefile_star2_O3/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:
movl $0xffffffff, %eax       # imm = 0xFFFFFFFF
cmpq $0x80, %rdx
jb 0x29a1
pushq %rbp
pushq %r15
pushq %r14
pushq %r12
pushq %rbx
movq %rsi, %rbx
cmpb $0x0, (%rsi)
jne 0x2999
cmpb $-0x1, 0x1(%rbx)
jne 0x2999
movq %rdi, %r14
movl $0x4, %edi
callq 0x2140
movq %rax, 0x18(%r14)
movb 0x8(%rbx), %cl
movl %ecx, %edx
shrb $0x2, %dl
andb $0x1f, %dl
orb $0x40, %dl
movb %dl, (%rax)
movb 0x9(%rbx), %dl
shlb $0x3, %cl
movl %edx, %esi
shrb $0x5, %sil
orb %cl, %sil
andb $0x1f, %sil
orb $0x40, %sil
movb %sil, 0x1(%rax)
andb $0x1f, %dl
orb $0x40, %dl
movb %dl, 0x2(%rax)
movb $0x0, 0x3(%rax)
movl 0xc(%rbx), %ebp
testl %ebp, %ebp
je 0x28f1
movl $0x9, %edi
callq 0x2140
movq %rax, 0x8(%r14)
movl %ebp, %edx
leaq 0x278a(%rip), %rsi      # 0x5071
movq %rax, %rdi
xorl %eax, %eax
callq 0x22b0
movl $0x3b, %r12d
cmpb $0x0, -0x5(%rbx,%r12)
jne 0x2907
cmpb $0x0, -0x3(%rbx,%r12)
je 0x291b
leaq 0x12(%r12), %rax
addq $-0x5, %r12
cmpq $0x5b, %r12
movq %rax, %r12
jb 0x28f7
jmp 0x2997
movzbl -0x2(%rbx,%r12), %eax
cmpl $0xff, %eax
je 0x2974
cmpl $0xfe, %eax
je 0x2954
cmpl $0xfc, %eax
jne 0x2907
leaq (%rbx,%r12), %rdi
callq 0x29a2
testq %rax, %rax
je 0x2907
movq %rax, %r15
movq (%r14), %rdi
callq 0x2210
movq %r15, (%r14)
jmp 0x2907
leaq (%rbx,%r12), %rdi
callq 0x29a2
testq %rax, %rax
je 0x2907
movq %rax, %r15
movq 0x10(%r14), %rdi
callq 0x2210
movq %r15, 0x10(%r14)
jmp 0x2907
leaq (%rbx,%r12), %rdi
callq 0x29a2
testq %rax, %rax
je 0x2907
movq %rax, %r15
movq 0x8(%r14), %rdi
callq 0x2210
movq %r15, 0x8(%r14)
jmp 0x2907
xorl %eax, %eax
popq %rbx
popq %r12
popq %r14
popq %r15
popq %rbp
retq