mirror of
https://git.ffmpeg.org/ffmpeg.git
synced 2024-12-26 09:12:33 +00:00
* some modifications to allow gcc to compile same code for -fPIC
- introduced MOVQ_WONE, MOVQ_WTWO * unrolled put_pixels_clamped_mmx * added .baling where the jump address would be compiled on odd address * added some testing code to disable all these routines (for time measurement) Originally committed as revision 308 to svn://svn.ffmpeg.org/ffmpeg/trunk
This commit is contained in:
parent
38d171ebbe
commit
d6a4c0b111
@ -40,6 +40,27 @@ static const unsigned long long int mm_wtwo __attribute__ ((aligned(8))) = 0x000
|
||||
//static const unsigned short mm_wone[4] __attribute__ ((aligned(8))) = { 0x1, 0x1, 0x1, 0x1 };
|
||||
//static const unsigned short mm_wtwo[4] __attribute__ ((aligned(8))) = { 0x2, 0x2, 0x2, 0x2 };
|
||||
|
||||
#define JUMPALIGN() __asm __volatile (".balign 8"::)
|
||||
#define MOVQ_ZERO(regd) __asm __volatile ("pxor %%" #regd ", %%" #regd ::)
|
||||
|
||||
#ifndef PIC
|
||||
#define MOVQ_WONE(regd) __asm __volatile ("movq %0, %%" #regd " \n\t" ::"m"(mm_wone))
|
||||
#define MOVQ_WTWO(regd) __asm __volatile ("movq %0, %%" #regd " \n\t" ::"m"(mm_wtwo))
|
||||
#else
|
||||
// for shared library it's better to use this way for accessing constants
|
||||
// pcmpeqd -> -1
|
||||
#define MOVQ_WONE(regd) \
|
||||
__asm __volatile ( \
|
||||
"pcmpeqd %%" #regd ", %%" #regd " \n\t" \
|
||||
"psrlw $15, %%" #regd ::)
|
||||
|
||||
#define MOVQ_WTWO(regd) \
|
||||
__asm __volatile ( \
|
||||
"pcmpeqd %%" #regd ", %%" #regd " \n\t" \
|
||||
"psrlw $15, %%" #regd " \n\t" \
|
||||
"psllw $1, %%" #regd ::)
|
||||
#endif
|
||||
|
||||
/***********************************/
|
||||
/* 3Dnow specific */
|
||||
|
||||
@ -77,7 +98,7 @@ static void get_pixels_mmx(DCTELEM *block, const UINT8 *pixels, int line_size)
|
||||
/* read the pixels */
|
||||
p = block;
|
||||
pix = pixels;
|
||||
__asm __volatile("pxor %%mm7, %%mm7":);
|
||||
MOVQ_ZERO(mm7);
|
||||
for(i=0;i<4;i++) {
|
||||
__asm __volatile(
|
||||
"movq %1, %%mm0\n\t"
|
||||
@ -104,12 +125,11 @@ static void put_pixels_clamped_mmx(const DCTELEM *block, UINT8 *pixels, int line
|
||||
{
|
||||
const DCTELEM *p;
|
||||
UINT8 *pix;
|
||||
int i;
|
||||
|
||||
/* read the pixels */
|
||||
p = block;
|
||||
pix = pixels;
|
||||
for(i=0;i<2;i++) {
|
||||
/* unrolled loop */
|
||||
__asm __volatile(
|
||||
"movq %3, %%mm0\n\t"
|
||||
"movq 8%3, %%mm1\n\t"
|
||||
@ -131,7 +151,29 @@ static void put_pixels_clamped_mmx(const DCTELEM *block, UINT8 *pixels, int line
|
||||
:"memory");
|
||||
pix += line_size*4;
|
||||
p += 32;
|
||||
}
|
||||
|
||||
// if here would be an exact copy of the code above
|
||||
// compiler would generate some very strange code
|
||||
// thus using "r"
|
||||
__asm __volatile(
|
||||
"movq (%3), %%mm0\n\t"
|
||||
"movq 8(%3), %%mm1\n\t"
|
||||
"movq 16(%3), %%mm2\n\t"
|
||||
"movq 24(%3), %%mm3\n\t"
|
||||
"movq 32(%3), %%mm4\n\t"
|
||||
"movq 40(%3), %%mm5\n\t"
|
||||
"movq 48(%3), %%mm6\n\t"
|
||||
"movq 56(%3), %%mm7\n\t"
|
||||
"packuswb %%mm1, %%mm0\n\t"
|
||||
"packuswb %%mm3, %%mm2\n\t"
|
||||
"packuswb %%mm5, %%mm4\n\t"
|
||||
"packuswb %%mm7, %%mm6\n\t"
|
||||
"movq %%mm0, (%0)\n\t"
|
||||
"movq %%mm2, (%0, %1)\n\t"
|
||||
"movq %%mm4, (%0, %1, 2)\n\t"
|
||||
"movq %%mm6, (%0, %2)\n\t"
|
||||
::"r" (pix), "r" (line_size), "r" (line_size*3), "r"(p)
|
||||
:"memory");
|
||||
}
|
||||
|
||||
static void add_pixels_clamped_mmx(const DCTELEM *block, UINT8 *pixels, int line_size)
|
||||
@ -143,8 +185,9 @@ static void add_pixels_clamped_mmx(const DCTELEM *block, UINT8 *pixels, int line
|
||||
/* read the pixels */
|
||||
p = block;
|
||||
pix = pixels;
|
||||
__asm __volatile("pxor %%mm7, %%mm7":);
|
||||
for(i=0;i<4;i++) {
|
||||
MOVQ_ZERO(mm7);
|
||||
i = 4;
|
||||
while (i) {
|
||||
__asm __volatile(
|
||||
"movq %2, %%mm0\n\t"
|
||||
"movq 8%2, %%mm1\n\t"
|
||||
@ -171,19 +214,47 @@ static void add_pixels_clamped_mmx(const DCTELEM *block, UINT8 *pixels, int line
|
||||
:"memory");
|
||||
pix += line_size*2;
|
||||
p += 16;
|
||||
}
|
||||
i--;
|
||||
};
|
||||
}
|
||||
|
||||
static void put_pixels_mmx(UINT8 *block, const UINT8 *pixels, int line_size, int h)
|
||||
{
|
||||
int dh, hh;
|
||||
int hh;
|
||||
UINT8 *p;
|
||||
const UINT8 *pix;
|
||||
|
||||
p = block;
|
||||
pix = pixels;
|
||||
pix = pixels; // 2s
|
||||
#if 0
|
||||
do {
|
||||
__asm __volatile(
|
||||
"movq %1, %%mm0\n\t"
|
||||
"movq %%mm0, %0\n\t"
|
||||
:"=m"(*p)
|
||||
:"m"(*pix)
|
||||
:"memory");
|
||||
pix += line_size;
|
||||
p += line_size;
|
||||
} while (--h);
|
||||
#else
|
||||
// this optimized code is not very usefull
|
||||
// the above loop is definitely faster
|
||||
// at least on Celeron 500MHz
|
||||
hh = h & 3;
|
||||
while (hh) {
|
||||
__asm __volatile(
|
||||
"movq %1, %%mm0\n\t"
|
||||
"movq %%mm0, %0\n\t"
|
||||
:"=m"(*p)
|
||||
:"m"(*pix)
|
||||
:"memory");
|
||||
pix += line_size;
|
||||
p += line_size;
|
||||
hh--;
|
||||
}
|
||||
hh=h>>2;
|
||||
dh=h&3;
|
||||
while(hh--) {
|
||||
while (hh) {
|
||||
__asm __volatile(
|
||||
"movq (%1), %%mm0 \n\t"
|
||||
"movq (%1, %2), %%mm1 \n\t"
|
||||
@ -195,19 +266,11 @@ static void put_pixels_mmx(UINT8 *block, const UINT8 *pixels, int line_size, int
|
||||
"movq %%mm3, (%0, %3) \n\t"
|
||||
::"r"(p), "r"(pix), "r"(line_size), "r"(line_size*3)
|
||||
:"memory");
|
||||
pix = pix + line_size*4;
|
||||
p = p + line_size*4;
|
||||
}
|
||||
while(dh--) {
|
||||
__asm __volatile(
|
||||
"movq %1, %%mm0\n\t"
|
||||
"movq %%mm0, %0\n\t"
|
||||
:"=m"(*p)
|
||||
:"m"(*pix)
|
||||
:"memory");
|
||||
pix = pix + line_size;
|
||||
p = p + line_size;
|
||||
pix += line_size*4;
|
||||
p += line_size*4;
|
||||
hh--;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
static void put_pixels_x2_mmx(UINT8 *block, const UINT8 *pixels, int line_size, int h)
|
||||
@ -216,10 +279,9 @@ static void put_pixels_x2_mmx(UINT8 *block, const UINT8 *pixels, int line_size,
|
||||
const UINT8 *pix;
|
||||
p = block;
|
||||
pix = pixels;
|
||||
__asm __volatile(
|
||||
"pxor %%mm7, %%mm7\n\t"
|
||||
"movq %0, %%mm4\n\t"
|
||||
::"m"(mm_wone));
|
||||
MOVQ_ZERO(mm7);
|
||||
MOVQ_WONE(mm4);
|
||||
JUMPALIGN();
|
||||
do {
|
||||
__asm __volatile(
|
||||
"movq %1, %%mm0\n\t"
|
||||
@ -251,10 +313,9 @@ static void put_pixels_y2_mmx(UINT8 *block, const UINT8 *pixels, int line_size,
|
||||
const UINT8 *pix;
|
||||
p = block;
|
||||
pix = pixels;
|
||||
__asm __volatile(
|
||||
"pxor %%mm7, %%mm7\n\t"
|
||||
"movq %0, %%mm4\n\t"
|
||||
::"m"(mm_wone));
|
||||
MOVQ_ZERO(mm7);
|
||||
MOVQ_WONE(mm4);
|
||||
JUMPALIGN();
|
||||
do {
|
||||
__asm __volatile(
|
||||
"movq %1, %%mm0\n\t"
|
||||
@ -287,11 +348,10 @@ static void put_pixels_xy2_mmx(UINT8 *block, const UINT8 *pixels, int line_size,
|
||||
UINT8 *p;
|
||||
const UINT8 *pix;
|
||||
p = block;
|
||||
pix = pixels;
|
||||
__asm __volatile(
|
||||
"pxor %%mm7, %%mm7\n\t"
|
||||
"movq %0, %%mm6\n\t"
|
||||
::"m"(mm_wtwo));
|
||||
pix = pixels; // 1s
|
||||
MOVQ_ZERO(mm7);
|
||||
MOVQ_WTWO(mm6);
|
||||
JUMPALIGN();
|
||||
do {
|
||||
__asm __volatile(
|
||||
"movq %1, %%mm0\n\t"
|
||||
@ -337,7 +397,7 @@ static void put_no_rnd_pixels_x2_mmx( UINT8 *block, const UINT8 *pixels, int
|
||||
const UINT8 *pix;
|
||||
p = block;
|
||||
pix = pixels;
|
||||
__asm __volatile("pxor %%mm7, %%mm7\n\t":);
|
||||
MOVQ_ZERO(mm7);
|
||||
do {
|
||||
__asm __volatile(
|
||||
"movq %1, %%mm0\n\t"
|
||||
@ -368,7 +428,8 @@ static void put_no_rnd_pixels_y2_mmx( UINT8 *block, const UINT8 *pixels, int li
|
||||
const UINT8 *pix;
|
||||
p = block;
|
||||
pix = pixels;
|
||||
__asm __volatile("pxor %%mm7, %%mm7\n\t":);
|
||||
MOVQ_ZERO(mm7);
|
||||
JUMPALIGN();
|
||||
do {
|
||||
__asm __volatile(
|
||||
"movq %1, %%mm0\n\t"
|
||||
@ -400,10 +461,9 @@ static void put_no_rnd_pixels_xy2_mmx( UINT8 *block, const UINT8 *pixels, int
|
||||
const UINT8 *pix;
|
||||
p = block;
|
||||
pix = pixels;
|
||||
__asm __volatile(
|
||||
"pxor %%mm7, %%mm7\n\t"
|
||||
"movq %0, %%mm6\n\t"
|
||||
::"m"(mm_wone));
|
||||
MOVQ_ZERO(mm7);
|
||||
MOVQ_WONE(mm6);
|
||||
JUMPALIGN();
|
||||
do {
|
||||
__asm __volatile(
|
||||
"movq %1, %%mm0\n\t"
|
||||
@ -449,10 +509,9 @@ static void avg_pixels_mmx(UINT8 *block, const UINT8 *pixels, int line_size, int
|
||||
const UINT8 *pix;
|
||||
p = block;
|
||||
pix = pixels;
|
||||
__asm __volatile(
|
||||
"pxor %%mm7, %%mm7\n\t"
|
||||
"movq %0, %%mm6\n\t"
|
||||
::"m"(mm_wone));
|
||||
MOVQ_ZERO(mm7);
|
||||
MOVQ_WONE(mm6);
|
||||
JUMPALIGN();
|
||||
do {
|
||||
__asm __volatile(
|
||||
"movq %0, %%mm0\n\t"
|
||||
@ -486,10 +545,9 @@ static void avg_pixels_x2_mmx( UINT8 *block, const UINT8 *pixels, int line_si
|
||||
const UINT8 *pix;
|
||||
p = block;
|
||||
pix = pixels;
|
||||
__asm __volatile(
|
||||
"pxor %%mm7, %%mm7\n\t"
|
||||
"movq %0, %%mm6\n\t"
|
||||
::"m"(mm_wone));
|
||||
MOVQ_ZERO(mm7);
|
||||
MOVQ_WONE(mm6);
|
||||
JUMPALIGN();
|
||||
do {
|
||||
__asm __volatile(
|
||||
"movq %1, %%mm1\n\t"
|
||||
@ -532,10 +590,9 @@ static void avg_pixels_y2_mmx( UINT8 *block, const UINT8 *pixels, int line_si
|
||||
const UINT8 *pix;
|
||||
p = block;
|
||||
pix = pixels;
|
||||
__asm __volatile(
|
||||
"pxor %%mm7, %%mm7\n\t"
|
||||
"movq %0, %%mm6\n\t"
|
||||
::"m"(mm_wone));
|
||||
MOVQ_ZERO(mm7);
|
||||
MOVQ_WONE(mm6);
|
||||
JUMPALIGN();
|
||||
do {
|
||||
__asm __volatile(
|
||||
"movq %1, %%mm1\n\t"
|
||||
@ -578,10 +635,10 @@ static void avg_pixels_xy2_mmx( UINT8 *block, const UINT8 *pixels, int line_s
|
||||
const UINT8 *pix;
|
||||
p = block;
|
||||
pix = pixels;
|
||||
__asm __volatile(
|
||||
"pxor %%mm7, %%mm7\n\t"
|
||||
"movq %0, %%mm6\n\t"
|
||||
::"m"(mm_wtwo));
|
||||
MOVQ_ZERO(mm7);
|
||||
// this doesn't seem to be used offten - so
|
||||
// the inside usage of mm_wone is not optimized
|
||||
MOVQ_WTWO(mm6);
|
||||
do {
|
||||
__asm __volatile(
|
||||
"movq %1, %%mm0\n\t"
|
||||
@ -638,7 +695,7 @@ static void avg_no_rnd_pixels_mmx( UINT8 *block, const UINT8 *pixels, int line_
|
||||
const UINT8 *pix;
|
||||
p = block;
|
||||
pix = pixels;
|
||||
__asm __volatile("pxor %%mm7, %%mm7\n\t":);
|
||||
MOVQ_ZERO(mm7);
|
||||
do {
|
||||
__asm __volatile(
|
||||
"movq %1, %%mm0\n\t"
|
||||
@ -669,8 +726,7 @@ static void avg_no_rnd_pixels_x2_mmx( UINT8 *block, const UINT8 *pixels, int
|
||||
const UINT8 *pix;
|
||||
p = block;
|
||||
pix = pixels;
|
||||
__asm __volatile(
|
||||
"pxor %%mm7, %%mm7\n\t":);
|
||||
MOVQ_ZERO(mm7);
|
||||
do {
|
||||
__asm __volatile(
|
||||
"movq %1, %%mm0\n\t"
|
||||
@ -709,8 +765,7 @@ static void avg_no_rnd_pixels_y2_mmx( UINT8 *block, const UINT8 *pixels, int
|
||||
const UINT8 *pix;
|
||||
p = block;
|
||||
pix = pixels;
|
||||
__asm __volatile(
|
||||
"pxor %%mm7, %%mm7\n\t":);
|
||||
MOVQ_ZERO(mm7);
|
||||
do {
|
||||
__asm __volatile(
|
||||
"movq %1, %%mm0\n\t"
|
||||
@ -749,10 +804,9 @@ static void avg_no_rnd_pixels_xy2_mmx( UINT8 *block, const UINT8 *pixels, int
|
||||
const UINT8 *pix;
|
||||
p = block;
|
||||
pix = pixels;
|
||||
__asm __volatile(
|
||||
"pxor %%mm7, %%mm7\n\t"
|
||||
"movq %0, %%mm6\n\t"
|
||||
::"m"(mm_wone));
|
||||
MOVQ_ZERO(mm7);
|
||||
MOVQ_WONE(mm6);
|
||||
JUMPALIGN();
|
||||
do {
|
||||
__asm __volatile(
|
||||
"movq %1, %%mm0\n\t"
|
||||
@ -806,7 +860,7 @@ static void sub_pixels_mmx( DCTELEM *block, const UINT8 *pixels, int line_size,
|
||||
const UINT8 *pix;
|
||||
p = block;
|
||||
pix = pixels;
|
||||
__asm __volatile("pxor %%mm7, %%mm7":);
|
||||
MOVQ_ZERO(mm7);
|
||||
do {
|
||||
__asm __volatile(
|
||||
"movq %0, %%mm0\n\t"
|
||||
@ -833,10 +887,9 @@ static void sub_pixels_x2_mmx( DCTELEM *block, const UINT8 *pixels, int line_si
|
||||
const UINT8 *pix;
|
||||
p = block;
|
||||
pix = pixels;
|
||||
__asm __volatile(
|
||||
"pxor %%mm7, %%mm7\n\t"
|
||||
"movq %0, %%mm6"
|
||||
::"m"(mm_wone));
|
||||
MOVQ_ZERO(mm7);
|
||||
MOVQ_WONE(mm6);
|
||||
JUMPALIGN();
|
||||
do {
|
||||
__asm __volatile(
|
||||
"movq %0, %%mm0\n\t"
|
||||
@ -873,10 +926,8 @@ static void sub_pixels_y2_mmx( DCTELEM *block, const UINT8 *pixels, int line_si
|
||||
const UINT8 *pix;
|
||||
p = block;
|
||||
pix = pixels;
|
||||
__asm __volatile(
|
||||
"pxor %%mm7, %%mm7\n\t"
|
||||
"movq %0, %%mm6"
|
||||
::"m"(mm_wone));
|
||||
MOVQ_ZERO(mm7);
|
||||
MOVQ_WONE(mm6);
|
||||
do {
|
||||
__asm __volatile(
|
||||
"movq %0, %%mm0\n\t"
|
||||
@ -913,10 +964,9 @@ static void sub_pixels_xy2_mmx( DCTELEM *block, const UINT8 *pixels, int line
|
||||
const UINT8 *pix;
|
||||
p = block;
|
||||
pix = pixels;
|
||||
__asm __volatile(
|
||||
"pxor %%mm7, %%mm7\n\t"
|
||||
"movq %0, %%mm6\n\t"
|
||||
::"m"(mm_wtwo));
|
||||
MOVQ_ZERO(mm7);
|
||||
MOVQ_WTWO(mm6);
|
||||
JUMPALIGN();
|
||||
do {
|
||||
__asm __volatile(
|
||||
"movq %1, %%mm0\n\t"
|
||||
@ -960,6 +1010,8 @@ static void sub_pixels_xy2_mmx( DCTELEM *block, const UINT8 *pixels, int line
|
||||
} while(--h);
|
||||
}
|
||||
|
||||
static void just_return() { return; }
|
||||
|
||||
void dsputil_init_mmx(void)
|
||||
{
|
||||
mm_flags = mm_support();
|
||||
@ -1053,4 +1105,44 @@ void dsputil_init_mmx(void)
|
||||
ff_idct = simple_idct_mmx;
|
||||
#endif
|
||||
}
|
||||
|
||||
#if 0
|
||||
// for speed testing
|
||||
get_pixels = just_return;
|
||||
put_pixels_clamped = just_return;
|
||||
add_pixels_clamped = just_return;
|
||||
|
||||
pix_abs16x16 = just_return;
|
||||
pix_abs16x16_x2 = just_return;
|
||||
pix_abs16x16_y2 = just_return;
|
||||
pix_abs16x16_xy2 = just_return;
|
||||
|
||||
put_pixels_tab[0] = just_return;
|
||||
put_pixels_tab[1] = just_return;
|
||||
put_pixels_tab[2] = just_return;
|
||||
put_pixels_tab[3] = just_return;
|
||||
|
||||
put_no_rnd_pixels_tab[0] = just_return;
|
||||
put_no_rnd_pixels_tab[1] = just_return;
|
||||
put_no_rnd_pixels_tab[2] = just_return;
|
||||
put_no_rnd_pixels_tab[3] = just_return;
|
||||
|
||||
avg_pixels_tab[0] = just_return;
|
||||
avg_pixels_tab[1] = just_return;
|
||||
avg_pixels_tab[2] = just_return;
|
||||
avg_pixels_tab[3] = just_return;
|
||||
|
||||
avg_no_rnd_pixels_tab[0] = just_return;
|
||||
avg_no_rnd_pixels_tab[1] = just_return;
|
||||
avg_no_rnd_pixels_tab[2] = just_return;
|
||||
avg_no_rnd_pixels_tab[3] = just_return;
|
||||
|
||||
sub_pixels_tab[0] = just_return;
|
||||
sub_pixels_tab[1] = just_return;
|
||||
sub_pixels_tab[2] = just_return;
|
||||
sub_pixels_tab[3] = just_return;
|
||||
|
||||
//av_fdct = just_return;
|
||||
//ff_idct = just_return;
|
||||
#endif
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user