[英]GCC PowerPC avoiding .rodata section for floats
我正在编写C
代码并为PowerPC
架构编译它。 那就是说C
代码包含浮点变量常量,我想把它放在.text
部分而不是.rodata
所以函数代码是自包含的。
这个问题是在PowerPC
, 将浮点值移动到浮点寄存器的唯一方法是从内存加载它 。 这是一个指令集限制。
为了说服GCC
帮助我,我尝试将浮动声明为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
无论如何都是纯整数运算。
由于volatile
原因,无法优化theActualFloat = y
这一行,因此编译器必须将整数写入堆栈中的变量,并且必须从变量中读取结果。
我找到了另一个避免stack frame
创建和.rodata
使用的解决方案,但需要一个绝对的内存地址来存储浮点数:
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
再次使用.rodata
。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.