第23部分- Linux ARM汇编ARM32到ARM64迁移
1、在32位ARM系统中,可以通过指令本身中的条件字段来支持的分支判断。 例如在T32中,有用于构建条件序列的IT(如果-则-then)指令。 A64不支持此功能,但有一组不同的特定条件说明。
2、64位仍可以对第二个操作数进行移位,旋转和符号扩展或零扩展,但A64位不支持以相同的方式将移位和旋转操作“嵌入”到数据处理指令中。
3、通常不再可以访问程序计数器(PC)。 特别是,它不能像其他通用寄存器一样被读取或修改。 有伪指令可用于间接使用它(例如,在运行时生成相对于PC的地址)。
4、加载和存储多条指令已被加载和存储成对的64位寄存器的指令所取代。 它们也用于堆栈操作,以代替早期的PUSH和POP。
5、NEON架构区别,32位时候
是
S0是D0的下半部分,是V0的下半部分。 S1是D1的下半部分,它是V1的下半部分,依此类推。 这消除了编译器在自动向量化高级代码时遇到的许多问题。
指令集
指令集,A64添加了将加载或存储与内存屏障结合在一起的加载获取(LDAR)和存储释放(STLR)指令。 简化了关键部分的实施。
另外,指令级别的可选加密加速支持。 这些指令在向量库上运行,提供了常见的构建块操作,可有效实现例如 AES和SHA加密算法。
与早期版本的指令集不同,A64不支持有条件地执行单个指令(例如ARM指令集)或指令组(例如Thumb指令集)。 相反,它支持一系列指令(如CSINC –条件选择和增量),其行为由条件代码标志的当前状态修改。 再加上全套的条件分支,这些使得控制流程非常紧凑和高效。
内存模式
普通内存中支持用于加载和存储的未对齐访问(只有极少数例外,例如“加载和存储独占”指令)。
尽管可以为Big-endian支持而构建数据接口,但是数据和指令接口本来就是little-endian。尽管单个应用程序无法更改其自己的字节序,但是操作系统可以同时托管big-endian和little-endian应用程序。
有更多的预加载提示说明。这些允许预加载以进行加载和存储,并提供有关是否应缓存预加载数据的提示。
一对“单向”屏障指令,即Load-Acquire(LDAR)和Store-Release(STLR),比DMB / DSB具有更大的灵活性。下面的“汇编代码”部分显示了一个示例。
AArch64不支持强排序的内存(在ARMv7-A中已弃用),并且设备内存已获得一些额外的功能以使其更加灵活(能够为收集,重新排序和早期写入确认定义各自的限制) 。
重编译或重写
在大多数情况下,目标是使前者最大化而使后者最小化。
好消息是,很多代码将简单地重新编译。 但是,由于许多基本类型的大小将发生变化,因此需要谨慎行事。 尽管编写良好的C代码不应对单个类型的大小有很多依赖性,但是不可避免地会遇到一些。
最佳实践必须是在重新编译时启用所有警告和错误,并确保您注意到编译器的所有警告问题,即使代码看起来没有编译器错误。
特别要特别注意代码中的任何显式类型转换,因为当基础类型的大小更改时,这些类型转换通常是错误的来源。
编译选项
--cpu 8A.32
--cpu 8A.32.crypto
--cpu 8A.32.no_neon
--cpu 8A.64
--cpu 8A.64.crypto