If statement 什么';s aarch64';有条件加载/存储的方法是什么?

If statement 什么';s aarch64';有条件加载/存储的方法是什么?,if-statement,assembly,conditional-statements,arm64,If Statement,Assembly,Conditional Statements,Arm64,我知道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 ... 每一条指令的谓词都是一个使高性能ARM CPU难以实现的特性

我知道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
...

每一条指令的谓词都是一个使高性能ARM CPU难以实现的特性,特别是在无序执行的情况下。它是为AArch64故意移除的。(引用供应商自己的理由)

如果您需要一些具有副作用/可能的故障(如存储和加载)的内容作为条件,通常需要进行分支


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

每条指令的预测功能使得高性能ARM CPU更难实现,特别是在无序执行的情况下。它是为AArch64故意移除的。(引用供应商自己的理由)

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
如果您需要一些具有副作用/可能的故障(如存储和加载)的内容作为条件,通常需要进行分支

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

void fun0(无符号整数x,无符号整数*y)
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
{ 如果(x)*y=0; 否则*y=1; } void fun1(无符号整数x,无符号整数*y) { 如果(x)*y=10; 否则*y=11; } void fun2(无符号整数x、无符号整数*y、无符号整数a、无符号整数b) { 如果(x)*y=a; else*y=b; } void fun5(无符号整数x、无符号整数*y、无符号整数*z) { 如果(x)*y=123; else*z=123; } 0000000000000000 : 0:7100001f cmp w0,#0x0 4:1a9f17e0 cset w0,等式//等式=无 8:B900020 str w0[x1] c:d65f03c0 ret 0000000000000010 : 10:7100001f cmp w0,#0x0 14:1a9f17e0 cset w0,等式//等式=无 18:11002800加上w0,w0,#0xa 1c:B900020 str w0[x1] 20:d65f03c0 ret 0000000000000024 : 24:7100001f cmp w0,#0x0 28:1a831042 csel w2,w2,w3,ne//ne=any 2c:B900002STR w2[x1] 30:d65f03c0 ret 0000000000000034 : 34:34000080 cbz w0,44 38:52800f60 mov w0,#0x7b/#123 3c:B900020 str w0[x1] 40:d65f03c0 ret 44:52800f60 mov w0,#0x7b/#123 48:b9000040街w0[x2] 4c:d65f03c0 ret
void fun0(无符号整数x,无符号整数*y)
{
如果(x)*y=0;
否则*y=1;
}
void fun1(无符号整数x,无符号整数*y)
{
如果(x)*y=10;
否则*y=11;
}
void fun2(无符号整数x、无符号整数*y、无符号整数a、无符号整数b)
{
如果(x)*y=a;
else*y=b;
}
void fun5(无符号整数x、无符号整数*y、无符号整数*z)
{
如果(x)*y=123;
else*z=123;
}
0000000000000000 :
0:7100001f cmp w0,#0x0
4:1a9f17e0 cset w0,等式//等式=无
8:B900020 str w0[x1]
c:d65f03c0 ret
0000000000000010 :
10:7100001f cmp w0,#0x0
14:1a9f17e0 cset w0,等式//等式=无
18:11002800加上w0,w0,#0xa
1c:B900020 str w0[x1]
20:d65f03c0 ret
0000000000000024 :
24:7100001f cmp w0,#0x0
28:1a831042 csel w2,w2,w3,ne//ne=any
2c:B900002STR w2[x1]
30:d65f03c0 ret
0000000000000034 :
34:34000080 cbz w0,44
38:52800f60 mov w0,#0x7b/#123
3c:B900020 str w0[x1]
40:d65f03c0 ret
44:52800f60 mov w0,#0x7b/#123
48:b9000040街w0[x2]
4c:d65f03c0 ret

ARM64上没有此类说明。考虑在加载/存储操作中执行条件分支。在ARM文档中,您看到了关于条件执行或分支等的什么内容?您不了解文档的哪一部分?ARM64上没有此类说明。考虑在加载/存储操作中执行条件分支。在ARM文档中,您看到了关于条件执行或分支等的什么内容?您不了解文档的哪一部分?这不适用于OPs场景,因为存储本身是有条件的,而不是存储的值。您显示的代码在这种情况下不起作用。@fuz询问编译器比阅读文档容易得多,这里显示了一些快捷方式,但随着每指令条件消失,一天结束时的条件分支也消失了。尽管在提出这个问题之前应该先阅读这些文件。演示您可以在几秒钟内询问编译器我同意这一点,但由于您的代码没有显示任何与OPs场景类似的内容,因此它无法回答他的问题。您甚至没有任何文本来解释代码的相关性。这使得您的答案很糟糕。这不适用于OPs场景,因为存储本身是有条件的,而不是存储的值。您显示的代码在这种情况下不起作用。@fuz询问编译器比阅读文档容易得多,这里显示了一些快捷方式,但随着每指令条件消失,一天结束时的条件分支也消失了。尽管在提出这个问题之前应该先阅读这些文件。演示您可以在几秒钟内询问编译器我同意这一点,但由于您的代码没有显示任何与OPs场景类似的内容,因此它无法回答他的问题。你甚至没有任何文字解释