历史上的今天
今天是:2025年02月07日(星期五)
2020年02月07日 | arm架构64位(AArch64)汇编优化总结
2020-02-07 来源:eefocus
1、参考
https://blog.csdn.net/SoaringLee_fighting/article/details/81906495
https://blog.csdn.net/SoaringLee_fighting/article/details/82155608
https://blog.csdn.net/u011514906/article/details/38142177
https://blog.csdn.net/listener51/article/details/82530464
2、前言
本文是arm架构64位(AArch64执行状态) neon优化的总结文档,主要包括arm架构64位优化的基础知识,特殊用法,打印调试和常用指令使用注意事项以及资料来源等相关知识。前文已有arm架构32位汇编优化总结对arm架构32位neon优化进行了全面总结,并且讲述了arm汇编语法,下面主要以gnu asm汇编语法为例讲述。
下图为arm架构汇编优化总结的思维导图:

3、arm架构64位优化基础知识
【arm】arm架构64位入门基础:架构分析、寄存器、调用规则、指令集以及参考手册
该博客已经分析了arm架构64位汇编优化的入门基础知识,主要包括架构分析,寄存器,调用规则,指令集和程序打印调试相关知识,可以作为入门arm64位汇编优化的基础知识。
4、ARMv8/AArch64 neon指令格式
In the AArch64 execution state, the syntax of NEON instruction has changed. It can be described as follows:
{ Where: < prefix> - prefix, such as using S/U/F/P to represent signed/unsigned/float/bool data type. < op> – operation, such as ADD, AND etc. < suffix> - suffix P: “pairwise” operations, such as ADDP,LDP,STP. V: the new reduction (across-all-lanes) operations, such as ADDV,SMAXV,FMAXV. 2:new widening/narrowing “second part” instructions, such as ADDHN2, SADDL2,SMULL2. < T> - data type, 8B/16B/4H/8H/2S/4S/2D. B represents byte (8-bit). H represents half-word (16-bit). S represents word (32-bit). D represents a double-word (64-bit). For example: UADDLP V0.8H, V0.16B FADD V0.4S, V0.4S, V0.4S 参考自: https://community.arm.com/android-community/b/android/posts/arm-neon-programming-quick-reference 5、ARM相关编译参数 嵌入式设备(即arm架构的板子)在编译时,最好加上 -fsigned-char 因为嵌入式设备默认类型为unsigned char类型,非char 类型。此外在编译arm汇编优化代码时,编译选项需要加上-c 。-c都表示编译或汇编源文件,但是不进行链接。 ARM相关或者硬件相关编译参数一般以-m开头,常用ARM平台编译选项包括: -mcpu = cortex-a7 -mabi = atpcs -march = armv7 -mtune = cortex-a53 -mfpu = neon, neon-vfpv4 -mfloat-api = soft, softfp, hard 更多详细内容可以参考:https://gcc.gnu.org/onlinedocs/gcc-5.2.0/gcc.pdf 3.17.1小节AArch64 option和3.17.4小节 ARM options. 6、查看状态标记位NZCV的方法 mrs x15, nzcv mov w0, w15 bl print 7、A64指令集特有的指令及其用法 1. shl和ushr指令 shl ushr ushr d2, d2, #8 使用注意事项:这两条指令只能操作64位数据,即只能对D寄存器进行处理。 ushr最多只能进行64位数据的右移,并且右移时会影响V2寄存器的高64位数据(清零),因此高64位数据需要在右移前保存,否则相关数据会被修改。 2. INS指令 用法与MOV指令基本一样,可以实现neon标量与neon标量之间的传送,以及ARM寄存器与neon标量之间的传送。 INS INS 3. SUQADD、USQADD指令 既有标量用法,也有矢量用法。 SUQADD SUQADD USQADD USQADD 4.RBIT、REV指令 RBIT REV 5. ADDV,SADDLV,SMAXV,SMINV (Vector Reduce(across lanes)) ADDV SADDLV SMAXV SMINV eg.: addv B0, v1.8B // 将v1寄存器中的低64位中8个8位数据相加求和后,赋给v0的最低8位。 更多详细解释可以参考:https://static.docs.arm.com/ddi0487/a/DDI0487A_j_armv8_arm.pdf 这里写图片描述 6.sxtw使用注意事项 负数在使用时必须进行符号扩展! 比如: sxtw x4, w4 7.w寄存器到v寄存器 直接使用dup指令 dup v0.8B, w2 8.常用指令对应关系(arm32---->arm64) vmovl------>uxtl/sxtl vqmovn----->sqxtn vqmovun----->sqxtun vqrshrun---->sqrshrun vceq------->cmeq vcge------->cmge vadd------>add vsub------>sub vaddl----->saddl,uaddl vaddw----->saddw,uaddw,sw2addw2,uadd vmull----->smull,smull2,umull,umull2 vmax,vmin----->smax,umax,smin,umin vmlal--------> smlal,smlal2,umlal,umlal2 vrshl--------> urshl,srshl vtrn---------> trn1,trn2 vstm/vstr----> stp/str vld1.32 {d0[]}, [r0], r2-----> ld1r {v0.S}[0], [x0], x2 addgt,addle,subgt,suble----->csel,csetm,cset,csinc,csinv 更多可参考: https://www.element14.com/community/servlet/JiveServlet/previewBody/41836-102-1-229511/ARM.Reference_Manual.pdf 8、资料文档查阅 在进行arm64位汇编语言编写之前,建议首先阅读学习arm官方英文手册(https://static.docs.arm.com/ddi0487/ca/DDI0487C_a_armv8_arm.pdf) ,重点阅读C7 AArch64 neon指令部分以及C3 ARM指令部分,在了解了基本指令和arm64位汇编格式之后就可以尝试编写了。 对于已有arm32位代码的情况下,从arm32位代码迁移到arm64时,可以参考(https://www.element14.com/community/servlet/JiveServlet/previewBody/41836-102-1-229511/ARM.Reference_Manual.pdf) 中 5.7.23小节的指令对照表。 对于代码迁移方法,可以参考我的博客:Some ways of Migrating code from ARM32 to AArch64。 对于快速查找指令,可以参考指令速查卡: https://courses.cs.washington.edu/courses/cse469/18wi/Materials/arm64.pdf 9、优化经验总结(满满的干货) 关于参数入栈和寄存器入栈 建议将入栈的参数取出之后,再对ARM寄存器或者NEON寄存器进行入栈。 尽量去除数据依赖 ,使指令并行 不要将当前指令的目的寄存器作为下一条指令的源寄存器,尤其对于vmul指令,vmla指令。 不要将当前指令的目的寄存器作为下一条指令的源寄存器,尤其对于vmul指令,vmla指令。 尽量减少分支跳转 可以采用条件执行指令或逻辑运算指令替代分支跳转,比如addgt,suble,vceq,vcge,vbit,vbsl等。 关注指令周期延迟 对于乘法指令,指令周期比较长,尽量不要立即使用指令计算结果,否则会等待耗时。 数据运算尽量在neon寄存器中,避免在arm寄存器和neon寄存器之间的运算。 尽量减少存取数据的次数。 尽量使用不需要保存的寄存器,寄存器出入栈很耗时。 对于宽度为4的倍数的情况下,尽量在宽度方向上处理,这样可以提高cache命中率。 使用尽量少的指令来编写代码,因为arm指令是精简指令,大部分指令都是单周期指令。 如果寄存器够用的话,尽量将一行的数据处理拆成两行或是四行来并行处理;尽量避免大数据之间的运算,可以将大数据的运算拆成小数据的运算。 减少循环判断和条件比较 在数据处理过程中,在循环判断或条件判断较多时,可以适当展开分支,可以在一定程度上提升性能。 THE END!
史海拾趣
|
HI-TECH C Compiler for PIC10-12-16 MCUs V9.70 已经测试过,破解成功! 1,先安装HI-TECH C Compiler for PIC10-12-16 MCUs V9.70 安装路径为默认路径 \"C 盘下\" 激活PICC 45天试用版! 2,破解,先写入注册文件,运行破解文件, ...… 查看全部问答> |
|
DDRAW程序问题,在全屏方式下,用创建程序的方式打开一个程序后,程序的界面显示不出来,LCD上显示的还是DDRAW的画面 请问如何解决这个问题 // // Copyright (c) Microsoft Corporation. All rights reserved. // // // Use of this source code is subject to the terms of the Microsoft end-user // license agreement (EULA) under which you l ...… 查看全部问答> |
|
求助 :最近学习uc/os-ii 用的任哲写的《嵌入式实时操作系统uc/os-ii原理及应用》编译无法通过 最近学习uc/os-ii 用的任哲写的《嵌入式实时操作系统uc/os-ii原理及应用》,把他书中的源码在网上找到了。书中是用的BORLAND C++ 3.1编译的,我用borland c v3.1 dos 界面下直接建立工程文件编译,可是搞了很久编译都无法通过,而且试了 ...… 查看全部问答> |
|
我在看wince5.0 usb从驱动源代码具体位置是:/%wince500boot%/public/common/oak/usbfn 这个文件下有3个文件夹: 1.CLASS文件: RNDIS,SERIAL, STORAGE三个文件夹 2.CONTROLLER文件: MDD,NET2280 3.UFNCLIENLIB文件 请问这三个文件都有什 ...… 查看全部问答> |
|
求助 AT89S51与C8051F单片机有什么区别啊?(急) 各位前辈,我是一名学生菜鸟,要用单片机做采集器,遇到了这么一个问题,AT89S51与C8051F单片机有什么区别,请各位帮忙解决,谢谢!… 查看全部问答> |
|
各位高手,本人摸电只是懂点基本的.想请教大家个问题.传感器输出的4-20ma如何转换成0-5V.我以前一直就是用250欧电阻将4-20ma转换成1-5V,再进行A/D转换,感觉这样处理没有0-5V方便.比如4-20ma表示0-50度的温度,0V的时候就表示温度是0度,5V的时候就表示 ...… 查看全部问答> |
|
一、摘要本应用报告介绍了如何使用Timer_A实现UART功能。该包括例子是专门为MSP430x11x家庭,但他们能适应任何MSP430家族成员纳入Timer_A。使用硬件UART的功能在Timer_A功能和软件。执行是半双工的,事件驱动,它支持的8N1波特率协议从1200到115200 ...… 查看全部问答> |




