PowerPC ブランチはターゲット オフセットに 24 ビットしか使用できないため、テキスト セクションが大きくなりすぎると、一方の端のブランチが他方のターゲットに到達できなくなります。より遠くのターゲットに到達できる長い命令シーケンスがあります (オフセットは 24 ビットではなく 32 ビットです) が、-mlongcall
オプションを渡さない限り、GCC はデフォルトでそれを使用しません。ただし、このオプションをオンにしても、GCC は特定の関数の短い呼び出しを生成しますoperator new
。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)
オプションを指定して GCC を実行すると、-mlongcall
以下が生成されます。
lis r9, _Z3foov@ha
addi r9, r9, _Z3foov@l
mtctr r9
bctrl
bl _Znwj
foo()
予想どおり、最初の 4 つの命令は への長い呼び出しですが、への呼び出しoperator new
は変更されていません。ランダムな libc および libstdc++ 関数への呼び出しはすべて、予想どおり長い呼び出しに変換されます。operator new
doとcall がまだ指示operator delete
として終わるのはなぜですか? bl
GCCに長い呼び出しを強制する方法はありますか? 64 ビットの PowerPC Fedora マシンで GCC 4.7.2 を使用しています (ただし、32 ビットをビルドしています)。