aarch64编译器能否编译含ARMv7l内联汇编的Armv8a程序
ARMv7l内联汇编移植ARMv8a编译问题
问题背景
现有集成ARMv7l架构内联汇编的C++文件,核心汇编代码片段如下:
"pld [%1, #96] \n" "vand q8, %q10, %q10 \n" "vand q9, %q11, %q11 \n" "vand q10, %q12, %q12 \n" "vand q11, %q13, %q13 \n" "vld1.f32 {d0-d1}, [%1]! \n" "vld1.f32 {d2-d3}, [%2]! \n" "vld1.f32 {d4-d5}, [%3]! \n" "vld1.f32 {d6-d7}, [%4]! \n" "vmul.f32 q12, q0, q9 \n" "vmla.f32 q12, q1, q8 \n" "vmul.f32 q13, q2, q9 \n" "vmla.f32 q13, q3, q8 \n" "vld1.f32 {d0-d1}, [%1]! \n" "vld1.f32 {d2-d3}, [%2]! \n" "vld1.f32 {d4-d5}, [%3]! \n" "vld1.f32 {d6-d7}, [%4]! \n" "vmul.f32 q12, q12, q11 \n" "vmla.f32 q12, q13, q10 \n" "vst1.f32 {d24-d25}, [%0]! \n"
使用ARMv8a目标编译器编译上述文件时,抛出如下编译错误:
{standard input}:2158: Error: unknown mnemonic `pld' -- `pld [x9,#96]' {standard input}:2159: Error: unknown mnemonic `vand' -- `vand q8,q16,q16' {standard input}:2160: Error: unknown mnemonic `vand' -- `vand q9,q17,q17' {standard input}:2161: Error: unknown mnemonic `vand' -- `vand q10,q18,q18' {standard input}:2162: Error: unknown mnemonic `vand' -- `vand q11,q19,q19' {standard input}:2163: Error: unknown mnemonic `vld1.f32' -- `vld1.f32 {d0-d1},[x9]!'
已知ARMv8a架构可兼容ARMv7l指令,需解答以下两个疑问:
- 是否可以使用armv8a编译器直接编译上述代码?
- 若无法直接编译,是否需要使用armv8a指令重写上述内联汇编代码?
解答
- 是否支持直接编译:不能。
所谓ARMv8a兼容ARMv7l指令,仅指CPU支持AArch32执行状态下运行32位A32/T32指令集。默认编译ARMv8a目标时,编译器会生成AArch64执行状态对应的A64指令集代码,这套指令集的助记符、寄存器命名、语法规则和ARMv7l使用的32位NEON指令完全不兼容,出现「未知助记符」报错的核心原因就是编译器按A64语法规则解析32位NEON指令,无法识别对应写法。
如果不需要生成64位程序,可通过添加编译参数指定编译器生成32位ARMv8兼容代码(例如GCC/Clang追加-march=armv8-a -marm参数),这种方式不需要修改原有汇编,但生成的是32位可执行文件,无法在仅支持AArch64运行态的环境中执行。 - 是否需要重写汇编:如果目标是生成64位AArch64可执行程序,必须重写内联汇编,核心修改点如下:
- 预取指令
pld替换为A64体系对应的prfm指令,例如原pld [%1, #96]可替换为prfm pldl1keep, [%1, #96] - 所有NEON指令切换为A64语法格式:原32位NEON的类型后缀从指令助记符后移到寄存器操作数后,浮点运算指令增加
f前缀,加载存储指令的后移寻址格式调整。例如原寄存器清零指令vand q8, %q10, %q10可直接替换为效率更高的movi v8.4s, #0;原vld1.f32 {d0-d1}, [%1]!对应A64写法为ld1 {v0.4s}, [%1], #16;原vst1.f32 {d24-d25}, [%0]!对应为st1 {v12.4s}, [%0], #16;原浮点乘、乘加指令vmul.f32/vmla.f32对应替换为fmul/fmla即可。
若没有极致的性能压榨需求,优先建议将这部分汇编逻辑替换为ARM NEON intrinsic实现,无需单独区分AArch32/AArch64适配,编译器会自动生成对应架构的正确指令,移植和维护成本远低于手写内联汇编。
- 预取指令
内容的提问来源于stack exchange,提问作者Frankdog Deng
相关产品推荐
相关产品推荐

