Автоматический пример с утверждением
Ниже я описал, как этот пример был достигнут.
Сборка
aarch64-linux-gnu-as
2.30 в Ubuntu 18.04 уже достаточно нов для SVE, как видно из: https://sourceware.org/binutils/docs-2.30/as/AArch64-Extensions.html#AArch64-Extensions
В противном случае скомпилировать Binutils из исходного кода в Ubuntu 16.04 несложно, просто выполните:
git clone git://sourceware.org/git/binutils-gdb.git
cd binutils-gdb
# master that I tested with.
git checkout 4de5434b694fc260d02610e8e7fec21b2923600a
./configure --target aarch64-elf --prefix "$(pwd)/ble"
make -j `nproc`
make install
Я не проверил тег, потому что последнему тегу несколько месяцев, и мне не хочется искать сообщения журнала, когда был введен SVE ;-)
Затем используйте скомпилированный as
и свяжите его с упакованным GCC в Ubuntu 16.04:
./binutils-gdb/ble/bin/aarch64-elf-as -c -march=armv8.5-a+sve \
-o example1.o example1.S
aarch64-linux-gnu-gcc -march=armv8.5-a -nostdlib -o example1 example1.o
В Ubuntu 16.04 aarch64-linux-gnu-gcc
5.4 не имеет -march=armv8.5-a
, поэтому просто используйте -march=armv8-a
, и все будет в порядке. В любом случае, ни в Ubuntu 16.04, ни в 18.04 нет -march=armv8-a+sve
, что будет лучшим вариантом, когда он появится.
Кроме того, вместо передачи -march=armv8.5-a+sve
вы также можете добавить следующее в начало исходного кода .S
:
.arch armv8.5-a+sve
В Ubuntu 19.04 Binutils 2.32 я также узнал и протестировал:
aarch64-linux-gnu-as -march=all
который также работает для SVE, я думаю, что буду использовать его больше в будущем, так как кажется, что он просто включает все функции за один раз, а не только SVE!
Моделирование QEMU
Процедура пошаговой отладки в QEMU объясняется по адресу: Как выполнить пошаговую сборку ARM в GDB на QEMU?
Сначала я превратил пример в минимальный автономный исполняемый файл Linux:
.data
x: .double 1.5, 2.5, 3.5, 4.5
y: .double 5.0, 6.0, 7.0, 8.0
y_expect: .double 8.0, 11.0, 14.0, 17.0
a: .double 2.0
n: .word 4
.text
.global _start
_start:
ldr x0, =x
ldr x1, =y
ldr x2, =a
ldr x3, =n
bl daxpy
/* exit */
mov x0, #0
mov x8, #93
svc #0
/* Multiply by a scalar and add.
*
* Operation:
*
* Y += a * X
*
* C signature:
*
* void daxpy(double *x, double *y, double *a, int *n)
*
* The name "daxpy" comes from LAPACK:
* http://www.netlib.org/lapack/explore-html/de/da4/group__double__blas__level1_ga8f99d6a644d3396aa32db472e0cfc91c.html
*
* Adapted from: https://alastairreid.github.io/papers/sve-ieee-micro-2017.pdf
*/
daxpy:
ldrsw x3, [x3]
mov x4, #0
whilelt p0.d, x4, x3
ld1rd z0.d, p0/z, [x2]
.loop:
ld1d z1.d, p0/z, [x0, x4, lsl #3]
ld1d z2.d, p0/z, [x1, x4, lsl #3]
fmla z2.d, p0/m, z1.d, z0.d
st1d z2.d, p0, [x1, x4, lsl #3]
incd x4
whilelt p0.d, x4, x3
b.first .loop
ret
Вы можете запустить его с помощью:
qemu-aarch64 -L /usr/aarch64-linux-gnu -E LD_BIND_NOW=1 ./example1
тогда он выходит красиво.
Затем мы можем выполнить пошаговую отладку, чтобы подтвердить, что сумма действительно была получена:
qemu-aarch64 -g 1234 -L /usr/aarch64-linux-gnu -E LD_BIND_NOW=1 ./example1
а также:
./binutils-gdb/ble/bin/aarch64-elf-gdb -ex 'file example1' \
-ex 'target remote localhost:1234' -ex 'set sysroot /usr/aarch64-linux-gnu'
Теперь подойдите сразу после bl daxpy
и запустите:
>>> p (double[4])y_expect
$1 = {[0] = 8, [1] = 11, [2] = 14, [3] = 17}
>>> p (double[4])y
$2 = {[0] = 8, [1] = 11, [2] = 14, [3] = 17}
что подтверждает, что сумма действительно была сделана так, как ожидалось.
Наблюдение за регистрами SVE кажется нереализованным, поскольку я ничего не могу найти в разделе: https://github.com/qemu/qemu/tree/v3.0.0/gdb-xml, но не должно быть слишком сложно реализовать копирование других регистров FP? Вопрос задан по адресу: http://lists.nongnu.org/archive/html/qemu-discuss/2018-10/msg00020.html
В настоящее время вы уже можете частично и косвенно наблюдать за этим, выполнив:
i r d0 d1 d2
потому что первая запись регистра SVE zX
используется совместно с более старыми регистрами vX
FP, но мы вообще не видим p
.
person
Ciro Santilli
schedule
19.10.2018