PageRenderTime 24ms CodeModel.GetById 14ms app.highlight 7ms RepoModel.GetById 1ms app.codeStats 0ms

/src/compiler/android/jni/ftk/pnggccrd.c

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