⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mmx_gcc.cpp

📁 Audacity是一款用於錄音和編輯聲音的、免費的開放源碼軟體。它可以執行於Mac OS X、Microsoft Windows、GNU/Linux和其它作業系統
💻 CPP
📖 第 1 页 / 共 2 页
字号:
        // multiply-add mm0*mm6 and mm1*mm7, store results into mm0 and mm1        // divide mm0 and mm1 by 512 (=right-shift by overlapDividerBits)        // pack the result into mm0 and store into [edx]        //        // Load [eax+8] into mm2 and mm3        // Load [ebx+8] into mm4        // unpack words of mm2, mm3 and mm4 into mm2 and mm3        // multiply-add mm2*mm6 and mm3*mm7, store results into mm2 and mm3        // divide mm2 and mm3 by 512 (=right-shift by overlapDividerBits)        // pack the result into mm2 and store into [edx+8]            "movq        (%%eax), %%mm0\n\t"             // mm0 = m1l m1r m0l m0r        "add         $16, %%edx\n\t"        "movq        (%%ebx), %%mm3\n\t"             // mm3 = i1l i1r i0l i0r        "movq        %%mm0, %%mm1\n\t"               // mm1 = m1l m1r m0l m0r        "movq        8(%%eax), %%mm2\n\t"            // mm2 = m3l m3r m2l m2r        "punpcklwd   %%mm3, %%mm0\n\t"               // mm0 = i0l m0l i0r m0r        "movq        8(%%ebx), %%mm4\n\t"            // mm4 = i3l i3r i2l i2r        "punpckhwd   %%mm3, %%mm1\n\t"               // mm1 = i1l m1l i1r m1r        "movq        %%mm2, %%mm3\n\t"               // mm3 = m3l m3r m2l m2r        "punpcklwd   %%mm4, %%mm2\n\t"               // mm2 = i2l m2l i2r m2r        "pmaddwd     %%mm6, %%mm0\n\t"               // mm0 = i0l*m63+m0l*m62 i0r*m61+m0r*m60        "punpckhwd   %%mm4, %%mm3\n\t"               // mm3 = i3l m3l i3r m3r        "movd        %%esi, %%mm4\n\t"               // mm4 = overlapDividerBits        "pmaddwd     %%mm7, %%mm1\n\t"               // mm1 = i1l*m73+m1l*m72 i1r*m71+m1r*m70        "paddw       %%mm5, %%mm6\n\t"        "paddw       %%mm5, %%mm7\n\t"        "psrad       %%mm4, %%mm0\n\t"               // mmo >>= overlapDividerBits        "pmaddwd     %%mm6, %%mm2\n\t"               // mm2 = i2l*m63+m2l*m62 i2r*m61+m2r*m60        "psrad       %%mm4, %%mm1\n\t"               // mm1 >>= overlapDividerBits        "pmaddwd     %%mm7, %%mm3\n\t"               // mm3 = i3l*m73+m3l*m72 i3r*m71+m3r*m70        "psrad       %%mm4, %%mm2\n\t"               // mm2 >>= overlapDividerBits        "packssdw    %%mm1, %%mm0\n\t"               // mm0 = mm1h mm1l mm0h mm0l        "psrad       %%mm4, %%mm3\n\t"               // mm3 >>= overlapDividerBits        "add         $16, %%eax\n\t"        "paddw       %%mm5, %%mm6\n\t"        "packssdw    %%mm3, %%mm2\n\t"               // mm2 = mm2h mm2l mm3h mm3l        "paddw       %%mm5, %%mm7\n\t"        "movq        %%mm0, -16(%%edx)\n\t"        "add         $16, %%ebx\n\t"        "movq        %%mm2, -8(%%edx)\n\t"        "dec         %%ecx\n\t"        "jnz         2b\n\t"        "emms\n\t"        "movl        %0, %%esi\n\t"      : "+rim" (shadow_esi)/* output */      : "rim" (local_overlapLength),        "rim" (local_overlapDividerBits),        "rim" (output),        "rim" (input),        "rim" (local_midBuffer)      /* input */      : "%edi", "%ecx", "%edx", "%eax", "%ebx" /* regs */    );#else    throw runtime_error("MMX not supported");#endif}////////////////////////////////////////////////////////////////////////////////// implementation of MMX optimized functions of class 'FIRFilter'////////////////////////////////////////////////////////////////////////////////#include "FIRFilter.h"FIRFilterMMX::FIRFilterMMX() : FIRFilter(){    filterCoeffsUnalign = NULL;}FIRFilterMMX::~FIRFilterMMX(){    delete[] filterCoeffsUnalign;}// (overloaded) Calculates filter coefficients for MMX routinevoid FIRFilterMMX::setCoefficients(const short *coeffs, uint newLength, uint uResultDivFactor){#ifdef __i386__    uint i;    FIRFilter::setCoefficients(coeffs, newLength, uResultDivFactor);    // Ensure that filter coeffs array is aligned to 16-byte boundary    delete[] filterCoeffsUnalign;    filterCoeffsUnalign = new short[2 * newLength + 8];    filterCoeffsAlign = (short *)(((uint)filterCoeffsUnalign + 15) & -16);    // rearrange the filter coefficients for mmx routines     for (i = 0;i < length; i += 4)     {        filterCoeffsAlign[2 * i + 0] = coeffs[i + 0];        filterCoeffsAlign[2 * i + 1] = coeffs[i + 2];        filterCoeffsAlign[2 * i + 2] = coeffs[i + 0];        filterCoeffsAlign[2 * i + 3] = coeffs[i + 2];        filterCoeffsAlign[2 * i + 4] = coeffs[i + 1];        filterCoeffsAlign[2 * i + 5] = coeffs[i + 3];        filterCoeffsAlign[2 * i + 6] = coeffs[i + 1];        filterCoeffsAlign[2 * i + 7] = coeffs[i + 3];    }#else    throw runtime_error("MMX not supported");#endif}// mmx-optimized version of the filter routine for stereo sounduint FIRFilterMMX::evaluateFilterStereo(short *dest, const short *src, const uint numSamples) const{#ifdef __i386__    // Create stack copies of the needed member variables for asm routines :    uint local_length = length;    uint local_lengthDiv8 = lengthDiv8;    uint local_resultDivider = resultDivFactor;    short *local_filterCoeffs = (short*)filterCoeffsAlign;    short *local_src = (short *)src;    asm volatile(        "\n\t"        // Load (num_samples-aa_filter_length)/2 to edi as a i        // Load a pointer to samples to esi        // Load a pointer to destination to edx        "movl        %0, %%edi\n\t"        "subl        %2, %%edi\n\t"        "movl        %3, %%edx\n\t"        "sar         $1, %%edi\n"        // Load filter length/8 to ecx        // Load pointer to samples from esi to ebx        // Load counter from edi to ecx        // Load [ebx] to mm3        // Load pointer to filter coefficients to eax        "3:\n\t"        "movl        %1, %%ebx\n\t"        "pxor        %%mm0, %%mm0\n\t"        "movl        %4, %%ecx\n\t"        "pxor        %%mm7, %%mm7\n\t"        "movq        (%%ebx), %%mm1\n\t"            // mm1 = l1 r1 l0 r0        "movl        %5, %%eax\n"        "4:\n\t"        "movq        8(%%ebx), %%mm2\n\t"           // mm2 = l3 r3 l2 r2        "movq        %%mm1, %%mm4\n\t"              // mm4 = l1 r1 l0 r0        "movq        16(%%ebx), %%mm3\n\t"          // mm3 = l5 r5 l4 r4        "punpckhwd   %%mm2, %%mm1\n\t"              // mm1 = l3 l1 r3 r1        "movq        %%mm2, %%mm6\n\t"              // mm6 = l3 r3 l2 r2        "punpcklwd   %%mm2, %%mm4\n\t"              // mm4 = l2 l0 r2 r0        "movq        (%%eax), %%mm2\n\t"            // mm2 = f2 f0 f2 f0        "movq        %%mm1, %%mm5\n\t"              // mm5 = l3 l1 r3 r1        "punpcklwd   %%mm3, %%mm6\n\t"              // mm6 = l4 l2 r4 r2        "pmaddwd     %%mm2, %%mm4\n\t"              // mm4 = l2*f2+l0*f0 r2*f2+r0*f0        "pmaddwd     %%mm2, %%mm5\n\t"              // mm5 = l3*f2+l1*f0 r3*f2+l1*f0        "movq        8(%%eax), %%mm2\n\t"           // mm2 = f3 f1 f3 f1        "paddd       %%mm4, %%mm0\n\t"              // mm0 += s02*f02        "movq        %%mm3, %%mm4\n\t"              // mm4 = l1 r1 l0 r0        "pmaddwd     %%mm2, %%mm1\n\t"              // mm1 = l3*f3+l1*f1 r3*f3+l1*f1        "paddd       %%mm5, %%mm7\n\t"              // mm7 += s13*f02        "pmaddwd     %%mm2, %%mm6\n\t"              // mm6 = l4*f3+l2*f1 r4*f3+f4*f1        "movq        24(%%ebx), %%mm2\n\t"          // mm2 = l3 r3 l2 r2        "paddd       %%mm1, %%mm0\n\t"              // mm0 += s31*f31        "movq        32(%%ebx), %%mm1\n\t"          // mm1 = l5 r5 l4 r4        "paddd       %%mm6, %%mm7\n\t"              // mm7 += s42*f31        "punpckhwd   %%mm2, %%mm3\n\t"              // mm3 = l3 l1 r3 r1        "movq        %%mm2, %%mm6\n\t"              // mm6 = l3 r3 l2 r2        "punpcklwd   %%mm2, %%mm4\n\t"              // mm4 = l2 l0 r2 r0        "movq        16(%%eax), %%mm2\n\t"          // mm2 = f2 f0 f2 f0        "movq        %%mm3, %%mm5\n\t"              // mm5 = l3 l1 r3 r1        "punpcklwd   %%mm1, %%mm6\n\t"              // mm6 = l4 l2 r4 r2        "add         $32, %%eax\n\t"        "pmaddwd     %%mm2, %%mm4\n\t"              // mm4 = l2*f2+l0*f0 r2*f2+r0*f0        "add         $32, %%ebx\n\t"        "pmaddwd     %%mm2, %%mm5\n\t"              // mm5 = l3*f2+l1*f0 r3*f2+l1*f0        "movq        -8(%%eax), %%mm2\n\t"          // mm2 = f3 f1 f3 f1        "paddd       %%mm4, %%mm0\n\t"              // mm0 += s02*f02        "pmaddwd     %%mm2, %%mm3\n\t"              // mm3 = l3*f3+l1*f1 r3*f3+l1*f1        "paddd       %%mm5, %%mm7\n\t"              // mm7 += s13*f02        "pmaddwd     %%mm2, %%mm6\n\t"              // mm6 = l4*f3+l2*f1 r4*f3+f4*f1        "paddd       %%mm3, %%mm0\n\t"              // mm0 += s31*f31        "paddd       %%mm6, %%mm7\n\t"              // mm7 += s42*f31        "dec         %%ecx\n\t"        "jnz         4b\n\t"        // Divide mm0 and mm7 by 8192 (= right-shift by 13),        // pack and store to [edx]        "movd        %6, %%mm4\n\t"        "psrad       %%mm4, %%mm0\n\t"              // divide the result        "add         $8, %%edx\n\t"        "psrad       %%mm4, %%mm7\n\t"              // divide the result        "add         $8, %1\n\t"        "packssdw    %%mm7, %%mm0\n\t"        "movq        %%mm0, -8(%%edx)\n\t"        "dec         %%edi\n\t"        "jnz         3b\n\t"        "emms\n\t"      : /* output */      : "rim" (numSamples),        "rim" (local_src),        "rim" (local_length),        "rim" (dest),        "rim" (local_lengthDiv8),        "rim" (local_filterCoeffs),        "rim" (local_resultDivider) /* input */      : "%eax", "%ebx", "%ecx", "%edx", "%edi"/*, "%esi"*/ /* regs */    );    return (numSamples & 0xfffffffe) - local_length;#else    throw runtime_error("MMX not supported");    return 0;#endif}#endif // ALLOW_MMX

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -