繁体   English   中英

GCC 为 ARM 上的未对齐浮点访问生成程序集

[英]GCC generated assembly for unaligned float access on ARM

您好,我目前正在开发一个程序,我需要处理一个包含一系列可能未对齐(有时也是)的浮点数的数据 blob。 我正在为 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 打包属性的浮点数,并通过结构体指针访问数据。 代码片段:

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;
}

正如您指出的ARM ARM A3.2.1状态,无论SCTLR.A值如何, VLDR生成Alignment fault

我已经在 Cortex-A9 上测试了你的例子,我得到了

# float_align                                                   
[1] + Stopped (signal)     float_align 

但是,我也对ARM Cortex-A8 TRM 4.2.1感到困惑,它指出

如果未指定对齐限定符,且 A=1,则如果未与元素大小对齐,则采用对齐错误。

如果未指定对齐限定符且 A=0,则将其视为未对齐访问

这可能是一个半生不熟的解释,因为ARM ARM提供了更多信息,并附有详细的指令表。

所以我认为答案是,您需要自己处理对齐,因为编译器无法找出您在所有情况下加载的地址,例如链接后地址可能可用等。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM