2012-12-26 90 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

相關問題