176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/* pnggccrd.c was removed from libpng-1.2.20. */
276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/* This code snippet is for use by configure's compilation test. */
476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#if (!defined _MSC_VER) && \
676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman    defined(PNG_ASSEMBLER_CODE_SUPPORTED) && \
776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman    defined(PNG_MMX_CODE_SUPPORTED)
876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanint PNGAPI png_dummy_mmx_support(void);
1076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
1176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanstatic int _mmx_supported = 2; // 0: no MMX; 1: MMX supported; 2: not tested
1276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
1376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanint PNGAPI
1476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanpng_dummy_mmx_support(void) __attribute__((noinline));
1576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
1676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanint PNGAPI
1776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanpng_dummy_mmx_support(void)
1876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman{
1976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman   int result;
2076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#ifdef PNG_MMX_CODE_SUPPORTED  // superfluous, but what the heck
2176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman    __asm__ __volatile__ (
2276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#ifdef __x86_64__
2376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman        "pushq %%rbx          \n\t"  // rbx gets clobbered by CPUID instruction
2476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman        "pushq %%rcx          \n\t"  // so does rcx...
2576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman        "pushq %%rdx          \n\t"  // ...and rdx (but rcx & rdx safe on Linux)
2676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman        "pushfq               \n\t"  // save Eflag to stack
2776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman        "popq %%rax           \n\t"  // get Eflag from stack into rax
2876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman        "movq %%rax, %%rcx    \n\t"  // make another copy of Eflag in rcx
2976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman        "xorl $0x200000, %%eax \n\t" // toggle ID bit in Eflag (i.e., bit 21)
3076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman        "pushq %%rax          \n\t"  // save modified Eflag back to stack
3176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman        "popfq                \n\t"  // restore modified value to Eflag reg
3276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman        "pushfq               \n\t"  // save Eflag to stack
3376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman        "popq %%rax           \n\t"  // get Eflag from stack
3476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman        "pushq %%rcx          \n\t"  // save original Eflag to stack
3576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman        "popfq                \n\t"  // restore original Eflag
3676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#else
3776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman        "pushl %%ebx          \n\t"  // ebx gets clobbered by CPUID instruction
3876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman        "pushl %%ecx          \n\t"  // so does ecx...
3976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman        "pushl %%edx          \n\t"  // ...and edx (but ecx & edx safe on Linux)
4076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman        "pushfl               \n\t"  // save Eflag to stack
4176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman        "popl %%eax           \n\t"  // get Eflag from stack into eax
4276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman        "movl %%eax, %%ecx    \n\t"  // make another copy of Eflag in ecx
4376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman        "xorl $0x200000, %%eax \n\t" // toggle ID bit in Eflag (i.e., bit 21)
4476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman        "pushl %%eax          \n\t"  // save modified Eflag back to stack
4576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman        "popfl                \n\t"  // restore modified value to Eflag reg
4676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman        "pushfl               \n\t"  // save Eflag to stack
4776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman        "popl %%eax           \n\t"  // get Eflag from stack
4876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman        "pushl %%ecx          \n\t"  // save original Eflag to stack
4976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman        "popfl                \n\t"  // restore original Eflag
5076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#endif
5176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman        "xorl %%ecx, %%eax    \n\t"  // compare new Eflag with original Eflag
5276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman        "jz 0f                \n\t"  // if same, CPUID instr. is not supported
5376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
5476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman        "xorl %%eax, %%eax    \n\t"  // set eax to zero
5576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman//      ".byte  0x0f, 0xa2    \n\t"  // CPUID instruction (two-byte opcode)
5676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman        "cpuid                \n\t"  // get the CPU identification info
5776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman        "cmpl $1, %%eax       \n\t"  // make sure eax return non-zero value
5876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman        "jl 0f                \n\t"  // if eax is zero, MMX is not supported
5976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
6076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman        "xorl %%eax, %%eax    \n\t"  // set eax to zero and...
6176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman        "incl %%eax           \n\t"  // ...increment eax to 1.  This pair is
6276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman                                     // faster than the instruction "mov eax, 1"
6376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman        "cpuid                \n\t"  // get the CPU identification info again
6476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman        "andl $0x800000, %%edx \n\t" // mask out all bits but MMX bit (23)
6576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman        "cmpl $0, %%edx       \n\t"  // 0 = MMX not supported
6676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman        "jz 0f                \n\t"  // non-zero = yes, MMX IS supported
6776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
6876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman        "movl $1, %%eax       \n\t"  // set return value to 1
6976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman        "jmp  1f              \n\t"  // DONE:  have MMX support
7076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
7176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman    "0:                       \n\t"  // .NOT_SUPPORTED: target label for jump instructions
7276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman        "movl $0, %%eax       \n\t"  // set return value to 0
7376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman    "1:                       \n\t"  // .RETURN: target label for jump instructions
7476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#ifdef __x86_64__
7576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman        "popq %%rdx           \n\t"  // restore rdx
7676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman        "popq %%rcx           \n\t"  // restore rcx
7776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman        "popq %%rbx           \n\t"  // restore rbx
7876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#else
7976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman        "popl %%edx           \n\t"  // restore edx
8076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman        "popl %%ecx           \n\t"  // restore ecx
8176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman        "popl %%ebx           \n\t"  // restore ebx
8276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#endif
8376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
8476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman//      "ret                  \n\t"  // DONE:  no MMX support
8576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman                                     // (fall through to standard C "ret")
8676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
8776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman        : "=a" (result)              // output list
8876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
8976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman        :                            // any variables used on input (none)
9076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
9176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman                                     // no clobber list
9276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman//      , "%ebx", "%ecx", "%edx"     // GRR:  we handle these manually
9376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman//      , "memory"   // if write to a variable gcc thought was in a reg
9476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman//      , "cc"       // "condition codes" (flag bits)
9576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman    );
9676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman    _mmx_supported = result;
9776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#else
9876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman    _mmx_supported = 0;
9976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#endif /* PNG_MMX_CODE_SUPPORTED */
10076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
10176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman    return _mmx_supported;
10276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman}
10376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#endif
104