PowerPC 分支只有 24 位可用于目标偏移量,因此如果文本部分变得太大,一端的分支将无法到达另一端的目标。有更长的指令序列可以到达更远的目标(偏移量是 32 位而不是 24 位),但 GCC 默认不使用它,除非您将-mlongcall
选项传递给它。operator new
然而,即使打开了这个选项,GCC 仍然会为某些函数生成短调用,即operator delete
例如,给定以下代码:
extern void foo();
int main(int argc, char** argv) {
foo();
new char;
}
GCC 的正常运行将生成程序集:
bl _Z3foov // void foo()
bl _Znwj // operator new(unsigned int)
-mlongcall
使用该选项运行 GCC 会生成:
lis r9, _Z3foov@ha
addi r9, r9, _Z3foov@l
mtctr r9
bctrl
bl _Znwj
正如预期的那样,前四个指令是对 的长时间调用foo()
,但对 的调用operator new
没有改变。对随机 libc 和 libstdc++ 函数的调用都按预期转换为长调用。为什么operator new
和operator delete
调用仍然作为bl
指令结束?有什么办法可以迫使 GCC 也进行长时间的通话吗?我在 64 位 PowerPC Fedora 机器上使用 GCC 4.7.2(虽然我正在构建 32 位)