GCC PowerPC避免浮动的.rodata节

我正在编写C代码并将其编译为PowerPC体系结构。 也就是说C代码包含浮点变量常量,我想将它放在.text节中,而不是.rodata因此函数代码是自包含的。

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

为了说服GCC帮助我,我尝试将float声明为static const 。 没有不同。 使用指针,结果相同。 对函数使用__attribute__((section(".text"))) ,单独使用相同的结果和每个浮点变量:

error: myFloatConstant causes a section type conflict with myFunction

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

unsigned int *myFloatConstant = (unsigned int *) (0x11000018);
*myFloatConstant = 0x4C000000;

使用浮点数:

float theActualFloat = *(float *) myFloatConstant;

我还是想保持-O3但它再次使用.rodata这样一个潜在的答案将包括优化标志使花车放置在.rodata因为从开始-O1这是怎么回事?

最好的情况是,我可以在代码中使用“正常”浮动和最大优化,并且它们永远不会放入.rodata中。

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


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

生成的汇编代码:

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

阐释:

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

*(int *)&y = x无论如何都是纯整数操作。

由于volatiletheActualFloat = y这一行不能被优化,因此编译器必须将整数写入堆栈中的变量,并且必须从变量中读取结果。


我发现了另一种避免stack frame创建和.rodata使用的解决方案,但需要一个绝对内存地址来将float存储在:

static inline volatile float *getFloatPointer(int address, float value) {
    float *pointer = (float *) address;
    *pointer = value;

    return pointer;
}

它是这样使用的:

volatile float *myFloat = getFloatPointer(0x12345678, 30.f);
printf("%f", *myFloat);

重要的是不要创建一个局部的float变量,只有volatile指针,所以它不会再使用.rodata

链接地址: http://www.djcxy.com/p/40267.html

上一篇: GCC PowerPC avoiding .rodata section for floats

下一篇: Nullable types in kotlin annotation processor