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做到这一点?强制每个变量的属性会导致上面的错误,但从技术上讲,这应该是可行的.
使用 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,因此编译器必须将整数写入堆栈上的变量,并且必须从变量中读取结果。