这段代码(非常相似的代码,还没有尝试过这段代码)使用Android NDK编译,但不能用XCode / armv7 arm64 / iOS编译
uint32_t *src; uint32_t *dst; #ifdef __ARM_NEON __asm__ volatile( "vld1.32 {d0,d1},[%[src]] \n" // error: Vector register expected "vrev32.8 q0,q0 \n" // error: Unrecognized instruction mnemonic "vst1.32 {d0,[%[dst]] \n" // error: Vector register expected : : [src]"r"(src),[dst]"r"(dst) : "d0","d1" ); #endif
这段代码出了什么问题?
EDIT1:
uint8x16_t x = vreinterpretq_u8_u32(vld1q_u32(src)); uint8x16_t y = vrev32q_u8(x); vst1q_u32(dst,vreinterpretq_u32_u8(y));
拆解后,我得到以下内容,这是我已经尝试的变体:
vld1.32 {d16,d17},[r0]! vrev32.8 q8,q8 vst1.32 {d16,[r1]!
__asm__ volatile("vld1.32 {d0,[%0]! \n" "vrev32.8 q0,q0 \n" "vst1.32 {d0,[%1]! \n" : : "r"(src),"r"(dst) : "d0","d1" );
EDIT2:
通过反汇编阅读,我实际上找到了该函数的第二个版本.事实证明,arm64使用略有不同的指令集.例如,arm64组件使用rev32.16b v0,v0代替.整个功能列表(我无法做出正面或反面)如下:
_My_Function: cmp w2,#0 add w9,w2,#3 csel w8,w9,lt cmp w9,#7 b.lo 0x3f4 asr w9,w8,#2 ldr x8,[x0] mov w9,w9 lsl x9,x9,#2 ldr q0,[x8],#16 rev32.16b v0,v0 str q0,[x1],#16 sub x9,#16 cbnz x9,0x3e0 ret
解决方法
我已成功发布了几个使用ARM汇编语言的iOS应用程序,内联代码是最令人沮丧的方法. Apple仍然需要应用程序来支持ARM32和ARM64设备.由于默认情况下代码将同时构建为ARM32和ARM64(除非您更改了编译选项),因此您需要设计能够在两种模式下成功编译的代码.正如您所注意到的,ARM64是一种完全不同的助记符格式和寄存器模型.有两种简单的方法:
1)使用NEON内在函数编写代码. ARM指定原始ARM32内在函数对于ARMv8目标基本保持不变,因此可以编译为ARM32和ARM64代码.这是最安全/最简单的选择.
2)为汇编语言代码编写内联代码或单独的“.S”模块.要处理2种编译模式,请使用“#ifdef __arm64 __”和“#ifdef __arm__”来区分这两种指令集.