pnggccrd.c
Go to the documentation of this file.
00001 /* pnggccrd.c was removed from libpng-1.2.20. */
00002 
00003 /* This code snippet is for use by configure's compilation test. */
00004 
00005 #if (!defined _MSC_VER) && \
00006     defined(PNG_ASSEMBLER_CODE_SUPPORTED) && \
00007     defined(PNG_MMX_CODE_SUPPORTED)
00008 
00009 int PNGAPI png_dummy_mmx_support(void);
00010 
00011 static int _mmx_supported = 2; // 0: no MMX; 1: MMX supported; 2: not tested
00012 
00013 int PNGAPI
00014 png_dummy_mmx_support(void) __attribute__((noinline));
00015 
00016 int PNGAPI
00017 png_dummy_mmx_support(void)
00018 {
00019    int result;
00020 #if defined(PNG_MMX_CODE_SUPPORTED)  // superfluous, but what the heck
00021     __asm__ __volatile__ (
00022 #if defined(__x86_64__)
00023         "pushq %%rbx          \n\t"  // rbx gets clobbered by CPUID instruction
00024         "pushq %%rcx          \n\t"  // so does rcx...
00025         "pushq %%rdx          \n\t"  // ...and rdx (but rcx & rdx safe on Linux)
00026         "pushfq               \n\t"  // save Eflag to stack
00027         "popq %%rax           \n\t"  // get Eflag from stack into rax
00028         "movq %%rax, %%rcx    \n\t"  // make another copy of Eflag in rcx
00029         "xorl $0x200000, %%eax \n\t" // toggle ID bit in Eflag (i.e., bit 21)
00030         "pushq %%rax          \n\t"  // save modified Eflag back to stack
00031         "popfq                \n\t"  // restore modified value to Eflag reg
00032         "pushfq               \n\t"  // save Eflag to stack
00033         "popq %%rax           \n\t"  // get Eflag from stack
00034         "pushq %%rcx          \n\t"  // save original Eflag to stack
00035         "popfq                \n\t"  // restore original Eflag
00036 #else
00037         "pushl %%ebx          \n\t"  // ebx gets clobbered by CPUID instruction
00038         "pushl %%ecx          \n\t"  // so does ecx...
00039         "pushl %%edx          \n\t"  // ...and edx (but ecx & edx safe on Linux)
00040         "pushfl               \n\t"  // save Eflag to stack
00041         "popl %%eax           \n\t"  // get Eflag from stack into eax
00042         "movl %%eax, %%ecx    \n\t"  // make another copy of Eflag in ecx
00043         "xorl $0x200000, %%eax \n\t" // toggle ID bit in Eflag (i.e., bit 21)
00044         "pushl %%eax          \n\t"  // save modified Eflag back to stack
00045         "popfl                \n\t"  // restore modified value to Eflag reg
00046         "pushfl               \n\t"  // save Eflag to stack
00047         "popl %%eax           \n\t"  // get Eflag from stack
00048         "pushl %%ecx          \n\t"  // save original Eflag to stack
00049         "popfl                \n\t"  // restore original Eflag
00050 #endif
00051         "xorl %%ecx, %%eax    \n\t"  // compare new Eflag with original Eflag
00052         "jz 0f                \n\t"  // if same, CPUID instr. is not supported
00053 
00054         "xorl %%eax, %%eax    \n\t"  // set eax to zero
00055 //      ".byte  0x0f, 0xa2    \n\t"  // CPUID instruction (two-byte opcode)
00056         "cpuid                \n\t"  // get the CPU identification info
00057         "cmpl $1, %%eax       \n\t"  // make sure eax return non-zero value
00058         "jl 0f                \n\t"  // if eax is zero, MMX is not supported
00059 
00060         "xorl %%eax, %%eax    \n\t"  // set eax to zero and...
00061         "incl %%eax           \n\t"  // ...increment eax to 1.  This pair is
00062                                      // faster than the instruction "mov eax, 1"
00063         "cpuid                \n\t"  // get the CPU identification info again
00064         "andl $0x800000, %%edx \n\t" // mask out all bits but MMX bit (23)
00065         "cmpl $0, %%edx       \n\t"  // 0 = MMX not supported
00066         "jz 0f                \n\t"  // non-zero = yes, MMX IS supported
00067 
00068         "movl $1, %%eax       \n\t"  // set return value to 1
00069         "jmp  1f              \n\t"  // DONE:  have MMX support
00070 
00071     "0:                       \n\t"  // .NOT_SUPPORTED: target label for jump instructions
00072         "movl $0, %%eax       \n\t"  // set return value to 0
00073     "1:                       \n\t"  // .RETURN: target label for jump instructions
00074 #if defined(__x86_64__)
00075         "popq %%rdx           \n\t"  // restore rdx
00076         "popq %%rcx           \n\t"  // restore rcx
00077         "popq %%rbx           \n\t"  // restore rbx
00078 #else
00079         "popl %%edx           \n\t"  // restore edx
00080         "popl %%ecx           \n\t"  // restore ecx
00081         "popl %%ebx           \n\t"  // restore ebx
00082 #endif
00083 
00084 //      "ret                  \n\t"  // DONE:  no MMX support
00085                                      // (fall through to standard C "ret")
00086 
00087         : "=a" (result)              // output list
00088 
00089         :                            // any variables used on input (none)
00090 
00091                                      // no clobber list
00092 //      , "%ebx", "%ecx", "%edx"     // GRR:  we handle these manually
00093 //      , "memory"   // if write to a variable gcc thought was in a reg
00094 //      , "cc"       // "condition codes" (flag bits)
00095     );
00096     _mmx_supported = result;
00097 #else
00098     _mmx_supported = 0;
00099 #endif /* PNG_MMX_CODE_SUPPORTED */
00100 
00101     return _mmx_supported;
00102 }
00103 #endif


openhrp3
Author(s): AIST, General Robotix Inc., Nakamura Lab of Dept. of Mechano Informatics at University of Tokyo
autogenerated on Thu Apr 11 2019 03:30:18