【发布时间】:2019-05-29 04:21:03
【问题描述】:
我正在使用带有 Thumb-2 指令的 ARMv7 处理器。
我执行了ADD、SUB 或CMP。现在我想将条件标志LE 移动到r2。在此之后,r2 应该包含 0 或 1。
我一直在查看 Thumb-2 手册,但没有找到条件 MOV 指令或读取标志的特殊指令。
最有效的方法是什么?提前致谢!
【问题讨论】:
标签: assembly arm embedded armv7 thumb
我正在使用带有 Thumb-2 指令的 ARMv7 处理器。
我执行了ADD、SUB 或CMP。现在我想将条件标志LE 移动到r2。在此之后,r2 应该包含 0 或 1。
我一直在查看 Thumb-2 手册,但没有找到条件 MOV 指令或读取标志的特殊指令。
最有效的方法是什么?提前致谢!
【问题讨论】:
标签: assembly arm embedded armv7 thumb
您需要使用ite (if-then-else) 指令开始一个条件块,然后使用条件赋值:
ite le @ if-then-else (le)
movle r2, #1 @ if (le) then r2 = #1
movgt r2, #0 @ else r2 = #0
一般来说,如果您在 Thumb-2 中使用适当的 IT 指令作为前缀,则可以使用任意条件指令。详细阅读手册。
【讨论】:
在 ARM 中,(几乎)任何指令都可以被断言。在 thumb 模式下,这需要 it 指令来为接下来的几条指令编码谓词和模式是否否定。
但我认为,在统一语法中,汇编程序可以为您执行此操作,而无需显式 it。
例如movle r0, #1 设置 r0 = 1 如果标志中的 LE 条件为真,否则保持不变。所以你首先需要一个mov r0, #0。
ARM32 没有像 x86 的 setcc 这样的从条件设置指令。
AArch64 可以:将标志条件转换为整数只需要一条 cset 指令。
这个 C 源代码:
int booleanize(int x, int y) { return x<y; }
int booleanize_u(unsigned a, unsigned b) { return a<b; }
使用 clang -O3 (on the Godbolt compiler explorer) 为 ARM32 thumb 编译,揭示了一些愚蠢的错过优化。 gcc 类似,在没有-mcpu 的情况下生成分支代码,甚至比使用-mcpu=cortex-a53 的clang 更糟糕。在简单的微控制器上,Branchy 可能并非完全不合理。
@@ BAD EXAMPLE, compiler missed optimizations
@ clang7.0 -target arm -mthumb -mcpu=cortex-a53
booleanize(int, int):
movs r2, #0 @ movs is 16-bit, mov is a 32-bit instruction, I think.
cmp r0, r1
it lt
movlt r2, #1
mov r0, r2 @ wasted instruction because the compiler wanted to mov #0 before cmp
bx lr
booleanize_u(unsigned int, unsigned int):
movs r2, #0
cmp r0, r1
it lo
movlo r2, #1
mov r0, r2
bx lr
这绝对比@fuz 的答案中的ite le / movle / movgt 差,有2条谓词指令。
ARM 模式的代码生成或多或少都很好,其中每个 32 位指令字在谓词条件的编码中都有 4 位。 (asm 源中不带后缀的默认是al = always。)
@ gcc8.2 -O3 -mcpu=cortex-a53
booleanize(int, int):
cmp r0, r1
movge r0, #0 @ a simple mov without predication or flag-setting would work
movlt r0, #1
bx lr
booleanize_u(unsigned int, unsigned int):
cmp r0, r1
movcs r0, #0
movcc r0, #1
bx lr
cset,在一个罐子里布尔化。@ clang and gcc make the same efficient code
booleanize(int, int):
cmp w0, w1
cset w0, lt @ signed less-than
ret
booleanize_u(unsigned int, unsigned int):
cmp w0, w1
cset w0, lo @ unsigned lower
ret
【讨论】:
我一直在查看 Thumb-2 手册,但没有找到条件 MOV 指令或读取标志的特殊指令。
您可以使用MRS,将条件标志复制到寄存器(即r2)。
最有效的方法是什么?
到目前为止,您还没有包含conditional execution code 不够的要求,因此这是最有效的方法。
【讨论】: