У ветвей PowerPC есть только 24 бита для смещения цели, поэтому, если текстовый раздел становится слишком большим, ветки на одном конце не смогут достичь целей на другом. Там более длинная последовательность инструкций, которые могут достигать цели дальше (смещение составляет 32 бита вместо 24), но GCC не использует его по умолчанию, если вы не передадите ему опцию -mlongcall
. Однако даже при включенной опции 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, [email protected]
addi r9, r9, [email protected]
mtctr r9
bctrl
bl _Znwj
Первые четыре команды являются длинным вызовом foo()
, как и ожидалось, но вызов operator new
не изменяется. Вызовы для случайных функций libc и libstdС++ преобразуются в длинные вызовы, как ожидалось. Почему вызовы operator new
и operator delete
все еще заканчиваются как инструкции bl
? Есть ли способ заставить GCC сделать их длинными вызовами? Я использую GCC 4.7.2 на 64-битной машине PowerPC Fedora (хотя я строю 32-разрядную версию)