Чтобы проверить работоспособность функции языка ассемблера, я хотел бы использовать ее в программе на Си со встроенной сборкой для замены существующих функций.
Мой ассемблер 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.