2

我正在尝试编写一些 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 解析器版本,这可能是一些奇怪的事情,但无论如何只需更改标签即可修复它。

4

2 回答 2

0

q3 既没有分配给某些特殊角色,也不需要保留。不要担心这个。

我认为 auselen 的猜测是正确的。只看拆解就清楚了。

试试下面这个:

.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:
  // 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
  subs r2, r2, #16
  bxmi lr

NEONFILL16_loop1:
  vstm r0!, {d0-d7}
  subs r2, r2, #16
  bpl NEONFILL16_loop1

  mov   r0, #0
  bx lr
  .subsections_via_symbols

除了循环中的 cmp 之外,我还完全删除了保留的过时寄存器。(你知道,我必须优化一切 :))

如果 auselen 的猜测是正确的,这可能已经改变了跟踪时间,并且将在稍后的时间点进入 ARClite。

于 2013-07-02T09:00:31.460 回答
0

几乎每次我在手写的 ARM 代码中跳到一个奇怪的地方时,都是因为我摸索了拇指交互操作,并且函数一直在错误的模式下执行——因此指令流对 CPU 来说就像垃圾一样,它会跳来跳去随机直到它自己受伤并摔倒。

对于作为函数入口点的所有标签,您应该具有以下汇编指令:

.type _fill_neon_loop1, %function

这告诉链接器,当它修复BL指令或计算函数的地址时,它应该进行适当的调整以确保它以正确的模式执行。

于 2013-07-05T15:38:46.360 回答