获得GCC要使用进位逻辑对于高精度计算如果没有内联汇编?(Get GCC To Use Carry

2019-08-18 04:06发布

当与高精度计算(如512位整数)的工作,有没有什么办法让GCC使用ADC和类似指令,而无需使用内联汇编?

在GMP的源代码中的第一瞥表明,他们只是对每一个支持的平台组件的实现。

下面是测试代码我写的,它通过命令行增加了两个128位的数并输出结果。 (通过微型GMP的add_n启发):

#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>

int main (int argc, char **argv)
{
    uint32_t a[4];
    uint32_t b[4];
    uint32_t c[4];
    uint32_t carry = 0;

    for (int i = 0; i < 4; ++i)
    {
        a[i] = strtoul (argv[i+1], NULL, 16);
        b[i] = strtoul (argv[i+5], NULL, 16);
    }

    for (int i = 0; i < 4; ++i)
    {
        uint32_t aa = a[i];
        uint32_t bb = b[i];
        uint32_t r = aa + carry;
        carry = (r < carry);
        r += bb;
        carry += (r < bb);
        c[i] = r;
    }

    printf ("%08X%08X%08X%08X + %08X%08X%08X%08X =\n", a[3], a[2], a[1], a[0], b[3], b[2], b[1], b[0]);
    printf ("%08X%08X%08X%08X\n", c[3], c[2], c[1], c[0]);

    return 0;
}

GCC -O3 -std=c99不产生任何adc指令,以作为托运objdump 。 我的gcc版本是i686-pc-mingw32-gcc (GCC) 4.5.2

Answer 1:

GCC 使用进位标志,如果它可以看到,它需要:
当添加两个uint64_t在32位机器上的值,例如,这必须导致一个32位ADD加一个32位的ADC 。 但除了这些情况下,如果编译器被迫使用随身携带,它可能无法劝他这样做W / O汇编。 因此,它可能是有益的使用可用的最大整数类型,让GCC通过有效地让它知道价值的单一的“部件”属于共同优化运营。

对于简单的加法,另一种方式来计算进可能是看在操作数的相关位,如:

uint32_t aa,bb,rr;
bool msbA, msbB, msbR, carry;
// ...

rr = aa+bb;

msbA = aa >= (1<<31); // equivalent: (aa & (1<<31)) != 0;
msbB = bb >= (1<<31);
msbR = rr >= (1<<31);


carry = (msbA && msbB) || ( !msbR && ( msbA || msbB) );


文章来源: Get GCC To Use Carry Logic For Arbitrary Precision Arithmetic Without Inline Assembly?