与 adc $0 不同的进位标志加法指令?
Carry flag addition instruction different to adc $0?
adc [=11=]
指令是在 x86/64 上将 Carry Flag
添加到 %rdx
的唯一方法吗?
add %rax,%rcx
adc [=10=] ,%rdx
这是最好的方法。
其他选项包括使用 jc
(跳过 inc
)、cmovc
(可能使用 lea
来跳过 no-flags add-1) , 或 setc
。使用 setc:
xor %edi, %edi
add %rax, %rcx
setc %dil # %rdi = CF, since we already zeroed the upper bytes
add %rdi, %rdx # no partial-register stall/extra uop from reading rdi after writing dil, because we used a recognized zeroing idiom (xor) to zero it.
这些选项显然更糟糕,即使 adc
是 Intel CPUs before Broadwell 上的 2-uop 指令。 (由于 Haswell 引入了 FMA 解码为单个 uop 的硬件更改,Broadwell 和 Skylake 也将其他一些 3 输入指令作为单个 uop 处理,包括 adc
和 cmov
。)
将 CF 放入寄存器的更糟糕的选择是缓慢 rotate-with-carry rcl
(在归零寄存器上)。
adc [=11=]
指令是在 x86/64 上将 Carry Flag
添加到 %rdx
的唯一方法吗?
add %rax,%rcx
adc [=10=] ,%rdx
这是最好的方法。
其他选项包括使用 jc
(跳过 inc
)、cmovc
(可能使用 lea
来跳过 no-flags add-1) , 或 setc
。使用 setc:
xor %edi, %edi
add %rax, %rcx
setc %dil # %rdi = CF, since we already zeroed the upper bytes
add %rdi, %rdx # no partial-register stall/extra uop from reading rdi after writing dil, because we used a recognized zeroing idiom (xor) to zero it.
这些选项显然更糟糕,即使 adc
是 Intel CPUs before Broadwell 上的 2-uop 指令。 (由于 Haswell 引入了 FMA 解码为单个 uop 的硬件更改,Broadwell 和 Skylake 也将其他一些 3 输入指令作为单个 uop 处理,包括 adc
和 cmov
。)
将 CF 放入寄存器的更糟糕的选择是缓慢 rotate-with-carry rcl
(在归零寄存器上)。