【发布时间】:2017-08-19 10:45:41
【问题描述】:
我正在编写C 代码并将其编译为PowerPC 架构。也就是说C 代码包含浮点变量常量,我希望将其放在.text 部分而不是.rodata,因此函数代码是自包含的。
这个问题是在PowerPC,the only way to move a floating point value into a floating point register is by loading it from memory。这是指令集限制。
为了说服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,因此可能的答案将包括which optimization flag causes the floats to be placed in .rodata,因为从-O1开始,这正在发生吗?
最好的情况是我可以在代码中“正常”使用浮点数以及最大优化,并且它们根本不会放在 .rodata 中。
我想GCC 可能做的是通过混合数据和代码将浮点常量放在代码之间,从该位置加载到浮点寄存器并继续。我相信这可以手动编写,但如何让GCC 做到这一点?强制每个变量的属性会导致上面的错误,但从技术上讲这应该是可行的。
【问题讨论】:
-
POWER ABI 有点搞笑;请参阅
man gcc和 POWER-msdata选项。在 GCC 开发邮件列表中,有人提到将-G 0添加到 gcc 选项“修复”此问题;你能试试这个并报告这是否让 gcc 做你喜欢的事情吗? -
为什么要“自包含”代码?
-
@fuz 我想优化缓存使用,减少 TLB 未命中,缓存错误等?
-
@fuz 也许代码以非标准方式使用(例如注入微控制器 RAM 并在那里执行的代码),这需要绝对与位置无关。
-
@AnttiHaapala:现代 CPU(包括 x86 和 PowerPC)具有分离的 L1 缓存和单独的第一级 TLB,用于指令和数据。但是,从当前正在执行的同一缓存行加载数据可能会在 L2 中命中。 (除非您的 L2 是 L1D 独有的,例如 AMD Bulldozer 系列)。 dTLB 也可能会丢失。在 x86 上,L2 TLB 保存从 iTLB 和 dTLB 中驱逐的条目是很常见的,但是当前页面的条目将在 iTLB 中,并且没有理由期望它在 L2 TLB 中,因此 dTLB 很可能会触发页面浏览。
标签: c gcc assembly floating-point powerpc