If statement 什么';s aarch64';有条件加载/存储的方法是什么?
我知道armv7可以使用条件代码进行加载/存储,比如ldrne/streq。但是A64不允许有条件地执行指令。那么,如何在arm64中存档此文件: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难以实现的特性
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场景类似的内容,因此它无法回答他的问题。你甚至没有任何文字解释