2012-12-26 53 views
0

如果给出角度,则使用以下代码计算sincos的值。为了尽可能快地计算这些函数,采用了汇编代码实现。使用gcc编译汇编代码时,为什么会出现操作数类型不匹配错误?

#include <stdio.h> 

float sinx(float degree) { 
    float result, two_right_angles = 180.0f ; 
    __asm__ __volatile__ ("fld %1;" 
          "fld %2;" 
          "fldpi;" 
          "fmul;" 
          "fdiv;" 
          "fsin;" 
          "fstp %0;" 
          : "=g" (result) 
          : "g"(two_right_angles), "g" (degree) 
    ) ; 
    return result ; 
} 

float cosx(float degree) { 
    float result, two_right_angles = 180.0f, radians ; 
    __asm__ __volatile__ ("fld %1;" 
          "fld %2;" 
          "fldpi;" 
          "fmul;" 
          "fdiv;" 
          "fstp %0;" 
          : "=g" (radians) 
          : "g"(two_right_angles), "g" (degree) 
    ) ; 
    __asm__ __volatile__ ("fld %1;" 
          "fcos;" 
          "fstp %0;" : "=g" (result) : "g" (radians) 
    ) ; 
    return result ; 
} 

float square_root(float val) { 
    float result ; 
    __asm__ __volatile__ ("fld %1;" 
          "fsqrt;" 
          "fstp %0;" 
          : "=g" (result) 
          : "g" (val) 
    ) ; 
    return result ; 
} 

int main() { 
    float theta ; 
    printf("Enter theta in degrees : ") ; 
    scanf("%f", &theta) ; 

    printf("sinx(%f) = %f\n", theta, sinx(theta)); 
    printf("cosx(%f) = %f\n", theta, cosx(theta)); 
    printf("square_root(%f) = %f\n", theta, square_root(theta)) ; 

    return 0 ; 
} 

上面的代码来自here,我试图用gcc编译上面的代码:

g++ -Wall -fexceptions -g  -c /filename.cpp 

但是,它失败,以下错误消息给出:

Error: operand type mismatch for `fstp'| 
Error: operand type mismatch for `fstp'| 

我想知道为什么编译会失败,以及如何成功编译它们。谢谢!

回答

2

manual说约g约束:Any register, memory or immediate integer operand is allowed, except for registers that are not general registers。编译器可能选择了一个fstp不接受但符合约束条件的寄存器。

顺便说一下,这是非常可怕的内联asm。

另外请注意,只是因为东西在asm中,它不一定会更快。编译器能够优化事情,而且它也做得更好。您可能对-ffast-math交换机感兴趣。从return sin(degree * M_PI/180);编译器产生这一小片的代码:

fldl .LC0 
fmuls 4(%esp) 
fsin 
ret 
+0

我现在替换为“M”“G”,并且它可以编译成功。我会比较这个实现和你建议的方法。谢谢! – feelfree

相关问题