移植到 Mac OS X 错误
Porting to Mac OS X error
我有跨平台音频处理应用程序。它是使用 Qt 和 PortAudio libraries. I also use Chaotic-Daw 源代码编写的,用于某些音频处理功能(Vibarto 效果和 Soft-Knee 动态范围压缩)。问题是我无法将我的应用程序从 Windows 移植到 Mac OSX 因为我得到 __asm
部分的编译器错误(我使用 Mac OSX Yosemite 和 Qt Creator 3.4.1 IDE):
/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);
}
我该如何解决这个问题?
代码显然是为 Microsoft 的 Visual C++ 编译器编写的,因为这是它用于 inline assembly 的语法。它使用Intel语法并且相当简单,这使得它易于编写但阻碍了它的优化潜力。
Clang 和 GCC 都使用不同的内联汇编格式。特别是,他们使用 GNU AT&T syntax。写起来更复杂,但表现力更强。编译器错误基本上是 Clang 告诉你的方式,"I can tell you're trying to write inline assembly, but you've formatted it all wrong!"
因此,要使这段代码通过编译,您需要将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 , %[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);
}
但是,由于 GAS 样式的额外表现力,我们可以将更多工作卸载到内置优化器,这可能会产生更优化的目标代码:
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 指令)。这取决于您:代码会 运行 两种方式,但如果不使用内联汇编来强制使用这种巧妙的优化,它会变慢。
我有跨平台音频处理应用程序。它是使用 Qt 和 PortAudio libraries. I also use Chaotic-Daw 源代码编写的,用于某些音频处理功能(Vibarto 效果和 Soft-Knee 动态范围压缩)。问题是我无法将我的应用程序从 Windows 移植到 Mac OSX 因为我得到 __asm
部分的编译器错误(我使用 Mac OSX Yosemite 和 Qt Creator 3.4.1 IDE):
/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);
}
我该如何解决这个问题?
代码显然是为 Microsoft 的 Visual C++ 编译器编写的,因为这是它用于 inline assembly 的语法。它使用Intel语法并且相当简单,这使得它易于编写但阻碍了它的优化潜力。
Clang 和 GCC 都使用不同的内联汇编格式。特别是,他们使用 GNU AT&T syntax。写起来更复杂,但表现力更强。编译器错误基本上是 Clang 告诉你的方式,"I can tell you're trying to write inline assembly, but you've formatted it all wrong!"
因此,要使这段代码通过编译,您需要将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 , %[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);
}
但是,由于 GAS 样式的额外表现力,我们可以将更多工作卸载到内置优化器,这可能会产生更优化的目标代码:
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 指令)。这取决于您:代码会 运行 两种方式,但如果不使用内联汇编来强制使用这种巧妙的优化,它会变慢。