Hash :
a2e6a9dd
Author :
Date :
2006-02-04T00:00:00
IJG R6b with x86SIMD V1.02 Independent JPEG Group's JPEG software release 6b with x86 SIMD extension for IJG JPEG library version 1.02
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95
/*
* jsimdgcc.c - SIMD instruction support check (gcc)
*
* x86 SIMD extension for IJG JPEG library
* Copyright (C) 1999-2006, MIYASAKA Masaru.
* For conditions of distribution and use, see copyright notice in jsimdext.inc
*
* Last Modified : January 24, 2006
*/
#define JPEG_INTERNALS
#include "jinclude.h"
#include "jpeglib.h"
#include <setjmp.h>
#include <signal.h>
static volatile int lockf /* = 0 */;
static jmp_buf jmpbuf;
/*
* Exception handler for signal()
*/
LOCAL(void)
exception_handler (int sig)
{
signal(SIGILL, SIG_DFL);
longjmp(jmpbuf, 1);
}
/*
* Check if the OS supports SIMD instructions
*/
GLOBAL(unsigned int)
jpeg_simd_os_support (unsigned int simd)
{
#ifdef __GNUC__ /* gcc (i386) */
unsigned int mxcsr = 0x1F80;
/* enter critical section */
__asm__ __volatile__ (
"get_lock: \n\t"
"movl $1,%%eax \n\t"
"xchgl %0,%%eax \n\t" /* try to get lock */
"cmpl $0,%%eax \n\t" /* test if successful */
"je critical_section \n"
"spin_loop: \n\t"
/*".byte 0xF3,0x90 \n\t"*/ /* "pause" on P4 (short delay) */
"cmpl $0,%0 \n\t" /* check if lock is free */
"jne spin_loop \n\t"
"jmp get_lock \n"
"critical_section: \n\t"
: "=m" (lockf) : "m" (lockf) : "%eax"
);
/* If floating point emulation is enabled (CR0.EM = 1),
* executing an MMX/3DNow! instruction generates invalid
* opcode exception (#UD).
*/
if (simd & (JSIMD_MMX | JSIMD_3DNOW)) {
if (!setjmp(jmpbuf)) {
signal(SIGILL, exception_handler);
__asm__ __volatile__ (
".byte 0x0F,0x77" /* emms */
);
signal(SIGILL, SIG_DFL);
} else {
simd &= ~(JSIMD_MMX | JSIMD_3DNOW);
}
}
if (simd & (JSIMD_SSE | JSIMD_SSE2)) {
if (!setjmp(jmpbuf)) {
signal(SIGILL, exception_handler);
__asm__ __volatile__ (
"leal %0,%%eax \n\t"
".byte 0x0F,0xAE,0x10 \n\t" /* ldmxcsr [eax] */
: : "m" (mxcsr) : "%eax"
);
signal(SIGILL, SIG_DFL);
} else {
simd &= ~(JSIMD_SSE | JSIMD_SSE2);
}
}
/* leave critical section */
lockf = 0; /* release lock */
#endif /* __GNUC__ */
return simd;
}