4

こんにちは私は現在、整列されていない可能性のある一連のフロートを含むデータブロブを処理する必要があるプログラムに取り組んでいます(また、整列されていない場合もあります)。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;
}
4

1 に答える 1