невозможное ограничение в asm - неопределенное сообщение GCC - PullRequest
0 голосов
/ 20 декабря 2011

Я изучаю расширенные параметры asm GCC

asm goto (
    "clc\n"
    "lo:\t"
    "lods\t%[ax]\n\t"
    "lea\t%[wc](%[base], %[off], %[k]), %[la]"
    "adc\t%[ax], (%[la])\n\t"
    "inc\t%[off]\n\t"
    "jnz\tlo\n\t"
    "jnc\t%l[nocarry]\n"
    : 
    : [base] "d" (th), [oz] "S" (oz), [wc] "I" (wc*sizeof(uInt)),
      [k] "N" (sizeof(uInt)), [la] "b" (0), [ax] "a" (0), [off] "c" (-wc)
    : 
    : nocarry
);

И в процессе компиляции:

>  impossible constraint in 'asm'

Попытка прокомментировать все ограничения по одному, один и тот же результат.Пожалуйста, помогите!

gcc версии 4.6.1 (Ubuntu / Linaro 4.6.1-9ubuntu3), i686-linux-gnu (32 бита), ядро ​​3.0.0-14-generic

Ответы [ 2 ]

3 голосов
/ 20 декабря 2011

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

Наиболее вероятным кандидатом является выражение [wc] "I" (wc * sizeof(uInt)), если wc - это что-то еще, кромеконстанта времени компиляции - "I" ограничения должны быть оценены немедленно.Также может быть [k] "N" (sizeof(uInt)), потому что это не соответствует lea.

. Я бы предложил изменить выражение на:

asm (
    "lea    (%[base], %[off], %[k]), %[base]\n\t"
    "neg    %[off]\n\t"
    "clc\n\t"
    "lo:    "
    "lods   %[ax]\n\t"
    "lea    (%[base], %[off], %[k]), %[la]\n\t"
    "adc    %[ax], (%[la])\n\t"
    "inc    %[off]\n\t"
    "jnz    lo\n\t"
    "jnc    %l[nocarry]\n"
: 
: [k] "I"(sizeof(uInt)), [base] "d" (th), [oz] "S" (oz),
  [la] "b" (0), [ax] "a" (0), [off] "c" (wc)
: 
: nocarry
);

, но вы можете захотеть оценить возможность компиляциибольше свободы выбора (как, скажем, [base] "r" (th + wc) при условии th - uInt*).Точно так же, с вашими инструкциями по сборке, нет явной необходимости использовать "a", "b", "c" или "d", так что вы искусственно ограничиваете, какой компилятор может выбрать.Если это то, что вам нужно, возможно, лучше написать / написать функцию полностью в ассемблере, чем пытаться принудительно заставить компилятор.

0 голосов
/ 20 декабря 2011
BigInt & BigInt::operator+=(const BigInt &rhs)
{
    this->grow(rhs.wc);
    uInt *th = (uInt*)words, *oz = (uInt*)rhs.words;
    asm goto (
        "clc\n"
        "l1:\t"
        "mov\t(%[oz]), %[ax]\n\t"
        "adc\t%[ax], (%[th])\n\t"
        "lahf\n\t"
        "add\t%[ws], %[th]\n\t"
        "add\t%[ws], %[oz]\n\t"
        "sahf\n\t"
        "loop\tl1\n\t"
        "jnc\t%l[nocarry]\n"
        : 
        : [th] "r" (th), [oz] "r" (oz),
          [ws] "I" (sizeof(uInt)), [ax] "a" ((uInt)0), "c" (wc)
        : 
        : nocarry
    );
...