【发布时间】:2018-11-08 14:58:56
【问题描述】:
我试图在我的代码进行算术运算时使用 CPSR 标志,而不是使用一系列 if 语句来检查溢出、进位等,以便获得更小、更快的代码。一个简单的例子是这个加法操作:
int16_t a = 0x5000;
int16_t b = 0x4000;
int16_t result = a+b;
uint32_t flags = getFlags();
代码需要在各种平台上运行,因此 getFlags() 是代码中唯一允许包含特定于体系结构的程序集的部分。
inline uint32_t getFlags() {
uint32_t flags = 0;
asm (“mrs %0, cpsr”
: “=r” (flags)
:
: );
return flags;
}
问题在于编译器无法知道本例中的加法运算应该设置标志,因此它生成的指令类似于:
ldrsh r3, [r0]
ldrsh r4, [r1]
add r3, r3, r4
strh r3, [r2]
mrs r3, cpsr
为了让 CPSR 包含任何有用的内容,我需要编译器使用添加而不是添加(s 后缀 = 更新 CPSR)。我可以在 C 代码中更改什么内容,或者可能是编译器选项会导致它选择标志更新指令吗?我可以使用 GCC 或 Clang。
【问题讨论】:
-
这种做法是非常错误的。现代编译器不是机械的汇编生成机器。你不能指望他们会根据源代码编写汇编指令,然后你可以进去插入额外的指令。
-
“代码需要在各种平台上运行” ...好吧,有些CPU根本没有标志...只是说...