ARMv9的SVE/SVE2入門教程 (2)

rlk8888發表於2022-03-29

如何執行SVE程式?

在深入學習SVE指令之前,我們需要搭建一個能執行和除錯SVE指令的實驗環境。由於樹莓派4b不支援SVE擴充套件,我們可以採用QEMU+ARM64實驗平臺來模擬SVE指令。runninglinuxkernel_5.0專案在github裡,或者騰訊coding倉庫中,如何使用請參考裡面的Readme.

訪問github:

https: //github.com/figozhang/runninglinuxkernel_5.0

訪問騰訊coding倉庫:
https: //benshushu.coding.net/public/runninglinuxkernel_5.0/runninglinuxkernel_5.0/git/files

要想在QEMU中使能SVE擴充套件,需要在QEMU程式中指定“-cpu”引數,例如“-cpu max,sve=on,sve256=on”表示使能所有CPU的特性,包括SVE擴充套件,另外SVE支援的向量長度設定為256位。讀者也可以設定其他長度的SVE,例如1024位的SVE長度。
啟動QEMU的命令如下。

$ qemu-system-aarch64 -m 
1024 

-cpu max,sve=on,sve256=on -M virt,gic-version=
3,its=on,iommu=smmuv3 -nographic -smp 
4 -kernel arch/arm64/boot/Image  -append 
"noinintrd sched_debug root=/dev/vda rootfstype=ext4 rw crashkernel=256M loglevel=8"  -drive 
if=none,file=rootfs_debian_arm64.ext4,id=hd0 -device virtio-blk-device,drive=hd0 --fsdev local,id=kmod_dev,path=./kmodules,security_model=none -device virtio
-9p-pci,fsdev=kmod_dev,mount_tag=kmod_mount

下面編寫一個使用SVE指令的簡單彙編程式。

<hello_sve.S>


1     .section .data
2 
3     .align   3
4     print_hello_sve:
5         .string  "hello sve\n"
6 
7     .section .text
8     .globl main
9     main:
10        stp     x29, x30, [sp,  -16]!
11
12        mov x2, # 4
13        whilelo p0.s, xzr, x2
14        mov z0.s, p0/z, # 0x55  
 
15
16        adrp x0, print_hello_sve
17        add x0, x0, :lo12:print_hello_sve
18        bl printf
19
20        mov x0, # 0
21        ldp  x29, x30, [sp],  16
22        ret

這個彙編程式列印“hello sve”。為了測試能否編譯和執行SVE指令,我們在第13~14行裡新增兩條SVE指令,其中WHILELO指令初始化P0預測暫存器,關於WHILELO指令我們後面會介紹。MOV是把立即數搬移到Z0向量暫存器中。

首先啟動QEMU+ARM64實驗平臺。關於如何使用 QEMU+ARM64實驗平臺,請參考《奔跑吧linux核心 入門篇》第二版第1.5.3節內容。

執行run_rlk_arm64.sh指令碼,輸入run引數即可。run_rlk_arm64.sh指令碼已經使能了SVE擴充套件。

$./run_rlk_arm64.sh run

登陸到QEMU+ARM64系統之後,可以通過“/proc/cpuinfo”節點來檢查系統是否支援SVE擴充套件。在“Features”中顯示了當前CPU支援的所有硬體特性,例如SVE等。

# cat /proc/cpuinfo 

processor    :  0
BogoMIPS    :  125.00
Features    : sve fp asimd evtstrm aes 
CPU implementer    :  0x00
CPU architecture:  8
CPU variant    :  0x0
CPU part    :  0x051
CPU revision    :  0

使用GCC來編譯這個彙編程式。GCC是從GCC 8開始支援SVE指令的。

# gcc hello_sve.S -o hello_sve

hello_sve.S: Assembler messages:
hello_sve.S: 13Error: selected processor does not support  `whilelo p0.s,xzr,x2'
hello_sve.S:14: Error: selected processor does not support `
mov z0.s,p0/z,# 0x55 '

直接使用“gcc hello_sve.S -o hello_sve”來編譯,會出現不能識別SVE指令的錯誤。我們需要設定“-march”引數來指定處理器架構,例如“-march=armv8-a+sve”表示要編譯的程式需要支援ARMv8架構以及SVE擴充套件。

# gcc hello_sve.S -o hello_sve -g -march=armv8-a+sve

編譯完成之後執行hello_sve程式。

# ./hello_sve 

hello sve

這樣我們就搭建了一個能執行SVE指令的實驗環境了。

如何單步除錯SVE程式?

接下來我們使用GDB來單步除錯SVE指令。啟動GDB來除錯程式。

# gdb hello_sve

在main函式入口設定斷點。

(gdb) b main

Breakpoint  1 at  0x76c: file hello_sve.S, line  10.

輸入“r”命令來啟動除錯。GDB會停在斷點中。

(gdb) r

Starting program:  /mnt/sve/example_hello_sve/hello_sve 
Breakpoint  1, main () at hello_sve.S: 10
10        stp     x29, x30, [sp,  -16]!
(gdb)

使用“s”命令來單步除錯。使用“info reg”命令來檢視暫存器的值,如圖所示,使用info reg p0來檢視預測暫存器p0的值,也可以使用info reg z0來檢視z0向量暫存器的值。



ARM64視訊課程


來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/70005277/viewspace-2884629/,如需轉載,請註明出處,否則將追究法律責任。

相關文章