GCC PowerPC避免浮动的.rodata部分

Bul*_*aza 8 c floating-point assembly gcc powerpc

我正在编写C代码并为PowerPC架构编译它.该C代码包含浮点变量常量,我希望将其放在该.text部分中,而不是.rodata功能代码是自包含的.

这个问题在于PowerPC,将浮点值移动到浮点寄存器的唯一方法是从内存加载它.这是一个指令集限制.

为了说服GCC帮助我,我尝试将浮标声明为static const.没有不同.使用指针,结果相同.使用__attribute__((section(".text")))该功能,相同的结果和每个浮点变量分别:

error: myFloatConstant causes a section type conflict with myFunction
Run Code Online (Sandbox Code Playgroud)

我也试过通过#pragma GCC push_options #pragma GCC optimize("O0")和禁用优化#pragma GCC pop_options.再假装我有一个unsigned int工作:

unsigned int *myFloatConstant = (unsigned int *) (0x11000018);
*myFloatConstant = 0x4C000000;
Run Code Online (Sandbox Code Playgroud)

使用浮点数:

float theActualFloat = *(float *) myFloatConstant;
Run Code Online (Sandbox Code Playgroud)

我仍然想保留,-O3但它再次使用,.rodata所以一个潜在的答案将包括哪个优化标志导致浮动被放置,.rodata因为从这开始-O1发生?

最好的情况是我可以在代码中"正常"使用浮点数加上最大优化,但它们根本就不会被放置.rodata.

我想象GCC的可能是通过混合数据和代码将浮点数置于代码之间,从该位置加载到浮点寄存器并继续.这可以手动编写我相信但是如何GCC做到这一点?强制每个变量的属性会导致上面的错误,但从技术上讲,这应该是可行的.

Mar*_*nau 3

使用 GCC 7.1.0 powerpc-eabi (Linux 下的交叉编译器)以下代码对我有用:

float test(void)
{
    int x;
    volatile float y;
    float theActualFloat;

    *(float *)&x = 1.2345f;
    *(int *)&y = x;
    theActualFloat = y;

    return theActualFloat;
}
Run Code Online (Sandbox Code Playgroud)

生成的汇编代码:

test:
    stwu 1,-24(1)
    lis 9,0x3f9e
    ori 9,9,0x419
    stw 9,8(1)
    lfs 1,8(1)
    addi 1,1,24
    blr
Run Code Online (Sandbox Code Playgroud)

说明:

在该行中,*(float *)&x = value您写入一个将由编译器优化的整数。编译器将执行整数运算,该运算不会访问 中的浮点值.rodata

无论如何,该行*(int *)&y = x都是纯整数运算。

theActualFloat = y由于该行无法优化volatile,因此编译器必须将整数写入堆栈上的变量,并且必须从变量中读取结果。