使SIGILL处于浮动状态以进行固定转换

时间:2010-04-06 15:08:39

标签: c++ arm porting

运行以下代码后,我收到了一个SIGILL。我无法确定它有什么问题。

目标平台是ARM,我正在尝试移植已知的库(其中包含此代码)

void convertFloatToFixed(float nX, float nY, unsigned int &nFixed) {
    short sx = (short) (nX * 32);
    short sy = (short) (nY * 32);

    unsigned short *ux = (unsigned short*) &sx;
    unsigned short *uy = (unsigned short*) &sy;

    nFixed = (*ux << 16) | *uy;
}

非常感谢任何帮助。

提前致谢

1 个答案:

答案 0 :(得分:1)

某些ARM处理器有硬件浮点数,有些没有,所以有可能这个函数是针对硬件浮点编译的,但是你的平台缺少一个浮点单元,所以浮点指令导致处理器报告非法指令。如果这是测试程序中的第一个浮点计算,则极有可能成为问题。检查平台的文档,找到需要传递给gcc的-march选项,或查看已经运行的某些程序使用的编译选项。

此功能没有定义的行为,并且没有指示所需的行为是什么,很难提出改进。尝试这样的事情开始: -

void convertFloatToFixed(float nX, float nY, unsigned int &nFixed) {
    assert(nX * 32 < INT_MAX);
    assert(nY * 32 < INT_MAX);

    int sx = nX * 32;
    int sy = nY * 32;

    unsigned int ux = sx;
    unsigned int uy = sy;

    nFixed = (ux << 16) | uy;
}

我已经摆脱了指针转换,(正如其他人指出的那样)打破了严格的别名规则。我还使用int代替short。通常没有short个自动变量,因为它们在计算之前已经扩展到int s。 (这是一个很好的工作,因为将short移位16位不会非常有用。)我添加了一些检查,因此您的调试版本可以找出浮点到整数转换是否会溢出,这会导致未定义的行为。