此代码(非常相似的代码,尚未完全尝试过此代码)使用 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, d1}, [%[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, d17}, [r1]!

所以我的代码现在看起来像这样,但给出了完全相同的错误:
__asm__ volatile("vld1.32 {d0, d1}, [%0]! \n"
                 "vrev32.8 q0, q0         \n"
                 "vst1.32 {d0, d1}, [%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, w2, 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, x9, #16
cbnz    x9, 0x3e0
ret

最佳答案

我已经成功发布了几个使用 ARM 汇编语言的 iOS 应用程序,而内联代码是最令人沮丧的方法。 Apple 仍然要求应用程序支持 ARM32 和 ARM64 设备。由于默认情况下代码将构建为 ARM32 和 ARM64(除非您更改编译选项),因此您需要设计能够在两种模式下成功编译的代码。如您所见,ARM64 是一种完全不同的助记符格式和寄存器模型。有两种简单的方法可以解决这个问题:

1) 使用 NEON 内在函数编写代码。 ARM 指定原始 ARM32 内在函数对于 ARMv8 目标将基本保持不变,因此可以编译为 ARM32 和 ARM64 代码。这是最安全/最简单的选择。

2) 为您的汇编语言代码编写内联代码或单独的“.S”模块。要处理这两种编译模式,请使用“#ifdef __arm64__”和“#ifdef __arm__”来区分这两种指令集。

关于ios - RGBA 到 ABGR : Inline arm neon asm for iOS/Xcode,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/38035351/

10-11 16:30