首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何用GAS或LLVM组装ARM SVE指令,并在QEMU上运行?

如何用GAS或LLVM组装ARM SVE指令,并在QEMU上运行?
EN

Stack Overflow用户
提问于 2018-10-19 08:51:27
回答 1查看 1.1K关注 0票数 1

我想使用开源工具来使用新的ARM SVE指令

首先,我想汇编一下下面的最小示例:https://developer.arm.com/docs/dui0965/latest/getting-started-with-the-sve-compiler/assembling-sve-code

代码语言:javascript
复制
// example1.s
    .global main
main:
    mov     x0, 0x90000000
    mov     x8, xzr
    ptrue   p0.s                        //SVE instruction
    fcpy    z0.s, p0/m, #5.00000000     //SVE instruction
    orr     w10, wzr, #0x400
loop:
    st1w    z0.s, p0, [x0, x8, lsl #2]  //SVE instruction
    incw    x8                          //SVE instruction
    whilelt p0.s, x8, x10               //SVE instruction
    b.any   loop                        //SVE instruction
    mov     w0, wzr
    ret

然而,当我在我的Ubuntu 16.04上尝试时:

代码语言:javascript
复制
sudo apt-get install binutils-aarch64-linux-gnu
aarch64-linux-gnu-as example1.S

它不承认任何SVE程序集指令,例如:

代码语言:javascript
复制
example1.S:6: Error: unknown mnemonic `ptrue' -- `ptrue p0.s'

我认为这是因为我的GNU2.26.1太老了,还没有SVE支持。

我也可以使用LLVM或任何其他开源汇编程序。

一旦我设法组装,我就想在QEMU用户模式下运行它,因为它是从3.0.0支持SVE开始的。

EN

回答 1

Stack Overflow用户

发布于 2018-10-19 08:51:27

带有断言的自动示例

下面我描述了这个例子是如何实现的。

程序集

aarch64-linux-gnu-as在Ubuntu18.04中已经足够新,可以从https://sourceware.org/binutils/docs-2.30/as/AArch64-Extensions.html#AArch64-Extensions中看到。

否则,在Ubuntu 16.04上从源代码编译Binutils很容易,只需做:

代码语言:javascript
复制
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引入时的日志消息打招呼;-)

然后在Ubuntu16.04上使用编译后的as并与打包的GCC链接:

代码语言:javascript
复制
./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

在Ubuntu16.04上,aarch64-linux-gnu-gcc 5.4没有-march=armv8.5-a,所以只需使用-march=armv8-a就可以了。无论如何,Ubuntu16.04和18.04都没有-march=armv8-a+sve,这将是它到达时的最佳选择。

或者,您也可以将以下内容添加到-march=armv8.5-a+sve源代码的开头,而不是传递.S

代码语言:javascript
复制
.arch armv8.5-a+sve

在Ubuntu 19.04 Binutils 2.32上,我还了解并测试了:

代码语言:javascript
复制
aarch64-linux-gnu-as -march=all

这也适用于SVE,我认为将来我会更多地使用它,因为它似乎只是一次启用所有功能,而不仅仅是SVE!

QEMU仿真

在QEMU上分步调试它的过程在:如何在QEMU上实现GDB单步臂装配?中解释。

首先,我将这个示例转化为一个最小的自包含Linux可执行文件:

代码语言:javascript
复制
.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

您可以通过以下方式运行它:

代码语言:javascript
复制
qemu-aarch64 -L /usr/aarch64-linux-gnu -E LD_BIND_NOW=1 ./example1

然后它就会很好地离开。

接下来,我们可以通过分步调试来确认和是否已实际完成:

代码语言:javascript
复制
qemu-aarch64 -g 1234 -L /usr/aarch64-linux-gnu -E LD_BIND_NOW=1 ./example1

以及:

代码语言:javascript
复制
./binutils-gdb/ble/bin/aarch64-elf-gdb -ex 'file example1' \
  -ex 'target remote localhost:1234' -ex 'set sysroot /usr/aarch64-linux-gnu'

现在,在bl daxpy之后立即开始运行:

代码语言:javascript
复制
>>> 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

通过执行以下操作,您目前可以部分和间接地观察到它:

代码语言:javascript
复制
i r d0 d1 d2

因为SVE寄存器zX的第一个条目是与旧的vX FP寄存器共享的,但是我们根本看不到p

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/52888916

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档