2010-02-03 6 views
4

Я хотел бы ввести код сборки в кодовую базу c99. Я хочу использовать инструкцию UMULL из CPU ARM, чтобы умножить 2 uint32_t и сразу получить результат в uint64_t.Как я могу получить инструкцию ARM MULL для вывода своего вывода в uint64_t в gcc?

Теперь uint64_t нуждается в 2 регистрах, так как я могу указать выходные данные и ограничения блока asm?

ответ

2

Хороший вопрос!

Следующий код выводит то, что вы хотите с помощью GCC -O или выше, не прибегая к ассемблеру:

 
uint32_t a, b; 
uint64_t c; 
... 
c = (uint64_t)a * (uint64_t)b; 
или если вы чувствуете, что вы должны использовать машинно-зависимый ассемблер, вы можете пойти:
 
uint32_t a, b; 
uint64_t c;

asm ("umull %Q0, %R0, %1, %2" : "=r"(c) : "r"(a), "r"(b));

c «s зарегистрировать имя является первым пары регистров, а% Q и% R выбирают нижний и верхний 32-разрядные регистры пары. См. Пример gcc/config/arm/arm.md -> umulsidi3.

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

+0

Спасибо за ответ! На самом деле версия C делает то, что я хочу, очень круто. И большое спасибо за синтаксис% Q и% R, вот что я искал в начале. – user265429

1

Инструкция umull дает результаты в двух 32-битных регистрах. Я предлагаю явно перекомпоновки 64-битное значение с чем-то вроде этого:

/* assuming the 64-bit result was stored in "hi" (upper 
    half) and "lo" (lower half) */ 
uint64_t v = ((uint64_t)hi << 32) | (uint64_t)lo; 

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