pnggccrd.c
上传用户:sesekoo
上传日期:2020-07-18
资源大小:21543k
文件大小:5k
源码类别:

界面编程

开发平台:

Visual C++

  1. /* pnggccrd.c was removed from libpng-1.2.20. */
  2. /* This code snippet is for use by configure's compilation test. */
  3. #if (!defined _MSC_VER) && 
  4.     defined(PNG_ASSEMBLER_CODE_SUPPORTED) && 
  5.     defined(PNG_MMX_CODE_SUPPORTED)
  6. int PNGAPI png_dummy_mmx_support(void);
  7. static int _mmx_supported = 2; // 0: no MMX; 1: MMX supported; 2: not tested
  8. int PNGAPI
  9. png_dummy_mmx_support(void) __attribute__((noinline));
  10. int PNGAPI
  11. png_dummy_mmx_support(void)
  12. {
  13.    int result;
  14. #if defined(PNG_MMX_CODE_SUPPORTED)  // superfluous, but what the heck
  15.     __asm__ __volatile__ (
  16. #if defined(__x86_64__)
  17.         "pushq %%rbx          nt"  // rbx gets clobbered by CPUID instruction
  18.         "pushq %%rcx          nt"  // so does rcx...
  19.         "pushq %%rdx          nt"  // ...and rdx (but rcx & rdx safe on Linux)
  20.         "pushfq               nt"  // save Eflag to stack
  21.         "popq %%rax           nt"  // get Eflag from stack into rax
  22.         "movq %%rax, %%rcx    nt"  // make another copy of Eflag in rcx
  23.         "xorl $0x200000, %%eax nt" // toggle ID bit in Eflag (i.e., bit 21)
  24.         "pushq %%rax          nt"  // save modified Eflag back to stack
  25.         "popfq                nt"  // restore modified value to Eflag reg
  26.         "pushfq               nt"  // save Eflag to stack
  27.         "popq %%rax           nt"  // get Eflag from stack
  28.         "pushq %%rcx          nt"  // save original Eflag to stack
  29.         "popfq                nt"  // restore original Eflag
  30. #else
  31.         "pushl %%ebx          nt"  // ebx gets clobbered by CPUID instruction
  32.         "pushl %%ecx          nt"  // so does ecx...
  33.         "pushl %%edx          nt"  // ...and edx (but ecx & edx safe on Linux)
  34.         "pushfl               nt"  // save Eflag to stack
  35.         "popl %%eax           nt"  // get Eflag from stack into eax
  36.         "movl %%eax, %%ecx    nt"  // make another copy of Eflag in ecx
  37.         "xorl $0x200000, %%eax nt" // toggle ID bit in Eflag (i.e., bit 21)
  38.         "pushl %%eax          nt"  // save modified Eflag back to stack
  39.         "popfl                nt"  // restore modified value to Eflag reg
  40.         "pushfl               nt"  // save Eflag to stack
  41.         "popl %%eax           nt"  // get Eflag from stack
  42.         "pushl %%ecx          nt"  // save original Eflag to stack
  43.         "popfl                nt"  // restore original Eflag
  44. #endif
  45.         "xorl %%ecx, %%eax    nt"  // compare new Eflag with original Eflag
  46.         "jz 0f                nt"  // if same, CPUID instr. is not supported
  47.         "xorl %%eax, %%eax    nt"  // set eax to zero
  48. //      ".byte  0x0f, 0xa2    nt"  // CPUID instruction (two-byte opcode)
  49.         "cpuid                nt"  // get the CPU identification info
  50.         "cmpl $1, %%eax       nt"  // make sure eax return non-zero value
  51.         "jl 0f                nt"  // if eax is zero, MMX is not supported
  52.         "xorl %%eax, %%eax    nt"  // set eax to zero and...
  53.         "incl %%eax           nt"  // ...increment eax to 1.  This pair is
  54.                                      // faster than the instruction "mov eax, 1"
  55.         "cpuid                nt"  // get the CPU identification info again
  56.         "andl $0x800000, %%edx nt" // mask out all bits but MMX bit (23)
  57.         "cmpl $0, %%edx       nt"  // 0 = MMX not supported
  58.         "jz 0f                nt"  // non-zero = yes, MMX IS supported
  59.         "movl $1, %%eax       nt"  // set return value to 1
  60.         "jmp  1f              nt"  // DONE:  have MMX support
  61.     "0:                       nt"  // .NOT_SUPPORTED: target label for jump instructions
  62.         "movl $0, %%eax       nt"  // set return value to 0
  63.     "1:                       nt"  // .RETURN: target label for jump instructions
  64. #if defined(__x86_64__)
  65.         "popq %%rdx           nt"  // restore rdx
  66.         "popq %%rcx           nt"  // restore rcx
  67.         "popq %%rbx           nt"  // restore rbx
  68. #else
  69.         "popl %%edx           nt"  // restore edx
  70.         "popl %%ecx           nt"  // restore ecx
  71.         "popl %%ebx           nt"  // restore ebx
  72. #endif
  73. //      "ret                  nt"  // DONE:  no MMX support
  74.                                      // (fall through to standard C "ret")
  75.         : "=a" (result)              // output list
  76.         :                            // any variables used on input (none)
  77.                                      // no clobber list
  78. //      , "%ebx", "%ecx", "%edx"     // GRR:  we handle these manually
  79. //      , "memory"   // if write to a variable gcc thought was in a reg
  80. //      , "cc"       // "condition codes" (flag bits)
  81.     );
  82.     _mmx_supported = result;
  83. #else
  84.     _mmx_supported = 0;
  85. #endif /* PNG_MMX_CODE_SUPPORTED */
  86.     return _mmx_supported;
  87. }
  88. #endif