让编译器生成adc指令

时间:2013-06-28 18:45:05

标签: c++ assembly compiler-construction optimization

有没有办法让Clang,GCC或VS只使用Standard-C ++(98/11/14)生成adc(带进位)指令? (编辑:我的意思是在x64模式下,如果不清楚则很抱歉。)

3 个答案:

答案 0 :(得分:3)

如果您的代码进行了比较并将比较结果添加到某些内容中,那么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是有点棘手的。

答案 1 :(得分:2)

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 compiler explorer上)编译为:

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

答案 2 :(得分:1)

如果为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指令。