简体   繁体   English

无分支方式有条件清除寄存器

[英]Branchless way to conditionally clear register

Is there branchless way to clear 32-bit register depending on status register state? 根据状态寄存器的状态,是否有无分支方式清除32位寄存器? It can be achieved using additional clear register and CMOVcc , but it is too expensive on x86 in 32bit mode for me. 可以使用附加的清除寄存器和CMOVcc来实现,但是对于我来说,在32位模式下的x86上它太昂贵了。 Sadly CMOVcc have no version with immideate operand. 遗憾的是, CMOVcc没有带有酰亚胺化操作数的版本。 Reading from memory is also bad variant. 从内存中读取也是一种不良的变体。

There is SETcc (though, operand is 1 byte) but not " CLEARcc " instruction on x86 . SETcc (虽然,操作数为1个字节),而不是“ CLEARccx86”指令。

This may disappoint you, but CMOVcc is very good in that regard. 这可能会让您失望,但是CMOVcc在这方面非常出色。 Using it with a variable ddZERO with the value 0 is not that bad, especially in a loop. 将其与值为0 ddZERO变量ddZERO使用并没有那么糟,尤其是在循环中。

CMOVcc rTarget, ddZERO

resets the rTarget register to zero if the cc conditions are met. 如果满足cc条件, rTarget寄存器重置为零。
Otherwise (there is an otherwise) you can invert the scenario and CMOVcc on a NOT MATCHING condition. 否则(否则),您可以在NOT MATCHING条件下反转方案和CMOVcc Which choice would be better depends on the frequency of the occurrence. 哪种选择更好取决于发生的频率。

If you have a register with the value 0 you should use that instead. 如果您的寄存器值为0 ,则应改用该寄存器。 But if you can't spare a register using a (cached) memory location is not that bad. 但是,如果您不能使用(缓存的)内存位置来保留寄存器,那还不错。 This estimation is based on experience and IIRC using a constant in a L1 cached memory location has a practically negligible latency in a loop. 此估计基于经验,并且IIRC在L1高速缓存的内存位置中使用常数在循环中的延迟可以忽略不计。

There is essentially one generic method in most ISAs providing branchess setting or clearing a register: generating an all zero or all ones mask from carry flag: sbb reg,reg clears a mask when carry is zero and sets the mask when carry is set. 在大多数ISA中,基本上有一种通用方法提供分支设置或清除寄存器:从进位标志生成全零或全掩码: sbb reg,reg在进位为零时清除掩码,并在设置进位时设置掩码。 Followed by and dst, reg will either clear the destination register, or leave it unchanged. and dst, reg将清除目标寄存器,或使其保持不变。

One can invert the condition by toggling the mask, or inverting the carry flag. 可以通过切换遮罩或反转进位标志来反转条件。 Test for zero can be achieved by either subtracting one from the register under test, or subtracting the register under test from zero. 零测试可以通过从被测寄存器中减去1或从零中减去被测寄存器来实现。 The first sets carry iff register was zero; 第一组进位的iff寄存器为零; the second form sets carry iff register was non-zero. 第二个形式集进位iff寄存器为非零。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM