Aarch64条件跳转编译

zed5wv10  于 12个月前  发布在  其他
关注(0)|答案(2)|浏览(90)

下面是使用clang的compiled代码:

#include <stdint.h>

int f(int32_t a, int32_t b) {
    int32_t result;
    if (a < 10) {
        result = a + b;
    } else {
        result = a * b;
    }
    return result;
}

int main() {;
  int res = f(5, 9);
  if (res > 5) {
    return res;
  }
  return 0;
}

字符串
现在为if (a < 10)生成的程序集如下所示:

subs w8, w8, #10
 cset w8, ge
 tbnz w8, #0, .LBB0_2
 ...

 .LBB0_1:
  ...
  add w8, w8, w9
  ...

 .LBB0_2:
  ...
  mul w8, w8, w9


我们可以看到,当w8 = 0时,分支将转到加法块。
cset指令不满足条件ge时,w8被设置为0
当标志N(负)和V(溢出)相等时,满足ge条件。
这两个标志都由最后一个标志设置指令subs指令设置。
现在我不明白的是,为什么要在cset指令中使用ge条件,而不是使用类似pl条件的东西。为什么我们要额外检查w8小于min有符号32 int,它如何转换为我们提供的原始高级编译代码?
我意识到我最初的问题并没有完全代表我对这个编译的怀疑,我也完全意识到我没有优化编译,我故意这样做是为了实现下面的编译程序集。
我主要关心的是,如果a被设置为-2147483643,现在结果是溢出的,因为它将小于-2^31,所以它将变成正数,因此负数标志不会被设置,所以我们有一个情况,即N != V通过高级代码-2147483643确实小于10

eqqqjvef

eqqqjvef1#

您的代码没有优化,因为您没有打开优化。您询问的低效率在启用任何数量的优化后都没有发现(例如-O3)。

jaxagkaj

jaxagkaj2#

我没什么经验,但我相信

subs w8, w8, #10
cset w8, ge
tbnz w8, #0, .LBB0_2

字符串
意味着如果w8 >= 10后藤LBBO_2
因为当w8大于或等于10时,subs w8, w8, #10将标志设置为真

相关问题