123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666 |
- /********************************************************************
- * *
- * THIS FILE IS PART OF THE OggTheora SOFTWARE CODEC SOURCE CODE. *
- * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS *
- * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE *
- * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. *
- * *
- * THE Theora SOURCE CODE IS COPYRIGHT (C) 1999-2006 *
- * by the Xiph.Org Foundation http://www.xiph.org/ *
- * *
- ********************************************************************/
- /*MMX fDCT implementation for x86_32*/
- /*$Id: fdct_ses2.c 14579 2008-03-12 06:42:40Z xiphmont $*/
- #include "x86enc.h"
- #if defined(OC_X86_ASM)
- # define OC_FDCT_STAGE1_8x4 \
- "#OC_FDCT_STAGE1_8x4\n\t" \
- /*Stage 1:*/ \
- /*mm0=t7'=t0-t7*/ \
- "psubw %%mm7,%%mm0\n\t" \
- "paddw %%mm7,%%mm7\n\t" \
- /*mm1=t6'=t1-t6*/ \
- "psubw %%mm6,%%mm1\n\t" \
- "paddw %%mm6,%%mm6\n\t" \
- /*mm2=t5'=t2-t5*/ \
- "psubw %%mm5,%%mm2\n\t" \
- "paddw %%mm5,%%mm5\n\t" \
- /*mm3=t4'=t3-t4*/ \
- "psubw %%mm4,%%mm3\n\t" \
- "paddw %%mm4,%%mm4\n\t" \
- /*mm7=t0'=t0+t7*/ \
- "paddw %%mm0,%%mm7\n\t" \
- /*mm6=t1'=t1+t6*/ \
- "paddw %%mm1,%%mm6\n\t" \
- /*mm5=t2'=t2+t5*/ \
- "paddw %%mm2,%%mm5\n\t" \
- /*mm4=t3'=t3+t4*/ \
- "paddw %%mm3,%%mm4\n\t" \
- # define OC_FDCT8x4(_r0,_r1,_r2,_r3,_r4,_r5,_r6,_r7) \
- "#OC_FDCT8x4\n\t" \
- /*Stage 2:*/ \
- /*mm7=t3''=t0'-t3'*/ \
- "psubw %%mm4,%%mm7\n\t" \
- "paddw %%mm4,%%mm4\n\t" \
- /*mm6=t2''=t1'-t2'*/ \
- "psubw %%mm5,%%mm6\n\t" \
- "movq %%mm7,"_r6"(%[y])\n\t" \
- "paddw %%mm5,%%mm5\n\t" \
- /*mm1=t5''=t6'-t5'*/ \
- "psubw %%mm2,%%mm1\n\t" \
- "movq %%mm6,"_r2"(%[y])\n\t" \
- /*mm4=t0''=t0'+t3'*/ \
- "paddw %%mm7,%%mm4\n\t" \
- "paddw %%mm2,%%mm2\n\t" \
- /*mm5=t1''=t1'+t2'*/ \
- "movq %%mm4,"_r0"(%[y])\n\t" \
- "paddw %%mm6,%%mm5\n\t" \
- /*mm2=t6''=t6'+t5'*/ \
- "paddw %%mm1,%%mm2\n\t" \
- "movq %%mm5,"_r4"(%[y])\n\t" \
- /*mm0=t7', mm1=t5'', mm2=t6'', mm3=t4'.*/ \
- /*mm4, mm5, mm6, mm7 are free.*/ \
- /*Stage 3:*/ \
- /*mm6={2}x4, mm7={27146,0xB500>>1}x2*/ \
- "mov $0x5A806A0A,%[a]\n\t" \
- "pcmpeqb %%mm6,%%mm6\n\t" \
- "movd %[a],%%mm7\n\t" \
- "psrlw $15,%%mm6\n\t" \
- "punpckldq %%mm7,%%mm7\n\t" \
- "paddw %%mm6,%%mm6\n\t" \
- /*mm0=0, m2={-1}x4 \
- mm5:mm4=t5''*27146+0xB500*/ \
- "movq %%mm1,%%mm4\n\t" \
- "movq %%mm1,%%mm5\n\t" \
- "punpcklwd %%mm6,%%mm4\n\t" \
- "movq %%mm2,"_r3"(%[y])\n\t" \
- "pmaddwd %%mm7,%%mm4\n\t" \
- "movq %%mm0,"_r7"(%[y])\n\t" \
- "punpckhwd %%mm6,%%mm5\n\t" \
- "pxor %%mm0,%%mm0\n\t" \
- "pmaddwd %%mm7,%%mm5\n\t" \
- "pcmpeqb %%mm2,%%mm2\n\t" \
- /*mm2=t6'', mm1=t5''+(t5''!=0) \
- mm4=(t5''*27146+0xB500>>16)*/ \
- "pcmpeqw %%mm1,%%mm0\n\t" \
- "psrad $16,%%mm4\n\t" \
- "psubw %%mm2,%%mm0\n\t" \
- "movq "_r3"(%[y]),%%mm2\n\t" \
- "psrad $16,%%mm5\n\t" \
- "paddw %%mm0,%%mm1\n\t" \
- "packssdw %%mm5,%%mm4\n\t" \
- /*mm4=s=(t5''*27146+0xB500>>16)+t5''+(t5''!=0)>>1*/ \
- "paddw %%mm1,%%mm4\n\t" \
- "movq "_r7"(%[y]),%%mm0\n\t" \
- "psraw $1,%%mm4\n\t" \
- "movq %%mm3,%%mm1\n\t" \
- /*mm3=t4''=t4'+s*/ \
- "paddw %%mm4,%%mm3\n\t" \
- /*mm1=t5'''=t4'-s*/ \
- "psubw %%mm4,%%mm1\n\t" \
- /*mm1=0, mm3={-1}x4 \
- mm5:mm4=t6''*27146+0xB500*/ \
- "movq %%mm2,%%mm4\n\t" \
- "movq %%mm2,%%mm5\n\t" \
- "punpcklwd %%mm6,%%mm4\n\t" \
- "movq %%mm1,"_r5"(%[y])\n\t" \
- "pmaddwd %%mm7,%%mm4\n\t" \
- "movq %%mm3,"_r1"(%[y])\n\t" \
- "punpckhwd %%mm6,%%mm5\n\t" \
- "pxor %%mm1,%%mm1\n\t" \
- "pmaddwd %%mm7,%%mm5\n\t" \
- "pcmpeqb %%mm3,%%mm3\n\t" \
- /*mm2=t6''+(t6''!=0), mm4=(t6''*27146+0xB500>>16)*/ \
- "psrad $16,%%mm4\n\t" \
- "pcmpeqw %%mm2,%%mm1\n\t" \
- "psrad $16,%%mm5\n\t" \
- "psubw %%mm3,%%mm1\n\t" \
- "packssdw %%mm5,%%mm4\n\t" \
- "paddw %%mm1,%%mm2\n\t" \
- /*mm1=t1'' \
- mm4=s=(t6''*27146+0xB500>>16)+t6''+(t6''!=0)>>1*/ \
- "paddw %%mm2,%%mm4\n\t" \
- "movq "_r4"(%[y]),%%mm1\n\t" \
- "psraw $1,%%mm4\n\t" \
- "movq %%mm0,%%mm2\n\t" \
- /*mm7={54491-0x7FFF,0x7FFF}x2 \
- mm0=t7''=t7'+s*/ \
- "paddw %%mm4,%%mm0\n\t" \
- /*mm2=t6'''=t7'-s*/ \
- "psubw %%mm4,%%mm2\n\t" \
- /*Stage 4:*/ \
- /*mm0=0, mm2=t0'' \
- mm5:mm4=t1''*27146+0xB500*/ \
- "movq %%mm1,%%mm4\n\t" \
- "movq %%mm1,%%mm5\n\t" \
- "punpcklwd %%mm6,%%mm4\n\t" \
- "movq %%mm2,"_r3"(%[y])\n\t" \
- "pmaddwd %%mm7,%%mm4\n\t" \
- "movq "_r0"(%[y]),%%mm2\n\t" \
- "punpckhwd %%mm6,%%mm5\n\t" \
- "movq %%mm0,"_r7"(%[y])\n\t" \
- "pmaddwd %%mm7,%%mm5\n\t" \
- "pxor %%mm0,%%mm0\n\t" \
- /*mm7={27146,0x4000>>1}x2 \
- mm0=s=(t1''*27146+0xB500>>16)+t1''+(t1''!=0)*/ \
- "psrad $16,%%mm4\n\t" \
- "mov $0x20006A0A,%[a]\n\t" \
- "pcmpeqw %%mm1,%%mm0\n\t" \
- "movd %[a],%%mm7\n\t" \
- "psrad $16,%%mm5\n\t" \
- "psubw %%mm3,%%mm0\n\t" \
- "packssdw %%mm5,%%mm4\n\t" \
- "paddw %%mm1,%%mm0\n\t" \
- "punpckldq %%mm7,%%mm7\n\t" \
- "paddw %%mm4,%%mm0\n\t" \
- /*mm6={0x00000E3D}x2 \
- mm1=-(t0''==0), mm5:mm4=t0''*27146+0x4000*/ \
- "movq %%mm2,%%mm4\n\t" \
- "movq %%mm2,%%mm5\n\t" \
- "punpcklwd %%mm6,%%mm4\n\t" \
- "mov $0x0E3D,%[a]\n\t" \
- "pmaddwd %%mm7,%%mm4\n\t" \
- "punpckhwd %%mm6,%%mm5\n\t" \
- "movd %[a],%%mm6\n\t" \
- "pmaddwd %%mm7,%%mm5\n\t" \
- "pxor %%mm1,%%mm1\n\t" \
- "punpckldq %%mm6,%%mm6\n\t" \
- "pcmpeqw %%mm2,%%mm1\n\t" \
- /*mm4=r=(t0''*27146+0x4000>>16)+t0''+(t0''!=0)*/ \
- "psrad $16,%%mm4\n\t" \
- "psubw %%mm3,%%mm1\n\t" \
- "psrad $16,%%mm5\n\t" \
- "paddw %%mm1,%%mm2\n\t" \
- "packssdw %%mm5,%%mm4\n\t" \
- "movq "_r5"(%[y]),%%mm1\n\t" \
- "paddw %%mm2,%%mm4\n\t" \
- /*mm2=t6'', mm0=_y[0]=u=r+s>>1 \
- The naive implementation could cause overflow, so we use \
- u=(r&s)+((r^s)>>1).*/ \
- "movq "_r3"(%[y]),%%mm2\n\t" \
- "movq %%mm0,%%mm7\n\t" \
- "pxor %%mm4,%%mm0\n\t" \
- "pand %%mm4,%%mm7\n\t" \
- "psraw $1,%%mm0\n\t" \
- "mov $0x7FFF54DC,%[a]\n\t" \
- "paddw %%mm7,%%mm0\n\t" \
- "movd %[a],%%mm7\n\t" \
- /*mm7={54491-0x7FFF,0x7FFF}x2 \
- mm4=_y[4]=v=r-u*/ \
- "psubw %%mm0,%%mm4\n\t" \
- "punpckldq %%mm7,%%mm7\n\t" \
- "movq %%mm4,"_r4"(%[y])\n\t" \
- /*mm0=0, mm7={36410}x4 \
- mm1=(t5'''!=0), mm5:mm4=54491*t5'''+0x0E3D*/ \
- "movq %%mm1,%%mm4\n\t" \
- "movq %%mm1,%%mm5\n\t" \
- "punpcklwd %%mm1,%%mm4\n\t" \
- "mov $0x8E3A8E3A,%[a]\n\t" \
- "pmaddwd %%mm7,%%mm4\n\t" \
- "movq %%mm0,"_r0"(%[y])\n\t" \
- "punpckhwd %%mm1,%%mm5\n\t" \
- "pxor %%mm0,%%mm0\n\t" \
- "pmaddwd %%mm7,%%mm5\n\t" \
- "pcmpeqw %%mm0,%%mm1\n\t" \
- "movd %[a],%%mm7\n\t" \
- "psubw %%mm3,%%mm1\n\t" \
- "punpckldq %%mm7,%%mm7\n\t" \
- "paddd %%mm6,%%mm4\n\t" \
- "paddd %%mm6,%%mm5\n\t" \
- /*mm0=0 \
- mm3:mm1=36410*t6'''+((t5'''!=0)<<16)*/ \
- "movq %%mm2,%%mm6\n\t" \
- "movq %%mm2,%%mm3\n\t" \
- "pmulhw %%mm7,%%mm6\n\t" \
- "paddw %%mm2,%%mm1\n\t" \
- "pmullw %%mm7,%%mm3\n\t" \
- "pxor %%mm0,%%mm0\n\t" \
- "paddw %%mm1,%%mm6\n\t" \
- "movq %%mm3,%%mm1\n\t" \
- "punpckhwd %%mm6,%%mm3\n\t" \
- "punpcklwd %%mm6,%%mm1\n\t" \
- /*mm3={-1}x4, mm6={1}x4 \
- mm4=_y[5]=u=(54491*t5'''+36410*t6'''+0x0E3D>>16)+(t5'''!=0)*/ \
- "paddd %%mm3,%%mm5\n\t" \
- "paddd %%mm1,%%mm4\n\t" \
- "psrad $16,%%mm5\n\t" \
- "pxor %%mm6,%%mm6\n\t" \
- "psrad $16,%%mm4\n\t" \
- "pcmpeqb %%mm3,%%mm3\n\t" \
- "packssdw %%mm5,%%mm4\n\t" \
- "psubw %%mm3,%%mm6\n\t" \
- /*mm1=t7'', mm7={26568,0x3400}x2 \
- mm2=s=t6'''-(36410*u>>16)*/ \
- "movq %%mm4,%%mm1\n\t" \
- "mov $0x340067C8,%[a]\n\t" \
- "pmulhw %%mm7,%%mm4\n\t" \
- "movd %[a],%%mm7\n\t" \
- "movq %%mm1,"_r5"(%[y])\n\t" \
- "punpckldq %%mm7,%%mm7\n\t" \
- "paddw %%mm1,%%mm4\n\t" \
- "movq "_r7"(%[y]),%%mm1\n\t" \
- "psubw %%mm4,%%mm2\n\t" \
- /*mm6={0x00007B1B}x2 \
- mm0=(s!=0), mm5:mm4=s*26568+0x3400*/ \
- "movq %%mm2,%%mm4\n\t" \
- "movq %%mm2,%%mm5\n\t" \
- "punpcklwd %%mm6,%%mm4\n\t" \
- "pcmpeqw %%mm2,%%mm0\n\t" \
- "pmaddwd %%mm7,%%mm4\n\t" \
- "mov $0x7B1B,%[a]\n\t" \
- "punpckhwd %%mm6,%%mm5\n\t" \
- "movd %[a],%%mm6\n\t" \
- "pmaddwd %%mm7,%%mm5\n\t" \
- "psubw %%mm3,%%mm0\n\t" \
- "punpckldq %%mm6,%%mm6\n\t" \
- /*mm7={64277-0x7FFF,0x7FFF}x2 \
- mm2=_y[3]=v=(s*26568+0x3400>>17)+s+(s!=0)*/ \
- "psrad $17,%%mm4\n\t" \
- "paddw %%mm0,%%mm2\n\t" \
- "psrad $17,%%mm5\n\t" \
- "mov $0x7FFF7B16,%[a]\n\t" \
- "packssdw %%mm5,%%mm4\n\t" \
- "movd %[a],%%mm7\n\t" \
- "paddw %%mm4,%%mm2\n\t" \
- "punpckldq %%mm7,%%mm7\n\t" \
- /*mm0=0, mm7={12785}x4 \
- mm1=(t7''!=0), mm2=t4'', mm5:mm4=64277*t7''+0x7B1B*/ \
- "movq %%mm1,%%mm4\n\t" \
- "movq %%mm1,%%mm5\n\t" \
- "movq %%mm2,"_r3"(%[y])\n\t" \
- "punpcklwd %%mm1,%%mm4\n\t" \
- "movq "_r1"(%[y]),%%mm2\n\t" \
- "pmaddwd %%mm7,%%mm4\n\t" \
- "mov $0x31F131F1,%[a]\n\t" \
- "punpckhwd %%mm1,%%mm5\n\t" \
- "pxor %%mm0,%%mm0\n\t" \
- "pmaddwd %%mm7,%%mm5\n\t" \
- "pcmpeqw %%mm0,%%mm1\n\t" \
- "movd %[a],%%mm7\n\t" \
- "psubw %%mm3,%%mm1\n\t" \
- "punpckldq %%mm7,%%mm7\n\t" \
- "paddd %%mm6,%%mm4\n\t" \
- "paddd %%mm6,%%mm5\n\t" \
- /*mm3:mm1=12785*t4'''+((t7''!=0)<<16)*/ \
- "movq %%mm2,%%mm6\n\t" \
- "movq %%mm2,%%mm3\n\t" \
- "pmulhw %%mm7,%%mm6\n\t" \
- "pmullw %%mm7,%%mm3\n\t" \
- "paddw %%mm1,%%mm6\n\t" \
- "movq %%mm3,%%mm1\n\t" \
- "punpckhwd %%mm6,%%mm3\n\t" \
- "punpcklwd %%mm6,%%mm1\n\t" \
- /*mm3={-1}x4, mm6={1}x4 \
- mm4=_y[1]=u=(12785*t4'''+64277*t7''+0x7B1B>>16)+(t7''!=0)*/ \
- "paddd %%mm3,%%mm5\n\t" \
- "paddd %%mm1,%%mm4\n\t" \
- "psrad $16,%%mm5\n\t" \
- "pxor %%mm6,%%mm6\n\t" \
- "psrad $16,%%mm4\n\t" \
- "pcmpeqb %%mm3,%%mm3\n\t" \
- "packssdw %%mm5,%%mm4\n\t" \
- "psubw %%mm3,%%mm6\n\t" \
- /*mm1=t3'', mm7={20539,0x3000}x2 \
- mm4=s=(12785*u>>16)-t4''*/ \
- "movq %%mm4,"_r1"(%[y])\n\t" \
- "pmulhw %%mm7,%%mm4\n\t" \
- "mov $0x3000503B,%[a]\n\t" \
- "movq "_r6"(%[y]),%%mm1\n\t" \
- "movd %[a],%%mm7\n\t" \
- "psubw %%mm2,%%mm4\n\t" \
- "punpckldq %%mm7,%%mm7\n\t" \
- /*mm6={0x00006CB7}x2 \
- mm0=(s!=0), mm5:mm4=s*20539+0x3000*/ \
- "movq %%mm4,%%mm5\n\t" \
- "movq %%mm4,%%mm2\n\t" \
- "punpcklwd %%mm6,%%mm4\n\t" \
- "pcmpeqw %%mm2,%%mm0\n\t" \
- "pmaddwd %%mm7,%%mm4\n\t" \
- "mov $0x6CB7,%[a]\n\t" \
- "punpckhwd %%mm6,%%mm5\n\t" \
- "movd %[a],%%mm6\n\t" \
- "pmaddwd %%mm7,%%mm5\n\t" \
- "psubw %%mm3,%%mm0\n\t" \
- "punpckldq %%mm6,%%mm6\n\t" \
- /*mm7={60547-0x7FFF,0x7FFF}x2 \
- mm2=_y[7]=v=(s*20539+0x3000>>20)+s+(s!=0)*/ \
- "psrad $20,%%mm4\n\t" \
- "paddw %%mm0,%%mm2\n\t" \
- "psrad $20,%%mm5\n\t" \
- "mov $0x7FFF6C84,%[a]\n\t" \
- "packssdw %%mm5,%%mm4\n\t" \
- "movd %[a],%%mm7\n\t" \
- "paddw %%mm4,%%mm2\n\t" \
- "punpckldq %%mm7,%%mm7\n\t" \
- /*mm0=0, mm7={25080}x4 \
- mm2=t2'', mm5:mm4=60547*t3''+0x6CB7*/ \
- "movq %%mm1,%%mm4\n\t" \
- "movq %%mm1,%%mm5\n\t" \
- "movq %%mm2,"_r7"(%[y])\n\t" \
- "punpcklwd %%mm1,%%mm4\n\t" \
- "movq "_r2"(%[y]),%%mm2\n\t" \
- "pmaddwd %%mm7,%%mm4\n\t" \
- "mov $0x61F861F8,%[a]\n\t" \
- "punpckhwd %%mm1,%%mm5\n\t" \
- "pxor %%mm0,%%mm0\n\t" \
- "pmaddwd %%mm7,%%mm5\n\t" \
- "movd %[a],%%mm7\n\t" \
- "pcmpeqw %%mm0,%%mm1\n\t" \
- "psubw %%mm3,%%mm1\n\t" \
- "punpckldq %%mm7,%%mm7\n\t" \
- "paddd %%mm6,%%mm4\n\t" \
- "paddd %%mm6,%%mm5\n\t" \
- /*mm3:mm1=25080*t2''+((t3''!=0)<<16)*/ \
- "movq %%mm2,%%mm6\n\t" \
- "movq %%mm2,%%mm3\n\t" \
- "pmulhw %%mm7,%%mm6\n\t" \
- "pmullw %%mm7,%%mm3\n\t" \
- "paddw %%mm1,%%mm6\n\t" \
- "movq %%mm3,%%mm1\n\t" \
- "punpckhwd %%mm6,%%mm3\n\t" \
- "punpcklwd %%mm6,%%mm1\n\t" \
- /*mm1={-1}x4 \
- mm4=u=(25080*t2''+60547*t3''+0x6CB7>>16)+(t3''!=0)*/ \
- "paddd %%mm3,%%mm5\n\t" \
- "paddd %%mm1,%%mm4\n\t" \
- "psrad $16,%%mm5\n\t" \
- "mov $0x28005460,%[a]\n\t" \
- "psrad $16,%%mm4\n\t" \
- "pcmpeqb %%mm1,%%mm1\n\t" \
- "packssdw %%mm5,%%mm4\n\t" \
- /*mm5={1}x4, mm6=_y[2]=u, mm7={21600,0x2800}x2 \
- mm4=s=(25080*u>>16)-t2''*/ \
- "movq %%mm4,%%mm6\n\t" \
- "pmulhw %%mm7,%%mm4\n\t" \
- "pxor %%mm5,%%mm5\n\t" \
- "movd %[a],%%mm7\n\t" \
- "psubw %%mm1,%%mm5\n\t" \
- "punpckldq %%mm7,%%mm7\n\t" \
- "psubw %%mm2,%%mm4\n\t" \
- /*mm2=s+(s!=0) \
- mm4:mm3=s*21600+0x2800*/ \
- "movq %%mm4,%%mm3\n\t" \
- "movq %%mm4,%%mm2\n\t" \
- "punpckhwd %%mm5,%%mm4\n\t" \
- "pcmpeqw %%mm2,%%mm0\n\t" \
- "pmaddwd %%mm7,%%mm4\n\t" \
- "psubw %%mm1,%%mm0\n\t" \
- "punpcklwd %%mm5,%%mm3\n\t" \
- "paddw %%mm0,%%mm2\n\t" \
- "pmaddwd %%mm7,%%mm3\n\t" \
- /*mm0=_y[4], mm1=_y[7], mm4=_y[0], mm5=_y[5] \
- mm3=_y[6]=v=(s*21600+0x2800>>18)+s+(s!=0)*/ \
- "movq "_r4"(%[y]),%%mm0\n\t" \
- "psrad $18,%%mm4\n\t" \
- "movq "_r5"(%[y]),%%mm5\n\t" \
- "psrad $18,%%mm3\n\t" \
- "movq "_r7"(%[y]),%%mm1\n\t" \
- "packssdw %%mm4,%%mm3\n\t" \
- "movq "_r0"(%[y]),%%mm4\n\t" \
- "paddw %%mm2,%%mm3\n\t" \
- /*On input, mm4=_y[0], mm6=_y[2], mm0=_y[4], mm5=_y[5], mm3=_y[6], mm1=_y[7].
- On output, {_y[4],mm1,mm2,mm3} contains the transpose of _y[4...7] and
- {mm4,mm5,mm6,mm7} contains the transpose of _y[0...3].*/
- # define OC_TRANSPOSE8x4(_r0,_r1,_r2,_r3,_r4,_r5,_r6,_r7) \
- "#OC_TRANSPOSE8x4\n\t" \
- /*First 4x4 transpose:*/ \
- /*mm0 = e3 e2 e1 e0 \
- mm5 = f3 f2 f1 f0 \
- mm3 = g3 g2 g1 g0 \
- mm1 = h3 h2 h1 h0*/ \
- "movq %%mm0,%%mm2\n\t" \
- "punpcklwd %%mm5,%%mm0\n\t" \
- "punpckhwd %%mm5,%%mm2\n\t" \
- "movq %%mm3,%%mm5\n\t" \
- "punpcklwd %%mm1,%%mm3\n\t" \
- "punpckhwd %%mm1,%%mm5\n\t" \
- /*mm0 = f1 e1 f0 e0 \
- mm2 = f3 e3 f2 e2 \
- mm3 = h1 g1 h0 g0 \
- mm5 = h3 g3 h2 g2*/ \
- "movq %%mm0,%%mm1\n\t" \
- "punpckldq %%mm3,%%mm0\n\t" \
- "movq %%mm0,"_r4"(%[y])\n\t" \
- "punpckhdq %%mm3,%%mm1\n\t" \
- "movq "_r1"(%[y]),%%mm0\n\t" \
- "movq %%mm2,%%mm3\n\t" \
- "punpckldq %%mm5,%%mm2\n\t" \
- "punpckhdq %%mm5,%%mm3\n\t" \
- "movq "_r3"(%[y]),%%mm5\n\t" \
- /*_y[4] = h0 g0 f0 e0 \
- mm1 = h1 g1 f1 e1 \
- mm2 = h2 g2 f2 e2 \
- mm3 = h3 g3 f3 e3*/ \
- /*Second 4x4 transpose:*/ \
- /*mm4 = a3 a2 a1 a0 \
- mm0 = b3 b2 b1 b0 \
- mm6 = c3 c2 c1 c0 \
- mm5 = d3 d2 d1 d0*/ \
- "movq %%mm4,%%mm7\n\t" \
- "punpcklwd %%mm0,%%mm4\n\t" \
- "punpckhwd %%mm0,%%mm7\n\t" \
- "movq %%mm6,%%mm0\n\t" \
- "punpcklwd %%mm5,%%mm6\n\t" \
- "punpckhwd %%mm5,%%mm0\n\t" \
- /*mm4 = b1 a1 b0 a0 \
- mm7 = b3 a3 b2 a2 \
- mm6 = d1 c1 d0 c0 \
- mm0 = d3 c3 d2 c2*/ \
- "movq %%mm4,%%mm5\n\t" \
- "punpckldq %%mm6,%%mm4\n\t" \
- "punpckhdq %%mm6,%%mm5\n\t" \
- "movq %%mm7,%%mm6\n\t" \
- "punpckhdq %%mm0,%%mm7\n\t" \
- "punpckldq %%mm0,%%mm6\n\t" \
- /*mm4 = d0 c0 b0 a0 \
- mm5 = d1 c1 b1 a1 \
- mm6 = d2 c2 b2 a2 \
- mm7 = d3 c3 b3 a3*/ \
- /*MMX implementation of the fDCT.*/
- void oc_enc_fdct8x8_mmx(ogg_int16_t _y[64],const ogg_int16_t _x[64]){
- ptrdiff_t a;
- __asm__ __volatile__(
- /*Add two extra bits of working precision to improve accuracy; any more and
- we could overflow.*/
- /*We also add biases to correct for some systematic error that remains in
- the full fDCT->iDCT round trip.*/
- "movq 0x00(%[x]),%%mm0\n\t"
- "movq 0x10(%[x]),%%mm1\n\t"
- "movq 0x20(%[x]),%%mm2\n\t"
- "movq 0x30(%[x]),%%mm3\n\t"
- "pcmpeqb %%mm4,%%mm4\n\t"
- "pxor %%mm7,%%mm7\n\t"
- "movq %%mm0,%%mm5\n\t"
- "psllw $2,%%mm0\n\t"
- "pcmpeqw %%mm7,%%mm5\n\t"
- "movq 0x70(%[x]),%%mm7\n\t"
- "psllw $2,%%mm1\n\t"
- "psubw %%mm4,%%mm5\n\t"
- "psllw $2,%%mm2\n\t"
- "mov $1,%[a]\n\t"
- "pslld $16,%%mm5\n\t"
- "movd %[a],%%mm6\n\t"
- "psllq $16,%%mm5\n\t"
- "mov $0x10001,%[a]\n\t"
- "psllw $2,%%mm3\n\t"
- "movd %[a],%%mm4\n\t"
- "punpckhwd %%mm6,%%mm5\n\t"
- "psubw %%mm6,%%mm1\n\t"
- "movq 0x60(%[x]),%%mm6\n\t"
- "paddw %%mm5,%%mm0\n\t"
- "movq 0x50(%[x]),%%mm5\n\t"
- "paddw %%mm4,%%mm0\n\t"
- "movq 0x40(%[x]),%%mm4\n\t"
- /*We inline stage1 of the transform here so we can get better instruction
- scheduling with the shifts.*/
- /*mm0=t7'=t0-t7*/
- "psllw $2,%%mm7\n\t"
- "psubw %%mm7,%%mm0\n\t"
- "psllw $2,%%mm6\n\t"
- "paddw %%mm7,%%mm7\n\t"
- /*mm1=t6'=t1-t6*/
- "psllw $2,%%mm5\n\t"
- "psubw %%mm6,%%mm1\n\t"
- "psllw $2,%%mm4\n\t"
- "paddw %%mm6,%%mm6\n\t"
- /*mm2=t5'=t2-t5*/
- "psubw %%mm5,%%mm2\n\t"
- "paddw %%mm5,%%mm5\n\t"
- /*mm3=t4'=t3-t4*/
- "psubw %%mm4,%%mm3\n\t"
- "paddw %%mm4,%%mm4\n\t"
- /*mm7=t0'=t0+t7*/
- "paddw %%mm0,%%mm7\n\t"
- /*mm6=t1'=t1+t6*/
- "paddw %%mm1,%%mm6\n\t"
- /*mm5=t2'=t2+t5*/
- "paddw %%mm2,%%mm5\n\t"
- /*mm4=t3'=t3+t4*/
- "paddw %%mm3,%%mm4\n\t"
- OC_FDCT8x4("0x00","0x10","0x20","0x30","0x40","0x50","0x60","0x70")
- OC_TRANSPOSE8x4("0x00","0x10","0x20","0x30","0x40","0x50","0x60","0x70")
- /*Swap out this 8x4 block for the next one.*/
- "movq 0x08(%[x]),%%mm0\n\t"
- "movq %%mm7,0x30(%[y])\n\t"
- "movq 0x78(%[x]),%%mm7\n\t"
- "movq %%mm1,0x50(%[y])\n\t"
- "movq 0x18(%[x]),%%mm1\n\t"
- "movq %%mm6,0x20(%[y])\n\t"
- "movq 0x68(%[x]),%%mm6\n\t"
- "movq %%mm2,0x60(%[y])\n\t"
- "movq 0x28(%[x]),%%mm2\n\t"
- "movq %%mm5,0x10(%[y])\n\t"
- "movq 0x58(%[x]),%%mm5\n\t"
- "movq %%mm3,0x70(%[y])\n\t"
- "movq 0x38(%[x]),%%mm3\n\t"
- /*And increase its working precision, too.*/
- "psllw $2,%%mm0\n\t"
- "movq %%mm4,0x00(%[y])\n\t"
- "psllw $2,%%mm7\n\t"
- "movq 0x48(%[x]),%%mm4\n\t"
- /*We inline stage1 of the transform here so we can get better instruction
- scheduling with the shifts.*/
- /*mm0=t7'=t0-t7*/
- "psubw %%mm7,%%mm0\n\t"
- "psllw $2,%%mm1\n\t"
- "paddw %%mm7,%%mm7\n\t"
- "psllw $2,%%mm6\n\t"
- /*mm1=t6'=t1-t6*/
- "psubw %%mm6,%%mm1\n\t"
- "psllw $2,%%mm2\n\t"
- "paddw %%mm6,%%mm6\n\t"
- "psllw $2,%%mm5\n\t"
- /*mm2=t5'=t2-t5*/
- "psubw %%mm5,%%mm2\n\t"
- "psllw $2,%%mm3\n\t"
- "paddw %%mm5,%%mm5\n\t"
- "psllw $2,%%mm4\n\t"
- /*mm3=t4'=t3-t4*/
- "psubw %%mm4,%%mm3\n\t"
- "paddw %%mm4,%%mm4\n\t"
- /*mm7=t0'=t0+t7*/
- "paddw %%mm0,%%mm7\n\t"
- /*mm6=t1'=t1+t6*/
- "paddw %%mm1,%%mm6\n\t"
- /*mm5=t2'=t2+t5*/
- "paddw %%mm2,%%mm5\n\t"
- /*mm4=t3'=t3+t4*/
- "paddw %%mm3,%%mm4\n\t"
- OC_FDCT8x4("0x08","0x18","0x28","0x38","0x48","0x58","0x68","0x78")
- OC_TRANSPOSE8x4("0x08","0x18","0x28","0x38","0x48","0x58","0x68","0x78")
- /*Here the first 4x4 block of output from the last transpose is the second
- 4x4 block of input for the next transform.
- We have cleverly arranged that it already be in the appropriate place,
- so we only have to do half the stores and loads.*/
- "movq 0x00(%[y]),%%mm0\n\t"
- "movq %%mm1,0x58(%[y])\n\t"
- "movq 0x10(%[y]),%%mm1\n\t"
- "movq %%mm2,0x68(%[y])\n\t"
- "movq 0x20(%[y]),%%mm2\n\t"
- "movq %%mm3,0x78(%[y])\n\t"
- "movq 0x30(%[y]),%%mm3\n\t"
- OC_FDCT_STAGE1_8x4
- OC_FDCT8x4("0x00","0x10","0x20","0x30","0x08","0x18","0x28","0x38")
- OC_TRANSPOSE8x4("0x00","0x10","0x20","0x30","0x08","0x18","0x28","0x38")
- /*mm0={-2}x4*/
- "pcmpeqw %%mm0,%%mm0\n\t"
- "paddw %%mm0,%%mm0\n\t"
- /*Round the results.*/
- "psubw %%mm0,%%mm1\n\t"
- "psubw %%mm0,%%mm2\n\t"
- "psraw $2,%%mm1\n\t"
- "psubw %%mm0,%%mm3\n\t"
- "movq %%mm1,0x18(%[y])\n\t"
- "psraw $2,%%mm2\n\t"
- "psubw %%mm0,%%mm4\n\t"
- "movq 0x08(%[y]),%%mm1\n\t"
- "psraw $2,%%mm3\n\t"
- "psubw %%mm0,%%mm5\n\t"
- "psraw $2,%%mm4\n\t"
- "psubw %%mm0,%%mm6\n\t"
- "psraw $2,%%mm5\n\t"
- "psubw %%mm0,%%mm7\n\t"
- "psraw $2,%%mm6\n\t"
- "psubw %%mm0,%%mm1\n\t"
- "psraw $2,%%mm7\n\t"
- "movq 0x40(%[y]),%%mm0\n\t"
- "psraw $2,%%mm1\n\t"
- "movq %%mm7,0x30(%[y])\n\t"
- "movq 0x78(%[y]),%%mm7\n\t"
- "movq %%mm1,0x08(%[y])\n\t"
- "movq 0x50(%[y]),%%mm1\n\t"
- "movq %%mm6,0x20(%[y])\n\t"
- "movq 0x68(%[y]),%%mm6\n\t"
- "movq %%mm2,0x28(%[y])\n\t"
- "movq 0x60(%[y]),%%mm2\n\t"
- "movq %%mm5,0x10(%[y])\n\t"
- "movq 0x58(%[y]),%%mm5\n\t"
- "movq %%mm3,0x38(%[y])\n\t"
- "movq 0x70(%[y]),%%mm3\n\t"
- "movq %%mm4,0x00(%[y])\n\t"
- "movq 0x48(%[y]),%%mm4\n\t"
- OC_FDCT_STAGE1_8x4
- OC_FDCT8x4("0x40","0x50","0x60","0x70","0x48","0x58","0x68","0x78")
- OC_TRANSPOSE8x4("0x40","0x50","0x60","0x70","0x48","0x58","0x68","0x78")
- /*mm0={-2}x4*/
- "pcmpeqw %%mm0,%%mm0\n\t"
- "paddw %%mm0,%%mm0\n\t"
- /*Round the results.*/
- "psubw %%mm0,%%mm1\n\t"
- "psubw %%mm0,%%mm2\n\t"
- "psraw $2,%%mm1\n\t"
- "psubw %%mm0,%%mm3\n\t"
- "movq %%mm1,0x58(%[y])\n\t"
- "psraw $2,%%mm2\n\t"
- "psubw %%mm0,%%mm4\n\t"
- "movq 0x48(%[y]),%%mm1\n\t"
- "psraw $2,%%mm3\n\t"
- "psubw %%mm0,%%mm5\n\t"
- "movq %%mm2,0x68(%[y])\n\t"
- "psraw $2,%%mm4\n\t"
- "psubw %%mm0,%%mm6\n\t"
- "movq %%mm3,0x78(%[y])\n\t"
- "psraw $2,%%mm5\n\t"
- "psubw %%mm0,%%mm7\n\t"
- "movq %%mm4,0x40(%[y])\n\t"
- "psraw $2,%%mm6\n\t"
- "psubw %%mm0,%%mm1\n\t"
- "movq %%mm5,0x50(%[y])\n\t"
- "psraw $2,%%mm7\n\t"
- "movq %%mm6,0x60(%[y])\n\t"
- "psraw $2,%%mm1\n\t"
- "movq %%mm7,0x70(%[y])\n\t"
- "movq %%mm1,0x48(%[y])\n\t"
- :[a]"=&r"(a)
- :[y]"r"(_y),[x]"r"(_x)
- :"memory"
- );
- }
- #endif
|