Ранние клоберы и именованные регистры - PullRequest
2 голосов
/ 19 марта 2020

Я пытаюсь понять использование "ранних выходов", но наткнулся на отрывок, который смущает меня. Рассмотрим следующую функцию умножения по модулю:

static inline uint64_t mulmod64(uint64_t a, uint64_t b, uint64_t n)
{
    uint64_t d;
    uint64_t unused;
    asm ("mulq %3\n\t"
         "divq %4"
         :"=a"(unused), "=&d"(d)
         :"a"(a), "rm"(b), "rm"(n)
         :"cc");
    return d;
}

Почему RDX имеет флаг раннего клоббера (&)? Это потому что mulq неявно изменено RDX? Будет ли пример работать без флага? (Я пытался, и, похоже, так и есть. Но будет ли это правильно?) С другой стороны, разве недостаточно, чтобы функция выводила RDX, чтобы сообщить, что компилятор RDX был изменен?

Кроме того, почему существует эта unused переменная? Я предполагаю, что это означает, что RAX был изменен, правильно? Могу ли я удалить это? (Я попытался, и это, кажется, работает.) Я ожидал, что правильный способ пометить измененный RAX - это включить "rax" в "clobbers" вместе с "cc". Но это не работает.

1 Ответ

1 голос
/ 20 марта 2020

Хотя это и не отвечает на вопрос - я думаю, что комментарии затронуты - я бы упростил это, позволив компилятору выбирать регистры по сравнению с памятью и позволяя ему планировать mulq и divq по мере необходимости .. Проблема в том, что div имеет ограничения регистра:

static inline uint64_t mulmod64(uint64_t a, uint64_t b, uint64_t n)
{
    uint64_t ret, q, rh, rl;

    __asm__ ("mulq %3" : "=a,a" (rl), "=d,d" (rh)
             : "%0,0" (a), "r,m" (b) : "cc");

    /* assert(rh < n), otherwise `div` raises a 'divide error' - the quotient is
     * too large to store in in `%rax`. */

    /* the "%0,0" notation implies that `(a)` and `(b)` are commutative.
     * the "cc" clobber is implicit in gcc / clang asm (and, I expect, Intel icc)
     * for the x86-64 asm statements. */

    __asm__ ("divq %4" : "=a,a" (q), "=d,d" (ret)
             : "0,0" (rl), "1,1" (rh), "r,m" (n), "cc");

    return ret;
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...