2016-02-08 5 views
4

Я действительно хочу использовать арифметику с плавающей запятой в модуле ядра Linux, просто для этого. Я не хочу ничего делать, просто используйте триггерные инструкции x87 и/или инструкцию sqrt, а затем присвойте результат переменной. Вот и все. До сих пор я пытался:Несоответствие типа операнда в встроенной сборке x87 в модуле ядра Linux

float sqroot(float arg){ 
    float returnValue; 
    asm(
    "fld %1\n" 
    "fsqrt\n" 
    "fst %0" 
    :"=r"(returnValue) 
    : "r"(arg) 
    ); 
    return returnValue; 
} 

Это с треском проваливается и дает следующее сообщение об ошибке:

Error: operand type mismatch for `fld' 
Error: operand type mismatch for `fst' 

Любые и вся помощь будет оценена.

+0

Whaaaaaat? Это не рекомендательный вопрос, у него просто плохой титул. Голосование для повторного открытия. – immibis

+1

Заголовок был изменен, чтобы более точно соответствовать содержанию вопроса и не представлял собой простую рекомендацию для учебника. –

+0

Согласен. Это законный вопрос. –

ответ

1

Похоже, это работает:

float sqroot(float arg) { 
    float returnValue; 
    asm(
     "fsqrt\n" 
    :"=&t"(returnValue) 
    : "t"(arg) 
    ); 
    return returnValue; 
} 

Реестре ограничения должны указать блок использовать регистры с плавающей точкой.

EDIT: включение точки iwillnotexist-idontexist @ iwillnotexist (повторная загрузка).

Кроме того, если бы это был я, я бы добавил static inline к объявлению и поместил его в файл заголовка. Это позволит компилятору более разумно управлять регистрами и избежать накладных расходов на стеке.

(я тоже был бы соблазну изменить float к double повсюду. В противном случае, вы отбрасывая дополнительную точность, которая используется в реальных операциях с плавающей запятой. Хотя, если вы будете в конечном итоге часто хранения значения, как float, будет дополнительно cvtpd2ps инструкция. Ото, если вы передаете аргументы printf, например, это на самом деле избегаетcvtps2pd.)

+0

Это помечено: 'error: output operand 0 должен использовать '&' constraint'. Вам нужно '= & t'? gcc version 5.3.1 –

+0

Я не вижу этого на моей коробке (версия gcc 4.8.4 (Ubuntu 4.8.4-2ubuntu1 ~ 14.04)). Он даже дает правильные результаты. Однако он также работает с '' & '', поэтому добавим это к моему ответу. –

+0

Я разобрал версию «m» [предложенную Iwillnotexist] и вашим. У вашего больше кода обертки. Я не анализировал, что правильно/некорректно [если либо] –