让编译器生成adc指令

Getting a compiler to generate adc instruction

本文关键字:adc 指令 编译器      更新时间:2023-10-16

是否有任何方法可以让Clang、GCC或VS仅使用Standard-C++(98/11/14)生成adc(带进位加法)指令?(编辑:我的意思是在x64模式下,如果不清楚的话,很抱歉。)

如果您的代码进行比较并将比较结果添加到某个值,那么adc通常由gcc 5发出(顺便说一句,gcc 4.8在这里不发出adc)。例如,

unsigned foo(unsigned a, unsigned b, unsigned c, unsigned d)
{
    return (a + b + (c < d));
}

组装到

foo:
    cmpl    %ecx, %edx
    movl    %edi, %eax
    adcl    %esi, %eax
    ret

然而,让gcc真正发出adc有点棘手。

GCC上有一个__int128_t类型可用于amd64和其他64位目标,它将使用一对add/adc指令进行简单添加。(请参阅下面的Godbolt链接)。

此外,这个纯ISO C代码可以编译为adc:

uint64_t adc(uint64_t a, uint64_t b)
{
    a += b;
    if (a < b) /* should simplify to nothing (setting carry is implicit in the add) */
        a++; /* should simplify to adc r0, 0 */
    return a;
}

对我(ARM)来说,它生成了一些愚蠢的东西,但它为x86-64(在Godbolt编译器资源管理器上)编译为:

    mov     rax, rdi  # a, a
    add     rax, rsi  # a, b
    adc     rax, 0    # a,
    ret

如果为X86(C++11中的int64_t)编译64位有符号加法,则编译的代码将包含adc指令。

编辑:代码示例:

int64_t add_numbers(int64_t x, int64_t y) {
    return x + y;
}

在X86上,加法是使用add指令和adc指令来实现的。在X64上,仅使用一条add指令。