9

任意精度演算 (512 ビット整数など) を扱う場合、GCC でインライン アセンブリを使用せずに ADC や同様の命令を使用する方法はありますか?

GMP のソースコードを一目見ただけで、サポートされているすべてのプラットフォームのアセンブリが実装されているだけであることがわかります。

これは私が書いたテスト コードで、コマンド ラインから 2 つの 128 ビット数値を加算し、結果を出力します。(mini-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=c99adcによってチェックされるように、命令を生成しませんobjdump。私のgccバージョンはi686-pc-mingw32-gcc (GCC) 4.5.2.

4

1 に答える 1

1

GCC、次のことが必要であることがわかった場合、キャリー フラグを使用します。たとえば、32 ビット マシンで
2 つの値を加算する場合、1 つの 32 ビットと 1 つの 32ビットが必要になります。しかし、コンパイラがキャリーの使用を強制される場合を除けば、おそらくアセンブラなしでそうするように説得することはできません。したがって、値の単一の「コンポーネント」が一緒に属していることを効果的に知らせることにより、GCC が操作を最適化できるように、利用可能な最大の整数型を使用することが有益な場合があります。uint64_tADDADC

単純な加算の場合、キャリーを計算する別の方法は、次のようにオペランド内の関連ビットを調べることです。

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) );
于 2013-03-29T13:57:27.123 に答える