Как использовать встроенные инструкции по сборке, которые поддерживаются GNU GAS, но являются более новыми, чем последний -марх, который есть в моем GCC? - PullRequest
1 голос

Чтобы проверить работоспособность функции языка ассемблера, я хотел бы использовать ее в программе на Си со встроенной сборкой для замены существующих функций.

Мой ассемблер GNU GAS уже распознает инструкцию с соответствующей -march.

Как заставить GCC генерировать код, который принимает такие встроенные инструкции по сборке, которые еще не могут отправлять и не распознает?

Например, расширения ARM SVE были добавлены более или менее недавнов архитектуру ARM.

Итак, в минимальном бесполезном встроенном примере сборки SVE я пытаюсь:

main.c

int main(void) {
    __asm__ __volatile__ ("ld1d z1.d, p0/z, [x0, x4, lsl 3]");
}

и пытаюсь скомпилировать:

aarch64-linux-gnu-gcc -c -o main.o --save-temps -v main.c

, но сборка завершается неудачно с:

main.s: Assembler messages:
main.s:10: Error: selected processor does not support `ld1d z1.d,p0/z,[x0,x4,lsl 3]'

Подробный вывод содержит:

/usr/lib/gcc-cross/aarch64-linux-gnu/7/../../../../aarch64-linux-gnu/bin/as -v -EL -mabi=lp64 -o main.o main.s

и main.s содержит:

    .arch armv8-a
    .file   "main.c"
    .text
    .align  2
    .global main
    .type   main, %function
main:
#APP
// 2 "main.c" 1
    ld1d z1.d, p0/z, [x0, x4, lsl 3]
// 0 "" 2
#NO_APP
    mov w0, 0
    ret
    .size   main, .-main
    .ident  "GCC: (Ubuntu/Linaro 7.4.0-1ubuntu1~18.04.1) 7.4.0"
    .section    .note.GNU-stack,"",@progbits

Тем не менее, мой ассемблер достаточно новый, чтобы собрать его, так как мне удалось заставить его собираться либо:

  • , заменив .arch armv8-a в сгенерированном файле main.s вручную на .arch armv8-a+sve
  • Removing .arch armv8-a в main.s и добавление -march=all или -march=armv8-a+sve в CLI GAS (TODO .arch all, к сожалению, не существует, интересно, почему?)

Однако, если я попытаюсьчтобы добавить -march=armv8-a+sve или -march=all к CLI GCC, он жалуется соответственно:

cc1: error: invalid feature modifier in ‘-march=armv8-a+sve’
cc1: error: unknown value ‘all’ for -march

Я также пытался добавить -Xassembler -march=all к CLI GCC:

aarch64-linux-gnu-gcc -Xassembler -march=all -c -o main.o --save-temps -v main.c

и эта опция перенаправляется ассемблеру в соответствии с -v, но все равно происходит сбой, потому что .arch armv8-a, который GCC помещает в файл сборки, имеет приоритет.

В отчаянии я наконец попытался изменитьмой пример на C:

int main(void) {
    __asm__ __volatile__ (".arch armv8-a+sve\nld1d z1.d, p0/z, [x0, x4, lsl 3]");
}

и это сработало, но я думаю, что это слишком безумно, чтобы его можно было использовать.Примечательно, что .arch armv8-a+sve остается в силе даже после моего встроенного оператора сборки, и я не знаю, как вернуться к предыдущему GCC .arch.

. Я также искал опции GCC -masm, которыеможет быть полезен как этот , но не может найти ничего интересного.

Протестировано в Ubuntu 18.04, aarch64-linux-gnu-gcc 7.4.0, aarch64-linux-gnu-as 2.30.

...