2016-02-29 94 views
0

我有跨平台的音频处理应用程序。它是使用Qt和PortAudio库编写的。我还使用Chaotic-Daw音源处理某些音频处理功能(Vibarto效果和Soft-Knee动态范围压缩)。问题是,我不能口我的应用程序从Windows到Mac OSX,因为我得到的编译器错误的__asm部分(我使用的是Mac OSX的优胜美地和Qt Creator IDE 3.4.1):移植到Mac OS X错误

/Users/admin/My projects/MySound/daw/basics/rosic_NumberManipulations.h:69:
error: expected '(' after 'asm' { ^

这样的线路:

INLINE int floorInt(double x) 
{ 
    const float round_towards_m_i = -0.5f; 
    int i; 

    #ifndef LINUX 
    __asm 
    { // <========= error indicates that row 
     fld x; 
     fadd st, st (0); 
     fadd round_towards_m_i; 
     fistp i; 
     sar i, 1; 
    } 
    #else 
    i = (int) floor(x); 
    #endif 

    return (i); 
} 

我该如何解决这个问题?

回答

1

该代码明显是为Microsoft的Visual C++编译器编写的,因为它是用于inline assembly的语法。它使用英特尔的语法,而且过于简单,这使得它易于编写,但阻碍了它的优化潜力。

Clang和GCC都使用不同的内联汇编格式。特别是,他们使用GNU AT&T syntax。写起来比较复杂,但更富有表现力。编译器错误基本上是Clang告诉你的,“我可以告诉你正在尝试编写内联汇编,但是你已经格式化了所有错误!”

因此,为了编译此代码,您需要将MSVC样式的内联程序集转换为GAS格式的内联程序集。这可能是这样的:

int floorInt(double x) 
{ 
    const float round_towards_m_i = -0.5f; 
    int i; 

    __asm__("fadd %[x], %[x] \n\t" 
      "fadds %[adj]  \n\t" 
      "fistpl %[i]  \n\t" 
      "sarl $1, %[i]" 
      : [i] "=m" (i) // store result in memory (as required by FISTP) 
      : [x] "t" (x), // load input onto top of x87 stack (equivalent to FLD) 
      [adj] "m" (round_towards_m_i) 
      : "st"); 

    return (i); 
} 

但是,由于气体风格的额外表现力,我们就可以将更多的工作,以内置的优化,这可能会产生更加优化的对象代码:

int floorInt(double x) 
{ 
    const float round_towards_m_i = -0.5f; 
    int i; 

    x += x;     // equivalent to the first FADD 
    x += round_towards_m_i; // equivalent to the second FADD 
    __asm__("fistpl %[i]" 
      : [i] "=m" (i) 
      : [x] "t" (x) 
      : "st"); 
    return (i >> 1);   // equivalent to the final SAR 
} 

Live demonstration
(需要注意的是,从技术上讲,这样的最后一行做了签名的右移是实现定义在C和通常是不可取的。但是,如果你使用内联汇编,你已经做出了针对特定平台的决定因此可以依赖于实现特定的行为。在这种情况下,我知道并且很容易证明所有的C编译器都会生成SAR指令来对带符号的整数值进行算术右移。)

这就是说,看起来代码的作者对于内联汇编仅在使用当您编译的平台不是LINUX(大概这是Windows,他们希望您使用的是Microsoft编译器)。所以你可以简单地通过确保在命令行或makefile中定义LINUX来编译代码。

我不知道为什么做出这个决定; Clang和GCC都将生成与MSVC相同的低效代码(假设您针对的是旧一代x86处理器并且无法使用SSE2指令)。这取决于你:代码将以任何方式运行,但是如果不使用内联汇编来强制使用这种巧妙的优化,代码将会变慢。