Thumb-2 中的长条件分支

Long conditional branches in Thumb-2

ARMv7-M reference manual 的 A6.7.12 节给出了分支指令 (B) 的四种可能编码:

对于 T3(以及 T1 和 T2),我只能从程序计数器跳转到 -1048576 和 1048574 之间的地址。想让条件分支更远怎么办?

以下(在 UAL 中):

it     ne
bne.w  some_far_label

给我一个弃用警告:

Warning: IT blocks containing 32-bit Thumb instructions are deprecated in ARMv8

What should I do if I want a conditional branch to further away?

只需将 MOV{cond} PC, Rx 指令与该寄存器中的目标地址一起使用:

LDR R1, =some_very_far_label
IT NE
MOVNE PC, R1

由于您是在谈论实际针对 ARMv7,因此针对该警告的最佳做法是简单地忽略或禁用它,理想情况下首先不要针对 ARMv8-A 来触发它。

对于 v7 CPUs 它完全不相关;对于现有的 v8-A CPUs,它在很大程度上也是无关紧要的,因为 AArch32 的要点是与现有的 v7 代码向后兼容,如果他们没有 运行 该代码至少也是如此作为他们的 v7 前辈,他们不会很受欢迎。对于未来的 v8-A CPUs,一旦很大一部分软件已过渡到 AArch64,可能 可能需要重构 AArch32 代码以尽可能避免 IT 阻塞,但无论哪种方式,最糟糕的事情就是以多个背靠背的单指令块结束。

整件事有点傻,真的。 ARMv8-A Architecture Reference Manual 对 "Partial deprecation of IT" 的描述是:

ARMv8-A deprecates some uses of the T32 IT instruction, for performance reasons. [...] The full ARMv7 IT instruction functionality remains available in order to execute legacy T32 code. [...]

是的,可以有一个可选的控制位来捕获 'deprecated' 的使用,但即使 v8-A CPU 确实实现了它,也没有 OS 期望 运行 v7 代码将永远设置它。未来的 AArch32 实现仍然需要支持多指令 IT 块,它们只是可能比替代代码慢,因此 ARM 试图说服我们避免它们。不过,坦率地说,我可以想象理论上未来的 v8-A CPUs 不针对 运行 现有的 32 位代码,因此可能会进行优化,这使得支持 multi 变得异常困难-instruction IT 块有效地,可能更有可能完全放弃 AArch32 支持。