Преобразуйте этот встроенный ассемблерный код в работу с gcc. - PullRequest
0 голосов
/ 08 декабря 2018

Я пытаюсь преобразовать этот фрагмент кода, чтобы он работал с сборкой AT & T, которую использует g ++:

double sqrt13(double n)
{
__asm{
 fld n
 fsqrt
 }
}

На основе этой ссылки: https://ibiblio.org/gferg/ldp/GCC-Inline-Assembly-HOWTO.html: Я пробовал это:

double raiz (double n)
    __asm__ ( "fld n\n\t"
    "fsqrt\n\t" );

но я продолжаю получать:

/tmp/cc2AQhHj.s|662|Error: junk `n' after expression|

Те же сообщения об ошибках повторяются еще четыре раза в других строках этого файла

Я скачал программу под названием "intel2gas", и онговорит мне, что код должен быть таким:

    __asm__ volatile__ (
    "fld %0\n"
    "fsqrt\n"
    :"=m"(n)
    :
    :"memory", "esi", "edi", "eax", "ebx", "ecx", "edx"
    );

помещая его внутрь функции и пытаясь запустить его, я получаю:

 |39|error: expected ‘(’ before ‘volatile__’|
|42|error: expected ‘)’ before ‘:’ token|
|45|error: ‘volatile__’ was not declared in this scope|

плюс предупреждение | 46 |:нет возвращаемого оператора в функции, возвращающей non-void |

Итак, есть предложения?

1 Ответ

0 голосов
/ 08 декабря 2018

intel2gas, очевидно, не реализует поддержку MSVC для того, чтобы оставить возвращаемое значение в EAX (или ST0) в asm, а затем опустить конец функции, не являющейся void.MSVC воспринимает это как фактическое возвращаемое значение даже при включении функции, содержащей блок __asm.В встроенном ассемблере GNU C значения регистров являются выходными, только если вы используете ограничения вывода или чтения / записи.

Вот почему вы получаете warning: no return statement in function returning non-void и неработающий код.

Как указывает @MichaelPetchВы должны запросить у компилятора уже введенный номер плавающего указателя в стеке регистров FP x87, используя ограничение t (вершина стека x87).

double raiz (double n) {
    __asm__ ("fsqrt"
       : "+t"(n)          // read-write operand: top of x87 stack
    );
     return n;
}

asm volatile не требуется:В блоке asm нет побочных эффектов, которые нужно запускать, даже если вывод не используется, а вывод является чистой функцией ввода.(Если вы не изменяете режим округления x87 или точность).

Можно позволить компилятору оптимизировать его или CSE между несколькими запусками.

Как отдельная функцияэто компилируется ( на Godbolt ) в

# gcc8.2 -O3 -ffast-math -m32   uses x87 by default, not SSE2
_Z4raizd:
    fld     QWORD PTR [esp+4]
   # start of inline asm
    fsqrt
   # end of inline asm.
    ret
...