1

如果给定角度,以下代码用于计算sincos值。为了尽可能快地计算这些函数,采用了汇编代码实现。

#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 ;
}

上面的代码来自这里,我正在尝试用 gcc 编译上面的代码:

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

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

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

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

4

1 回答 1

2

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

顺便说一句,这是相当可怕的内联汇编。

另请注意,仅仅因为某些东西在 asm 中,它不一定会更快。编译器非常有能力优化事物,它也做得更好。您可能对-ffast-math开关感兴趣。从return sin(degree * M_PI / 180);编译器生成这段代码:

fldl    .LC0
fmuls   4(%esp)
fsin
ret
于 2012-12-26T15:22:10.333 回答