【问题标题】:What's aarch64's way to conditionally load/store?aarch64 有条件地加载/存储的方式是什么?
【发布时间】:2020-12-01 14:04:28
【问题描述】:

我知道 armv7 可以使用条件代码进行加载/存储,例如 ldrne/streq。但是 A64 不允许有条件地执行指令。那么我如何在 arm64 中存档:

ands    tmp1, dstend, 7 # set nzcv flag with ands
# if not zero, ldr w6, [srcend, -4]!, str w6, [dstend, -4]!
# else, do nothing and goes on
...

【问题讨论】:

标签: if-statement assembly conditional-statements arm64


【解决方案1】:

每条指令的预测功能使高性能 ARM CPU 更难实现,尤其是在乱序执行的情况下。它是为 AArch64 故意删除的。 (Why are conditionally executed instructions not present in later ARM instruction sets?引用供应商自己的理由)

如果您需要有副作用/可能的错误(如存储和加载)是有条件的,您通常需要分支。

我能想到的唯一值得考虑的无分支选项是csel,它带有指向虚拟位置(例如在堆栈上)与真实位置的指针。然后你仍然实际加载和存储,但不是到你关心的位置。这可能会更糟,除非分支错误预测惩罚很高并且分支难以预测。

【讨论】:

    【解决方案2】:
    void fun0 ( unsigned int x, unsigned int *y )
    {
        if(x) *y=0;
        else  *y=1;
    }
    void fun1 ( unsigned int x, unsigned int *y )
    {
        if(x) *y=10;
        else  *y=11;
    }
    void fun2 ( unsigned int x, unsigned int *y, unsigned int a, unsigned int b )
    {
        if(x) *y=a;
        else  *y=b;
    }
    void fun5 ( unsigned int x, unsigned int *y, unsigned int *z )
    {
        if(x) *y=123;
        else  *z=123;
    }
    0000000000000000 <fun0>:
       0:   7100001f    cmp w0, #0x0
       4:   1a9f17e0    cset    w0, eq  // eq = none
       8:   b9000020    str w0, [x1]
       c:   d65f03c0    ret
    
    0000000000000010 <fun1>:
      10:   7100001f    cmp w0, #0x0
      14:   1a9f17e0    cset    w0, eq  // eq = none
      18:   11002800    add w0, w0, #0xa
      1c:   b9000020    str w0, [x1]
      20:   d65f03c0    ret
    
    0000000000000024 <fun2>:
      24:   7100001f    cmp w0, #0x0
      28:   1a831042    csel    w2, w2, w3, ne  // ne = any
      2c:   b9000022    str w2, [x1]
      30:   d65f03c0    ret
    
    0000000000000034 <fun5>:
      34:   34000080    cbz w0, 44 <fun5+0x10>
      38:   52800f60    mov w0, #0x7b                   // #123
      3c:   b9000020    str w0, [x1]
      40:   d65f03c0    ret
      44:   52800f60    mov w0, #0x7b                   // #123
      48:   b9000040    str w0, [x2]
      4c:   d65f03c0    ret
    

    【讨论】:

    • 这不适用于 OPs 场景,因为存储本身是有条件的,而不是存储的值。您显示的代码在这种情况下将不起作用。
    • @fuz 询问编译器比阅读文档要容易得多,这里显示了一些快捷方式,但随着每条指令条件的消失,条件分支结束了。尽管在问这个问题之前应该阅读文档。证明您可以在几秒钟内询问编译器
    • 我同意这一点,但由于您的代码没有显示任何与 OP 场景真正相似的内容,因此无法回答他的问题。您甚至没有任何文字来解释为什么代码是相关的。这会让你的答案很糟糕。
    猜你喜欢
    • 2010-11-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多