こんにちは私は現在、整列されていない可能性のある一連のフロートを含むデータブロブを処理する必要があるプログラムに取り組んでいます(また、整列されていない場合もあります)。ARM cortex-a8 用に gcc 4.6.2 でコンパイルしています。生成されたアセンブリ コードについて質問があります。
例として、最小限の例を書きました: 次のテスト コードの場合
float aligned[2];
float *unaligned = (float*)(((char*)aligned)+2);
int main(int argc, char **argv)
{
float f = unaligned[0];
return (int)f;
}
コンパイラ (gcc 4.6.2 - 最適化 -O3 を使用) が生成する
00008634 <main>:
8634: e30038ec movw r3, #2284 ; 0x8ec
8638: e3403001 movt r3, #1
863c: e5933000 ldr r3, [r3]
8640: edd37a00 vldr s15, [r3]
8644: eefd7ae7 vcvt.s32.f32 s15, s15
8648: ee170a90 vmov r0, s15
864c: e12fff1e bx lr
ここでのコンパイラは、データが整列されているかどうかを知ることはできませんが、少なくとも整列されたデータを必要とする VLDR を使用しないと、プログラムがバス エラーでクラッシュします。
ここに私の実際の質問があります:これはコンパイラから正しく、C++ コードでアラインメントを処理する必要がありますか、それともコンパイラのバグですか?
また、現在の回避策を追加して、値にアクセスする前に gcc にコピーを作成させることもできます。トリックは、gcc パック属性を持つ float のみを含む構造体を定義し、構造体ポインターを介してデータにアクセスすることです。コードスニペット:
struct FloatWrapper { float f; } __attribute__((packed));
const FloatWrapper *x = reinterpret_cast<const FloatWrapper *>(rawX.data());
const FloatWrapper *y = reinterpret_cast<const FloatWrapper *>(rawY.data());
for (size_t i = 0; i < vertexCount; ++i) {
vertices[i].x = x[i].f;
vertices[i].y = y[i].f;
}