iPhone/iPad で単語配列を最適に埋めるための NEON コードを書き込もうとしています。この問題の非常に奇妙な点は、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 パーサーのバージョンでは奇妙なことかもしれませんが、とにかくラベルを変更するだけで修正されました。