Встроенная ошибка макроса asm - PullRequest
2 голосов
/ 26 августа 2011

Я пытаюсь использовать следующий макрос:

#define M_MA(out, L_v, var1, var2)({ \
    asm volatile(  \
    "movswl %2, %%edi\n\t" \
    "movswl %3, %%ebx\n\t" \
    "imull %%edi, %%ebx\n\t" \
    "sall $1,%%ebx\n\t" \
    "cmpl %4,%%ebx\n\t" \
    "cmove %5,%%ebx\n\t" \
    "addl %1, %%ebx\n\t" \
    "jno out%=\n\t" \
    "cmovg %5, %%ebx\n\t" \
    "cmovl %4, %%ebx\n\t" \
    "out%=: nop\n\t" \
    "movl %%ebx, %0\n\t" : "=r"(out) : "r"(L_v), "m"(var1), "m"(var2), "r"(-2147483648), "r"(+2147483647) : "%ebx","%edi");  })

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

error: ‘asm’ operand has impossible constraints

var1 и var2 - 16-битные слова. out и L_v являются 32-битными словами.

После некоторого чтения я думаю, что проблема в том, что компилятору нужно больше регистров, чем доступно, но я не уверен в этом.Если это проблема, я понятия не имею, как использовать меньше регистров, чем сейчас, или как исправить ошибку.

Я использую gcc поверх Linux на 32-битной платформе.

Любой может уточнитьчто-то об этом?

С уважением

1 Ответ

3 голосов
/ 26 августа 2011

«Я понятия не имею, как использовать меньше регистров, чем сейчас» - как насчет использования немедленных вместо регистров для двух констант maxint / minint? (Ах, cmov не требует немедленных действий. Но вы можете сохранить константы в %edi для себя, вместо того, чтобы компилятор заранее устанавливал их в другом регистре).

Кроме того, почему вы хотите построить все в %ebx, а затем скопировать его в другой регистр в самом конце? Ни одна из операций не является такой, для которой %ebx имеет особое значение, поэтому простая замена %%ebx на %0 во всем и объявление ее "&=r" вместо "=r" будет либо победой, либо, по крайней мере, не проигрышем.

...