2017-09-12 15 views
1

下記の質問に私の無知を許してください。私たちはGCC 4.8(以上)とIBM XL C/C++ 12(以上)をサポートしています。また、AIXおよびLinux上でビッグエンディアンおよびリトルエンディアンをサポートしています。コンパイラとプラットフォームによってコードがかなり乱雑になりました。小さな定数をベクトルにロードするには?

定数1をVSXレジスタにロードします。これは私たちが作ったコードですが、それはとても複雑なので間違っています。マクロXLC_VERSION,GCC_VERSIONおよびLITTLE_ENDIANは慣習的な意味を持っているので、それらにつながる追加のプリプロセッサマクロは省略されています。

typedef __vector unsigned char  uint8x16_p8; 
typedef __vector unsigned long long uint64x2_p8; 

#if defined(XLC_VERSION) 
    typedef uint8x16_p8 VectorType; 
#elif defined(GCC_VERSION) 
    typedef uint64x2_p8 VectorType; 
#endif 

#if defined(LITTLE_ENDIAN) 
    const VectorType one = {1}; 
#else 
    const VectorType one = (VectorType)((uint64x2_p8){0,1}); 
#endif 

明白ではないが、XL C/C++はすべてのデータ配列をサポートし、豊富なAPIセットを備えています。 IBMコンパイラーは、(理解しにくい警告やエラーが発生していない)作業が容易です。

4.8に戻るGCCは、64x2配列のみをサポートし、APIのサブセットのみを持っています。たとえば、GCCには8x16構成のIBM APIがなく、GCCにはvec_reve(エンディアンの逆転が容易になる)がありません。私は本当に何をしたいのか

は次のようなもので、それはどこでも「ただ働き」が、それはコンパイルに失敗しています

VectorType one = 1; 

ベクターに小さな定数をロードするために、あまり複雑な方法はあります登録?

+0

ああ、各ベクトルスロットに1をロードしようとしていますか?または1つだけ? –

+0

@Jeremy - ちょうど1つ; 1つのsplat'd.The私が持っている問題は、我々はエンディアンの変換を手動で処理する必要があります。たとえば、['rijndael.cpp':1152](https://github.com/weidai11/cryptopp/blob/master/rijndael-simd.cpp#L1152)を参照してください。私はコンパイルしない文のように、あまり複雑でなく直感的なものを望みます。 – jww

+0

@Jeremy - それを信じるかどうか、AES/CTRモードで失敗した自己テストを6時間追跡しました。それは私が 'VectorType one = 1;'を望んでいたので、 'VectorType one = {1};'と書いたからです。リトルエンディアンLinuxマシンでは正常に動作しましたが、ビッグエンディアンのAIXマシンでは失敗しました。今、問題を回避するコントロールを追加したいと思います。この質問は、問題が将来浮上するように配置できるコントロールを見つけようとしています。 – jww

答えて

2

VectorType one = 1; 

のあなたの例では、ベクトルにスカラーを割り当てるしようとしています。代わりにベクトルを使用してみてください。 16文字のベクトルの場合、これは次のようになります。

vector char one = {1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1}; 

gcc-4.8がこのようにコンパイルされているようです。私はLE 4.8便利を持っていますが、少なくともビッグエンディアンで動作しません:

0: 10 41 03 0c  vspltisb v2,1 

のgcc-5とのLEはあまりにも正常に動作します。

0: 0c 03 41 10  vspltisb v2,1 
2

BCD_INITの例hereを確認するとよいでしょう。これは、マクロを使用してベクトルの初期化を逆にします。

vec_reveについて:vec_permの構文砂糖です。それをヘッダーまたはライブラリ関数としてインライン関数として実装し、それを持たないコンパイラに使用することができます。

関連する問題