pnggccrd.c 4.67 KB
Newer Older
Dimitri van Heesch's avatar
Dimitri van Heesch committed
1
/* pnggccrd.c was removed from libpng-1.2.20. */
2

Dimitri van Heesch's avatar
Dimitri van Heesch committed
3
/* This code snippet is for use by configure's compilation test. */
4

Dimitri van Heesch's avatar
Dimitri van Heesch committed
5 6 7
#if defined(PNG_ASSEMBLER_CODE_SUPPORTED) && \
    defined(PNG_MMX_CODE_SUPPORTED)
int PNGAPI png_dummy_mmx_support(void);
8

Dimitri van Heesch's avatar
Dimitri van Heesch committed
9
static int _mmx_supported = 2; // 0: no MMX; 1: MMX supported; 2: not tested
10

Dimitri van Heesch's avatar
Dimitri van Heesch committed
11 12
int PNGAPI
png_dummy_mmx_support(void) __attribute__((noinline));
13 14

int PNGAPI
Dimitri van Heesch's avatar
Dimitri van Heesch committed
15
png_dummy_mmx_support(void)
16
{
Dimitri van Heesch's avatar
Dimitri van Heesch committed
17 18
   int result;
#if defined(PNG_MMX_CODE_SUPPORTED)  // superfluous, but what the heck
19
    __asm__ __volatile__ (
Dimitri van Heesch's avatar
Dimitri van Heesch committed
20 21 22 23 24 25 26 27 28 29 30 31 32 33 34
#if defined(__x86_64__)
        "pushq %%rbx          \n\t"  // rbx gets clobbered by CPUID instruction
        "pushq %%rcx          \n\t"  // so does rcx...
        "pushq %%rdx          \n\t"  // ...and rdx (but rcx & rdx safe on Linux)
        "pushfq               \n\t"  // save Eflag to stack
        "popq %%rax           \n\t"  // get Eflag from stack into rax
        "movq %%rax, %%rcx    \n\t"  // make another copy of Eflag in rcx
        "xorl $0x200000, %%eax \n\t" // toggle ID bit in Eflag (i.e., bit 21)
        "pushq %%rax          \n\t"  // save modified Eflag back to stack
        "popfq                \n\t"  // restore modified value to Eflag reg
        "pushfq               \n\t"  // save Eflag to stack
        "popq %%rax           \n\t"  // get Eflag from stack
        "pushq %%rcx          \n\t"  // save original Eflag to stack
        "popfq                \n\t"  // restore original Eflag
#else
35 36 37 38 39 40 41 42 43 44 45 46 47
        "pushl %%ebx          \n\t"  // ebx gets clobbered by CPUID instruction
        "pushl %%ecx          \n\t"  // so does ecx...
        "pushl %%edx          \n\t"  // ...and edx (but ecx & edx safe on Linux)
        "pushfl               \n\t"  // save Eflag to stack
        "popl %%eax           \n\t"  // get Eflag from stack into eax
        "movl %%eax, %%ecx    \n\t"  // make another copy of Eflag in ecx
        "xorl $0x200000, %%eax \n\t" // toggle ID bit in Eflag (i.e., bit 21)
        "pushl %%eax          \n\t"  // save modified Eflag back to stack
        "popfl                \n\t"  // restore modified value to Eflag reg
        "pushfl               \n\t"  // save Eflag to stack
        "popl %%eax           \n\t"  // get Eflag from stack
        "pushl %%ecx          \n\t"  // save original Eflag to stack
        "popfl                \n\t"  // restore original Eflag
Dimitri van Heesch's avatar
Dimitri van Heesch committed
48
#endif
49
        "xorl %%ecx, %%eax    \n\t"  // compare new Eflag with original Eflag
Dimitri van Heesch's avatar
Dimitri van Heesch committed
50
        "jz 0f                \n\t"  // if same, CPUID instr. is not supported
51 52 53 54 55

        "xorl %%eax, %%eax    \n\t"  // set eax to zero
//      ".byte  0x0f, 0xa2    \n\t"  // CPUID instruction (two-byte opcode)
        "cpuid                \n\t"  // get the CPU identification info
        "cmpl $1, %%eax       \n\t"  // make sure eax return non-zero value
Dimitri van Heesch's avatar
Dimitri van Heesch committed
56
        "jl 0f                \n\t"  // if eax is zero, MMX is not supported
57 58 59 60 61 62 63

        "xorl %%eax, %%eax    \n\t"  // set eax to zero and...
        "incl %%eax           \n\t"  // ...increment eax to 1.  This pair is
                                     // faster than the instruction "mov eax, 1"
        "cpuid                \n\t"  // get the CPU identification info again
        "andl $0x800000, %%edx \n\t" // mask out all bits but MMX bit (23)
        "cmpl $0, %%edx       \n\t"  // 0 = MMX not supported
Dimitri van Heesch's avatar
Dimitri van Heesch committed
64
        "jz 0f                \n\t"  // non-zero = yes, MMX IS supported
65 66

        "movl $1, %%eax       \n\t"  // set return value to 1
Dimitri van Heesch's avatar
Dimitri van Heesch committed
67
        "jmp  1f              \n\t"  // DONE:  have MMX support
68

Dimitri van Heesch's avatar
Dimitri van Heesch committed
69
    "0:                       \n\t"  // .NOT_SUPPORTED: target label for jump instructions
70
        "movl $0, %%eax       \n\t"  // set return value to 0
Dimitri van Heesch's avatar
Dimitri van Heesch committed
71 72 73 74 75 76
    "1:                       \n\t"  // .RETURN: target label for jump instructions
#if defined(__x86_64__)
        "popq %%rdx           \n\t"  // restore rdx
        "popq %%rcx           \n\t"  // restore rcx
        "popq %%rbx           \n\t"  // restore rbx
#else
77 78 79
        "popl %%edx           \n\t"  // restore edx
        "popl %%ecx           \n\t"  // restore ecx
        "popl %%ebx           \n\t"  // restore ebx
Dimitri van Heesch's avatar
Dimitri van Heesch committed
80
#endif
81 82 83 84

//      "ret                  \n\t"  // DONE:  no MMX support
                                     // (fall through to standard C "ret")

Dimitri van Heesch's avatar
Dimitri van Heesch committed
85
        : "=a" (result)              // output list
86 87 88

        :                            // any variables used on input (none)

Dimitri van Heesch's avatar
Dimitri van Heesch committed
89
                                     // no clobber list
90 91 92 93
//      , "%ebx", "%ecx", "%edx"     // GRR:  we handle these manually
//      , "memory"   // if write to a variable gcc thought was in a reg
//      , "cc"       // "condition codes" (flag bits)
    );
Dimitri van Heesch's avatar
Dimitri van Heesch committed
94 95
    _mmx_supported = result;
#else
96 97 98 99 100
    _mmx_supported = 0;
#endif /* PNG_MMX_CODE_SUPPORTED */

    return _mmx_supported;
}
Dimitri van Heesch's avatar
Dimitri van Heesch committed
101
#endif