2016-10-28 2 views
3
int main(){ 
__asm volatile 
{ 
    // load data 
    vld1.16 {q0, q1}, [r0]! 

...ARMCC жалуется, что `q0` не определена компиляцией неоновых сборок

используя команду

armcc --cpu=Cortex-A9 -O2 -Otime --vectorize --remarks -g --md --depend_format=unix_escaped --no_depend_system_headers -c -o test.o test.c 

Это ошибка показывает, что

"test.c", line 7: Error: #20: identifier "q0" is undefined 
     vld1.16 {q0, q1}, [r0]! 
      ^
"test.c", line 8: Error: #20: identifier "q2" is undefined 
      vld1.16 {q2, q3}, [r0]! 
       ^

Я не пропустить какие-либо флаги в команде armcc?

версия armcc является

Product: ARM Compiler 5.05 
Component: ARM Compiler 5.05 (build 41) 
Tool: armcc [4d0eb9] 
For support see http://www.arm.com/support/ 
Software supplied by: ARM Limited 
+0

Просто FYI, внутренне присущие ручной векторизации, как правило, лучший выбор, чем inline asm, поскольку в наши дни компиляторы отлично справляются с ними. (По крайней мере, gcc и clang, не знаю о armcc.) См. Https://gcc.gnu.org/wiki/DontUseInlineAsm по причинам, в том числе, что это может фактически привести к более медленному коду, предотвращая распространение компилятора константами или другие оптимизации. –

ответ

3

Хотя я не использую ARMCC, я не верю, что ваш компилятор поддерживает ассемблерные для NEON.

https://static.docs.arm.com/dui0472/k/DUI0472K_armcc_user_guide.pdf

Посмотрите на раздел 7.3, в котором говорится:

7.3 Ограничения на инлайн поддержку ассемблера в компиляторе

встроенный ассемблер в компилятор не поддерживает ряд инструкция. В частности, встроенный ассемблер не поддерживает:

• Язык аксессуаров Thumb в процессорах без технологии Thumb-2. • Инструкции VFP, добавленные в VFPv3 или выше. • NEON инструкции. • Инструкция ARMv6 SETEND и некоторые расширения системы . • Инструкции ARMv5 BX, BLX и BXJ.

Причина, по которой, вероятно, почти работает, заключается в том, что vld является частью поддерживаемого VFPv2, и только до тех пор, пока он не попадет в «q», что он запутался.

Если вы использовали варианты gcc/clang, то да, я бы предложил вам неявно скомпилировать таргетинг NEON с -march=armv7-a -mfpu=neon, указав как базовые ISA, так и расширения модулей с плавающей запятой, но только для использования встроенных функций компилятора, не встроенная сборка. (Как упоминалось в комментарии).

+1

С помощью gcc inline-asm передается из компилятора в ассемблер без изменений (только с '% [name]' операнды заменены и так далее), поэтому опции '-march' влияют только на inline asm, если они приводят к некоторому директивой выхода asm компилятора. IDK о ARM, но для x86, '-msse4' или всего, что просто сообщает компилятору, он может использовать эти инструкции сам, и вам не требуется использовать их из inline asm. (Требуется для использования соответствующих встроенных функций) –

+0

Спасибо, да, я постоянно удивляюсь тому, насколько простой и глупый ассемблер gcc. Инструменты IIR, ARM были намного лучше и, вероятно, передавали архитектурные флаги ассемблеру, чтобы помочь проверить совместимость с ISA (хотя прошло уже 8 лет с тех пор, как я сам их использовал). –

+0

Если вы используете asm для ручной записи, вы можете использовать макросы NASM или YASM для проверки совместимости с ISA, как это делает проект x264. Я не изучал, как они это делают (будь то макросы или нужна поддержка ассемблера), или если он может быть адаптирован к газу.В любом случае, цель '-march' заключается в том, чтобы сообщить компилятору, что он * это может испустить, а не ограничивать то, что вы можете сделать с встроенным asm. Если вы избегаете '-march =' или '-msse4', вы можете вручную проверить CPUID перед использованием инструкций SSE4. (Конечно, лучший способ сделать это - отдельные единицы компиляции, но дизайн gcc/gas имеет смысл таким образом.) –

Смежные вопросы