我正在尝试编写一些 NEON 代码以优化 iPhone/iPad 上的单词数组填充。这个问题非常奇怪的是,当 NEON 指令为 q3 赋值时,代码似乎跳转到了一个名为 _ ARCLite _load 的函数中。有没有人见过这样的东西:
(使用 xcode 4.6 和 -no-integrated-as 标志编译的 test_time_asm.s)
.section __TEXT,__text,regular
.section __TEXT,__textcoal_nt,coalesced
.section __TEXT,__const_coal,coalesced
.section __TEXT,__picsymbolstub4,symbol_stubs,none,16
.text
.align 2
.globl _fill_neon_loop1
.private_extern _fill_neon_loop1
_fill_neon_loop1:
push {r4, r5, r6, r7, lr}
// r0 = wordPtr
// r1 = inWord
// r2 = numWordsToFill
mov r2, #1024
// Load r1 (inWord) into NEON registers
vdup.32 q0, r1
vdup.32 q1, r1
vdup.32 q2, r1
vdup.32 q3, r1 (Stepping into this instruction jumps into __ARCLite__load)
NEONFILL16_loop1:
vstm r0!, {d0-d7}
sub r2, r2, #16
cmp r2, #15
bgt NEONFILL16_loop1
mov r0, #0
pop {r4, r5, r6, r7, pc}
.subsections_via_symbols
单步执行 ASM 指令,直到分配给 q3 的指令。当我跳过该指令时,代码似乎跳到了这里:
(gdb) bt
#0 0x0009a568 in __ARCLite__load () at /SourceCache/arclite_iOS/arclite-31/source/arclite.m:529
#1 0x0007b050 in test_time_run_cases () at test_time.h:147
这真的很奇怪,我真的很不明白为什么分配给 NEON 寄存器会导致这种情况。NEON 是否将 q3 用于我不知道的特殊事物?
我还尝试使用 dN(64 位 regs)加载寄存器,分配给 d7 的结果相同。
vdup.32 d0, r1
vdup.32 d1, r1
vdup.32 d2, r1
vdup.32 d3, r1
vdup.32 d4, r1
vdup.32 d5, r1
vdup.32 d6, r1
vdup.32 d7, r1
(后来)在弄乱了建议的更改之后,我找到了问题的根本原因。这是这个分支标签:
NEONFILL16_loop1:
vstm r0!, {d0-d7}
sub r2, r2, #16
cmp r2, #15
bgt NEONFILL16_loop1
出于某种原因,分支标签导致跳转到代码中的另一个位置。用以下内容替换上面的标签可以解决问题:
1:
vstm r0!, {d0-d7}
sub r2, r2, #16
cmp r2, #15
bgt 1b
对于随 xcode 4.6 提供的 clang 中的 ASM 解析器版本,这可能是一些奇怪的事情,但无论如何只需更改标签即可修复它。