1

次のコードは、角度が指定されている場合の値sinを計算するために使用されます。cosこれらの関数をできるだけ速く計算するために、アセンブリ コードの実装が採用されています。

#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'|

コンパイルが失敗する理由と、それらを正常にコンパイルする方法を知りたいと思っていました。ありがとう!

4

1 に答える 1

2

マニュアルには、g制約について次のように書かれていますAny register, memory or immediate integer operand is allowed, except for registers that are not general registersfstpコンパイラーは、受け入れないが制約に適合するレジスターを選択した可能性があります。

ところで、これは非常に恐ろしいインライン asm です。

また、何かがasmにあるからといって、必ずしも高速になるとは限りません。コンパイラは物事を最適化する能力があり、より良い仕事もします。-ffast-mathスイッチに興味があるかもしれません。コンパイラからreturn sin(degree * M_PI / 180);、次の小さなコードが生成されます。

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