Вперед Назад Содержание

6. Target Description Macros

В дополнение к файлу 'MACHINE.md', машинное описание включает файл С-заголовка, которому традиционно дано имя 'MACHINE.h'. Этот файл заголовка определяет многочисленные макрокоманды, которые передают информацию относительно целевой машины, не вписывающеюся в схему файла `.md'. Файл 'tm.h' должен быть связан с 'MACHINE.h'. Файл заголовка 'config.h' включает 'tm.h' и большинство исходных файлов транслятора так же включают 'config.h'.

6.1 Управление Драйвером Трансляции " gcc "

Вы можете управлять драйвером трансляции.

" SWITCH_TAKES_ARG (CHAR) "

Выражение C, которое определяет, имеет ли опция " -CHAR " параметры. Значение должно быть числом параметров опции, и нулем, если опций несколько.

По умолчанию эта макрокоманда определяется, чтобы правильно обрабатывать стандартные опции. Вы не должны определять ее, если Вы не собираетесь добавлять дополнительные опции, которые имеют параметры.

" WORD_SWITCH_TAKES_ARG (NAME) "

Выражение C, которое определяет, имеет ли опция " -NAME " параметры. Значение должно быть числом параметров опции, и нулем, если опций несколько. Эта макрокоманда скорее, чем " SWITCH_TAKES_ARG ", используется для многосимвольных имен опции.

По умолчанию, эта макрокоманда определена как " DEFAULT_WORD_SWITCH_TAKES_ARG ", которая правильно обрабатывает стандартные опции. Вы не должны не определять " WORD_SWITCH_TAKES_ARG ", если Вы не собираетесь добавлять дополнительные опции, которые имеют параметры. Всякое переопределение должно вызывать " DEFAULT_WORD_SWITCH_TAKES_ARG " и затем проверять дополнительные опции.

" SWITCHES_NEED_SPACES "

Строковое выражение C, которое является непустым, если компоновщику требуется пробел между опцией " -L " или " -o " и ее параметром.

Если эта макрокоманда не определена, значение по умолчанию - 0.

" CPP_SPEC "

Строковая константа C, которая сообщает программе драйвера GNU CC опции для передачи CPP. Она может также указывать, как транслировать опции, которые Вы задали GNU CC, в опции GNU CC для передачи CPP.

Не определяйте эту макрокоманду, если не требуется ничего делать.

" NO_BUILTIN_SIZE_TYPE "

Если эта макрокоманда определена, препроцессор не будет определять встроенную макрокоманду " __SIZE_TYPE__ ". Макрокоманда " __SIZE_TYPE__ " будет определена вместо этого " CPP_SPEC ".

Она должна быть определена, если " SIZE_TYPE " зависит от машинно-зависимый флагов, которые не доступны для препроцессора. Иначе, она не должна быть определена.

" NO_BUILTIN_PTRDIFF_TYPE "

Если эта макрокоманда определена, препроцессор не будет определять встроенную макрокоманду " __PTRDIFF_TYPE__ ". Макрокоманда " __PTRDIFF_TYPE__ " будет определена вместо этого " CPP_SPEC ".

Она должна быть определена, если " PTRDIFF_TYPE " зависит от машинно-зависимый флагов, которые не доступны для препроцессора. Иначе, она не должна быть определена.

" SIGNED_CHAR_SPEC "

Строковая константа C, которая сообщает программе драйвера GNU CC опции для передачи CPP. По умолчанию эта макрокоманда определена, чтобы передать опцию " -D__CHAR_UNSIGNED__ " CPP, если " char " будет обрабатываться " cc1 " как " unsigned char ".

Не определяйте эту макрокоманду, если Вам не нужно перекрывать определение по умолчанию.

" CC1_SPEC "

Строковая константа C, которая сообщает программе драйвера GNU CC опции для передачи " cc1 ". Она может также определять, как транслировать опции, которые Вы задали GNU CC, в опции для GNU CC для передачи " cc1 ".

Не определяйте эту макрокоманду, если не требуется ничего делать.

" CC1PLUS_SPEC "

Строковая константа C, которая сообщает программе драйвера GNU CC опции для передачи " cc1plus ". Она может также определять, как транслировать опции, которые Вы задали GNU CC, в опции для GNU CC для передачи " cc1plus ".

Не определяйте эту макрокоманду, если не требуется ничего делать.

" ASM_SPEC "

Строковая константа C, которая сообщает программе драйвера GNU CC опции для передачи ассемблеру. Она может также определять, как транслировать которые Вы задали GNU CC, в опции для GNU CC для передачи ассемблеру. Для примера см. файл " sun3.h ".

Не определяйте эту макрокоманду, если не требуется ничего делать.

" ASM_FINAL_SPEC "

Строковая константа C, которая сообщает программе драйвера GNU CC, как выполнять программы, которые производят чистку после нормального ассемблера. Обычно это не является необходимым. Для примера см. файл " mips.h ".

Не определяйте эту макрокоманду, если не требуется ничего делать.

" LINK_SPEC "

Строковая константа C, которая сообщает программе драйвера GNU CC опции для передачи компоновщику. Она может также определять, как транслировать опции, которые Вы задали GNU CC, в опции для GNU CC для передачи компоновщику.

Не определяйте эту макрокоманду, если не требуется ничего делать.

" LIB_SPEC "

Другая строковая константа C, используемая подобно " LINK_SPEC ". Различие заключается в том, что " LIB_SPEC " используется в конце команды, задаваемой компоновщику.

Если эта макрокоманда не определена, значение по умолчанию - то, при условии, что загрузки Стандарт C библиотека из обычного места. См. " gcc.c ".

" LIBGCC_SPEC "

Другая строковая константа C, которая сообщает программе драйвера GNU CC, как и когда помещать ссылку на " libgcc.a " в командную строку компоновщика. Эта константа помещается и до, и после значения " LIB_SPEC ".

Если эта макрокоманда не определена, драйвер GNU CC по умолчанию передает строку " -lgcc " компоновщику, если опция " -shared " не определена.

" STARTFILE_SPEC "

Другая строковая константа C, используемая подобно " LINK_SPEC ". Различие заключается в том, что " STARTFILE_SPEC " используется в самом начале команды, задаваемой компоновщику.

Если эта макрокоманда не определена, по умолчанию стандартный файл запуска C загружается из обычного места. См. " gcc.c ".

" ENDFILE_SPEC "

Другая строковая константа C, используемая подобно " LINK_SPEC ". Различие заключается в том, что " ENDFILE_SPEC " используется в самом конце команды, задаваемой компоновщику.

Не определяйте эту макрокоманду, если не требуется ничего делать.

" LINK_LIBGCC_SPECIAL "

Определите эту макрокоманду, если программа драйвера сама должна искать библиотеку " libgcc.a " и не должна передавать опции " -L " компоновщику. Если Вы не определяете эту макрокоманду, программа драйвера передаст параметр " -lgcc ", чтобы компоновщик произвел поиск и передаст ему опции " -L ".

" LINK_LIBGCC_SPECIAL_1 "

Определите эту макрокоманду, если программа драйвера сама должна искать библиотеку " libgcc.a ". Если Вы не определяете эту макрокоманду, программа драйвера передаст параметр " -lgcc ", чтобы компоновщик произвел поиск. Эта макрокоманда подобна " LINK_LIBGCC_SPECIAL ", за исключением того, что она не воздействуют на " -L " опции.

" MULTILIB_DEFAULTS "

Определите эту макрокоманду как выражение C для инициализатора массива строк, чтобы сообщить программе драйвера, какие опции являются значениями по умолчанию в данной ситуации и, таким образом, не нуждаются в специальной обработке при использовании " MULTILIB_OPTIONS ".

Не определяйте эту макрокоманду, если " MULTILIB_OPTIONS " не определен во фрагменте makefile адресата или если ни одна из опций, перечисленных в " MULTILIB_OPTIONS ", не имеет значения по умолчанию. * См.: Фрагмент адресата::.

" RELATIVE_PREFIX_NOT_LINKDIR "

Определите эту макрокоманду, чтобы сообщить " gcc " что он должен транслировать префикс " -B " в опцию " -L " компоновщика, если префикс указывает абсолютное имя файла.

" STANDARD_EXEC_PREFIX "

Определите эту макрокоманду как строковую константу C, если Вы хотите изменить стандартный выбор " /usr/local/lib/gcc-lib/ " как префикс по умолчанию при поиске исполняемых файлов транслятора.

" MD_EXEC_PREFIX "

Если определено, эта макрокоманда - дополнительный префикс после " STANDARD_EXEC_PREFIX ". " MD_EXEC_PREFIX " не ищется, если используется опция " -b " или транслятор построен как перекрестный.

" STANDARD_STARTFILE_PREFIX "

Определите эту макрокоманду как строковую константу C, если Вы хотите изменить стандартный выбор " /usr/local/lib/ " как префикс по умолчанию, чтобы при поиске файлов запуска типа " crt0.o ".

" MD_STARTFILE_PREFIX "

Если определена, эта макрокоманда обеспечивает дополнительный префикс после стандартных префиксов. " MD_EXEC_PREFIX " не ищется, если используется опция " -b " или транслятор построен как перекрестный.

" MD_STARTFILE_PREFIX_1 "

Если определена, эта макрокоманда обеспечивает еще один префикс после стандартных префиксов. Она не ищется, если используется опция " -b " или транслятор построен как перекрестный (кросс-транслятор).

" INIT_ENVIRONMENT "

Определите эту макрокоманду как строковую константу C, если Вы хотите установить переменные среды для программ, вызываемых драйвером, таких, как ассемблер и загрузчик. Драйвер передает значение этой макрокоманды " putenv ", чтобы инициализировать необходимые переменные среды.

" LOCAL_INCLUDE_DIR "

Определите эту макрокоманду как строковую константу C, если Вы хотите изменить стандартный выбор " /usr/local/include " как префикс по умолчанию при поиске локальных файлов заголовка. " LOCAL_INCLUDE_DIR " идет перед " SYSTEM_INCLUDE_DIR " в порядке поиска.

Перекрестные трансляторы не используют эту макрокоманду и не ищут " /usr/local/include " или его замену.

" SYSTEM_INCLUDE_DIR "

Определите эту макрокоманду как строковую константу C, если Вы хотите указать свой каталог для поиска файлов заголовка перед стандартным каталогом. " SYSTEM_INCLUDE_DIR " идет перед " STANDARD_INCLUDE_DIR " в порядке поиска.

Перекрестные трансляторы не используют эту макрокоманду и не ищут указанный каталог.

" STANDARD_INCLUDE_DIR "

Определите эту макрокоманду как строковую константу C, если Вы хотите изменить стандартный выбор " /usr/include " как префикс по умолчанию при поиске файлов заголовка.

Перекрестные трансляторы не используют эту макрокоманду и не ищут " /usr/include " или его замену.

" INCLUDE_DEFAULTS "

Определите эту макрокоманду, если Вы хотите полностью изменить значение по умолчанию пути поиска включаемых файлов. Заданный по умолчанию путь поиска включает " GCC_INCLUDE_DIR ", " LOCAL_INCLUDE_DIR ", " SYSTEM_INCLUDE_DIR ", " GPLUSPLUS_INCLUDE_DIR ", и " STANDARD_INCLUDE_DIR ". Кроме того, " GPLUSPLUS_INCLUDE_DIR " и " GCC_INCLUDE_DIR " определяются автоматически " Makefile " и указывают частные области поиска для GCC. Каталог " GPLUSPLUS_INCLUDE_DIR " используется только для C++ программ.

Определение должно быть инициализаторос для массива структур. Каждый элемент массива должен иметь два элемента: имя каталога ( строковая константа) и флаг; для C ++ - только каталоги. Массив должен заканчиваться нулевым элементом. Вот, например, определение, используемое для VMS:

           #define INCLUDE_DEFAULTS \
           {                                       \
             { "GNU_GXX_INCLUDE:", 1},             \
             { "GNU_CC_INCLUDE:", 0},              \
             { "SYS$SYSROOT:[SYSLIB.]", 0},        \
             { ".", 0},                            \
             { 0, 0}                               \
           }
Вот порядок префиксов для исполняемых файлов:
  1. Любые префиксы, определенные пользователем с " -B ".
  2. Переменная " GCC_EXEC_PREFIX ", если есть.
  3. Каталоги, указанные в переменной среды " COMPILER_PATH ".
  4. Макрокоманда " STANDARD_EXEC_PREFIX ".
  5. " /usr/lib/gcc/ ".
  6. Макрокоманда " MD_EXEC_PREFIX ", если есть.
Вот порядок префиксов для стартовых файлов:
  1. Любые префиксы, определенные пользователем с " -B ".
  2. Системная переменная " GCC_EXEC_PREFIX ", если есть.
  3. Каталоги, указанные в переменной среды " LIBRARY_PATH " (только "местная", кросс-трансляторы не используют ее).
  4. Макрокоманда " STANDARD_EXEC_PREFIX ".
  5. " /usr/lib/gcc/ ".
  6. Макрокоманда " MD_EXEC_PREFIX ", если есть.
  7. Макрокоманда " MD_STARTFILE_PREFIX ", если есть.
  8. Макрокоманда " STANDARD_STARTFILE_PREFIX ".
  9. " /lib/ ".
  10. " /usr/lib/ ".

6.2 Целевая Спецификация времени выполнения

Вот целевые спецификации времени выполнения.

" CPP_PREDEFINES "

Определите ее строковой константой, содержащей " -D " опции для определения предопределенных макрокоманд, которые идентифицируют эту машину и эту систему. Эти макрокоманды будут предопределенными, если не указана опция " -ansi ".

Кроме того, предопределен параллельный набор макрокоманд, чьи имена получаются добавлением " __ " в начале и в конце. Эти " __ " макрокоманды разрешаются ANSI стандартом, так что они предопределены независимо от того, указано ли " -ansi ".

Например, на Sun можно использовать следующее значение:

           " -Dmc68000 -Dsun -Dunix "
Результат должен определять макрокоманды " __ mc68000 __ ", " __ sun __ " и " __ unix __ " в любом случае, и макрокоманды " mc68000 ", " sun " и " unix ", если не указано " -ansi ".

" extern int target_flags; "

Это объявление должно присутствовать.

" TARGET_ ... "

Этот набор макрокоманд предназначен для того, чтобы позволить параметрам команд транслятора включать или отключать использование опциональных особенностей целевой машины. Например, одно машинное описание служит и для 68000, и для 68020; параметр команды сообщает транслятору, использовать ли ему команды, имеющиеся только на 68020 или нет. Этот параметр команды работает посредством макрокоманды " TARGET_68020 " которая проверяет бит в " target_flags ".

Определите макрокоманду " TARGET_FEATURENAME " для каждой такой опции. Ее определение должно проверять бит в " target_flags "; например:

           *define TARGET_68020 (target_flags & 1)
Одним из мест, где используются эти макрокоманды, являются условные выражения образцов команд. Заметьте, как часто " TARGET_68020 " появляется в файле машинного описания 68000, " m68k.md ". Другое место их использования - это определение других макрокоманд в файле" MACHINE.h ".

" TARGET_SWITCHES "

Эта макрокоманда определяет имена опций команды, чтобы устанавливать и очищать биты в " target_flags ". Определение - инициализатор с подгруппировкой для каждой опции команды.

Каждая подгруппировка содержит строковую константу, которая определяет имя опции, и число, которое содержит биты для установки в " target_flags ". Отрицательное число указывает на очистку битов; противоположное ему число указывает, какие биты очищать. Фактическое имя опции получается добавлением " -m " к указанному имени.

Одна из подгруппировок должна иметь пустую строку. Число в этой группировке - значение по умолчанию для " target_flags ". Любое действие опций начинается с этим значением.

Вот пример, который определяет " -m68000 " и " -m68020 " с противоположными значениями и выбирает последний как значение по умолчанию:

           #define TARGET_SWITCHES \
             { { "68020", 1},      \
               { "68000", -1},     \
               { "", 1}}
" TARGET_OPTIONS "

Эта макрокоманда аналогична " TARGET_SWITCHES ", но определяет имена опций команды, которые имеют значения. Ее определение - инициализатор с подгруппировкой для каждой опции команды.

Каждая подгруппировка содержит строковую константу, которая определяет фиксированную часть имени опции и адрес переменной. Переменная типа " char * " устанавливается на переменную часть данной опции, если фиксированная часть соответствует. Фактическое имя опции получается добавлением " -m " к указанному имени.

Вот пример, который определяет " -mshort-data-NUMBER ". Если данная опция - " -mshort-data-512 ", переменная " m88k_short_data " будет установлена на строку " "512" ".

           extern char *m88k_short_data;
           #define TARGET_OPTIONS \
            { { "short-data-", &m88k_short_data } }
" TARGET_VERSION "

Эта макрокоманда - оператор C, выводящий на " stderr " строку, описывающую конкретный выбор машинного описания. Каждое машинное описание должно определять " TARGET_VERSION ". Например:

           #ifdef MOTOROLA
           #define TARGET_VERSION \
             fprintf (stderr, " (68k, Motorola syntax)");
           #else
           #define TARGET_VERSION \
             fprintf (stderr, " (68k, MIT syntax)");
           #endif
" OVERRIDE_OPTIONS "

Иногда некоторые комбинации опций команды не имеют смысла на конкретной целевой машине. Вы можете определить макрокоманду " OVERRIDE_OPTIONS ", чтобы принять это во внимание. Эта макрокоманда, если она определена, выполняется только однажды - сразу после того, как все опции команды будут проанализированы.

Не используйте эту макрокоманду, чтобы включить различные дополнительные оптимизации для " -O ". Для этого есть " OPTIMIZATION_OPTIONS ".

" OPTIMIZATION_OPTIONS (LEVEL) "

Некоторые машины могут хотеть изменить то, какие оптимизации выполняются для различных уровней оптимизации. Эта макрокоманда, если она определена, выполняется однажды - сразу после того, как уровень оптимизации определен и перед тем, как остаток опций команды проанализируется. Набор значений в этой макрокоманде используется по умолчанию для других опций командной строки.

LEVEL - заданный уровень оптимизации; 2, если указано " -O2 ", 1, если указано " -O " , и 0, если ничего не указано.

Вы не должны использовать эту макрокоманду, для изменения опций, которые не являются машинно-специфическими. Они должны одинаково зависеть от уровня оптимизации на всех поддериваемых машинах. Используйте эту макрокоманду для разрешения машинно-специфических оптимизаций.

* Не используйте " write_symbols " в этой макрокоманде! * Предполагается, что отладочные опции не изменяют сгенерированный код.

" CAN_DEBUG_WITHOUT_FP "

Определите эту макрокоманду, если отладка может выполняться даже без указателя кадра. Если эта макрокоманда определена, GNU CC будет включать опцию " -fomit-frame-pointer " всякий раз, когда указано " -O ".

6.3 Распределение Памяти

Обратите внимание, что определения макрокоманд в этой таблице, которые являются размерами или выравниваниями, измеряемыми в битах, не обязаны быть постоянными. Они Это могут быть выражения C, который ссылаются на статические переменные, такие как "target_flags ". См.: Адресат времени выполнения::.

" BITS_BIG_ENDIAN "

Задайте этому макросу значение 1, если старший бит в байте имеет наименьший номер; иначе задайте ему значение 0. Это означает, что побитовые команды отсчитывают биты от старшего. Если машина не имеет побитовых команды, то значение этого макроса не играет роли. Этот макрос не обязан быть константой.

Этот макрос не воздействует на способ упаковки полей структур, байтами или словами; этим управляет " BYTES_BIG_ENDIAN ".

" BYTES_BIG_ENDIAN "

Задайте этому макросу значение 1, если старший байт в слове имеет меньший номер. Этот макрос не обязан быть константой.

" WORDS_BIG_ENDIAN "

Задайте этому макросу значение 1 если в объекте из нескольких слов старшее слово имеет наименьший номер. Это применяется и к ячейкам памяти, и к регистрам; GNU CC всегда считает,что порядок слов в памяти такой же, как и в регистрах. Этот макрос не обязан быть константой.

" LIBGCC2_WORDS_BIG_ENDIAN "

Определите эту макрокоманду, если WORDS_BIG_ENDIAN - не константа. Это должно быть постоянное значение с тем же самым значением, что и WORDS_BIG_ENDIAN, которое будет использоваться только при компиляции libgcc2.c. Обычно значение устанавливается, основываясь на определениях препроцессора.

" FLOAT_WORDS_BIG_ENDIAN "

Задайте этому макросу значение 1, если числа с плавающей точкой " DFmode ", " XFmode " или " TFmode " сохраняются в памяти со словом, содержащим знаковый разряд по наименьшему адресу; иначе задайте ему значение 0. Этот макрос не обязан быть константой.

Вы не должны определять этот макрос, если упорядочение такое же, как для целых чисел из нескольких слов.

" BITS_PER_UNIT "

Задайте этому макросу значение, равное числу битов в минимальной адресуемой ячейке памяти (байте); обычно 8.

" BITS_PER_WORD "

Число битов в слове; обычно 32.

" MAX_BITS_PER_WORD "

Максимальное число битов в слове. Если это неопределено, значение по умолчанию - " BITS_PER_WORD ". Иначе, это - константа, равная наибольшему значению, которое может иметь " BITS_PER_WORD " во время выполнения.

" UNITS_PER_WORD "

Число байтов в слове; обычно 4.

" MIN_UNITS_PER_WORD "

Минимальное число байтов в слове. Если это неопределено, значение по умолчанию - " UNITS_PER_WORD ". Иначе, это - константа, равная наименьшему значению, которое может иметь " UNITS_PER_WORD " во время выполнения.

" POINTER_SIZE "

Длина указателя в битах. Вы не должны указывать значение, большее, чем длина " Pmode ". Если оно не равно ширине " Pmode ", Вы должны определить " POINTERS_EXTEND_UNSIGNED ".

" POINTERS_EXTEND_UNSIGNED "

Выражение C, чье значение отлично от нуля, если указатели, которые должны быть расширены от длины " POINTER_SIZE " до длины " Pmode ", следует расширять знаком, и ноль, если их следует расширять нулем.

Вы не должны определять эту макрокоманду, если " POINTER_SIZE " равно длине " Pmode ".

" PROMOTE_MODE (M, UNSIGNEDP, TYPE) "

Макрокоманда для модификации M и UNSIGNEDP, когда объект, чей тип - TYPE и который имеет указанный тип и знаковость, должен быть сохранен в регистре. Эта макрокоманда вызывается только тогда, когда TYPE - скалярный тип.

На большинстве RISC машин, которые имеют операции для манипуляции только полными регистрами, определите эту макрокоманду, чтобы установить M в " word_mode ", если M - целочисленный тип, более узкий, чем " BITS_PER_WORD ". В большинстве случаев расширяться должны только целочисленные типы, потому что большая точность широких операций с плавающей точкой обычно дороже, чем для их более узких аналогов.

Для большинства машин макроопределение не изменяет UNSIGNEDP. Однако некоторые машины имеют команды, которые предпочтительно обрабатывают некоторые как знаковые, так и беззнаковые типы. Например, на DEC Alpha 32-битные команды загрузки из памяти и 32-битные команды сложения расширяются знаком до 64 бит. На таких машинах устанавливайте UNSIGNEDP в зависимости от того, какой вид расширения более эффективен.

Не определяйте эту макрокоманду, если она не должна изменять M.

" PROMOTE_FUNCTION_ARGS "

Определите эту макрокоманду, если продвижение, описанное " PROMOTE_MODE ", должно быть также сделано для исходящих параметров функции.

" PROMOTE_FUNCTION_RETURN "

Определите эту макрокоманду, если продвижение, описанное " PROMOTE_MODE ", должно быть также сделано для возвращаемых значений функции.

Если эта макрокоманда определена, " FUNCTION_VALUE " должна выполнить те же самые продвижения, что и сделанные " PROMOTE_MODE ".

" PROMOTE_FOR_CALL_ONLY "

Определите эту макрокоманду, если продвижение, описанное " PROMOTE_MODE " должно быть выполнено *только* для исходящих параметров функции или возвращаемых функцией значений, как указано " PROMOTE_FUNCTION_ARGS " и " PROMOTE_FUNCTION_RETURN ", соответственно.

" PARM_BOUNDARY "

Нормальное выравнивание, требуемое для параметров функции в стеке, в битах. Все параметры стека получают по крайней мере это выравнивание независимо от типа данных. На большинстве машин оно совпадает с размером целого числа.

" STACK_BOUNDARY "

Определите эту макрокоманду, если Вы хотите сохранить некоторое выравнивание для указателя стека. Определение - выражение C для желаемого выравнивания (измеряемое в битах).

Если " PUSH_ROUNDING " не определено, стек будет всегда выравниваться на указанную границу. Если " PUSH_ROUNDING " определено и определяет менее строгое выравнивание, чем " STACK_BOUNDARY ", выравнивание может быть потеряно на короткое время при записи параметров в стек.

" FUNCTION_BOUNDARY "

Выравнивание, требуемое для точки входа в функцию, в битах.

" BIGGEST_ALIGNMENT "

Самое большое выравнивание, которое может потребоваться какому-либо типу данных на этой машине, в битах.

" BIGGEST_FIELD_ALIGNMENT "

Самое большое выравнивание, которое может потребоваться какому-либо полю структуры на этой машине, в битах. Если определено, оно отменяет " BIGGEST_ALIGNMENT " для полей структур.

" MAX_OFILE_ALIGNMENT "

Самое большое выравнивание, поддерживаемое форматом объектного файла на этой машине. Используйте эту макрокоманду, чтобы ограничить выравнивание, которое может быть определено с использованием конструкции " __ attribute __ ((aligned (N))) ". Если не определено, значением по умолчанию является " BIGGEST_ALIGNMENT ".

" DATA_ALIGNMENT (TYPE, BASIC-ALIGN) "

Если определено, выражение C, чтобы вычислить выравнивание для статической переменной. TYPE - тип данных, а BASIC-ALIGN - выравнивание, которое объект имел бы без этой макрокоманды. Значение этой макрокоманды используется вместо этого выравнивания для выравнивания объекта.

Если эта макрокоманда не определена, то используется BASIC-ALIGN.

Одно из применений этой макрокоманды заключается в увеличении выравнивания данных среднего размера, чтобы все они поместились на меньшем количестве строк кэша. Другое - выравнивать символьные массивы на границу слова, чтобы вызовы " strcpy ", копирующие константы в символьные массивы, можно было сделать встроенными.

" CONSTANT_ALIGNMENT (CONSTANT, BASIC-ALIGN) "

Если определено, выражение C для вычисления выравнивания для константы, которая помещается в память. CONSTANT - константа, а BASIC-ALIGN - выравнивание, которое объект имел бы без этой макрокоманды. Значение этой макрокоманды используется вместо этого выравнивания для выравнивания объекта.

Если эта макрокоманда не определена, то используется BASIC-ALIGN.

Типичным использованием этой макрокоманды является увеличение выравнивание для строковой константы до выравнивания на границу слова, так, чтобы вызовы " strcpy ", копирующие константы в символьные массивы, можно было сделать встроенными.

" EMPTY_FIELD_BOUNDARY "

Выравнивание в битах, задаваемое битовому полю структуры, которое следует за пустым полем, типа " int: 0; ".

Обратите внимание, что " PCC_BITFIELD_TYPE_MATTERS " также воздействует на выравнивание, которое получается после пустого поля.

" STRUCTURE_SIZE_BOUNDARY "

Число битов, которым должен быть кратным размер любой структуры или объединения. Размер каждой структуры и объединения округляется вверх до его кратного.

Если Вы не определяете эту макрокоманду, значение по умолчанию совпадает с " BITS_PER_UNIT ".

" STRICT_ALIGNMENT "

Задайте этому макросу значение 1, если команды не будут работать, в случае если заданные данные не будут иметь номинального выравнивания. Если команды в этом случае просто будут работать медленнее, задайте этому макросу значение 0.

" PCC_BITFIELD_TYPE_MATTERS "

Определите это, если Вы хотите имитировать способ многих других трансляторов C обработки выравнивания битовых полей и структур, которые содержат их.

Поведение состоит в том, что тип, заданный для битового поля (" int ", " short " или другой целочисленный тип) налагает выравнивание для всей структуры, как будто структура действительно содержит обычное поле этого типа. Кроме того, битовое поле помещается внутри структуры так, чтобы это поместилось бы внутри такого поля, не пересекая его границы.

Таким образом, на большинстве машин битовое поле, чей тип описан как " int " не будет пересекать границу четырех байт, и вынудит выравнивание на границу четырех байт для целой структуры. (Используемое выравнивание может быть не четыре байта; этим управляют другие параметры выравнивания.)

Если макрокоманда определена, определение должно быть выражением C; значение выражения, отличное от нуля, допускает такое поведение.

Обратите внимание, что, если эта макрокоманда не определена, или ее значение - ноль, некоторые битовые поля могут пересекать более чем одну границу выравнивания. Транслятор может поддерживать такие ссылки, если имеются insns " insv ", " extv " и " extzv ", которые могут непосредственно ссылаться на память.

Другой известный способ работы с битовыми полями состоит в том, чтобы определить " STRUCTURE_SIZE_BOUNDARY " такого размера, как " BIGGEST_ALIGNMENT ". Тогда к каждой структуре можно будет обращаться полными словами.

Если машина не имеет команд для работы с битовыми полями или если Вы определяете " STRUCTURE_SIZE_BOUNDARY " этим путем, Вы должны задать " PCC_BITFIELD_TYPE_MATTERS " значение, отличное от нуля.

Если ваша цель состоит в том, чтобы заставить GNU CC использовать те же самые соглашения для расположения битовых полей, которые используются другим транслятором, вот как исследовать то, что делает другой транслятор. Скомпилируйте и выполните вот эту программу:

           struct foo1
           {
             char x;
             char :0;
             char y;
           };

           struct foo2
           {
             char x;
             int :0;
             char y;
           };

           main ()
           {
             printf ("Size of foo1 is %d\n",
                     sizeof (struct foo1));
             printf ("Size of foo2 is %d\n",
                     sizeof (struct foo2));
             exit (0);
           }
Если она напечатает 2 и 5, то транслятор ведет себя так же, как Вы получили бы, определив " PCC_BITFIELD_TYPE_MATTERS ".

" BITFIELD_NBYTES_LIMITED "

Подобно PCC_BITFIELD_TYPE_MATTERS, за исключением того, что эффект ограничивается выравниванием битовых полей внутри структуры.

" ROUND_TYPE_SIZE (STRUCT, SIZE, ALIGN) "

Определите эту макрокоманду как выражение для полного размера структуры (задаваемой STRUCT как узел дерева), если вычисленный размер полей - SIZE, а выравнивание - ALIGN.

Значение по умолчанию - округление SIZE вверх до числа, кратного ALIGN.

" ROUND_TYPE_ALIGN (STRUCT, COMPUTED, SPECIFIED) "

Определите эту макрокоманду как выражение для выравнивания структуры (задаваемой STRUCT как узел дерева), если выравнивание, вычисленное обычным путем - COMPUTED, а выравнивание, явно указанное - SPECIFIED.

Значением по умолчанию является SPECIFIED, если оно больше; иначе используется меньшее из COMPUTED и " BIGGEST_ALIGNMENT "

" MAX_FIXED_MODE_SIZE "

Целочисленное выражение для размера в битах самого большого целого числа машинного типа, который должен фактически использоваться. Все целочисленные машинные типы этого размера или меньше могут использоваться для структур и объединений с соответствующими размерами. Если эта макрокоманда не определена, предполагается " GET_MODE_BITSIZE (DImode) ".

" CHECK_FLOAT_VALUE (MODE, VALUE, OVERFLOW) "

Оператор C для проверки допустимости значения VALUE (типа " double ") для типа MODE. Это означает, что Вы проверяете, входит ли VALUE в диапазон возможных значений для типа MODE на этой целевой машине. Режим MODE - всегда тип класса " MODE_FLOAT ". OVERFLOW отлично от нуля, если значение оказывается вне диапазона.

Если VALUE недопустимо или если OVERFLOW отлично от нуля, Вы должны установить OVERFLOW в 1 и затем присвоить какое-нибудь допустимое значение VALUE. Прохождение недопустимого значения через транслятор может произвести неправильный код ассемблера, который может даже повлечь аварию ассемблеров Unix.

Эта макрокоманда не обязана определяться, если в ней нет потребности.

" TARGET_FLOAT_FORMAT "

Код, отличающий формат с плавающей точкой на целевой машине. Имеется три определенных значения:

" IEEE_FLOAT_FORMAT "

Этот код указывает формат с плавающей точкой IEEE. Это - значение по умолчанию; нет необходимости определять эту макрокоманду, если формат - IEEE.

" VAX_FLOAT_FORMAT "

Этот код указывает специфический формат, используемый на Vax.

" UNKNOWN_FLOAT_FORMAT "

Этот код указывает любой другой формат.

Значение этой макрокоманды сравнивается с " HOST_FLOAT_FORMAT " (* См.: Конфигурация::.), чтобы определить, имеет ли целевая машина тот же самый формат, что и главная машина. Если на поддерживаемых машинах фактически используются какие-то другие форматы, для них должны быть определены новые коды.

Порядок слов, составляющих значение с плавающей запятой, записанное в памяти, управляется " FLOAT_WORDS_BIG_ENDIAN " для целевой машина и " HOST_FLOAT_WORDS_BIG_ENDIAN " для главной ЭВМ.

6.4 Формат Исходных Типов Данных Языка

Эти макрокоманды определяют размеры и другие характеристики стандартных базисных типов данных, используемых в компилируемых программах. В отличие от макрокоманд предыдущего раздела, они обращаются скорее к специфическим особенностям C и родственных языков, чем к фундаментальным аспектам формата хранения данных.

" INT_TYPE_SIZE "

Выражение C для размера в битах типа " int " на целевой машине. Если Вы не определяете его, значение по умолчанию - одно слово.

" MAX_INT_TYPE_SIZE "

Максимальное число для размера в битах типа " int " на целевой машине. Если оно не определено, значение по умолчанию - " INT_TYPE_SIZE ". Иначе, это - постоянное значение, которое является самым большим значением, какое " INT_TYPE_SIZE " может иметь во время выполнения программы. Оно используется в " cpp ".

" SHORT_TYPE_SIZE "

Выражение C для размера в битах типа " short " на целевой машине. Если Вы не определяете его, значение по умолчанию - половина слова. (Если оно меньше, чем одна адресуемая единица памяти, то оно округляется вверх до ее размера.)

" LONG_TYPE_SIZE "

Выражение C для размера в битах типа " long " на целевой машине. Если Вы не определяете его, значение по умолчанию - одно слово.

" MAX_LONG_TYPE_SIZE "

Максимальное число для размера в битах типа " long " на целевой машине. Если оно не определено, значение по умолчанию - " LONG_TYPE_SIZE ". Иначе, это - постоянное значение, которое является самым большим значением, какое " LONG_TYPE_SIZE " может иметь во время выполнения программы. Оно используется в " cpp ".

" LONG_LONG_TYPE_SIZE "

Выражение C для размера в битах типа " long long " на целевой машине. Если Вы не определяете его, значение по умолчанию - два слова. Если Вы хотите поддерживать GNU Ada на вашей машине, это значение должно быть по крайней мере 64.

" CHAR_TYPE_SIZE "

Выражение C для размера в битах типа " char " на целевой машине. Если Вы не определяете его, значение по умолчанию - четверть слова. (Если оно меньше, чем одна адресуемая единица памяти, то оно округляется вверх до ее размера.)

" MAX_CHAR_TYPE_SIZE "

Максимальное число для размера в битах типа " char " на целевой машине. Если оно не определено, значение по умолчанию - " CHAR_TYPE_SIZE ". Иначе, это - постоянное значение, которое является самым большим значением, какое " CHAR_TYPE_SIZE " может иметь во время выполнения программы. Оно используется в " cpp ".

" FLOAT_TYPE_SIZE "

Выражение C для размера в битах типа " float " на целевой машине. Если Вы не определяете его, значение по умолчанию - одно слово.

" DOUBLE_TYPE_SIZE "

Выражение C для размера в битах типа " double " на целевой машине. Если Вы не определяете его, значение по умолчанию - два слова.

" LONG_DOUBLE_TYPE_SIZE "

Выражение C для размера в битах типа " long double " на целевой машине. Если Вы не определяете его, значение по умолчанию - два слова.

" DEFAULT_SIGNED_CHAR "

Выражение, равное 1 или 0, в зависимости от того, должен тип " char " быть знаковым или беззнаковым по умолчанию. Пользователь всегда может отменить это значение по умолчанию с опциями " -fsigned-char " и " -funsigned-char ".

" DEFAULT_SHORT_ENUMS "

Выражение C, определяющее, давать ли типу " enum " только столько байтов, сколько требуется, чтобы представить диапазон возможных значений этого типа. Значение, отличное от нуля, означает делать это; значение ноля означает, что все " enum " типы должны распределяться подобно " int ".

Если Вы не определяете макрокоманду, значение по умолчанию - 0.

" SIZE_TYPE "

Выражение C для строки, описывающей имя типа данных, используемого для значений размера. Тип " size_t " определяется с использованием содержимого строки.

Строка может содержать больше одного ключевого слова. Если это так, отделяйте их пробелами, и пишите сначала ключевое слово, указывающее длину, затем " unsigned ", если нужно, и в заключение " int ". Строка должна точно соответствовать одному из имен типа данных, определенных в функции " init_decl_processing " в файле " c-decl.c ". Вы не можете опускать " int " или изменять порядок - это приведет к аварии при запуске транслятора.

Если Вы не определяете эту макрокоманду, значение по умолчанию - " "long unsigned int " ".

" PTRDIFF_TYPE "

Выражение C для строки, описывающей имя типа данных, используемого для значений разности двух указателей. Тип " ptrdiff_t " определяется с использованием содержимого строки. См. " SIZE_TYPE " выше для более подробной информации.

Если Вы не определяете эту макрокоманду, значение по умолчанию - " " long int " ".

" WCHAR_TYPE "

Выражение C для строки, описывающей имя типа данных, используемого для длинных символов. Тип " wchar_t " определяется с использованием содержимого строки. См. " SIZE_TYPE " выше для более подробной информации.

Если Вы не определяете эту макрокоманду, значение по умолчанию - " "int" ".

" WCHAR_TYPE_SIZE "

Выражение C для размера в битах типа данных для длинных символов. Это используется в " cpp ", который не может использовать " WCHAR_TYPE ".

" MAX_WCHAR_TYPE_SIZE "

Максимальное число для размера в битах типа данных для длинных символов. Если оно не определено, значение по умолчанию - " WCHAR_TYPE_SIZE ". Иными словами, это - константа, которое является самым большим значением, которое " WCHAR_TYPE_SIZE " может иметь во время выполнения программы. Это используется в " cpp ".

" OBJC_INT_SELECTORS "

Определите эту макрокоманду, если тип селекторов Objective C должен быть " int ".

Если эта макрокоманда не определена, то селекторы должны иметь тип " struct objc_selector * ".

" OBJC_SELECTORS_WITHOUT_LABELS "

Определите эту макрокоманду, если транслятор может группировать все селекторы вместе в вектор и использовать только одну метку в начале вектора. Иными словами, транслятор должен дать каждому селектору собственную ассемблерную метку.

На некоторых машинах важно иметь отдельную метку для каждого селектора, потому что это дает возможность компоновщику устранить двойные селекторы.

" TARGET_BELL "

Константное выражение C для целого значения управляющей последовательности " \a ".

" TARGET_BS "

" TARGET_TAB "

" TARGET_NEWLINE "

Константное выражение C для целых значений управляющих последовательностей " \b ", " \t " и " \n ".

" TARGET_VT "

" TARGET_FF "

" TARGET_CR "

Константное выражение C для целых значений управляющих последовательностей " \v ", " \f " и " \r ".

6.5 Использование Регистров

В этом разделе объясняется, как описывать, какие регистры имеет целевая машина и как (вообще) они могут использоваться.

Описание того, какие регистры могут использовать конкретные команды, сделано с классами регистров; см. *Классы Регистров::. По поводу информации об использовании регистров для обращения к кадру стека, см. *Регистры Кадра::. О передаче значений в регистрах см. *Параметры Регистров::. О возврате значений в регистрах, см. *Возврат скаляров::.

Базовые Характеристики Регистров

Регистры имеют различные характеристики.

" FIRST_PSEUDO_REGISTER "

Число аппаратных регистров, известных транслятору. Они получают номера от 0 до " FIRST_PSEUDO_REGISTER-1 "; таким образом, первому псевдорегистру действительно присваивается номер " FIRST_PSEUDO_REGISTER ".

" FIXED_REGISTERS "

Инициализатор, который говорит, какие регистры используются для фиксированных целей на протяжении всего оттранслированного кода и, следовательно, недоступны для общего распределения. Они могут включать указатель стека, указатель кадра (за исключением машинах, где он может использоваться как общий регистр, если указатель кадра не нужен), программный счетчик на машинах, где он рассматривается как адресуемый регистр, и любой другой пронумерованный регистр со стандартным использованием.

Эта информация выражается как последовательность чисел, разделяемых запятыми и заключенная в фигурные скобки. N-е число равно 1, если регистр N фиксирован, и 0 в противном случае.

Таблица, инициализированная этой макрокомандой, и таблица, инициализированной следующей, могут быть изменены во время выполнения программы как автоматически, под действием макрокоманды " CONDITIONAL_REGISTER_USAGE ", так и пользователем, при помощи опций команды " -ffixed-REG ", " -fcall-used-REG " и " -fcall-saved-REG ".

" CALL_USED_REGISTERS "

Подобно " FIXED_REGISTERS ", но имеет 1 для каждого регистра, который затирается (вообще говоря) обращениями к функции так же, как для фиксированных регистров. Эта макрокоманда, следовательно, идентифицирует регистры, которые не доступны для общего распределения значений, которые должны жить во время обращений к функции.

Если регистр имеет 0 в " CALL_USED_REGISTERS ", транслятор автоматически сохраняет его на входе в функцию и восстанавливает его на выходе из функции, если регистр используется внутри функции.

" CONDITIONAL_REGISTER_USAGE "

Ноль или более операторов C, которые могут условно изменять две переменных " fixed_regs " и " call_used_regs " (обе - типа " char[] ") после того, как они были инициализированы двумя предыдущими макрокомандами.

Это необходимо в случае, если фиксированные или затиаремые при вызове регистры зависят от целевых флажков.

Не определяйте эту макрокоманду, если не требуется ничего делать.

Если использование всего класса регистров зависит от целевых флагов, Вы можете сообщить об этом GCC, используя эту макрокоманду для установки " fixed_regs " и " call_used_regs " в 1 для каждого из регистров в классах, которые не должны использоваться GCC. Также определите макрокоманду " REG_CLASS_FROM_LETTER " так, чтобы она возвращала " NO_REGS ", если она вызывается с символом для класса, который не должен использоваться.

(Однако, если этот класс не включен в " GENERAL_REGS " и все образцы insn, чей ограничения разрешают этот класс, управляются целевыми переключателями, то GCC будет автоматически избегать использования этих регистров, когда целевые переключатели запрещают это.)

" NON_SAVING_SETJMP "

Если эта макрокоманда определена и имеет значение, отличное от нуля, это означает, что " setjmp " и связанные с ней функции не могут сохранить регистров, или что " longjmp " не может восстановить их. В качестве компенсации транслятор избегает помещать переменные в регистры в функциях, использующих " setjmp ".

" INCOMING_REGNO (OUT) "

Определите эту макрокоманду, если целевая машина имеет окна регистров. Это выражение C возвращает номер регистра, который видит вызываемая функция, в зависимости от номера регистра OUT, который видит вызывающая функция. Возвратите OUT, если номер регистра OUT не выходящий (outbound) регистр.

" OUTGOING_REGNO (В) "

Определите эту макрокоманду, если целевая машина имеет окна регистров. Это выражение C возвращает номер регистра, который видит вызывающая функция, в зависимости от номера регистра IN, который видит вызываемая функция. Возвратите IN, если номер регистра IN не входящий (inbound) регистр.

Порядок Распределения Регистров

Регистры распределяются по порядку.

" REG_ALLOC_ORDER "

Если определено, инициализатор для вектора целых чисел, содержащих номера аппаратных регистров в порядке, в котором GNU CC предпочтительно должен использовать их (от наиболее прдпочтительных к наименее).

Если эта макрокоманда не определена, самыми первыми используются регистры с самыми маленькими номерами ( все, кроме эквивалентных).

Одно из применений этой макрокоманды - на машинах, где регистры с самыми большими номерами всегда должны сохраняться и команды сохранения нескольких регистров поддерживают только последовательности последовательных регистров. На таких машинах определите " REG_ALLOC_ORDER " как инициализатор, заносящий в список первыми годные для распределения регистры с самыми большими номерами.

" ORDER_REGS_FOR_LOCAL_ALLOC "

Оператор C (без точки с запятой) для выбора порядка распределения аппаратных регистров для псевдорегистров, локальных для базового блока.

Сохраните желательный порядок регистров в массиве " reg_alloc_order ". Элемент 0 должен быть регистр, распределяемым первым; элемент 1 - следующим, и так далее.

Тело макрокоманды не должно делать никаких предположений относительно содержимого " reg_alloc_order " перед выполнением макрокоманды.

На большинстве машин нет необходимости определять эту макрокоманду.

Как Располагать Значения В Регистрах

В этом разделе обсуждаются макрокоманды, которые описывают, какие виды значений (конкретно, какие машинные типы) каждый регистр может содержать, и сколько последовательных регистров необходимо для данного типа.

" HARD_REGNO_NREGS (REGNO, MODE) "

Выражение C для числа последовательных аппаратных регистров, начиная с регистра с номером REGNO, требуемого для хранения значения типа MODE.

Например, на машине, где все регистры - ровно одно слово, эту макрокоманду следует определить так:

           #define HARD_REGNO_NREGS(REGNO, MODE)            \
              ((GET_MODE_SIZE (MODE) + UNITS_PER_WORD - 1)  \
               / UNITS_PER_WORD))
" HARD_REGNO_MODE_OK (REGNO, MODE) "

Выражение C, которое отлично от нуля, если допустимо сохранение значения типа MODE в аппаратном регистре с номером REGNO (или в нескольких регистрах, начиная с него). Для машины, где все регистры одинаковы, определения должно выглядеть так:

           #define HARD_REGNO_MODE_OK (REGNO, MODE) 1
Для этой макрокоманды не является необходимой проверка номеров фиксированных регистров, потому что механизм распределения рассматривает их как всегда занятые.

На некоторых машинах, значения двойной точности должны храниться в четных/нечетных парах регистров. Способ сделать это заключается в том, чтобы запретить в этой макрокоманде нечетные номера регистров для таких типов.

Минимальное требование для типа, чтобы он подходил для регистра, заключается в том, что образец команды " movMODE " поддерживает перемещение между регистром и любым другим аппаратным регистром, для которого этот тип подходит; и это перемещение значения в регистр и обратно не изменяет его.

Так как та же самая команда, используемая для передвижения " SImode ", будет работать для всех более узких целочисленных типов, для " HARD_REGNO_MODE_OK " не обязательно на любой машине различать эти типы, если Вы определяете образцы " movhi ", и т.д., чтобы воспользоваться преимуществом этого. Это полезно из-за взаимодействия между " HARD_REGNO_MODE_OK " и " MODES_TIEABLE_P "; очень желательно, чтобы все целочисленные типы были связываемы таким образом.

Многие машины имеют специальные регистры для арифметики с плавающей точкой. Часто люди считают, что машинные типы с плавающей точкой позволяются только в регистрах с плавающей точкой. Это не так. Любые регистры, которые могут хранить целые числа, могут безопасно *сохранять* машинный тип с плавающей точкой, независимо от того, может или нет выполняться в этих регистрах плавающая арифметика. Целочисленные команды перемещения могут использоваться и для перемещения этих значений.

На некоторых машинах, однако, верно обратное: машинные типы с фиксированной точкой не могут находиться в плавающих регистрах. Это так, если плавающие регистры нормализуют любое значение, сохраненное в них, потому что сохранение не-плавающего значения там исказило бы его. В этом случае " HARD_REGNO_MODE_OK " должен запретить машинные типы с фиксированной точкой в плавающих регистрах. Но если плавающие регистры не нормализуются автоматически, если Вы можете сохранять любой набор битов в регистр и восстанавливать его без изменений, то любой машинный тип может храниться в плавающем регистре, и Вы можете определять с учетом этого эту макрокоманду.

Основное значение специальных плавающих регистров - это то, что к ним применимы команды арифметики с плавающей точкой. Однако это не имеет никакого отношения к " HARD_REGNO_MODE_OK ". Вы обрабатываете это, записывая соответствующие ограничения для этих команд.

На некоторых машинах доступ к плавающим регистрам особенно медленный, так что лучше хранить значение во кадре стека, чем в таком регистре, если с ним не выполняется команд плавающей арифметики. Поскольку плавающие регистры не содержатся в классе " GENERAL_REGS ", они не будут использоваться, если этого не потребует какое-нибудь ограничение образца.

" MODES_TIEABLE_P (MODE1, MODE2) "

Выражение C, которое отлично от нуля, если желательно выбирать распределение регистров так, чтобы избегать команд перемещения между a значениями типа MODE1 и значениями типа MODE2.

Если " HARD_REGNO_MODE_OK (R, MODE1) " и " HARD_REGNO_MODE_OK (R, MODE2) " являются различным для любого R, то " MODES_TIEABLE_P (MODE1, MODE2) " должно быть нулем.

Обработка leaf-функций

На некоторых машинах, leaf-функция (то есть та, которая не производит никаких вызовов) может выполняться более эффективно, если не делает собственного окна регистров. Часто это означает, что она требует, чтобы параметры были в регистрах, в которые их передает вызывающая функция, вместо регистров, через которые они обычно поступают.

Специальная обработка для leaf-функций применяется только когда другие условия выполнены; например, часто они могут использовать только эти же регистры для собственных переменных и временных данных. Мы используем термин "leaf-функция", чтобы обозначить функцию, которая подходит для этой специальной обработки, так что функции без обращений не обязательно - "leaf-функции".

GNU CC назначает номера регистрам прежде чем узнает, является ли функция подходящая для обработки как leaf-функция. Так что ему требуется перенумеровать регистры, чтобы получить leaf-функцию. Следующие макрокоманды выполняют это.

"LEAF_REGISTERS' ("leaf-регистры") Инициализатор C для вектора, индексированного номерами аппаратных регистров, который содержит 1 для регистра, который является кандидатом на обработку для leaf-функции.

Если обработка leaf-функции включает перенумеровку регистров, то регистры, отмеченные выше, должны содержать 1 перед перенумерацией, как GNU CC обычно и распределяет. Регистры, которые будут фактически использоваться в ассемблерном коде, после изменения нумерации, не должны быть отмечены 1 в этом векторе.

Определите эту макрокоманду только если целевая пытается оптимизировать обработку leaf-функций.

"LEAF_REG_REMAP (REGNO)" Выражение C, значение которого - номер регистра, которому должен быть присвоен номер REGNO, когда функция обрабатывается как leaf-функция.

Если REGNO - номер регистра, который не должен появиться в leaf-функции перед изменением нумерации, то выражение должно выдать -1, что заставит транслятор прерваться.

Определите эту макрокоманду только если целевая машина пытается оптимизировать обработку leaf-функций, и чтобы сделать это, регистры должны быть перенумерованы.

Обычно, "FUNCTION_PROLOGUE" и "FUNCTION_EPILOGUE" ("пролог функции" и "эпилог функции") должны обрабатывать leaf-функции особо. Они могут проверить переменную C "leaf_function", которая отлична от нуля для leaf-функций. (Переменная "leaf_function" определена только если "LEAF_REGISTERS" определена.)

Регистры, образующие стек

На компьютерах, где некоторые из регистров образуют стек (как в 80387 сопроцессоре для 80386), имеются некоторые особенности. Регистры стека обычно записываются, проталкиванием в стек, и пронумерованы относительно вершины стека.

В настоящее время, GNU CC может обрабатывать только одну группу стекоподобных регистров, а они должны быть последовательно пронумерованы.

"STACK_REGS' ("Регистры стека")

Определите ее, если машина имеет стекоподобные регистры.

"FIRST_STACK_REG" ("Первый регистр стека")

Номер первого стекоподобного регистра. Это - вершина стека.

"LAST_STACK_REG" ("Последний регистр стека")

Номер последнего стекоподобного регистра. Этот - дно стека.

Устаревшие Макрокоманды для Управления Использованием Регистров

Эти возможности работают не очень хорошо. Они существуют, потому что требуются для генерации правильного кода для 80387 сопроцессора 80386. Они больше не используются в соответствии c машинным описанием и могут быть удалены в более поздней версии транслятора. Не используйте их!

"OVERLAPPING_REGNO_P (REGNO)" ("Перекрывающиеся номера регистров")

Если определена, то это - выражение C, значение которого отлично от нуля, если аппаратный номер регистра REGNO - перекрывающийся регистр. Это означает аппаратный регистр, который перекрывается c аппаратным регистром с другим номером. (Такое перекрытие нежелательно, но иногда позволяет поддерживаться машине, которая иначе не поддерживалась бы.) Эта макрокоманда должна возвратить значение, отличное от нуля, для *всех* регистров, которые накладываются на друг друга. GNU CC может использовать накладывающийся регистр только в некоторых ограниченных случаях. Они могут использоваться для распределения внутри базисного блока и могут быть spilled для перезагрузки; вот и все.

Если эта макрокоманда не определена, это означает, что ни один из аппаратных регистров не накладывается друг на друга. Это - обычная ситуация.

"INSN_CLOBBERS_REGNO_P (INSN, REGNO)"

Если определена, то это - выражение C, значение которого должно быть отлично от нуля, если insn INSN имеет эффект таинственного затирания (clobbering) содержимого аппаратного регистра номер REGNO. "Таинственного" потому, что выражение insn RTL не описывает такого эффекта.

Если эта макрокоманда не определена, это означает, что никакая insn не clobbers регистры. Это - обычная ситуация; при прочих равных условиях, выражению RTL лучше всего показать весь процесс.

"PRESERVE_DEATH_INFO_REGNO_P (REGNO)"

Если определена, то это - выражение C, значение которого отлично от нуля, если точные "REG_DEAD" замечания необходимы для номера аппаратного регистра REGNO во время получения ассемблерного кода. Когда это так, некоторые оптимизации, которые происходят после распределения регистров и могли бы свести на нет эти замечания, не выполняются, когда этот регистр включается в процесс.

Вы могли бы принять меры, чтобы предотвратить "смертельную" информацию о регистре, когда некоторый код в машинном описании, который выполняется, чтобы писать ассемблерный код, видит "смертельные" замечания. Это необходимо только, когда фактическая аппаратная возможность, о которой GNU CC думает как о регистре, не является регистром обычного типа. (Это может быть, например, аппаратный стек.)

Если эта макрокоманда не определена, это означает, что никакие "смертельные" примечания не должны сохраняться. Это - обычная ситуация.

6.6 Классы Регистров

На многих машинах пронумерованные регистры - не все эквивалентны. Например, некоторые регистры нельзя использовать для индексной адресации; некоторые регистры нельзя использовать в некоторых командах. Эти машинные ограничения известны транслятору через "классы регистров".

Вы определяете ряд классов регистров, придавая каждому имя и говоря, какие из регистров принадлежат ему. Затем вы можете задать классы регистров, которые разрешены как операнды в конкретных командах.

Вообще, каждый регистр будет принадлежать нескольким классам. Фактически, один класс должен быть назван "ALL_REGS" ("все регистры") и содержать все регистры. Другой класс должен быть назван "NO_REGS" ("никаких регистров") и не содержать никаких регистров. Часто объединение двух классов будет другим классом, однако это необязательно.

Один из классов должен быть назван "GENERAL_REGS" ("регистры общего назначения"). Имя не столь важно, но символы "r" и "g" определяет этот класс. Если "GENERAL_REGS' - то же, что "ALL_REGS", просто определите это как макрокоманду, которая разворачивается до "ALL_REGS".

Упорядочьте классы так, чтобы, если класс X содержится в классе Y то X, имел меньший номер класса чем Y.

Классы, отличные от "GENERAL_REGS", указываются в ограничениях на операнд через машинно-зависимые символы ограничения операнда. Вы можете определять такие символы, чтобы отвечать различным классам, затем использовать их в ограничениях на операнд.

Вы должны определить класс для объединения двух классов всякий раз, когда некоторая команда позволяет использовать оба класса. Например, если команда позволяет использовать как регистр с плавающей точкой (сопроцессорный), так и регистр общего назначения для некоторого операнда, вы должны определить класс "FLOAT_OR_GENERAL_REGS" ("вещественные или общие регистры"), который включает оба из них. Иначе вы получите неоптимальный код.

Вы должны также определить некоторую избыточную информацию относительно классов регистров: для каждого класса : какие классы он содержит и какие содержатся в нем; для каждой пары классов - самый большой класс, содержащийся в их объединении.

Когда значение, занимающее несколько последовательных регистров ожидается в некотором классе, все используемые регистры должны принадлежать этому классу. Следовательно, классы регистров не могут использоваться для усиления требования к регистровой паре, чтобы начаться регистром с четным номером. Способ определять это требование - "HARD_REGNO_MODE_OK".

Классы регистров, используемых как операнды побитового "И" или команд сдвига, имеют специальное требование: каждый такой класс должен иметь для каждого типа с фиксированной точкой, подкласс, регистры которого могут передать этот тип в память или из нее. Например, на некоторых машинах, операции для однобайтовых значений ("QImode") ограничены конкретными регистрами. Когда это так, каждый класс регистров, который используется в побитовом "И" , или командах сдвига, должен иметь подкласс, состоящий из регистров, из которых однобайтовые значения могут быть загружены или сохранены. Так что "PREFERRED_RELOAD_CLASS" всегда имеет значение для возврата.

"enum reg_class"

Перечислимый тип, который должен быть определен всеми именами классов регистров как перечисляемыми значениями. "NO_REGS" должен быть первым. "ALL_REGS" должен быть последним классом регистров, сопровождаемым еще одним значением, "LIM_REG_CLASSES", которое не является классом регистров, но сообщает о количестве классов.

Каждый класс регистров имеет номер, который является значением приведения имени класса, к типу "int". Номер служит индексом во многих таблицах, описанных ниже.

"N_REG_CLASSES"

Число различных классов регистров, определенных следующим образом:

 #define N_REG_CLASSES (int) LIM_REG_CLASSES
"REG_CLASS_NAMES"

Инициализатор, содержащий имена классов регистров как строковые константы C. Эти имена используются при писании некоторых отладочных дампов.

"REG_CLASS_CONTENTS"

Инициализатор, содержащий оглавление классов регистров как целые числа, являющиеся битовыми масками. N-ое целое число определяет оглавление класса N. Целочисленная маска MASK интерпретируется так : регистр R находится в классе, если "MASK & (1 << R)" не равно нулю.

Когда машина имеет больше чем 32 регистра, целого числа ("int") не хватает. Тогда целые числа заменяются под-инициализаторами, группами по несколько целых чисел. Каждый под-инициализатор должен подходить как инициализатор для типа "HARD_REG_SET", который определен в "hard-reg-set.h".

"REGNO_REG_CLASS (REGNO)"

Выражение C, значение которого - класс регистров, содержащий REGNO аппаратного регистра. В общем случае имеется более, чем один такой класс; выберите "минимальный" (такой что никакой меньший класс не содержит данный регистр).

"BASE_REG_CLASS"

Макрокоманда, определение которой - имя класса которому должен принадлежать правильный базовый регистр . Базовый регистр - тот, который используется в адресе, являющемся значением этого регистра плюс смещение.

"INDEX_REG_CLASS"

Макрокоманда, определение которой - имя класса, которому должен принадлежать индексный регистр . Индексный регистр - тот, который используется в адресе, где значение его умножается на масштабирующий коэффициент или прибавляется к другому регистру (или добавляется к смещению).

"REG_CLASS_FROM_LETTER (CHAR)"

Выражение C, которое определяет машинно-зависимые символы ограничения операнда для классов регистров. Если CHAR - такой символ, значением должен быть класс регистров, соответствующий ему. Иначе, значение должно быть "NO_REGS". Символ регистра "r", соответствующий классу "GENERAL_REGS", не будет передан этой макрокоманде; вы не должны обрабатывать его.

"REGNO_OK_FOR_BASE_P (NUM)"

Выражение C, которое отлично от нуля, если регистр номер NUM подходит для использования как базовый регистр в адресах операндов. Это может быть как подходящий аппаратный регистр, так и псевдорегистр, в котором был распределен аппаратный регистр.

"REGNO_OK_FOR_INDEX_P (NUM)"

Выражение C, которое отлично от нуля если регистр номер NUM подходит для использования как индексный регистр в адресах операндов. Это может быть как подходящий аппаратный регистр, так и псевдорегистр, в котором был распределен аппаратный регистр.

Различие между индексным регистром и базовым регистром в том, что индексный регистр может масштабироваться. Если адрес включает сумму двух регистров, ни один из них не масштабирован, то любой может быть помечен как "основной", а другой как "индексный"; но какая бы пометка не использовалась, она должна удовлетворять ограничениям машины, регистры которой могут служить только в определенных местах. Транслятор пробует оба способа, ища правильный, и перезагружает один или оба регистра, только если никакой способ пометки не проходит.

"PREFERRED_RELOAD_CLASS (X, CLASS)"

Выражение C, которое налагает дополнительные ограничения на класс регистров, если необходимо копировать значение X в регистр класса CLASS. Значение - класс регистров; возможно CLASS, или другой, меньший класс. На многих машинах, безопасно следующее определение :

 #define PREFERRED_RELOAD_CLASS (X, CLASS) CLASS
Иногда возвращение более ограниченного класса приводит к лучшему коду. Например, на 68000, когда X - целочисленная константа, которая находится в диапазоне для команды "moveq", значение этой макрокоманды - всегда "DATA_REGS", так как CLASS включает регистры данных. Требование регистра данных гарантирует, что "moveq" будет использоваться.

Если X - "const_double", возвращая "NO_REGS" вы может превратить X в константу в памяти. Это полезно на некоторых машинах, где непосредственные вещественные значения не могут быть загружены в некоторые типы регистров.

"PREFERRED_OUTPUT_RELOAD_CLASS (X,CLASS)"

То же, что и "PREFERRED_RELOAD_CLASS", но для перезагрузки вывода вместо перезагрузки ввода. Если Вы не определяете эту макрокоманду, по умолчанию используется CLASS, неизмененный.

"LIMIT_RELOAD_CLASS (MODE, CLASS)"

Выражение C, которое налагает дополнительные ограничения на класс регистров, чтобы использовать, когда необходимо держать значение типа MODE в перезагружаемом регистре для которого обычно использовался бы класс CLASS.

В отличие от "PREFERRED_RELOAD_CLASS", эта макрокоманда должна использоваться, когда имеются некоторые типы, которые просто не могут входить в некоторые классы перезагрузки.

Значение - класс регистров; возможно CLASS, или другой, меньший класс.

Не определяйте эту макрокоманду, если целевая машина имеет ограничения, которые требуют, чтобы макрокоманда делала нечто нетривиальное.

"SECONDARY_RELOAD_CLASS (CLASS, MODE, X)"

"SECONDARY_INPUT_RELOAD_CLASS (CLASS, MODE, X)"

"SECONDARY_OUTPUT_RELOAD_CLASS (CLASS, MODE, X)"

Многие машины имеют некоторые регистры, которые не могут быть скопированы непосредственно в память или из нее или даже из других типов регистров. Пример - "MQ" регистр, который на большинстве машин может быть скопирован только через регистр общего назначения, но не через память. Некоторые машины позволяют копировать все регистры в память или из нее , но требуют рабочего регистра для памяти (например, с символическим адресом на RT, и с некоторым символическим адресом на Sparc при компиляции PIC). В некоторых случаях требуются и промежуточный, и рабочий регистры.

Вы должны определить эти макрокоманды, чтобы указать для фазы перезагрузки, что может потребоваться распределить по крайней мере один регистр для перезагрузки в дополнение к регистру, содержащему данные. А именно, если при копировании X в регистр класса CLASS типа MODE требуется промежуточный регистр, вы должны определить "SECONDARY_INPUT_RELOAD_CLASS", чтобы возвратить самый большой класс регистров, все регистры которого могут использоваться как промежуточные или рабочие регистры.

Если при копировании регистра класса CLASS типа MODE в X требуется промежуточный или рабочий регистр, "SECONDARY_OUTPUT_RELOAD_CLASS" должна быть определена, чтобы возвратить самый большой требуемый класс регистров. Если требования для перезагрузок ввода и вывода одни и те же, то должна использоваться макрокоманда "SECONDARY_RELOAD_CLASS" вместо того, чтобы определять обе макрокоманды совершенно одинаковыми.

Значения, возвращенные этими макрокомандами - часто "GENERAL_REGS". Возвращается "NO_REGS", если не требуется никакого запасного регистра; то есть, если X может быть непосредственно скопирован в или из регистра класса CLASS типа MODE, не требуя рабочего регистра. Не определяйте эту макрокоманду, если она всегда возвращала бы "NO_REGS".

Если требуется рабочий регистр (с промежуточным регистром или без него), вы должны определить образцы для "reload_inM" или "reload_outM", как требуется (*обратите внимание на Стандартные Имена::.. Эти образцы, которые будут обычно выполняться с "define_expand", должны быть подобны образцам "movM", за исключением того, что операнд 2 - рабочий регистр.

Определите ограничения для регистра перезагрузки и рабочего регистра, которые содержат единственный класс регистров. Если первоначальный регистр перезагрузки (класс которого - CLASS) может встречать ограничение, данное в образце, значение, возвращенное этими макрокомандами используется для класса рабочего регистра. Иначе, требуются два дополнительных регистра перезагрузки. Их классы получены из ограничений в образце insn.

X может быть псевдорегистром или подрегистром псевдорегистра, который может быть в аппаратном регистре или в памяти. Используйте "true_regnum", чтобы выяснить это; она возвратит -1, если псевдорегистр находится в памяти или номер аппаратного регистра, если псевдорегистр находится в регистре.

Эти макрокоманды не должны использоваться в случае, если специфический класс регистров может быть только скопирован в память или в другой класс регистров. В этом случае, вторичные регистры перезагрузки необязательны и не помогают. Вместо этого для выполнения копирования должен использоваться стек, и образец "movM" должен использовать память как место промежуточного хранения. Это часто происходит между регистрами с плавающей точкой и регистрами общего назначения.

"SECONDARY_MEMORY_NEEDED (CLASS1, CLASS2, M)"

Некоторые машины имеют свойство, что некоторые регистры не могут быть скопированы в некоторые другие регистры без использования памяти. Определите эту макрокоманду на этих машинах, чтобы это было выражением C, которое отлично от нуля, если объекты типа M в регистрах CLASS1 могут быть скопированы в регистры класса CLASS2, только сохраняя регистр CLASS1 в память и загружая ячейку памяти в регистр класса CLASS2.

Не определяйте эту макрокоманду, если значение было бы всегда ноль.

"SECONDARY_MEMORY_NEEDED_RTX (MODE)"

Обычно, когда "SECONDARY_MEMORY_NEEDED" определена, транслятор распределяет слот (slot) стека для ячейки памяти, необходимой для копии регистра. Если эта макрокоманда определена, то транслятор вместо этого использует ячейку памяти, определенную этой макрокомандой.

Не определяйте эту макрокоманду, если Вы не определили "SECONDARY_MEMORY_NEEDED".

"SECONDARY_MEMORY_NEEDED_MODE (MODE)"

Когда транслятор нуждается во вторичной ячейке памяти, чтобы копировать один регистр типа MODE в другой, он обычно распределяет достаточное количество памяти, чтобы хранить "BITS_PER_WORD" битов и выполняет операции сохранения/загрузки в типе шириной в много битов, класс которого - MODE.

Это пойдет на большинстве машин, потому что это гарантирует, что все биты регистра скопированы, и предотвращает доступ к регистрам в более узкого (по ширине) типа, что некоторые машины запрещают для регистров с плавающей точкой.

Однако, это заданное по умолчанию поведение неправильно на некоторых машинах, таких как, например, DEC Alpha, которые сохраняют короткие целых числа в регистрах с плавающей точкой не так, как в целочисленных регистрах. На этих машинах, заданное по умолчанию расширение не будет работать правильно, и вы должны определить эту макрокоманду, чтобы подавить это расширение в некоторых случаях. См. подробности в файле "alpha.h".

Не определяйте эту макрокоманду, если Вы не определяете "SECONDARY_MEMORY_NEEDED" или если расширение MODE до типа, который имеет ширину "BITS_PER_WORD" бит, работает правильно на вашей машине.

"SMALL_REGISTER_CLASSES"

Обычно транслятор избегает выбирать регистры, которые были явно упомянуты в rtl, как spill-регистры (те, которые используются, для передачи параметров и возвращаемого значения). Однако, некоторые машины имеют слишком мало регистров некоторых классов, что не хватит регистров, чтобы использовать их как spill-регистры, если это было выполнено.

Определите "SMALL_REGISTER_CLASSES" на этих машинах. Когда она определена, транслятор позволяет регистрам, явно используемым в rtl, использоваться как spill-регистры, но предотвращает расширение времени существования этих регистров.

Определять эту макрокоманду всегда безопасно, но если вы без необходимости определяете ее, то в некоторых случаях вы уменьшите возможности оптимизации, которая может выполняться. Если вы не определяете эту макрокоманду, когда это требуется, что транслятор исчерпает все spill-регистры и напечатает сообщение о фатальной ошибке. На большинстве машин, вы не должны определять эту макрокоманду.

"CLASS_LIKELY_SPILLED_P (CLASS)"

Выражение C, значение которого отлично от нуля если псевдорегистры, которые были назначены регистрам класса CLASS, могут быть использованы как spill-регистры, потому что регистры класса CLASS необходимы для spill-регистров.

Значение по умолчанию этой макрокоманды равно 1, если CLASS имеет ровно один регистр, иначе - ноль . На большинстве машин, это значение по умолчанию должно использоваться. Просто определите эту макрокоманду как некоторое другое выражение, если псевдорегистры, распределенные "local-alloc.c", заканчиваются в памяти, потому что их аппаратные регистры были необходимы для spill-регистров. Если эта макрокоманда возвращает не ноль для этих классов, эти псевдорегистры будут распределены "global.c", который знает, как перераспределить псевдорегистр в другой регистр. Если не имелось бы другого регистра для перераспределения, вам не следовало бы изменять определение этой макрокоманды, так как единственный эффект такого определения был бы замедление распределения регистров.

"CLASS_MAX_NREGS (CLASS, MODE)"

Выражение C для максимального числа последовательных регистров класса CLASS, требуемых для хранения значения типа MODE.

Макрокоманда тесно связана с макрокомандой "HARD_REGNO_NREGS". Фактически, значение макрокоманды "CLASS_MAX_NREGS (CLASS, MODE)" должно быть максимальным значением "HARD_REGNO_NREGS(REGNO,MODE)" по всем значениям REGNO в классе CLASS.

Эти макрокоманды помогают управлять обработкой значений в много слов в процессе перезагрузки.

"CLASS_CANNOT_CHANGE_SIZE"

Если определена, то это выражение C для класса, который содержит регистры, к которым транслятор должен всегда обращаться в типе, размер которого - тот же, что у типа, в котором он загрузил регистр.

Для примера, загрузка 32-битного целого числа или числа с плавающей точкой в регистры с плавающей точкой на Альфе расширяет их до 64 битов. Следовательно, загрузка 64-битного объекта и затем сохранение его как 32-битного не сохраняют младшие 32 бита, как было бы в случае нормального регистра. Так что "alpha.h" определяет эту макрокоманду как "FLOAT_REGS".

Три других специальных макрокоманды описывают, какие операнды пригодны для каких символов ограничения.

"CONST_OK_FOR_LETTER_P (VALUE, C)"

Выражение C, которое определяет машинно-зависимые символы ограничения операнда которые определяют специфические диапазоны целочисленных значений. Если C - один из этих символов, выражение должно проверить, что VALUE, целое число, находится в соответствующем диапазоне и возвратить 1 если это так, иначе - 0. Если C - не является одним из этих символов, то значение должно быть 0 независимо от VALUE.

"CONST_DOUBLE_OK_FOR_LETTER_P (VALUE, C)"

Выражение C, которое определяет машинно-зависимые символы ограничения операнда, которые специфицируют конкретные диапазоны значений "const_double".

Если C - один из этих символов, выражение должно проверить, что VALUE, RTX кода "const_double", находится в соответствующем диапазоне и возвратить 1 если так, иначе - 0. Если C - не является одним из этих символов, значение должно быть 0 независимо от VALUE.

"const_double" используется для всех констант с плавающей точкой и для "DImode" констант с фиксированной точкой. Данный символ может принимать любое или оба вида значений. Он может использовать "GET_MODE " чтобы различить эти виды.

"EXTRA_CONSTRAINT (VALUE, C) "

Выражение C, которое определяет опциональные машинно-зависимые символы ограничения, которые могут использоваться, чтобы выделять специфические типы операндов, обычно ссылки в памяти, для целевой машины. Обычно эта макрокоманда не будет определена. Если это требуется для специфической целевой машины, она должна возвратить 1, если VALUE соответствует типу операнда, представленному символом ограничения C. Если C не определен как дополнительное ограничение, возвращенное значение должно быть 0 независимо от VALUE.

Например, на ROMP, команды загрузки не могут иметь вывод в r0, если ссылка в памяти содержит символический адрес. Символ ограничения "Q" определен как представляющий адрес в памяти, который *не* содержит символического адреса. Альтернатива определена как "Q"-ограничение на ввод и "r"-ограничение на вывод. Следующая альтернатива определяет "m" на вводе и класс регистров, который не включает r0 на выводе.

6.7 Формат Стека и Соглашения о вызовах

Здесь описываются формат стека и соглашения о вызовах.

6.6.1.Основные Параметры Стека

Вот основные параметры стека.

"STACK_GROWS_DOWNWARD" ("Стек растет вниз")

Определите эту макрокоманду, если при вталкивании слова в стек указатель стека перемещается на меньший адрес.

Когда мы говорим, "определите эту макрокоманду, если ...", это означает, что транслятор проверяет эту макрокоманду только с "#ifdef", так что точное определение не имеет значения.

"FRAME_GROWS_DOWNWARD" ("Кадр растет вниз")

Определите эту макрокоманду, если адреса локальных переменных имеют отрицательные смещения относительно указателя кадра.

"ARGS_GROW_DOWNWARD" ("Аргументы растут вниз")

Определите эту макрокоманду, если последовательные параметры к функции занимают уменьшающиеся адреса в стеке.

"STARTING_FRAME_OFFSET" ("Начальное смещение кадра")

Смещение от указателя кадра до первой локальной переменной, которая может быть распределена.

Если "FRAME_GROWS_DOWNWARD", то смещение следующей локальной переменной слота находится вычитанием длины первой локальной переменной из "STARTING_FRAME_OFFSET". Или же прибавлением длины первой локальной переменной к значению "STARTING_FRAME_OFFSET".

"STACK_POINTER_OFFSET" ("Смещение указателя стека")

Смещение от регистра указателя стека до первого расположения, в которое помещены поступающие параметры. Если не определена, то используется значение по умолчанию - 0. Это - верное значение для большинства машин.

Если "ARGS_GROW_DOWNWARD", то это - смещение к расположению над первым расположением, в которое помещены поступающие параметры.

"FIRST_PARM_OFFSET (FUNDECL)" ("Смещение первого параметра")

Смещение регистра-указателя параметров до адреса первого параметра. На некоторых машинах это может зависеть от типа функции.

Если "ARGS_GROW_DOWNWARD", это - смещение расположения над адресом первого параметра.

"STACK_DYNAMIC_OFFSET (FUNDECL)" ("Динамическое смещение стека")

Смещение от регистра указателя стека до того, что динамически размещено в стеке, например "alloca".

Значение по умолчанию для этой макрокоманды - "STACK_POINTER_OFFSET" плюс длина параметров. Значение по умолчанию правильно для большинства машин. См. подробности в "function.c".

"DYNAMIC_CHAIN_ADDRESS (FRAMEADDR)" ("Динамический адрес цепи")

Выражение C, значение которого - RTL-представление адреса в кадре стека, где сохранен указатель на кадр вызывающей функции. Имейте в виду, что FRAMEADDR - RTL-выражение для адреса самого кадра стека.

Если Вы не определяете эту макрокоманду, по умолчанию должно быть возвращено значение FRAMEADDR - то есть адрес кадра стека, или адрес слова стека, которое указывает на предыдущий кадр.

"SETUP_FRAME_ADDRESSES ()"

Если определена, то это выражение C, которое производит машинно - специфический код установки стека в такое положение, чтобы можно было обращаться к произвольным кадрам. Например, на Sparc, мы должны сбросить все окна регистров в стек прежде, чем мы можем обращаться к произвольным кадрам. Эту макрокоманду редко надо определять.

"RETURN_ADDR_RTX (COUNT, FRAMEADDR)"

Выражение C, значение которого - RTL-представление значения адреса возврата для COUNT кадра, полученное из текущего кадра. FRAMEADDR - указатель COUNT кадра, или указатель на COUNT-1 кадра, если "RETURN_ADDR_IN_PREVIOUS_FRAME" определена.

"RETURN_ADDR_IN_PREVIOUS_FRAME"

Определите ее, если к адресу возврата конкретного кадра стека обращаются из указателя предыдущего кадра стека.

Регистры, Адресующие Кадр стека

Обсуждение регистров, адресующих кадр стека.

"STACK_POINTER_REGNUM"

Номер регистра указателя стека, который должен также быть фиксированным регистром из "FIXED_REGISTERS". На большинстве машин, аппаратные средства определяют, какой это регистр.

"FRAME_POINTER_REGNUM"

Номер регистра указателя кадра, который используется, чтобы обратиться к автоматическим переменным в кадре стека. На некоторых машинах, аппаратные средства определяют, какой это регистр. На других машинах вы можете выбирать любой регистр, какой пожелаете, для этой цели.

"HARD_FRAME_POINTER_REGNUM"

На некоторых машинах смещение между указателем кадра и начальным смещением автоматических переменных неизвестно, пока не выполнено распределение регистров (например, потому что сохраненные регистры - между этими двумя расположениями). На таких машинах определите "FRAME_POINTER_REGNUM" как номер специального, фиксированного регистра, который должен использоваться внутри (internally), пока смещение не станет известным, и определите "HARD_FRAME_POINTER_REGNUM" как фактический номер аппаратного регистра, используемого для указателя кадра.

Вы должны определить эту макрокоманду только в очень редком случае, когда невозможно вычислить смещение между указателем кадра и автоматическими переменными, пока распределение регистров не было завершено. Когда эта макрокоманда определена, вы должны также указать в вашем определении "ELIMINABLE_REGS", как заменить "FRAME_POINTER_REGNUM" на "HARD_FRAME_POINTER_REGNUM" или на "STACK_POINTER_REGNUM".

Не определяйте эту макрокоманду, если она совпадала бы с "FRAME_POINTER_REGNUM".

"ARG_POINTER_REGNUM"

Номер arg регистра указателя, который используется для обращения к списку параметров функции. На некоторых машинах, это - то же, что и регистр указателя кадра. На некоторых машинах, аппаратные средства определяют, какой это регистр. На других машинах вы можете выбрать любой регистр, который пожелаете, для этой цели. Если это - не тот же самый регистр, что и регистр указателя кадра, то Вы должны отметить его как фиксированный регистр из "FIXED_REGISTERS", или принять меры для устранения его (*обратите внимание на Удаление::.).

"STATIC_CHAIN_REGNUM", "STATIC_CHAIN_INCOMING_REGNUM"

Номера регистров, используемые для передачи указателя статической цепи функции. Если используются окна регистров, то это номер регистра, видимый вызываемой функцией - "STATIC_CHAIN_INCOMING_REGNUM", в то время как номер регистра, видимый вызванной функцией - "STATIC_CHAIN_REGNUM". Если эти регистры одни и те же, то "STATIC_CHAIN_INCOMING_REGNUM" не должна быть определена.

Статический регистр цепи не должен быть фиксированным регистром.

Если статическая цепочка передана в память, эти макрокоманды не должны быть определены; вместо этого должны быть определены следующие две макрокоманды.

"STATIC_CHAIN"

"STATIC_CHAIN_INCOMING"

Если статическая цепочка передана в память, эти макрокоманды обеспечивают rtx данных выражений "mem", которые обозначают, где они сохранены. "STATIC_CHAIN" и "STATIC_CHAIN_INCOMING" делают ячейки видимыми как вызывающим, так и вызываемым функциям, соответственно. Часто первая будет при смещении из указателя стека и последняя при смещении из указателя кадра.

Переменные "stack_pointer_rtx", "frame_pointer_rtx" и "arg_pointer_rtx" будут проинициализированы до использования этих макрокоманд и должны использоваться для обращения к этим структурам.

Если статическая цепочка передана в регистр, две предыдущих макрокоманды должны быть определены вместо этих.

Удаление Указателя Кадра и Указателя Аргументов

Что касается удаления указателя кадра и указателя аргументов.

"FRAME_POINTER_REQUIRED"

Выражение C, которое отлично от нуля, если функция имеет и использует указатель кадра. Это выражение вычисляется в процессе перезагрузки. Если значение отлично от нуля, функция будет иметь указатель кадра.

Это выражение может в принципе исследовать текущую функцию и решить, опираясь на факты, но на большинстве машин, достаточно констант 0 и 1. Используйте 0, когда машина позволяет коду быть сгенерированному без указателя кадра, и это сохраняет немного времени и места. Используйте 1, когда нет преимущества от отсутствия указателя кадра.

В некоторых случаях, транслятор не знает, как произвести правильный код без указателя кадра. Транслятор распознает такие случаи и автоматически делает указатель кадра для функции, независимо от значения "FRAME_POINTER_REQUIRED". Не надо беспокоиться о них.

В функции, которой не требуется указатель кадра, регистр указателя кадра может быть распределен для обычного использования, если Вы не отметили его как фиксированный регистр. Для дополнительной информации об этом ищите "FIXED_REGISTERS".

"INITIAL_FRAME_POINTER_OFFSET (DEPTH-VAR)"

Оператор C сохранения в переменной DEPTH-VAR разности между указателем кадра и указателем стека сразу после пролога функции. Значение было бы вычислено из информации типа результата "get_frame_size()" и таблиц регистров "regs_ever_live" и "call_used_regs".

Если "ELIMINABLE_REGS" определена, эта макрокоманда не будет использоваться и не должна быть определена. Иначе она должна быть определена, даже если "FRAME_POINTER_REQUIRED" определена как тождественно истинный; в этом случае, вы можете присвоить DEPTH-VAR любое значение.

"ELIMINABLE_REGS"

Если определена, эта макрокоманда определяет таблицу пар регистров, используемую для устранения ненужных регистров, которые указывают на кадр стека. Если не определена, единственное удаление, которое транслятор пытается сделать - замена ссылок на указатель кадра на ссылки на указатель стека.

Определение этой макрокоманды состоит в списке инициализаций структур, каждая из которых определяет оригинальный регистр и регистр замены.

На некоторых машинах позиция указателя параметров неизвестна, пока трансляция не завершена. В таком случае, отдельный аппаратный регистр должен использоваться как указатель параметров. Этот регистр может быть удален путем замены на указатель кадра или на указатель параметров, в зависимости от того, удален или не удален указатель кадра.

В этом случае, вы могли бы определить: #define ELIMINABLE_REGS \ {{ARG_POINTER_REGNUM, STACK_POINTER_REGNUM}, \ {ARG_POINTER_REGNUM, FRAME_POINTER_REGNUM}, \ {FRAME_POINTER_REGNUM, STACK_POINTER_REGNUM}}

Обратите внимание, что удаление указателя параметров с указателем стека определено сначала, так как это удаление предпочтительно.

"CAN_ELIMINATE (FROM-REG, TO-REG)"

Выражение C, которое возвращает значение, отличное от нуля, если транслятору позволяется пробовать заменять регистр номер FROM-REG на регистр номер TO-REG. Эта макрокоманда должна быть определена только если определена "ELIMINABLE_REGS", и будет обычно константной 1, так как большинство случаев, предотвращающих удаление регистра - вещи о которых транслятор уже знает.

"INITIAL_ELIMINATION_OFFSET (FROM-REG, TO-REG, OFFSET-VAR)"

Эта макрокоманда подобна "INITIAL_FRAME_POINTER_OFFSET". Она определяет начальное различие между парой регистров. Макрокоманда должна быть определена, если "ELIMINABLE_REGS" определена.

"LONGJMP_RESTORE_FROM_STACK"

Определяйте эту макрокоманду, если функция "longjmp" восстанавливает регистры из кадра стека, а не из сохраненных "setjmp". Некоторые величины не должны сохраняться в регистрах во время обращения к "setjmp" на таких машинах.

Передача Аргументов Функции через Стек

Макрокоманды в этом разделе управляют тем, как параметры передаются в стек. См. следующий раздел о других макрокомандах, которые управляют передачей конкретных типов параметров через регистры.

"PROMOTE_PROTOTYPES"

Определяйте эту макрокоманду, если параметр, объявленный в прототипе как целый тип меньший, чем "int", должен фактически быть передан как "int". В дополнение к избежанию ошибок в некоторых случаях несоответствия, это также приводит к лучшему коду на некоторых машинах.

"PUSH_ROUNDING (NPUSHED)"

Выражение C, которое является числом байт, фактически переданных через стек, когда команда пытается помещать NPUSHED байт.

Если целевая машина не имеет команды push ("поместить в стек"), не определяйте эту макрокоманду. Это указывает GNU CC использовать альтернативную стратегию: распределить весь блок параметров и затем сохранить параметры в стеке.

На некоторых машинах, определение

 #define PUSH_ROUNDING (BYTES) (BYTES)
будет в самый раз. Но на других машинах команды, которые помещают в стек один байт, фактически помещает два байта, поддерживая выравнивание. Тогда определение должно быть :

 #define PUSH_ROUNDING (BYTES) (((BYTES) + 1) и ~1)
"ACCUMULATE_OUTGOING_ARGS"

Если определена, то максимальный размер области, требуемой для параметров, будет вычислен и будет помещен в переменную "current_function_outgoing_args_size". Ничего не будет помещаться на стек при каждом вызове; вместо этого пролог функции должен увеличить размер кадра стека на это количество байт.

Нельзя определять "PUSH_ROUNDING" и "ACCUMULATE_OUTGOING_ARGS" одновременно.

"REG_PARM_STACK_SPACE (FNDECL)"

Определите эту макрокоманду, если функции рассчитывают, что место в стеке распределено для параметров даже когда их значения переданы в регистрах.

Значение этой макрокоманды - размер в байтах области, зарезервированной для параметров, переданных в регистрах функции, представляемой FNDECL.

Это место может быть распределено вызывающей функцией, или быть частью машинно-зависимого кадра стека: "OUTGOING_REG_PARM_STACK_SPACE" говорит, кто его распределит.

"MAYBE_REG_PARM_STACK_SPACE" "FINAL_REG_PARM_STACK_SPACE(CONST_SIZE, VAR_SIZE)"

Определите эти макрокоманды в дополнение к описанной выше, если функции могут распределять место в стеке для параметров даже когда их значения переданы через регистры. Они должны использоваться, когда место в стеке, распределенное для параметров в регистрах - не простая константа, независимая от декларации функции.

Значение первой макрокоманды - размер в байтах области, которую мы должны первоначально считать зарезервированной для параметров, переданных в регистрах.

Значение второй макрокоманды - фактический размер в байтах области, которая будет зарезервирована для параметров, переданных в регистрах. У нее два параметра: целое число, представляющее число байт параметров фиксированного размера, и дерево, представляющее число байт параметров переменного размера, переданных в стек.

Когда эти макрокоманды определены, "REG_PARM_STACK_SPACE" будет вызываться только для функций libcall, текущей функции и для функции, вызываемой, когда о ней известно, что такое место в стека должно быть распределено. В любом случае это значение может быть легко вычислено.

При выяснении, нуждается ли вызываемая функция в таком пространстве стека, и сколько надо резервировать, GNU CC использует эти две макрокоманды вместо "REG_PARM_STACK_SPACE".

"OUTGOING_REG_PARM_STACK_SPACE"

Определите ее, если вызывающая функция обязана распределить область, зарезервированную для параметров, переданных в регистрах.

Если "ACCUMULATE_OUTGOING_ARGS" определена, эта макрокоманда управляет, не превосходит ли место для параметров значение "current_function_outgoing_args_size".

"STACK_PARMS_IN_REG_PARM_AREA"

Определите эту макрокоманду, если "REG_PARM_STACK_SPACE" определена, но стековые параметры не пропускают область, определенную ею.

Обычно, когда параметр не передан в регистрах, он помещен в стек за "REG_PARM_STACK_SPACE" областью. Определение этой макрокоманды подавляет такое поведение и заставляет параметр передаваться в стек на естественное место.

"RETURN_POPS_ARGS (FUNDECL, FUNTYPE, STACK-SIZE)"

Выражение C, которое должно указать размер в байтах параметров функции, которые она выталкивает при возврате, или 0, если функция не выталкивает параметры, а вызывающая функция должна следовательно вытолкнуть их после возврата из функции.

FUNDECL - переменная C, значение которой - узел дерева, который описывает рассматриваемую функцию. Обычно это - узел типа "FUNCTION_DECL", который описывает декларацию функции. Из нее можно получить DECL_MACHINE_ATTRIBUTES для функции.

FUNTYPE - переменная C, значение которой - узел дерева, который описывает рассматриваемую функцию. Обычно это - узел типа "FUNCTION_TYPE", который описывает тип функции. Из нее можно получить типы значения и параметров (если они есть).

Когда рассматривается обращение к библиотечной функции, FUNTYPE будет содержать идентификатор узла для библиотечной функции. Таким образом, если нужно различить библиотечные функции, вы можете сделать это по их именам. Обратите внимание, что "библиотечная функция" в этом контексте означает арифметическую функцию, имя которой известно только транслятору и не упомянуто в компилируемом C-коде.

STACK-SIZE - число байтов параметров, переданных в стек. Если передано переменное число байт, это - ноль, и выталкивание параметров всегда будет обязанностью вызывающей функции.

На Vax все функции всегда выталкивают свои аргументы, так что определение этой макрокоманды - STACK-SIZE. На 68000, согласно стандартному соглашению о вызовах, никакие функции не выталкивают свои параметры, так что значение макрокоманды - всегда 0 в этом случае. Но альтернативное соглашение о вызовах имеет место, если функции, которые берут фиксированное число параметров, выталкивают их, но другие функции (типа "printf") не выталкивают ничего (вызывающая функция делает это за них). Когда используется это соглашение, исследуется FUNTYPE для определения, берет ли функция фиксированное число аргументов.

Передача Параметров В Регистрах

Этот раздел описывает макрокоманды, которые позволяют Вам управлять тем, как различные типы параметров передаются в регистрах или как они размещаются в стеке.

" FUNCTION_ARG (CUM, MODE, TYPE, NAMED) "

Выражение C, которые управлял тем, передается ли параметр функции в регистре, и в каком регистре.

Параметры - CUM, который суммирует все предыдущие параметры; MODE, машинный тип параметра; TYPE, тип данных параметра как узел дерева или 0, если он не известен (как бывает для библиотечных функций поддержки C); и NAMED, который равен 1 для обычного парамета и 0 для безымянных параметров, что соответствет " ... " в прототипе вызываемой функции.

Значение выражения должно быть или " reg " RTX для аппаратного регистра, в котором следует передавать параметр, или ноль для передачи параметра в стеке.

Для машин подобно Vax и 68000, где обычно все параметры передаются в стеке, можно задавать в качестве определения тождественный ноль.

Обычный способ заставить ANSI библиотеку " stdarg.h " работать на машине, на которой некоторые параметры обычно передаются в регистрах, заключается в передаче через стек безымянных параметров. Это достигается возвращением " FUNCTION_ARG " 0 всякий раз, когда NAMED равно 0.

Вы можете использовать макрокоманду " MUST_PASS_IN_STACK (MODE, TYPE) " в определении этой макрокоманды, чтобы определить, имеет ли этот параметр тип, который должен передаваться в стеке. Если " REG_PARM_STACK_SPACE " не определено и " FUNCTION_ARG " возвращает отличное от нуля число для такого параметра, транслятор прервет работу. Если " REG_PARM_STACK_SPACE " определено, параметр будет вычислен в стеке и затем загружен в регистр.

" FUNCTION_INCOMING_ARG (CUM, MODE, TYPE, NAMED) "

Определите эту макрокоманду, если целевая машина имеет " окна регистра ", то есть регистр, в котором функция видит параметры, не обязательно является тем, в котором вызывающая функция их передала.

Для таких машин " FUNCTION_ARG " вычисляет регистр, в котором вызывающая функция передает значение, а " FUNCTION_INCOMING_ARG " должен определяться подобным способом и сообщать вызываемой функции, где получать параметры.

Если " FUNCTION_INCOMING_ARG " не определено, " FUNCTION_ARG " служит для обеих целей.

" FUNCTION_ARG_PARTIAL_NREGS (CUM, MODE, TYPE, NAMED) "

Выражение C для числа слов, в начале параметра, которые должны быть помещены в регистры. Значение должно быть нулем для параметров, которые полностью передаются в регистрах или полностью помещаются в стек.

На некоторых машинах определенные параметры должны передаваться частично в регистрах и частично в памяти. На этих машинах обычно первые N слов параметров передаются в регистрах, а остальные - в стеке. Если параметр, состоящий из нескольких слов (" double " или структура), пересекает эту границу, его первые несколько слов должны передаваться в регистрах, а остальные - в стеке. Эта макрокоманда сообщает транслятору, когда это происходит и сколько слов должен идти в регистры.

" FUNCTION_ARG " для этих параметров должна возвращать первый регистр, который должен использоваться вызывающей функцией для этого параметра; аналогично " FUNCTION_INCOMING_ARG " - для вызываемой функции.

" FUNCTION_ARG_PASS_BY_REFERENCE (CUM, MODE, TYPE, NAMED) "

Выражение C, которое указывает, когда параметр должен передаваться по ссылке. Если оно отлично от нуля для параметра, в памяти делается копия этого параметра и указатель на параметр передается вместо него самого. Указатель передается любым способом, соответствующий передаче указателя на этот тип.

На машинах, где " REG_PARM_STACK_SPACE " не определено, определения этой макрокоманды может выглядеть так:

           #define FUNCTION_ARG_PASS_BY_REFERENCE\
           (CUM, MODE, TYPE, NAMED)  \
             MUST_PASS_IN_STACK (MODE, TYPE)
" FUNCTION_ARG_CALLEE_COPIES (CUM, MODE, TYPE, NAMED) "

Если определено, выражение C, которое указывает когда задача создания копий параметров, переданных по невидимой ссылке, возлагается на вызываемую функцию. Обычно вызывающая функция делает копию и передает ее адрес вызываемой подпрограмме. Когда FUNCTION_ARG_CALLEE_COPIES определена и отлична от нуля, вызывающая функция не делает копии. Вместо этого она передает указатель на "настоящее" значение. Вызываемая функция не должна изменять это значение. Если можно определить, будет ли значение изменяться, делать копию не обязательно; иначе копия должна быть сделана.

" CUMULATIVE_ARGS "

Тип C для объявления переменной, которая используется как первый параметр " FUNCTION_ARG " и другие связанных значений. Для некоторых целевых машин тип " int " подходит для этой цели и может хранить количество байтов.

Нет необходимости записывать в " CUMULATIVE_ARGS " что-либо о параметрах, которые передаются через стек. Транслятор другие переменные, чтобы следить за этим. Для целевых машин, на которых все параметры передаются через стек, нет необходимости записывать что-либо в " CUMULATIVE_ARGS "; однако, структура данных должна существовать и не должна быть пустой, так что используйте " int ".

" INIT_CUMULATIVE_ARGS (CUM, FNTYPE, LIBNAME) "

Оператор C (без точки с запятой) для инициализации переменной CUM для состояния в начале списка параметров. Переменная имеет тип " CUMULATIVE_ARGS ". Значение FNTYPE - узел дерева для типа данных функции, которая получит параметры, или 0 если аргументы - для библиотечной функции поддержки транслятора.

При обработке обращения к библиотечной функции поддержки транслятора, LIBNAME определяет, к какой именно. Это - " symbol_ref " rtx, который содержит имя функции как строку. LIBNAME равно 0, если обрабатывается обычное обращение к функции C. Таким образом, каждый раз эта макрокоманда вызывается, или LIBNAME, или FNTYPE отличны от нуля, но не оба сразу.

" INIT_CUMULATIVE_INCOMING_ARGS (CUM, FNTYPE, LIBNAME) "

Подобно " INIT_CUMULATIVE_ARGS ", но перекрывает ее для целей нахождения параметров для компилируемой функции. Если это макрокоманда не определена, используется " INIT_CUMULATIVE_ARGS ".

Значение, передаваемое для LIBNAME - всегда 0, потому что библиотечные подпрограммы со специальными соглашениями о вызовах никогда не компилируются GNU CC. Параметр LIBNAME существует для симметрии с " INIT_CUMULATIVE_ARGS ".

" FUNCTION_ARG_ADVANCE (CUM, MODE, TYPE, NAMED) "

Оператор C (без точки с запятой) для продвижения сумматора переменной CUM мимо параметра в списке параметров. Значения MODE, TYPE и NAMED описывают этот параметр. Как только это выполнено, переменная CUM подходит для анализа *следующего* параметра при помощи " FUNCTION_ARG ", и т.д.

Эта макро не должно ничего делать, если рассматриваемый параметр передается в стеке. Транслятор знает, как отслеживать количество свободного места в стеке, используемого для параметров, без специальной помощи.

" FUNCTION_ARG_PADDING (MODE, TYPE) "

Если определено, выражение C, которое определяет, добавлять ли, и в каком направлении дополнительное пространство параметру. Значение должно иметь тип " enum direction ": " upward ", чтобы дополнить сверху, " downward ", чтобы дополнить снизу, или " none ", чтобы запретить дополнение.

*Размера* дополнения всегда в точночти достаточно, чтобы достигнуть следующего кратного " FUNCTION_ARG_BOUNDARY "; эта макрокоманда не управляет этим.

Эта макрокоманда имеет заданное по умолчанию определение, которое является правильным для большинства систем. Для little-endian машин значение по умолчанию - вверх. Для big-endian машин - вниз для параметра постоянного размера, короче чем " int ", и вверх в противном случае.

" FUNCTION_ARG_BOUNDARY (MODE, TYPE) "

Если определено, выражение C, которое дает границу выравнивания, в битах, параметра с указанными типом и типом. Если оно не определено, для всех параметров используется " PARM_BOUNDARY ".

" FUNCTION_ARG_REGNO_P (REGNO) "

Выражение C, которое является отличным от нуля если REGNO - номер аппаратного регистра, в котором иногда передаются параметры функций. Это *не включает* неявные параметры типа статической цепочки и адрес значения структуры. На многих машинах никакие регистры не могут использоваться для этой цели, так как все параметры функций передаются через стек.

Как Возвращаются Значения Скалярной Функции

В этом разделе обсуждаются макрокоманды, которые управляют возвращением скаляров как значений - значений, которые помещаются в регистрах.

" TRADITIONAL_RETURN_FLOAT "

Определите эту макрокоманду, если " -traditional " не должно заставлять функции, объявленные возвращающими " float ", преобразовывать значение в " double ".

" FUNCTION_VALUE (VALTYPE, FUNC) "

Выражение C для создания RTX представления места, где a функция возвращает значение типа данных VALTYPE. VALTYPE - узел дерева, представляющий тип данных. Пишите " TYPE_MODE (VALTYPE) ", чтобы получить машинный тип, используемый, чтобы представить этот тип. На многих машинах, уместен только тип. (Фактически, на большинстве машин, скалярные значения возвращаются в одном и том же месте независимо от типа).

Если " PROMOTE_FUNCTION_RETURN " определено, Вы должны применить те же правила поддержки, что и определенные в " PROMOTE_MODE ", если VALTYPE - скалярный тип.

Если точная вызываемая функция известна, FUNC - узел дерева (" FUNCTION_DECL ") для нее; иначе, FUNC - нулевой указатель. Это делает возможным использовать различные соглашения о возвращении значений для отдельных функций, когда известны все обращения к ним.

" FUNCTION_VALUE " не используется для возврата значений составных типов данных, потому что они возвращаются другим способом. См. ниже " STRUCT_VALUE_REGNUM " и связанные с ним макрокоманды.

" FUNCTION_OUTGOING_VALUE (VALTYPE, FUNC) "

Определите эту макрокоманду, если целевая машина имеет " окна регистра ", то есть регистр, в котором функция видит параметры, не обязательно является тем, в котором вызывающая функция их передала.

Для таких машин " FUNCTION_VALUE " вычисляет регистр, в котором вызывающая функция получит значение, а " FUNCTION_INCOMING_ARG " должен определяться подобным способом и сообщать функции, куда записать параметры.

Если " FUNCTION_OUTGOING_VALUE " не определена, " FUNCTION_VALUE " служит для обеих целей.

" FUNCTION_OUTGOING_VALUE " не используется для возврата значений составных типов данных, потому что они возвращаются другим способом. См. ниже " STRUCT_VALUE_REGNUM " и связанные с ним макрокоманды.

" LIBCALL_VALUE (MODE) "

Выражение C, чтобы создать RTX представление места, где библиотечная функция возвращает значение типа MODE. Если точная вызываемая функция известна, FUNC - узел дерева (" FUNCTION_DECL ") для нее; иначе, FUNC - нулевой указатель. Это делает возможным использовать различные соглашения о возвращении значений для отдельных функций, когда известны все обращения к ним.

Обратите внимание, что "библиотечная функция" в этом контексте означает подпрограмму поддержки транслятора, используемую для выполнения арифметической операции, чье имя специально указано транслятору и не было упомянуто в компилируемом C коде.

Определение " LIBRARY_VALUE " не должно касаться составных типов данных, потому что ни одна из библиотечных функций не возвращает таких типов.

" FUNCTION_VALUE_REGNO_P (REGNO) "

Выражение C, которое является отличным от нуля, если REGNO - номер аппаратного регистра, в котором могут возвращаться значения вызываемой функции.

Регистр, чей использование для возврата значений ограничено употреблением как второго в пары (для значения типа " double ", например), не требуется распознавать этой макрокомандой. Поэтому для большинства машин, достаточно такого определения:

           #define FUNCTION_VALUE_REGNO_P(N) ((N) == 0)
Если машина имеет окна регистра, так, чтобы вызывающая и вызываемая функции использует различные регистры для возврата значения, эта макрокоманда должна распознать только номера регистров вызывающей функции.

" APPLY_RESULT_SIZE "

Определите эту макрокоманду, если " untyped_call " и " untyped_return " требуется больше места, чем подразумевается " FUNCTION_VALUE_REGNO_P ", для сохранения и восстановления произвольного возвращаемого значения.

Как Возвращаются Структурированные Значения

Когда тип значения функции - " BLKmode " (и в некоторых других случаях), значение не возвращается согласно " FUNCTION_VALUE " (*См.:Возврат скаляров::.). Вместо этого вызывающая функция передает адрес блока памяти, в котором значение должно быть сохранено. Этот адрес называется " структурным адресом значения ".

Этот раздел описывает, как управлять возвратом значений структур в памяти.

" RETURN_IN_MEMORY (TYPE) "

Выражение C, которое может запрещать возврат определенных значений функции в регистрах, основываясь на типе значения. Ненулевое значение требует возврата значения функции в памяти, так, как это делается для больших структур. Здесь TYPE будет выражение C типа " tree ", представляя тип данных значения.

Обратите внимание, что значения типа " BLKmode " должны явно обрабатываться этой макрокомандой. Также, опция " -fpcc-struct-return " имеет эффект независимо от этой макрокоманды. На большинстве систем можно оставить макрокоманду неопределенной; тогда используется определение по умолчанию, чье значение - константа 1 для значений ` BLKmode ' и 0 в противном случае.

Не используйте эту макрокоманду, чтобы указать, что структуры и объединения всегда должны возвращаться в памяти. Вы должны использовать " DEFAULT_PCC_STRUCT_RETURN ", чтобы указать это.

" DEFAULT_PCC_STRUCT_RETURN "

Определите эту макрокоманду значением 1, если все возвращаемые значения структур и объединений должны быть в памяти. Так как это приводит к более медленному коду, это должно делаться, только если это необходимо для совместимости с другими трансляторами или с ABI. Если Вы определяете эту макрокоманду значением 0, то соглашения, используемые для возвращаемых значений структур и объединений, определяются макрокомандой " RETURN_IN_MEMORY ".

По умолчанию значение равно 1.

" STRUCT_VALUE_REGNUM "

Если адрес значения структуры передается в регистре, то " STRUCT_VALUE_REGNUM " должно быть номером этого регистра.

" STRUCT_VALUE "

Если адрес значения структуры не передается в регистре, определите " STRUCT_VALUE " как выражение, возвращающее RTX для места, где адрес передается. Если возвращается 0, адрес передается как "невидимый" первый параметр.

" STRUCT_VALUE_INCOMING_REGNUM "

При некоторых архитектурах - место, где вызываемая функция находит адрес значения структуры - не то же самое место, куда его помещает вызывающая. Это может быть из-за регистровых окон или из-за того, что пролог функции перемещает его в другое место.

Если входящее расположение адреса значения структуры находится в регистре, определите эту макрокоманду как номер регистра.

" STRUCT_VALUE_INCOMING "

Если входящее расположение - не регистр, то Вы должны определить " STRUCT_VALUE_INCOMING " как выражение для RTX, содержащее место, в котором вызываемая функция должна найти значение. Если она должна найти его в стеке, определите ее как " mem ", которое ссылается на указатель кадра. Определение нулем означает, что адрес передается как "невидимый" первый параметр.

" PCC_STATIC_STRUCT_RETURN "

Определите эту макрокоманду, если обычное системное соглашение на целевой машине для возврата структур и объединений заключается в том, что вызываемая функция должна возвращать адрес статической переменной, содержащей значение.

Не определите ее, если обычное системное соглашение системы заключается в том, что вызывающая функция передает адрес подпрограмме.

Эта макрокоманда имеет эффект в типе " -fpcc-struct-return " , но не играет роли, когда Вы используете тип " -freg-struct-return ".

Распределение Регистров с Сохранением

Если Вы разрешаете это, GNU CC может сохранять регистры на время обращений к функции. Это делает возможным использование затираемых регистров для содержания переменных, которые должны существовать и до, и после обращения.

" DEFAULT_CALLER_SAVES "

Определите эту макрокоманду, если обращения к функции на целевой машине не сохраняют никаких регистров; другими словами, если " CALL_USED_REGISTERS " имеет 1 для всех регистров. Эта макрокоманда допускает " -fcaller-saves " по умолчанию. В конечном счете эта опция будет установлена по умолчанию на всех машинах и как опция, так и эта макрокоманда будут удалены.

" CALLER_SAVE_PROFITABLE (REFS, CALLS) "

Выражение C, которое определяет, имеет ли смысл рассмотреть размещение псевдорегистра в затираемом аппаратном регистре и сохранять и восстанавливать его при каждом обращении к функции. Выражение должно быть равно 1, если так следует поступать, и 0 - если нет.

Если Вы не определяете эту макрокоманду, используется значение по умолчанию, который является разумным для большинства машин: " 4 * CALLS < REFS ".

Вход и Выход из Функции

Этот раздел описывает макрокоманды, которые выводят код входа функции ("пролог") и выхода ("эпилог").

" FUNCTION_PROLOGUE (FILE, SIZE) "

Составной оператор C, который выводит код ассемблера для входа функции. Пролог ответственен за установку кадра стека, инициализацию регистра указателя кадра, сохранение регистров, которые должны быть сохранены и распределение SIZE дополнительных байтов в памяти для локальных переменных. SIZE - целое число. FILE - stdio поток (поток стандартного ввода-вывода), в который должен выводиться код ассемблера.

Метка для начала функции не должна выводиться этой макрокомандой. Это выполняется при запуске макрокоманды.

Чтобы определить, какие регистры сохранять, макрокоманда могут обратиться к массиву " regs_ever_live ": элемент R отличен от нуля, если аппаратный регистрир R используется где-нибудь внутри функции. Это подразумевает, что пролог функции должен сохранить регистр R, если это - не один из используемых обращением регистры. (" FUNCTION_EPILOGUE " должен аналогично использовать " regs_ever_live ".)

На машинах, которые имеют " окна регистра ", код входа функции не сохраняет в стеке регистры, которые находятся в окнах, даже если предполагается, что они должны сохраняться при обращении к функции; вместо этого требуется соответствующие шаги, чтобы "поместить" в стек регистр, если какие-то регистры, не используемые в вызове, используются в функции.

На машинах, где функции могут иметь или могут не иметь указатели кадра, код входа функции должен изменяться соответственно; он должно устанавливать указатель кадра, если он требуется, и не устанавливать в противном случае. Чтобы определить нужен ли указатель кадра, макрокоманда может обратиться к переменной " frame_pointer_needed ". Значение переменной будет 1 во время выполнения фнукции, которая нуждается в указателе кадра. * См.: Удаление::.

Код входа функции ответственен за распределение любого места в стеке, требуемого для функции. Этот пространство состоит из областей, перечисленных ниже. В большинстве случаев эти области, распределяются в перечисленном порядке, причем названная последней область - самой близкой к вершине стека (наименьший адрес, если " STACK_GROWS_DOWNWARD " определено, и наибольший адрес, если не определено). Вы можете использовать другой порядок для машины, если это будет удобнее или требуется по причинам совместимости. За исключением случаев, когда это требуется стандартом или отладчиком, не имеется никакой причины считать, что распределение стека, используемое GCC, должно согласовываться с используемым другими трансляторами для машины.

  • Область из " current_function_pretend_args_size " байтов неинициализированного места под первым параметром, помещаемым в стек. (Оно не может быть в самом начале распределяемой области стека, если последовательность вызовов поместила в стек что-нибудь еще, кроме с параметров стека. Но обычно на таких машинах ничто больше не помещается, потому что пролог функции делает это сам.) Эта область используется на машинах, где параметр может передаваться частично в регистрах и частично в памяти, и, в некоторых случаях, чтобы поддерживать особенности " varargs.h " и " stdargs.h ".
  • Область памяти, используемая для сохранения некоторых регистров, используемых функцией. Размер этой области, которая может также включать место для таких вещей, как адрес возврата и указателей предыдущие кадры стека, является машинно-специфическими и обычно зависит от того, какие регистры используются в функции. Машины с окнами регистра часто не требуют области сохранения.
  • Область по крайней мере SIZE байтов, возможно округленных до границы распределения, для содержания локальных переменных функции. На некоторых машинах эта область и область сохранения могут располагаться в противоположном порядке, так что область сохранения будет ближе к вершине стека.
  • Опционально, когда " ACCUMULATE_OUTGOING_ARGS " определено, область из " current_function_outgoing_args_size " байтов для использования для выходящих списков параметров функции. * См.: Параметры Стека::.
Обычно, это необходимо для макрокоманд " FUNCTION_PROLOGUE " и " FUNCTION_EPILOGUE ", особенно чтобы обработать функции листа. Переменная C " leaf_function " отлична от нуля для такой функции.

" EXIT_IGNORE_STACK "

Определите эту макрокоманду как выражение C, которое отлично от нуля, если команда возврата или эпилог функции игнорирует значение указателя стека; другими словами, если безопасно удалить команду корректировки указателя стека перед возвратом из функции.

Обратите внимание, что значение этой макрокоманды имеет значение только для функций, которые поддерживают указатели кадра. Не бывает безопасно удалить конечную корректировка стека в функции, которая не имеет указателя кадра, и транслятор знает это независимо от " EXIT_IGNORE_STACK ".

" FUNCTION_EPILOGUE (FILE, SIZE) "

Составной оператор C, который выводит код ассемблера для выхода из функции. Эпилог ответственен за восстановление сохраненных регистров и указателя стека на их значения, когда функция вызывалась, и возвращения управления вызывающей функции. Эта макрокоманда имеет те же параметры, что и макрокоманда " FUNCTION_PROLOGUE ", и регистры, которые нужно восстановить, определяются из " regs_ever_live " и " CALL_USED_REGISTERS " таким же образом.

На некоторых машинах имеется одиночная команда, которая делает всю работу для возврата из функции. На этих машинах, задайте этой команде имя " return " и не определяйте макрокоманду " FUNCTION_EPILOGUE " вообще.

Не определяйте образец по имени " return ", если Вы хотите использовать " FUNCTION_EPILOGUE ". Если Вы хотите, чтобы целевые переключатели управляли тем, используются команды возврата или эпилоги, определите образец " return " с условием проверки правильности, которое соответственно проверяет целевые переключатели. Если условие правильности образца " return " ложно, будут использоваться эпилоги.

На машинах, где функции могут иметь или могут не иметь указатели кадра, код завершения функции должен изменяться соответственно. Иногда код для этих двух случаев полностью различен. Чтобы определить, требуется ли указатель кадра, макрокоманда может обратиться к переменной " frame_pointer_needed ". Значение переменной равно 1, если компилируется функция, которая нуждается в указателе кадра.

Обычно, " FUNCTION_PROLOGUE " и " FUNCTION_EPILOGUE " должен обрабатывать функции листа специальным образом. Переменная C " leaf_function " отлична от нуля для такой функции. * См.: Функции Листа::.

На некоторых машинах некоторые функции восстанавливают из стека их параметры на выходе, в то время как другие оставляют делать это вызывающей функции. Например, 68020, когда задано " -mrtd ", восстанавливает из стека параметры в функциях, которые имеют фиксированное число параметров.

Ваше определение макрокоманды " RETURN_POPS_ARGS " решает, какие функции восстанавливают из стека их собственные параметры. " FUNCTION_EPILOGUE " требуется знать, что было решено. Переменная, которая называется " current_function_pops_args " - число байтов параметров, которые функция должна восстанавливать из стека. * См.: Возвращение Скаляров::.

" DELAY_SLOTS_FOR_EPILOGUE "

Определите эту макрокоманду, если эпилог функции содержит слоты задержки, в которые команды из остальной части функции могут "перемещаться". Определение должно быть выражением C, чье значение - целое число, представляющее число слотов задержки.

" ELIGIBLE_FOR_EPILOGUE_DELAY (INSN, N) "

Выражение C, которое возвращает 1, если INSN может быть помещен в слот задержки номер N эпилога.

Параметр N - целое число, которое идентифицирует рассматриваемый слот задержки (так как различные слоты могут иметь различные правила "подходящести"). Это всегда неотрицателен и всегда меньше, чем количество слотов задержки эпилога (которое возвращает " DELAY_SLOTS_FOR_EPILOGUE "). Если Вы отклоняете данный insn для данного слота задержки, в принципе, это может быть пересмотрено для последующего слота задержки. Также, другой insns могут (по крайней мере, в принципе) рассматриваться для пока незаполненного слота задержки.

Insns, принятые для заполнения слотов задержки эпилога, помещаются в список RTL, сделанный объектами " insn_list ", сохраненными в переменной " current_function_epilogue_delay_list ". Insn для первого слота задержки входит в список первым. Ваше определение макрокоманды " FUNCTION_EPILOGUE " должно заполнять слоты задержки при помощи вывода insns в этом списке, обычно при помощи вызова " final_scan_insn ".

Вам не нужно определять эту макрокоманду, если Вы не определяли " DELAY_SLOTS_FOR_EPILOGUE ".

Генерация Кода для Профилирования

Эти макрокоманды помогут Вам генерировать код для профилирования.

" FUNCTION_PROFILER (FILE, LABELNO) "

Оператор C или составной оператор для вывода в FILE некоторого кода ассемблера, вызывающего подпрограмму профилирования " mcount ". Перед вызовом код ассемблера должен загрузить адрес переменной-счетчика в регистр, где " mcount " ожидает адрес. Имя этой переменной " LP " сопровождается номером LABELNO, так что Вам следует генерировать имя, используюя " LP%d " в " fprintf ".

Подробности того, как адрес должен передаваться " mcount ", определяются вашей средой операционной системы, а не GNU CC. Чтобы представить их себе, скомпилируйте маленькую программу для профилирования, используя установленный C транслятор системы и посмотрите не получившийся код ассемблера.

" PROFILE_BEFORE_PROLOGUE "

Определите эту макрокоманду, если код для профилирования функции должен идти перед прологом функции. Обычно код профилирования идет после него.

" FUNCTION_BLOCK_PROFILER (FILE, LABELNO) "

Оператор C или составной оператор для вывода в FILE некоторого кода ассемблера, инициализирующего профилирование базового блока для текущего объектнго модуля. Этот код должен вызывать подпрограмму " __ bb_init_func " по одному разу для каждого объектного модуля, передавая ей к качестве единственного параметра адрес блока, распределенного в объектном модуле.

Имя блока - локальный символ, созданный этим оператором:

          ASM_GENERATE_INTERNAL_LABEL (BUFFER, "LPBX", 0);
Конечно, так как Вы записываете определение " ASM_GENERATE_INTERNAL_LABEL " так же, как для этой макрокоманды, Вы можете сделать вырезку из определения этой макрокоманды и использовать имя, которое, как Вы знаете, даст результат.

Первое слово этого блока - флаг, который будет отличный от нуля, если объектный модуль уже был инициализирован. Поэтому проверяйте вначале это слово и не вызывайте " __ bb_init_func ", если флаг отличен от нуля.

" BLOCK_PROFILER (FILE, BLOCKNO) "

Оператор C или составной оператор для увеличения счетчика, связанного с базовым номером блока BLOCKNO. Базовые блоки нумеруются отдельно от нуля внутри каждой трансляции. Счетчик, связанный с номером блока BLOCKNO - это индекс BLOCKNO в векторе слов; имя этого массива - локальный символ, сделанный создаваемый таким оператором:

           ASM_GENERATE_INTERNAL_LABEL (BUFFER, "LPBX", 2);
Конечно, так как Вы записываете определение " ASM_GENERATE_INTERNAL_LABEL " так же, как для этой макрокоманды, Вы можете сделать вырезку из определения этой макрокоманды и использовать имя, которое, как Вы знаете, даст результат.

" BLOCK_PROFILER_CODE "

Функция или функции C, которые необходимы в библиотеке для поддержки блока профилирования.

6.8 Выполнение Varargs Макрокоманд

GNU CC имеет встроенную реализацию " varargs.h " и " stdarg.h ", которая работает без изменения на машинах, которые передают параметры через стек. Другие машины требуют собственных реализаций varargs, и два машиннонезависимых файла заголовка должны иметь условные выражения, чтобы включить их.

ANSI " stdarg.h " отличается от традиционного " varargs.h " главным образом соглашением о вызовах для " va_start ". Традиционная реализация имеет только один параметр, который является переменной для сохранения указателя на параметр. ANSI реализация " va_start " имеет дополнительный второй параметр. Предполагается, что пользователь пишет здесь последний именованный параметр функции.

Однако, " va_start " не должна использовать этот параметр. Способ нахождения окончания именованных параметров встроенными функциями описан ниже.

" __ builtin_saveregs () "

Используйте эту встроенную функцию, чтобы сохранить параметры из регистров в памяти так, чтобы varargs механизм мог обращаться к ним. И ANSI, и традиционная версии " va_start " должны использовать " __ builtin_saveregs ", если Вы не используете вместо этого " SETUP_INCOMING_VARARGS " (см. ниже).

На некоторых машинах " __ builtin_saveregs " открыта закодировано под контролем над макрокомандой " EXPAND_BUILTIN_SAVEREGS ". На других машинах она вызывает подпрограмму, написанную на языке ассемблеров, находящуюся в " libgcc2.c ".

Код, сгенерированный для обращения к " __ builtin_saveregs " появляется в начале функции, в противоположность тому, где обращение к " __ builtin_saveregs " написано, независимо от того, что это за код. Поэтому регистры должны быть сохранены перед тем, как функция начинает их использовать для собственных целей.

" __ builtin_args_info (CATEGORY) "

Используйте эту встроенную функцию, чтобы найти первые безымянные параметры в регистрах.

Вообще, машина может иметь несколько категорий регистров, используемых для параметров, каждый для специфической категории типов данных. (Например, на некоторых машинах регистры с плавающей запятой используются для параметров с плавающей запятой, в то время как другие параметры передаются в общих регистрах.) Чтобы добиться того, чтобы не-varargs функции использовали соответствующее соглашение о вызовах, Вы должны определить Тип данных " CUMULATIVE_ARGS " для записи того, сколько регистров в каждой категории использовано.

" __ builtin_args_info " обращается к той же самой структуре данных типа " CUMULATIVE_ARGS " после того, как обычное размещение параметра законченный с ним, с CATEGORY, определяющей, к какому слову обращаться. Таким образом, значение указывает первый неиспользуемый регистр в данной категории.

Обычно Вы использовали бы " __ builtin_args_info " в реализации " va_start " для доступа к каждой категории только однажды и сохранения значения в объекте ` va_list '. Поэтому " va_list " должна будет обновлять значения, и нет никакого способа изменить значения, обращаясь при помощи " __ builtin_args_info ".

" __ builtin_next_arg (LASTARG) "

Это - эквивалент " __ builtin_args_info ", для стековых параметров. Он возвращает адрес первого безымянного стекового параметр, как тип " void * ". Если " ARGS_GROW_DOWNWARD ", он возвращает адрес ячейки выше первого безымянного стекового параметра. Используйте его в " va_start ", чтобы инициализировать указатель для выборки параметров из стека. Также используйте его в " va_start " , чтобы проверить, что второй параметр LASTARG - последний именованный параметр текущей функции.

" __ builtin_classify_type (OBJECT) "

Так как каждая машина имеет собственные соглашения, какие типы данных могут передаваться в каких видах регистров, ваша реализация " va_arg " должна воплотить эти соглашения. Самый простой способ категоризировать определенный тип данных заключается в использовании " __ builtin_classify_type " вместе с " sizeof " и " __ alignof __ ".

" __ builtin_classify_type " игнорирует значение OBJECT, рассматривая только тип данных. Он возвращает целое число, описывающее, какой это тип - целое число, плавающее, указатель, структура и так далее.

Файл " typeclass.h " определяет перечисление, к которому Вы можете использовать для интерпретации значений " __ builtin_classify_type ".

Эта макрокоманды машинного описания помогают выполнять varargs:

" EXPAND_BUILTIN_SAVEREGS (ARGS) "

Если определено, является выражением C, которое генерирует машинно-специфический код для обращения к " __ builtin_saveregs ". Этот код будет помещен в самое начало функции, перед тем, как будет получен доступ к какому-либо параметру. Возвращаемое значение этой функции должно быть RTX, которое содержит значение, которое следует использовать как результат " __ builtin_saveregs ".

Параметр ARGS - " tree_list ", содержащий параметры, которые были переданы " __ builtin_saveregs ".

Если эта макрокоманда не определена, транслятор выведет обычный вызов библиотечной функции " __ builtin_saveregs ".

" SETUP_INCOMING_VARARGS (ARGS_SO_FAR, MODE, TYPE, PRETEND_ARGS_SIZE, SECOND_TIME)

Эта макрокоманда предлагает альтернативный вариант использования " __ builtin_saveregs " и определения макрокоманды " EXPAND_BUILTIN_SAVEREGS ". Используйте его, чтобы сохранить безымянные регистровые параметры в стеке так, как будто все параметры были переданы последовательно в стек. Как только это сделано, Вы можете использовать стандартную реализацию varargs, которая работает на машинах, которые передают все параметры через стек.

Параметр ARGS_SO_FAR - структура данных " CUMULATIVE_ARGS ", содержащая значения, которые получаются после обработки именованных параметров. Параметры MODE и TYPE описывают последний именованный параметр - его машинный тип и тип данных как узел дерева.

Реализация макрокоманды должна делать две вещи: первое, поместить в в стек все регистровые параметры, *не* используемые для именованных параметров, и второе, сохранить размер этих записанных в стек данных, в переменной типа " int ", чье имя поддерживается как параметр PRETEND_ARGS_SIZE. Значение, которое Вы сохраняете, будет служить как дополнительное смещение для установки кадра стека.

Поскольку Вы должны генерировать код, чтобы поместить в стек безымянные параметры во время компиляции, не зная их типов данных, " SETUP_INCOMING_VARARGS " имеет смысл использовать только на машинах, которые имеют только одну категорию регистровых параметров и используют ее одинаково для всех типов данных.

Если параметр SECOND_TIME отличен от нуля, это означает, что параметры функции анализируются второй раз. Так случается для встроенной функции, которая фактически не компилируется до конца исходного файла. Макрокоманда " SETUP_INCOMING_VARARGS " не должна генерировать никаких команд для этого случая.

" STRICT_ARGUMENT_NAMING "

Определите эту макрокоманду, если место, где передается параметр функции, зависит от того, является ли он именованным параметром.

Эта макрокоманда управляет тем, как устанавливается параметр NAMED к " FUNCTION_ARG " для функций varargs и stdarg. Если эта макрокоманда определена, параметр NAMED - всегда истина для именованных параметров и ложь - для безымянных параметров. Если она не определена, но " SETUP_INCOMING_VARARGS " определена, то все параметры обрабатываются как именованные. В противном случае, все именованные параметры, за исключением последнего, обрабатываются как именованные.

6.9 Trampolines для вложенных функций

"Trampoline" - маленькая часть кода, которая создается во время выполнения, когда принимается адрес вложенной функции. Она обычно располагается в стеке, во кадре стека содержащей функции. Эти макрокоманды сообщают GNU CC, как генерировать код, чтобы распределять и инициализировать trampoline.

Команды в trampoline должны делать две вещи: загрузка константного адреса в статический цепной регистр, и переход к реальному адресу вложенной функции. На CISC машинах типа m68k это требует двух команд, перемещение и переход. Тогда два адреса присутствуют в trampoline как непосредственные операнды размера word. На RISC машинах часто необходимо загрузить каждый адрес в регистр в двух частях. Тогда части каждого адреса образуют отдельные непосредственные операнды.

Код, сгенерированный, чтобы инициализировать trampoline, должен сохранить переменные части - статическое цепное значение и адрес функции - в непосредственные операнды команд. На CISC машине это просто вопрос копирования каждого адреса к ссылку памяти в соответствующее смещение от начала trampoline. На RISC машине может оказаться необходимо выбирать части адреса и сохранять их отдельно.

" TRAMPOLINE_TEMPLATE (FILE) "

Оператор C для вывода в поток FILE кода ассемблера для блока данных, который содержит постоянные части trampoline. Этот код не должен включать метку - о метке позаботятся автоматически.

" TRAMPOLINE_SECTION "

Имя подпрограммы для включения в раздел, в который должен быть помещен trampoline шаблон (* См.: Разделы::.). Значение по умолчанию - значение " readonly_data_section ", который помещает trampoline в разделе, содержащем данные только для чтения.

" TRAMPOLINE_SIZE "

Выражение C для размера в байтах trampoline, как целое число.

" TRAMPOLINE_ALIGNMENT "

Выравнивание, требуемое для trampolines, в битах.

Если Вы не определяете эту макрокоманду, для выравнивания trampolines используется значение " BIGGEST_ALIGNMENT ".

" INITIALIZE_TRAMPOLINE (ADDR, FNADDR, STATIC_CHAIN) "

Оператор C для инициализации переменных частей trampoline. ADDR - RTX для адреса trampoline; FNADDR - RTX для адреса вложенной функции; STATIC_CHAIN - RTX для статического цепного значения, которое должно быть передано функции, когда она вызывается.

" ALLOCATE_TRAMPOLINE (FP) "

Выражение C для распределения места во время выполнения для trampoline. Значение выражения должно быть RTX, представляющим ссылку памяти на место для trampoline.

Если эта макрокоманда не определена, по умолчанию trampoline распределяется как слот стека. Это значение по умолчанию подходит для большинства машин. Исключения - машины, где невозможно выполнение команд в области стека. На таких машинах Вам, возможно, следует создать отдельный стек, используя эту макрокоманду в сочетании с " FUNCTION_PROLOGUE " и " FUNCTION_EPILOGUE ".

FP указывает на структуру данных, " struct function", которая описывает состояние трансляции непосредственных содержащий функции для функции, которой принадлежит trampoline. Обычно (когда " ALLOCATE_TRAMPOLINE " не определено), слот стека для trampoline находится во кадре стека этой содержащей функции. Другие cтратегии распределения, вероятно, должны делать что-либо аналогичное с этой информацией.

Выполнение trampolines трудно на многих машинах, потому что они имеют раздельные кэши команд и данных. Запись в ячейку стека не может очистить память в кэше команд, так что когда программа переходит к этой ячейке, выполняется старое содержимое.

Имеется два возможных решения. Одно заключается в очистить относящихся к делу частей кэша команд всякий раз, когда trampoline устанавливается. Другой - сделать все trampoline идентичными, сделав в них переходы на стандартную подпрограмму. Вышеупомянутая методика делает выполнение trampoline быстрее; последний способ делает инициализацию быстрее.

Чтобы очистить кэш команд, когда trampoline инициализирован, определите следующие макрокоманды, которые описывают форму кэша.

" INSN_CACHE_SIZE "

Полный размер в байтах кэша.

" INSN_CACHE_LINE_WIDTH "

Длина в байтах каждой линии кэша. Кэш разделен на линии кэша, которые являются непересекающимися слотами, каждый из которых содежит часть данных, выбранных из памяти. Каждый раз, когда данные записываются в кэш, вся линия читается целиком. Данные, загруженные в линию кэша, всегда выравниваются на границе, равной размеру линии.

" INSN_CACHE_DEPTH "

Число альтернативных линий кэша, которые могут содержать любую конкретную ячейку памяти.

Альтернативно, если машина имеет системные вызовы или команды для очистки кэша команды непосредственно, Вы можете определять следующую макрокомандуа.

" CLEAR_INSN_CACHE (BEG, END) "

Если определена, расширяется до выражения C, очищающего *кэш команд* в указанном интервале. Если она не определена, и макрокоманда INSN_CACHE_SIZE определена, генерируется некоторый родовой код для очистки кэша. Определение этой макрокоманды обычно является цепочкой операторов " asm ". BEG и END - выражения-указатели.

Чтобы использовать стандартную подпрограмму, определите следующую макрокоманду. Кроме того, Вы должны удостовериться, что команды в trampoline заполняют всю линию кэша идентичными командами, или же гарантируют, что начало trampoline кода всегда выравнивается по той же самой точке на линии кэша. Смотрите " m68k.h " как руководство.

" TRANSFER_FROM_TRAMPOLINE "

Определите эту макрокоманду, если trampolines нуждаются в специальной подпрограмме для выполнения их работы. Макрокоманда должна расширяться до ряда " asm " операторов, которые будут компилироваться GNU CC. Они входят в библиотечную функцию под названием " __ transfer_from_trampoline ".

Если Вам нужно избежать выполнения кода обычного пролога cкомпилированной функции C, когда Вы переходите к подпрограмме, Вы можете добиться этого, помещая Вашу собственную специальную метку в коде ассемблера. Использование один оператор " asm ", чтобы сгенерировать метку ассемблера, и другой, чтобы сделать метку глобальной. Тогда trampolines смогут использовать эту метку для перехода непосредственно к вашему специальному коду ассемблера.

6.10 Неявные Обращения к Библиотечным Подпрограммам

"MULSI3_LIBCALL"

Строковая константа C имени функции умножения одного знакового полного слова на другое. Если вы не определяете эту макрокоманду, используется имя, заданное по умолчанию, "__mulsi3" функции, определенной в "libgcc.a".

"DIVSI3_LIBCALL"

Строковая константа C имени функции деления одного знакового полного слова на другое. Если вы не определяете эту макрокоманду, используется имя, заданное по умолчанию, "__divsi3" функции, определенной в "libgcc.a".

"UDIVSI3_LIBCALL"

Строковая константа C имени функции деления одного беззнакового полного слова на другое. Если вы не определяете эту макрокоманду, используется имя, заданное по умолчанию " __udivsi3 " функции, определенной в "libgcc.a".

"MODSI3_LIBCALL"

Строковая константа C имени функции вычисления остатка деления одного знакового полного слова на другое. Если вы не определяете эту макрокоманду, используется имя, заданное по умолчанию " __modsi3 " функции, определенной в "libgcc.a".

"UMODSI3_LIBCALL"

Строковая константа C имени функции вычисления остатка деления одного беззнакового полного слова на другое. Если вы не определяете эту макрокоманду, используется имя, заданное по умолчанию "__umodsi3" функции, определенной в "libgcc.a"

"MULDI3_LIBCALL"

Строковая константа C имени функции умножения одного знакового двойного слова на другое. Если вы не определяете эту макрокоманду, используется имя, заданное по умолчанию "__muldi3" функции, определенной в "libgcc.a".

"DIVDI3_LIBCALL"

Строковая константа C имени функции деления одного знакового двойного слова на другое. Если вы не определяете эту макрокоманду, используется имя, заданное по умолчанию "__divdi3" функции, определенной в "libgcc.a".

"UDIVDI3_LIBCALL"

Строковая константа C имени функции деления одного беззнакового полного слова на другое. Если вы не определяете эту макрокоманду, используется имя, заданное по умолчанию "__ divdi3" функции, определенной в "libgcc.a".

"MODDI3_LIBCALL"

Строковая константа C имени функции вычисления остатка деления одного знакового двойного слова на другое. Если вы не определяете эту макрокоманду, используется имя, заданное по умолчанию "__moddi3" функции, определенной в "libgcc.a".

"UMODDI3_LIBCALL"

Строковая константа C имени функции вычисления остатка деления одного беззнакового полного слова на другое. Если вы не определяете эту макрокоманду, используется имя, заданное по умолчанию "__umoddi3" функции, определенной в "libgcc.a".

"INIT_TARGET_OPTABS"

Определите эту макрокоманду как оператор C, который объявляет дополнительные библиотечные подпрограммы и переименовывает существующие. "Init_optabs" вызывает эту макрокоманду после инициализации всех нормальных библиотечных подпрограмм.

"TARGET_EDOM"

Значение "EDOM" на целевой машине в виде целочисленной константы C. Если вы не определяете эту макрокоманду, GNU CC не пытается вносить значение "EDOM" в "errno" непосредственно. Посмотрите в "/usr/include/errno.h" чтобы найти значение "EDOM" для вашей системы.

Если вы не определяете "TARGET_EDOM", то откомпилированный код сообщит об ошибке, заставляя это делать библиотечную функцию. Если математические функции на вашей системе при ошибке используют "matherr", то вы должны оставить "TARGET_EDOM" неопределенным, чтобы "matherr" могла нормально использоваться.

"GEN_ERRNO_RTX"

Определите эту макрокоманду как выражение C для создания выражения rtl, которое ссылается на глобальную "переменную" "errno". (На некоторых системах, "errno" может не быть переменной.) Если вы не определяете эту макрокоманду, используется приемлемое значение по умолчанию.

"TARGET_MEM_FUNCTIONS"

Определите эту макрокоманду, если GNU CC должен генерировать обращения к библиотечным функциям System V (и ANSI C) "memcpy" и "memset", а не к BSD-функциям "bcopy" и "bzero".

"LIBGCC_NEEDS_DOUBLE"

Определите эту макрокоманду только если параметры типа "float" не могут быть переданы библиотечным подпрограммам (так что они должны быть преобразованы в "double"). Эта макрокоманда воздействует и на то, как генерируются библиотечные вызовы и как библиотечные подпрограммы в "libgcc1.c" принимают свои параметры. Это полезно на машинах, где параметры с плавающей и фиксированной точкой передаются по-разному, например в i860.

"FLOAT_ARG_TYPE"

Определите эту макрокоманду, чтобы изменить тип, используемый библиотечными подпрограммами, чтобы передавать параметры типа "float". (По умолчанию, они используют объединение "float" и "int".)

Очевидно выбор должен быть "float", но это не будет работать на традиционных трансляторах C, которые все параметры, объявленные как "float" переделывают в "double". Чтобы избежать такого преобразования, библиотечные подпрограммы запрашивают значение какого-то другого типа, а затем обрабатывают его как "float".

На некоторых системах никакой другой тип не будет так работать. На этих системах вы должны вместо этой использовать "LIBGCC_NEEDS_DOUBLE", заставляя транслятор преобразовывать "double"-значения до того, как они переданы.

"FLOATIFY (PASSED-VALUE)"

Определите эту макрокоманду, чтобы изменить способ, которым библиотечные подпрограммы повторно назначают параметр типа "float" как "float" вместо типа, в качестве которого он был передан. По умолчанию это выражение, которое берет "float"-поле из объединения.

"FLOAT_VALUE_TYPE"

Определите эту макрокоманду, чтобы изменить тип, используемый для возвращения значения библиотечными подпрограммами, которые должны возвращать тип "float". (По умолчанию они используют "int".)

Очевидный выбор был бы "float", но это не будет работать на трансляторе традиционного C, который сам преобразовывает значения, объявленные как "float", в "double".

"INTIFY (FLOAT-VALUE)"

Определите эту макрокоманду, чтобы изменить способ, каким образом значение, возвращаемое библиотечной подпрограммой, которая должна возвращать тип "float", должно быть упаковано, чтобы возвратить его. Эти функции объявляются как возвращающие тип "FLOAT_VALUE_TYPE" (обычно "int").

Эти значения не могут быть возвращены как тип "float" потому что традиционные C трансляторы сами преобразовывают значение в "double".

Локальная переменная, названная "intify" всегда доступна, когда используется макрокоманда "INTIFY". Она - объединение "float"-поля с именем "f" и поля с именем "i" типа "FLOAT_VALUE_TYPE" или "int".

Если вы не определяете эту макрокоманду, работает заданное по умолчанию определение : копирует значения через это объединение.

"Nongcc_SI_type"

Определите эту макрокоманду как имя типа данных, соответствующего "SImode" в собственном C-трансляторе системы.

Вы не должны определять эту макрокоманду, если вышеуказанный тип - "long int", а это обычно он и есть.

"Nongcc_word_type"

Определяйте эту макрокоманду как имя типа данных, соответствующего word_mode в собственном C-трансляторе системы.

Вы не должны определять эту макрокоманду, если вышеуказанный тип - "long int", а это обычно так.

"perform_ ..."

Определите эти макрокоманды, чтобы обеспечить явные операторы C, выполняющие различные арифметические операции от типов "float" и "double" в библиотечных подпрограммах "libgcc1.c". См. в этом файле полный список этих макрокоманд и их параметров.

На большинстве машин вы не должны определять эти макрокоманды, потому что C-транслятор, который приходит с системой, сам заботится об их создании.

"NEXT_OBJC_RUNTIME"

Определите эту макрокоманду, чтобы сгенерировать код для посылки сообщений в Objective C , используя соглашения о вызовах системы NeXT. Это соглашение о вызовах включает передачу объекта, селектора и аргументов метода всех сразу к поисковой функции библиотеки методов.

Заданное по умолчанию соглашение о вызовах передает только объект и селектор к функции поиска, которая возвращает указатель на метод.

6.11 Способы адресации

Здесь содержится информация о способах адресации.

"HAVE_POST_INCREMENT"

Определите эту макрокоманду, если машина поддерживает постинкрементную адресацию.

"HAVE_PRE_INCREMENT"

"HAVE_POST_DECREMENT"

"HAVE_PRE_DECREMENT"

Аналогично и для других способов адресации.

"CONSTANT_ADDRESS_P (X)"

Выражение C, которое равно 1, если RTX X - константа, содержащая правильный адрес. На большинстве машин, оно может быть определено как "CONSTANT_P(X)", но на некоторых машинах больше ограничений на поддерживаемые базовые адреса.

"CONSTANT_P" принимает целочисленные значения выражений, значения которых явно

неизвестны, такие как "symbol_ref", "label_ref", "high"-выражения и "const"-арифметические выражения в дополнение к выражениям "const_int" и "const_double".

"MAX_REGS_PER_ADDRESS"

Максимальное число регистров, которые могут появляться в правильном адресе памяти. Обратите внимание, что это вы должны определять значение, равное максимальному числу, которое может принимать "GO_IF_LEGITIMATE_ADDRESS".

"GO_IF_LEGITIMATE_ADDRESS (MODE, X, LABEL)"

Сложный оператор C с условным оператором "goto LABEL;", выполняющимся, если X (RTX) - правильный адрес в памяти на целевой машине для операнда памяти типа MODE.

Обычно лучше определить несколько более простых макрокоманд, служащих подпрограммами для этой. В противном случае эта макрокоманда может оказаться слишком сложной для понимания.

Эта макрокоманда должна существовать в двух вариантах: строгом и нестрогом. Строгий вариант используется в процессе перезагрузки. Она должна быть определена так, чтобы любой псевдорегистр, который не был распределен в аппаратном регистре, считался ячейкой памяти. В контекстах, где требуется некоторый регистр, следует отклонить псевдорегистр, не представленный аппаратным.

Нестрогий вариант используется в других проходах. Она должна быть определена, чтобы принимать все псевдорегистры в каждом контексте, где требуется некоторый регистр.

Исходные файлы транслятора, которые используют строгий вариант этой макрокоманды, определяют макрокоманду "REG_OK_STRICT". Вы должны использовать условную директиву "#ifdef REG_OK_STRICT", чтобы определить строгий вариант в этом случае, иначе - нестрогий вариант.

Подпрограммы для проверки приемлемых регистров для различных целей (одна для базовых регистров, одна для индексных регистров, и так далее) - типичны среди подпрограмм, используемых для определения "GO_IF_LEGITIMATE_ADDRESS". Только эти подпрограммы-макрокоманды должны иметь два варианта; макрокоманды более высоких уровней тоже могут быть строгими или нет.

Обычно, постоянные адреса, которые являются суммой "symbol_ref" и целого числа, располагаются внутри "const" RTX, чтобы отметить их как константы. Следовательно, не надо распознавать такие суммы как правильные адреса. Обычно вы просто распознаете любую "const" как правильную.

Обычно "PRINT_OPERAND_ADDRESS" не подготовлена к обработке константных сумм, которые не отмечены "const". Она принимает, что явный "plus" указывает на индексацию. Если так, то вы должны отбросить такие явные постоянные суммы как неправильные адреса, так чтобы ни одна из них не была передана "PRINT_OPERAND_ADDRESS".

Является ли символический адрес правильным, зависит от раздела, к которому адрес обращается (на некоторых машинах). На таких машинах определите макрокоманду "ENCODE_SECTION_INFO", чтобы сохранить информацию в "symbol_ref", и затем проверите ее там. Когда вы видите "const", вы должны будете заглянуть внутрь нее, чтобы найти "symbol_ref" для определения раздела. *Обратите внимание на Ассемблерный Формат::.

Самый лучший способ изменить строку имени - добавить текст к началу с подходящей пунктуацией, чтобы предотвратить любую неоднозначность. Распределите новое имя в "saveable_obstack". Вы должны будете изменить "ASM_OUTPUT_LABELREF", чтобы удалить и декодировать добавленный текст и вывести имя соответственно, и определить "STRIP_NAME_ENCODING", чтобы обратиться к первоначальной строке имени.

Вы можете проверить информацию, сохраненную в "symbol_ref" в определениях макрокоманд "GO_IF_LEGITIMATE_ADDRESS" и "PRINT_OPERAND_ADDRESS".

"REG_OK_FOR_BASE_P (X)"

Выражение C, которое отлично от нуля если X (считающийся "reg" RTX) подходит для использования в качестве базисного регистра. Для аппаратных регистров оно должно принимать только разрешенные аппаратными возможностями и отклонять остальные. Отклоняет ли макрокоманда псевдорегистры, должен контролироваться "REG_OK_STRICT", как описано выше. Это обычно требует двух различных вариантов определения, причем "REG_OK_STRICT" управляет, какое фактически используется.

"REG_OK_FOR_INDEX_P (X)"

Выражение C, которое отлично от нуля если X (считающийся "reg" RTX) годится для использования как индексный регистр.

Различие между индексным регистром и основным регистром в том, что индексный регистр может масштабироваться. Если адрес включает сумму двух регистров, ни один из которых не масштабирован, то любой может быть помечен как "основной", а другой как "индексный"; но какая бы пометка ни использовалась, она должна удовлетворить ограничениям машины, регистры которой могут служить только в определенных местах. Транслятор пробует оба способа, ища правильный, и перезагрузит один или оба регистров только, если никакой способ не сработает.

"LEGITIMIZE_ADDRESS (X, OLDX, MODE, WIN)"

Сложный оператор C, который пытается заменять X на правильный адрес в памяти для операнда типа MODE. WIN будет меткой оператора в C в другом месте в коде; определение макрокоманды может использовать :

GO_IF_LEGITIMATE_ADDRESS (MODE, X, WIN);

во избежание дальнейшей обработки, если адрес стал правильным.

X будет всегда результатом обращения к "break_out_memory_refs", а OLDX будет операндом, который был передан той функции, чтобы получить X.

Код, сгенерированный этой макрокомандой не должен изменить структуру X. Если он трансформирует X в более правильную форму, он должен назначить X (который будет всегда C переменная) новое значение.

Эта макрокоманда необязательно выдаст правильный адрес. Транслятор имеет стандартные пути выполнения этого всех случаях. Фактически, этой макрокоманде безопасно ничего не делать. Но часто машинно-зависимая стратегия может привести к лучшему коду.

"GO_IF_MODE_DEPENDENT_ADDRESS (ADDR, LABEL)"

Оператор C или составной оператор с условным "goto LABEL; ", выполняемым, если адрес в памяти X (RTX) может иметь различные значения, в зависимости от машинного типа ячейки памяти, для которой он используется или если адрес правильный для некоторых типов, но не для других.

Автоинкрементные и автодекрементные адреса обычно имеют зависимые от типа эффекты, потому что размер приращения или декремента - размер адресуемого операнда. Некоторые машины имеют другие зависимые от типа адреса. Многие RISC-машины имеют независимые от типа адреса.

Вы можете принять, что ADDR - правильный адрес для данной машины.

"LEGITIMATE_CONSTANT_P (X)"

Выражение C, которое отлично от нуля, если X - правильная константа для непосредственного операнда на целевой машине. Вы можете принять, что X удовлетворяет "CONSTANT_P", так что вам не надо проверять это. Фактически, "1" является подходящим определением для этой макрокоманды на машинах, где какая-нибудь "CONSTANT_P" правильна.

6.12 Состояние Кода Условия

Описание состояния кода условия.

Файл "conditions.h" определяет переменную "cc_status" для описания того, как был вычислен код условия (в случае, если интерпретация кода условия зависит от команды, которой он был установлен). Эта переменная содержит выражения RTL, на которых основан код условия, и несколько стандартных флажков.

Иногда дополнительные машинно-специфические флаги должны быть определены в заголовочном файле описания машины. Он может также добавлять дополнительную машинно-специфическую информацию, определяя "CC_STATUS_MDEP".

"CC_STATUS_MDEP"

C-код для типа данных, который используется для объявления "mdep" компонент "cc_status". Его значение по умолчанию : "int".

Эта макрокоманда не используется на машинах, которые не используют "cc0".

"CC_STATUS_MDEP_INIT"

Выражение C для инициализации поля "mdep" в "empty". Заданное по умолчанию определение не делает ничего, так как большинство машин не использует это поле. Если вы хотите использовать поле, вы должны, вероятно, определить эту макрокоманду, чтобы инициализировать его.

Эта макрокоманда не используется на машинах, которые не используют "cc0".

"NOTICE_UPDATE_CC (EXP, INSN)"

Составной оператор C для установки компонент "cc_status" соответственно для insn INSN, тело которого - EXP. Эта макрокоманда отвечает за распознавание insn, которые устанавливают код условия как побочный эффект другого действия, такого как установка "(cc0)".

Эта макрокоманда не используется на машинах, которые не используют "cc0".

Если имеются insn, которые не устанавливают код условия, но изменяют другие машинные регистры, эта макрокоманда должна проверить, портят ли они выражения, код условия которых зарегистрирован как отраженный. Например, на 68000, insn, которые сохраняют значения в регистрах адреса, не устанавливают код условия, что означает что обычно "NOTICE_UPDATE_CC" может оставлять "cc_status" неизменным для таких insn. Но предположите, что предыдущий insn установил код условия, основанный на расположении "a4@ (102)", а текущий insn сохраняет новое значение в "a4". Хотя код условия не изменен, он никогда не будет отражать содержимое "a4@ (102)". Следовательно, "NOTICE_UPDATE_CC" должен изменить "cc_status" в этом случае, чтобы сообщить, что ничто не известно относительно значения кода условия.

Определение "NOTICE_UPDATE_CC" должно быть готово иметь дело с результатами peephole-оптимизации: insn, чьи образцы "параллельны" RTX, содержащим различные "reg", "mem" или константы, которые являются только операндами. RTL - структуры этих insn недостаточно, чтобы указать, что insn фактически делают. Что "NOTICE_UPDATE_CC" должен делать, когда видит, что каждый должен только выполнить "CC_STATUS_INIT".

Возможное определение "NOTICE_UPDATE_CC" состоит в вызове функции, которая смотрит на атрибут (*Обратите внимание на Insn Атрибуты::.), например, "cc". Это избавляет от детальной информации относительно образцов в двух местах : в "md" файле и в "NOTICE_UPDATE_CC".

"EXTRA_CC_MODES"

Список имен, которые нужно использовать для дополнительных режимов для значений кода условия в регистрах (*Обратите внимание на Образцы Переходов::.). Эти имена добавлены к "enum machine_mode", и все они имеют класс "MODE_CC". В соответствии c соглашением, они должны начинаться с "CC" и заканчиваться на "mode".

Вы должны определить эту макрокоманду, только, если ваша машина не использует "cc0" и только, если требуются дополнительные типы.

"EXTRA_CC_NAMES"

Список C-строк имен для типов, перечисленных в "EXTRA_CC_MODES". Например, Sparc определяет эту макрокоманду и "EXTRA_CC_MODES" так :

 #define EXTRA_CC_MODES CC_NOOVmode, CCFPmode, CCFPEmode
 #define EXTRA_CC_NAMES "CC_NOOV", "CCFP", "CCFPE"
Эта макрокоманда не требуется, если "EXTRA_CC_MODES" не определена.

"SELECT_CC_MODE (OP, X, Y)"

Возвращает тип из класса "MODE_CC" для использования, когда код операции сравнения OP применяется к rtx X и Y. Например, на Sparc, "SELECT_CC_MODE" определена, как описано в "Образцы Переходов::.".

 #define SELECT_CC_MODE(OP,X,Y) \ (GET_MODE_CLASS (GET_MODE (X)) ==
 MODE_FLOAT
 \ ? ((OP == EQ || OP == NE) ? CCFPmode : CCFPEmode)    \ : ((GET_CODE (X) ==
 PLUS || GET_CODE (X) == MINUS    \ || GET_CODE (X) == NEG) \ ? CC_NOOVmode :
 CCmode))
Вам не нужно определить эту макрокоманду, если "EXTRA_CC_MODES" не определена.

"CANONICALIZE_COMPARISON (CODE, OP0, OP1)"

На некоторых машинах не все возможные сравнения определены, но вы можете получить недопустимое сравнение через допустимые. Например, на Alpha нет "GT"-сравнения, но вы можете использовать вместо него "LT"-сравнение и поменять порядок операндов.

На таких машинах определите эту макрокоманду, как оператор C, делающий любые требуемые преобразования. CODE - начальный код сравнения, OP0 и OP1 - левые и правые операнды сравнения, соответственно. Вы можете изменить CODE, OP0, и OP1, если требуется.

GNU CC не будет считать сравнение, полученное в этой макрокоманде, правильным, но посчитает, если возникающий в результате insn соответствует образцу в "md" файле.

Вам не нужно определять эту макрокоманду, если она никогда не изменяла бы код сравнения или операнды.

"REVERSIBLE_CC_MODE (MODE)"

Выражение C, значение которого - 1, если всегда можно безопасно обратить сравнение типа MODE. Если "SELECT_CC_MODE" может когда-либо возвращать MODE для неравенства с плавающей точкой, то "REVERSIBLE_CC_MODE (MODE)" должно быть 0.

Вам не нужно определять эту макрокоманду, если она всегда возвращала бы ноль или если формат с плавающей точкой отличается от "IEEE_FLOAT_FORMAT". Например, вот определение, используемое на Sparc, где неравенства с плавающей точкой всегда даны "CCFPEmode":

 #define REVERSIBLE_CC_MODE(MODE)  ((MODE) != CCFPEmode)

6.13 Описание Относительных Стоимостей Операций

Эти макрокоманды позволяют Вам описывать относительное быстродействие различных операций на целевой машине.

"CONST_COSTS (X, CODE, OUTER_CODE)"

Часть C "switch"-оператора, которая описывает относительные издержки постоянных выражений RTL. Она должна содержать "case"-метки для кодов выражений "const_int", "const", "symbol_ref", "label_ref" и "const_double". Каждый "case" должен в конечном счете достигнуть оператора "return", чтобы возвратить относительную стоимость использования данного вида константы в выражении. Стоимость может зависеть от точного значения константы, которая доступна для исследования в X, и rtx-кода выражения, в котором содержится, и который может быть найден в OUTER_CODE.

CODE - код выражения - избыточный, так как может быть получен, как "GET_CODE(X)".

"RTX_COSTS (X, CODE, OUTER_CODE)"

То же, что "CONST_COSTS", но применяется к неконстантным выражениям RTL. Может использоваться, например, для указания, насколько дорогостоящей является команда умножения. В написании этой макрокоманды, вы можете использовать конструкцию "COSTS_N_INSNS (N)" чтобы определить стоимость, равную N, быстрых команд. OUTER_CODE - код выражения, в котором содержится X.

Эту макрокоманду можно не определять, если заданные по умолчанию предположения стоимости адекватны для целевой машины.

"ADDRESS_COST (ADDRESS)"

Выражение, дающее стоимость способа адресации, который содержит ADDRESS. Если не определена, то стоимость вычисляется из выражения ADDRESS и значения "CONST_COSTS".

Для большинства CISC машин, заданная по умолчанию стоимость - хорошее приближение истинной стоимости способа адресации. Однако, на RISC машинах, все команды обычно имеют ту же самую длину и время выполнения. Следовательно все адреса будут иметь равные издержки.

В случаях, где известна более, чем одна форма адреса, будет использоваться форма с самой низкой стоимостью. Если многие формы имеют одну и ту же самую низкую стоимость, то будет использоваться та, которая наиболее сложна.

Например, представьте, что адрес, который является суммой регистра и константы, используется дважды в одном базисном блоке. Когда эта макрокоманда не определена, адрес будет вычислен в регистре, и ссылки на память будут косвенными, через этот регистр. На машинах, где стоимость способа адресации, содержащего сумму, не выше чем простой косвенной ссылки, она произведет дополнительную команду и, возможно, потребует дополнительного регистра. Правильная спецификация этой макрокоманды устраняет эту добавку для таких машин.

Подобным образом эта макрокоманда используется при оптимизации циклов.

ADDRESS должен быть правильным, как адрес. В таком случае, стоимость не имеет значения и может быть принята произвольной; недопустимым адресам не должны присваиваться различные стоимости.

На машинах, где адрес, включающий больше, чем один регистр, - такой же дешевый, как адреса, включающий только один регистр, определение "ADDRESS_COST", для отражения этого, может заставить два регистра жить в области кода, где был бы только один, если "ADDRESS_COST" не была бы определена. Этот эффект должен рассматриваться в определении этой макрокоманды. Эквивалентные издержки должны быть приданы, вероятно, только адресам с различными числами регистров на машинах с очень большим количеством регистров.

Эту макрокоманду можно не определять или определять, как константу.

"REGISTER_MOVE_COST (FROM, TO)"

Выражение C стоимости перемещения данных из регистра класса FROM в регистр класса TO. Классы выражены используя порядковые значения "GENERAL_REGS". Значение 4 - значение по умолчанию; другие значения интерпретируются относительно этого.

Не требуется, чтобы стоимость всегда равнялась 2, если FROM = TO; на некоторых машинах дорого перемещать данные между регистрами, если они - не регистры общего назначения.

Если перезагрузка видит insn, состоящий из одиночного "set" между двумя аппаратными регистрами, и если "REGISTER_MOVE_COST" для их классов возвращает значение 2, перезагрузка не проверяет, что ограничения insn выполнены. Установка стоимости на значение, не равное 2, позволяет перезагрузке проверять, что ограничения выполнены. Вы должны делать это, если "movM" ограничения на образец не позволяют такое копирование.

"MEMORY_MOVE_COST (M)"

Выражение C стоимости перемещения данных типа M между регистром и памятью. По умолчанию : 2; это стоимость относительно стоимости в "REGISTER_MOVE_COST".

Если копирование между регистрами и памятью дороже, чем между двумя регистрами, вы должны определить эту макрокоманду, чтобы выразить относительную стоимость.

"BRANCH_COST"

Выражение C стоимости команды перехода (ветвления). По умолчанию : 1; другие значения интерпретируются относительно этого.

Вот дополнительные макрокоманды, которые определяют не точные относительные издержки, а некоторые действия, которые более дороги, чем GNU CC обычно ожидает.

"SLOW_BYTE_ACCESS"

Определите эту макрокоманду как выражение C, которое отлично от нуля, если обращение менее, чем в слову в памяти (то есть к "char" или "short") не быстрее, чем обращение к слову, то есть, если такой доступ требует более одной команды или если нет различия в стоимости загрузки байта и (выровненного) слова.

Когда эта макрокоманда не определена, транслятор обратится к полю, находя самый маленький содержащийся объект; когда определена, будет использоваться загрузка полного слова, если разрешает выравнивание. Если к доступ к байтам не быстрее, чем доступ к словам, использование слов предпочтительно, так как может устранить последующее обращение к памяти, если последующие обращения происходят к другим полям в том же слове из структуры, но к различным байтам.

"SLOW_ZERO_EXTEND"

Определите эту макрокоманду, если расширение нулем (типов "char" или "short" до "int") может быть выполнено быстрее, если адресат - регистр, про который известно, что он - ноль.

Если вы определяете эту макрокоманду, вы должны иметь образцы команды, которые распознают структуры RTL подобно этому:

 (set (strict_low_part (subreg:QI (reg:SI ...) 0)) ...)
и аналогично для "HImode".

"SLOW_UNALIGNED_ACCESS"

Определите эту макрокоманду, равной 1, если доступ к невыровненным данным имеет стоимость во много раз большую, чем доступ к выровненным данным, например, если они эмулированы в обработчике ловушки.

Когда эта макрокоманда отлична от нуля, транслятор будет действовать, как будто "STRICT_ALIGNMENT" была отлична от нуля при генерации кода для блочного копирования. Это может заставлять транслятор генерировать гораздо больше инструкций. Следовательно, не устанавливайте эту макрокоманду в отличное от нуля значение, если доступ к невыровненным данным только добавляет цикл или два к времени доступа к памяти.

Если значение этой макрокоманды - всегда ноль, ее не нужно определять.

"DONT_REDUCE_ADDR"

Определите эту макрокоманду, чтобы запретить уменьшение количества адресов памяти. (На некоторых машинах, такое уменьшение количества делает больше вреда, чем пользы.)

"MOVE_RATIO"

Количество insn, занимающихся скалярным перемещением, которые должны быть сгенерированы вместо insn, реализующего строковое перемещение или вызова библиотечной функции. Увеличение значения будет всегда делать код более быстрым, но в конечном счете сильно увеличивает размер кода.

Если вы не определяете эту макрокоманду, используется приемлемое значение по умолчанию.

"NO_FUNCTION_CSE"

Определите эту макрокоманду, если вызвать постоянную функцию не дороже, чем по адресу в регистре.

"NO_RECURSIVE_FUNCTION_CSE"

Определите эту макрокоманду, если функции не дороже вызвать саму себя по явному адресу, чем по адресу в регистре.

"ADJUST_COST (INSN, LINK, DEP_INSN, COST)"

Оператор C (без точки с запятой) для модификации целой переменной COST (стоимость) , основанную на связи между INSN, который зависит от DEP_INSN через LINK зависимость. По умолчанию не производится корректировка COST. Это может использоваться например, чтобы указать планировщику, что вывод или анти-зависимость не несет ту же самую стоимость как зависимость данных.

6.14 Деление Вывода на Разделы

Объектный файл разделен на разделы, содержащие различные типы данных. В наиболее общем случае, имеются три раздела: "текстовый раздел", который содержит команды и данные только для чтения; "раздел данных", который содержит инициализированные перезаписываемые данные; и "раздел bss", который содержит неинициализированные данные. Некоторые системы имеют другие виды разделов.

Транслятор должен сообщить ассемблеру, когда переключать разделы. Эти макрокоманды управляют тем, какие команды вывести, чтобы сообщить об этом ассемблеру. Вы можете также определять дополнительные разделы.

"TEXT_SECTION_ASM_OP"

Выражение C, значение которого - строка, содержащая ассемблерную операцию, которая должна предшествовать командам и данным только для чтения. Обычно ".text".

"DATA_SECTION_ASM_OP"

Выражение C, значение которого - строка, содержащая ассемблерную операцию для идентификации следующих данных как перезаписываемые инициализированные данные. Обычно ".data".

"SHARED_SECTION_ASM_OP"

Если определена, то это выражение C, значение которого - строка, содержащая ассемблерную операцию для идентификации следующих данных как разделяемых данных. Если не определена, будет использоваться "DATA_SECTION_ASM_OP".

"INIT_SECTION_ASM_OP"

Если определена, это выражение C, значение которого - строка, содержащая ассемблерную операцию для идентификации следующих данных как кода инициализации. Если не определена, GNU CC считает, что такого раздела не существует.

"EXTRA_SECTIONS"

Список имен для разделов, отличных от двух стандартных, которые являются "in_text" и "in_data". Вы не должны определять эту макрокоманду, если на системе нет других разделов (которые GCC должен использовать).

"EXTRA_SECTION_FUNCTIONS'

Одна или больше функций, которые определены в "varasm.c". Эти функции должны производить действия, аналогичные функциям из "text_section" и "data_section", но для ваших дополнительных разделов. Не определяйте эту макрокоманду, если вы не определили "EXTRA_SECTIONS".

"READONLY_DATA_SECTION"

На большинстве машин переменные только для чтения, константы и таблицы переходов помещены в текстовый раздел. Если на вашей машине это не так, эта макрокоманда должна быть определена именем функции (из "data_section" или определенной в "EXTRA_SECTIONS") которая переключается на соответствующий раздел, который используется для элементов только для чтения.

Если эти элементы были помещены в текстовый раздел, эту макрокоманду не нужно определять.

"SELECT_SECTION (EXP, RELOC)"

Оператор(ы) C для переключения на соответствующий раздел для вывода EXP. Вы можете считать, что EXP - или "VAR_DECL" узел, или константа некоторого типа. RELOC указывает, требует ли начальное значение EXP настроек времени компоновки. Выберите раздел, вызывая "text_section" или одну из альтернатив для других разделов.

Не определяйте эту макрокоманду, если вы помещаете все переменные только для чтения и константы в раздел данных только для чтения (обычно текстовый раздел).

"SELECT_RTX_SECTION (MODE, RTX)"

Оператор(ы) C для переключения на соответствующий раздел для вывода RTX в типе MODE. Вы можете принять, что RTX - некоторая константа в RTL. Параметр MODE избыточен за исключением случая "const_int" rtx. Выберите раздел, вызывая "text_section" или одну из альтернатив для других разделов.

Не определяйте эту макрокоманду, если вы помещаете все константы в раздел данных только для чтения.

"JUMP_TABLES_IN_TEXT_SECTION"

Определите эту макрокоманду, если таблицы перехода (для "tablejump" insns) должны быть выведены в текстовый раздел, наряду с командами ассемблера. Иначе используется раздел данных только для чтения.

Эта макрокоманда не имеет значения, если нет отдельного раздела данных только для чтения.

"ENCODE_SECTION_INFO (DECL)"

Определите эту макрокоманду, если ссылки на символ должны обрабатываться по-разному в зависимости от переменной или функции, названной символом (так же как, в каком разделе она находится).

Определение макрокоманды, если есть, выполняется немедленно после того, как rtl для DECL был создан и сохраняется в "DECL_RTL (DECL)". Значение rtl будет "mem", адрес которого - "symbol_ref".

Обычная вещь для этой макрокоманды : записывать флажок в "symbol_ref" (типа "SYMBOL_REF_FLAG") или сохранять измененную строку имени в "symbol_ref" (если одного бита недостаточно для информации).

"STRIP_NAME_ENCODING (VAR, SYM_NAME)"

Декодируйте SYM_NAME, и сохраните реальную часть имени в VAR, без символов, которые кодируют информацию о разделе. Определите эту макрокоманду, если "ENCODE_SECTION_INFO" изменяет строку имени символа.

6.15 Позиционно-Независимый Код

Этот раздел описывает макрокоманды, которые помогают генерировать позиционно-независимый код. Простое определение этих макрокоманд недостаточно для генерации правильного PIC; вы должны также добавить поддержку макрокоманд "GO_IF_LEGITIMATE_ADDRESS" и "PRINT_OPERAND_ADDRESS", также как "LEGITIMIZE_ADDRESS". Вы должны изменить определение "movsi" так, чтобы она выполняла соответствующее действие, когда исходный операнд содержит символический адрес. Вам может понадобиться также изменение обработки переключающих операторов так, чтобы они использовали относительные адреса.

"PIC_OFFSET_TABLE_REGNUM"

Номер регистра, используемого для адресации таблицы адресов статических данных в памяти. В некоторых случаях этот регистр определен в "application binary interface" (ABI). Когда эта макрокоманда определена, RTL сгенерирован для этого регистра один раз, как с указателем стека и регистрами указателя кадра. Если эта макрокоманда не определена, машинно-зависимые файлы обязаны распределить такой регистр (в случае необходимости).

"PIC_OFFSET_TABLE_REG_CALL_CLOBBERED"

Определите эту макрокоманду, если регистр, определенный "PIC_OFFSET_TABLE_REGNUM", затирается (clobbered) обращениями. Не определяйте эту макрокоманду, если "PIC_OFFSET_TABLE_REGNUM" не определена.

"FINALIZE_PIC"

Генерируя позиционно-независимый код, когда две различных программы (A и B) совместно используют общую библиотеку (libC.a), текст библиотеки может быть разделен, в зависимости от того, скомпонована ли библиотека к тому же самому адресу к обеим программам. В некоторых из этих сред позиционно-независимый код требует не только использования различных способов адресации, но также специального кода разрешения использования этих способов адресации.

Макрокоманда "FINALIZE_PIC" служит как ловушка, чтобы выдавать эти специальные коды, как только функция компилируется в ассемблерный код, но не раньше. (Это не выполнено раньше, потому что в случае компиляции inline-функции, это вело бы к большому числу прологов PIC, включаемых в функции, которые использовали inline-функции и компилировались в ассемблер.)

"LEGITIMATE_PIC_OPERAND_P (X)"

Выражение C, которое отлично от нуля если X - правильный непосредственный операнд на целевой машине при генерации позиционно-независимого кода. Вы можете принять, что X удовлетворяет "CONSTANT_P", так что вы не должны проверять этого. Вы можете также принять, что FLAG_PIC истинен, так что вы не должны проверять этого. Вы не должны определять эту макрокоманду, если все константы (включая "SYMBOL_REF") могут быть непосредственными операндами при генерации позиционно-независимого кода.

6.16 Определение Выходного Языка Ассемблера

Этот раздел описывает макрокоманды, принципиальная цель которых состоит в описании того, как писать команды на языке ассемблеров, а не того, что эти команды делают.

Полная Структура Ассемблерного Файла

Описание полной структуры ассемблерного файла.

"ASM_FILE_START (STREAM)"

Выражение C, которое выводит на stdio STREAM текст, которым должен начинаться ассемблерный файл.

Обычно эта макрокоманда определяется, чтобы вывести строку, содержащую "#NO_APP", которое является комментарием, который не имеет эффекта на большинстве ассемблеров, но сообщает GNU ассемблеру, что он может не тратить время, проверяя некоторые конструкций ассемблера.

На системах, которые используют SDB, необходимо вывести некоторые команды; см. "attasm.h".

"ASM_FILE_END (STREAM)"

Выражение C, которое выводит на stdio STREAM текст, которым должен заканчиваться ассемблерный файл.

Если эта макрокоманда не определена, по умолчанию ничего особенного не должно вывестись в конце файла. Большинство систем не требует никакого определения.

На системах, которые используют SDB, необходимо вывести некоторые команды; см. "attasm.h".

"ASM_IDENTIFY_GCC (FILE)"

Оператор C вывода команд ассемблера, которые идентифицируют объектный файл как компилированный GNU CC (или другим GNU-транслятором).

Если вы не определяете эту макрокоманду, выводится строка "gcc_compiled.:". Эта строка вычисляется, чтобы определить символ, который на BSD системах, никогда не будет определен по любой другой причине. GDB проверяет присутствие этого символа при чтении таблицы символов выполнимой программы.

На не-BSD системах вы должны установить связь с GDB другим способом. Если GDB не используется на вашей системе, вы можете определить эту макрокоманду с пустым телом.

"ASM_COMMENT_START"

Строковая константа C, описывающая, как начинать комментарий на целевом ассемблере. Транслятор принимает, что комментарий заканчивается в конце строки.

"ASM_APP_ON"

Строковая константа C для текста, который нужно вывести перед каждым оператором (или последовательной группой) "asm". Обычно это - "#APP", который является комментарием, не имеющим эффекта на большинстве ассемблеров, но сообщающим GNU ассемблеру, что он должно проверить последующие строки на правильность ассемблерных конструкций.

"ASM_APP_OFF"

Строковая константа C для текста, который нужно вывести после каждого оператора (или последовательной группы) "asm". Обычно это - "#NO_APP", который говорит GNU ассемблеру экономить время, делая предположения, которые правильны для обычного вывода транслятора.

"ASM_OUTPUT_SOURCE_FILENAME (STREAM, NAME)"

Оператор C вывода COFF информации или DWARF-отладочной информации, который пишет на stdio поток STREAM, что файл с именем NAME - текущий исходный файл.

Эта макрокоманду не надо определять, если подходит стандартная форма вывода для формата используемого файла.

"ASM_OUTPUT_SOURCE_LINE (STREAM, LINE)"

Оператор C вывода на stdio STREAM DBX или SDB отладочной информации перед кодом для строки номер LINE текущего исходного файла.

Эта макрокоманду не надо определять, если стандартная форма отладочной информации для используемого отладчика, подходящая.

"ASM_OUTPUT_IDENT (STREAM, STRING)"

Оператор C вывода чего-то в ассемблерный файл, чтобы обработать "#ident" директиву, содержащую текст STRING. Если эта макрокоманда не определена, ничего не выводится для "#ident" директивы.

"ASM_OUTPUT_SECTION_NAME (STREAM, DECL, NAME)"

Оператор C вывода чего-то в ассемблерный файл, чтобы переключиться на раздел NAME для объекта DECL, который является "FUNCTION_DECL", "VAR_DECL" или "NULL_TREE". Некоторые целевые форматы не поддерживают произвольные разделы. Не определяйте эту макрокоманду в таких случаях.

В настоящее время эта макрокоманда используется только чтобы поддерживать атрибуты раздела. Когда эта макрокоманда не определена, атрибуты раздела запрещены.

"OBJC_PROLOGUE"

Оператор C вывода любых ассемблерных операторов, которые должны предшествовать любым определениям Objective C объектов или посылке сообщений. Оператор выполняется только при компиляции программы на Objective C.

Вывод Данных

Описание вывода данных.

"ASM_OUTPUT_LONG_DOUBLE (STREAM, VALUE)"

"ASM_OUTPUT_DOUBLE(STREAM, VALUE)"

"ASM_OUTPUT_FLOAT(STREAM, VALUE)"

"ASM_OUTPUT_THREE_QUARTER_FLOAT(STREAM, VALUE)"

"ASM_OUTPUT_SHORT_FLOAT(STREAM, VALUE)"

"ASM_OUTPUT_BYTE_FLOAT(STREAM, VALUE)"

Операторы C вывода на stdio STREAM ассемблерной команды для трансляции константы с плавающей точкой из "TFmode", "DFmode", "SFmode", "TQFmode", "HFmode", или "QFmode", соответственно, значение которой - VALUE. VALUE - выражение C типа "REAL_VALUE_TYPE". Макрокоманды типа "REAL_VALUE_TO_TARGET_DOUBLE" полезны для написания этих определений.

"ASM_OUTPUT_QUADRUPLE_INT(STREAM, EXP)"

"ASM_OUTPUT_DOUBLE_INT(STREAM, EXP)"

"ASM_OUTPUT_INT(STREAM, EXP)"

"ASM_OUTPUT_SHORT(STREAM,EXP)"

"ASM_OUTPUT_CHAR(STREAM,EXP)"

Оператор C вывода на stdio STREAM ассемблерной команды для трансляции целого числа длиной 16, 8, 4, 2 или 1 байт, соответственно, значение которого - VALUE. Параметр EXP будет выражением RTL, которое представляет постоянное значение. Используйте "output_addr_const(STREAM,EXP)" чтобы вывести это значение как ассемблерное выражение.

Вам не нужно определять эту макрокоманду для размеров больших, чем "UNITS_PER_WORD", если действие макрокоманды было бы многократным вызовом макрокоманды, соответствующей размеру "UNITS_PER_WORD", по одному для каждого слова.

"ASM_OUTPUT_BYTE (STREAM, VALUE)"

Оператор C вывода на STREAM ассемблерной команды для трансляции одиночного байта, содержащего значение VALUE.

"ASM_BYTE_OP"

Строковая константа C, дающая псевдооперацию, используемую для последовательности констант в один байт. Если эта макрокоманда не определена, по умолчанию - "byte".

"ASM_OUTPUT_ASCII (STREAM, PTR, LEN)"

Оператор C вывода на stdio STREAM ассемблерной команды для трансляции строковой константы, содержащей LEN байт в PTR. PTR - выражение C типа "char*", а LEN - выражение C типа "int".

Если ассемблер имеет ".ascii" псевдооперацию, как в Berkeley Unix ассемблере, не определяйте макрокоманду "ASM_OUTPUT_ASCII".

"ASM_OUTPUT_POOL_PROLOGUE (FILE FUNNAME FUNDECL SIZE)"

Оператор C вывода ассемблерных команд для определения начала постоянного pool для функции. FUNNAME - строка, дающая имя функции. Если требуется тип возврата функции, он может быть получен через FUNDECL. SIZE - размер в байтах константного pool, который будет написан немедленно после этого обращения.

Если pool-префикс не требуется (обычный случай), то не надо определять эту макрокоманду.

"ASM_OUTPUT_SPECIAL_POOL_ENTRY (FILE, X, MODE, ALIGN, LABELNO, JUMPTO)"

Оператор C (с точкой с запятой или без нее) вывода константы в константный pool, если она требует специальной обработки. (Этой макрокоманде не требуется делать что бы то ни было для выражений RTL, которые могут выводиться обычным образом.)

Параметр FILE - стандартный I/O-поток, для вывода ассемблерного кода. X - выражение RTL для константы, которую надо вывести, и MODE - тип (в случае, если X - "const_int"). ALIGN - требуемое выравнивание для значения X; вы должны вывести ассемблерную директиву, чтобы форсировать это выравнивание.

Параметр LABELNO - номер, используемый во внутренней метке для адреса этого pool. Определение этой макрокоманды ответственно за вывод определения метки на соответствующее место. Вот как это делается :

ASM_OUTPUT_INTERNAL_LABEL (FILE, "LC", LABELNO);

Когда вы выводите ячейку pool особенным образом, вы должны завершить ее переходом "goto" к метке JUMPTO. Это предотвратит вторичный вывод той же ячейки обычным способом.

Вам не нужно определять эту макрокоманду, если она ничего не делала бы.

"IS_ASM_LOGICAL_LINE_SEPARATOR (C)"

Определите эту макрокоманду как выражение C, которое отлично от нуля, если C используется как логический разделитель строк ассемблером.

Если вы не определяете эту макрокоманду, то по умолчанию только символ ";" обрабатывается как логический разделитель строк.

"ASM_OPEN_PAREN"

"ASM_CLOSE_PAREN"

Эти макрокоманды определены как строковые константы C, описывающие синтаксис ассемблера для группировки арифметических выражений. Следующие определения правильны для большинства ассемблеров :

 #define ASM_OPEN_PAREN "("
 #define ASM_CLOSE_PAREN ")"
Эти макрокоманды обеспечиваются "real.h" для написания определений "ASM_OUTPUT_DOUBLE" и подобных :

"REAL_VALUE_TO_TARGET_SINGLE (X, L)"

"REAL_VALUE_TO_TARGET_DOUBLE (X, L)"

"REAL_VALUE_TO_TARGET_LONG_DOUBLE (X, L)"

Они транслируют X типа "REAL_VALUE_TYPE" в целевое представление с плавающей точкой, и сохраняют битовый образец в массиве с элементами типа "long int", адрес которого - L. Число элементов в выводимом массиве определено размером желаемого целевого типа данных с плавающей точкой : 32 бита от него входят в каждый "long int" элемент массива. Каждый элемент массива содержит 32 бита результата, даже если "long int" на данной машине шире, чем 32 бита.

Значения элементов массива разработаны так, чтобы вы могли печатать их, используя "fprintf", в порядке, в котором они должны появиться в памяти целевой машины.

"REAL_VALUE_TO_DECIMAL (X, FORMAT, STRING)"

Эта макрокоманда преобразует X типа "REAL_VALUE_TYPE" к десятичному числу и сохраняет в виде строки STRING. Вы должны передать в STRING адрес достаточно длинного блока памяти, чтобы содержать результат.

Параметр FORMAT - это "printf"-спецификация, которая служит предложением того, как форматировать строку вывода.

Вывод Неинициализированных Переменных

Каждая из макрокоманд в этом разделе используется, чтобы выполнять всю работу по выводу одиночной неинициализированной переменной.

" ASM_OUTPUT_COMMON (STREAM, NAME, SIZE, ROUNDED) "

Оператор C (без точки с запятой) для вывода в stdio поток STREAM ассемблерного определения общей метки NAME размером SIZE байт. Переменная ROUNDED - размер, округленный кверху до любого выравнивания которое требуется вызывающей функцией.

Используйте выражение " assemble_name (STREAM, NAME) " для вывода самого имени; до и после которого, выводится дополнительный синтаксис ассемблера для определения имени и переход на новую строку.

Эти макрокоманды контролируют, как выводятся ассемблерные определения неинициализированных глобальные переменные.

" ASM_OUTPUT_ALIGNED_COMMON (STREAM, NAME, SIZE, ALIGNMENT) "

Подобно " ASM_OUTPUT_COMMON ", за исключением того, что требует выравнивание как отдельный, явный параметр. Если Вы определяете эту макрокоманду, она используется вместо " ASM_OUTPUT_COMMON ", и дает Вам больше гибкости в обработке требуемого выравнивания переменной. Выравнивание определяется как число битов.

" ASM_OUTPUT_SHARED_COMMON (STREAM, NAME, SIZE, ROUNDED) "

Если определена, то подобна " ASM_OUTPUT_COMMON ", за исключением того, что она используется, если участвует NAME. Если она не определена, будет использоваться " ASM_OUTPUT_COMMON".

" ASM_OUTPUT_LOCAL (STREAM, NAME, SIZE, ROUNDED) "

Оператор C (без точки с запятой) для вывода в stdio поток STREAM определения ассемблера локальной общей метки NAME размером SIZE байтов. Переменная ROUNDED - это размер, округленный кверху до любого выравнивания, требуемого вызывающей функцией.

Используйте выражение " assemble_name (STREAM, NAME) " для вывода самого имени; до и после него выводите дополнительный синтаксис ассемблера для определения имени и переход на новую строку.

Эти макрокоманды контролируют, как выводятся ассемблерные определения неинициализированных статических переменных.

" ASM_OUTPUT_ALIGNED_LOCAL (STREAM, NAME, SIZE, ALIGNMENT) "

Подобно " ASM_OUTPUT_LOCAL ", за исключением того, что требует выравнивание как отдельный, явный параметр. Если Вы определяете эту макрокоманду, она используется вместо " ASM_OUTPUT_LOCAL " и дает Вам большую гибкость в обработке требуемого выравнивания переменной. Выравнивание определяется как число битов.

" ASM_OUTPUT_SHARED_LOCAL (STREAM, NAME, SIZE, ROUNDED) "

Если определено, подобно " ASM_OUTPUT_LOCAL ", за исключением того, что оно используется, если участвует NAME. Если не определено, будет использоваться " ASM_OUTPUT_LOCAL".

Вывод и Генерация Меток

Это относится к выводу меток.

" ASM_OUTPUT_LABEL (STREAM, NAME) "

Оператор C (без точки с запятой) для вывода в stdio поток STREAM ассемблерной метки NAME. Используйте выражение " assemble_name (STREAM, NAME) " для вывода имени непосредственно; до и после этого, выводится дополнительный синтаксис ассемблера для определения имени и переход на новую строку.

" ASM_DECLARE_FUNCTION_NAME (STREAM, NAME, DECL) "

Оператор C (без точки с запятой) для вывода в stdio поток STREAM любого текста, необходимого для объявления имени NAME определяемой функции. Эта макрокоманда отвечает за вывод определения метки (возможно использование "ASM_OUTPUT_LABEL "). Параметр DECL - это " FUNCTION_DECL " узел дерева, представляющего функцию.

Если эта макрокоманда не определена, то имя функции определяется обычным способом как метка (посредством " ASM_OUTPUT_LABEL ").

" ASM_DECLARE_FUNCTION_SIZE (STREAM, NAME, DECL) "

Оператор C (без точки с запятой) для вывода в stdio поток STREAM любого текста, необходимого для объявления размера функции, которая определяется. Параметр NAME - имя функции. Параметр DECL - это " FUNCTION_DECL " узел дерева, представляющего функцию.

Если эта макрокоманда не определена, то размер функции не определен.

" ASM_DECLARE_OBJECT_NAME (STREAM, NAME, DECL) "

Оператор C (без точки с запятой) для вывода в stdio поток STREAM любого текста, необходимого для объявления имени NAME инициализированной определяемой переменной. Эта макрокоманда должна выводить определение метки (возможно, используя " ASM_OUTPUT_LABEL "). Параметр DECL - " VAR_DECL " узел дерева, представляющего переменную.

Если эта макрокоманда не определена, то имя переменной определяется обычным способом как метка (посредством " ASM_OUTPUT_LABEL ").

" ASM_FINISH_DECLARE_OBJECT (STREAM, DECL, TOPLEVEL, ATEND) "

Оператор C (без точки с запятой) для завершения объявления имени переменной, когда компилятор обработал инициализатор полностью и, таким образом, имел возможность определить размер массива, когда он контролировался инициализатором. Используется в системах, где необходимо объявлять что-либо относительно размера объекта.

Если Вы не определяете эту макрокоманду, то это эквивалентно тому, что Вы определяете ее как пустую команду.

" ASM_GLOBALIZE_LABEL (STREAM, NAME) "

Оператор C (без точки с запятой) для вывода в stdio поток STREAM некоторых команд, которые делают метку NAME глобаль- ной, т.е. доступной для ссылки из других файлов. Используйте выражение " аssemble_name (STREAM, NAME) " для вывода самого имени; до и после этого выводится дополнительный синтаксис ассемблера, который делает это имя глобальным и переход на новую строку.

" ASM_WEAKEN_LABEL "

Оператор С (без точки с запятой) для вывода в stdio поток STREAM некоторых команд, которые делают метку NAME "сла- бой", то есть доступной для ссылки из других файлов, но ис- пользуемой только тогда, когда нет других доступных опреде- лений. Используйте выражение " assemble_name (STREAM, NAME) " для вывода самого имени; до и после этого выводится дополнительный синтаксис ассемблера, который делает имя "слабым" и переход на новую строку.

Если Вы не определяете эту макрокоманду, GNU CC не будет поддерживать "слабые" символы и Вы не должны определять макрокоманду " SUPPORTS_WEAK ".

" SUPPORTS_WEAK "

Это выражение C, которое истинно, если поддерживаются "слабые" символы.

Если Вы не определяете эту макрокоманду, " defaults.h " дает определение по умолчанию. Если " ASM_WEAKEN_LABEL " определено, определение по умолчанию " 1 "; иначе - " 0 ". Определите эту макрокоманду, если Вы хотите управлять поддержкой слабых символов с флагом транслятора типа " -melf ".

" ASM_OUTPUT_EXTERNAL (STREAM, DECL, NAME) "

Оператор C (без точки с запятой) для вывода в stdio поток STREAM любого текста, необходимого для объявления имени внешнего символа NAME, на который ссылаются при компиляции, но который не определен. Значение DECL - узел дерева для объявления.

Эту макрокоманду не обязательно определять, если не требуется ничего выводить.В GNU ассемблере и большинстве Unix ассемблеров ничего не требуется.

" ASM_OUTPUT_EXTERNAL_LIBCALL (STREAM, SYMREF) "

Оператор C (без точки с запятой) для вывода в STREAM ассемблерного псевдооператора для объявления внешнего имени библиотечной функции. Имя библиотечной функции задается SYMREF, который имеет тип " rtx " и является " symbol_ref ".

Эту макрокоманду не обязательно определять, если не требуется ничего выводить.В GNU ассемблере и большинстве Unix ассемблеров ничего не требуется.

" ASM_OUTPUT_LABELREF (STREAM, NAME) "

Оператор C (без точки с запятой) для вывода в stdio поток STREAM ссылки в синтаксисе ассемблера на метку NAME. Это должно добавить " _ " перед именем, если так принято в вашей операционной системе, как в большинстве Berkeley Unix систем. Эта макрокоманда используется в " assemble_name ".

" ASM_OUTPUT_INTERNAL_LABEL (STREAM, PREFIX, NUM) "

Оператор C для вывода в stdio поток STREAM метку, имя которой состоит из строки PREFIX и номера NUM.

Крайне необходимо, чтобы эти метки были отличны от меток, используемых для функций и переменных на уровне пользователя. Иначе соответствующие программы будут иметь конфликты с внутренними метками.

Желательно исключить внутренние метки из символьной таблицы объектного файла. Большинство ассемблеров имеет соглашение для наименований меток, которые должны быть исключены; во многих системах символ "L" в начале метки имеет этот эффект. Вы должны выяснить, какие соглашения использует ваша система, и следовать этому.

Обычное определение этой макрокоманды следующее:

  fprintf (STREAM, "L%s%d:\n", PREFIX, NUM)
" ASM_GENERATE_INTERNAL_LABEL (STRING, PERFIX, NUM) "

Оператор C для сохранения в строке STRING метки, имя которой состоит из строки PREFIX и номера NUM.

Эта строка, когда выводится следом за " assemble_name ", должна генерировать вывод, который " ASM_OUTPUT_INTERNAL_LABEL " сгенерировал бы с теми же PREFIX и NUM.

Если строка начинается со "*", то " assemble_name " выведет остальную часть строки без изменений. Использование "*" таким образом часто удобно для " ASM_GENERATE_INTERNAL_LABEL ". Если строка не начинается со "*", то " ASM_OUTPUT_LABELREF " может изменить строку при выводе. (Конечно, " ASM_OUTPUT_LABELREF " является также частью вашего машинного описания, так что Вы должны знать то, что она делает на вашей машине.)

" ASM_FORMAT_PRIVATE_NAME (OUTVAR, NAME, NUMBER) "

Оператор C для присваивания OUTVAR (переменной типа " сhar* ") заново распределенной строки, полученной из строки NAME и номера NUMBER, с добавлением некоторой подходящей пунктуации. Используйте " аlloca ", чтобы получить память для строки.

Строка будет использоваться как параметр для " ASM_OUTPUT_LABELREF ", чтобы сделать метку ассемблера для внутренней статической переменной NAME. Следовательно, строка должна быть такой, чтобы дать в результате верный код ассемблера. Параметр NUMBER меняется каждый раз, когда эта макрокоманда выполняется; это предотвращает конфликты между одинаково названными внутренними статическими переменными в различных контекстах.

В идеале, эта строка не должна быть допустимым C идентификатором, чтобы предотвратить любой конфликт с собственными символами пользователя. Большинство ассемблеров допускают знаки "." или "%" в символах ассемблера; помещения по крайней мере одного из этих знаков между именем и номером будет достаточно.

" ASM_OUTPUT_DEF (STREAM, NAME, VALUE) "

Оператор C для вывода в stdio поток STREAM кода ассемблера, который определяет(присваивает) символу NAME значение VALUE.

Если SET_ASM_OP определен, обеспечивается определение по умолчанию, которое корректно для большинства систем.

" OBJC_GEN_METHOD_LABEL (BUF, IS_INST, CLASS_NAME, CAT_NAME, SEL_NAME) "

Определите эту макрокоманду, чтобы изменить заданные по умолчанию ассемблерные имена, используемые для методов Objective C.

Заданное по умолчанию имя - уникальный номер метода, сопровождаемый именем класса (например, " _1_Foo "). Для методов в категориях имя категории также включается в имя ассемблера (например, " _1_Foo_Bar ").

Эти имена безопасны в большинстве систем, но создают трудности при отладке, так как селектор метода не представлен в имени. Поэтому отдельные системы определяют другие способы вычисления имен.

BUF - выражение типа " char * ", которое дает Вам буфер, в котором хранится имя; его длина равна суммарной длине CLASS_NA- ME, CAT_NAME и SEL_NAME плюс 50 символов.

Параметр IS_INST определяет, является ли метод экземпляром метода или классом метода; CLASS_NAME - имя класса; CAT_NAME - имя категории (или NULL, если метод не содержится в категории); и SEL_NAME - имя селектора.

На системах, где ассемблер может обрабатывать имена в кавычках, Вы можете использовать эту макрокоманду, чтобы обеспечить более читаемые имена.

Как обрабатываются функции инициализации

Оттранслированная программа для некоторых языков включает "конструкторы" (называемые также " подпрограммами инициализации ") - функции для инициализации данных программы, когда она начинает работу. Эти функции должны быть вызваны прежде, чем программа "запускается" - то есть перед вызовом " main "

Компилирование некоторых языков генерирует "деструкторы" (называемые также " подпрограммами завершения "), которые должны вызываться, когда программа завершает работу.

Чтобы заставить работать функции инициализации и завершения, компилятор должен вывести кое-что в коде ассемблера, чтобы эти функции вызывались в соответствующее время. Когда Вы адаптируете транслятор к новой системе, Вы должен указать, как сделать это.

Имеются два основных способа, которыми GCC поддерживает выполнение функций инициализации и завершения. Каждый способ имеет два варианта. Многое из структуры является общим для всех четырех вариантов.

Компоновщик должен формировать два списка из этих функций - список функций инициализации, называемый " __ CTOR_LIST __ ", и список функций завершения, называемый " __ DTOR_LIST __ ".

Каждый список всегда начинается с игнорируемого указателя на функцию (который может содержать 0, -1 или количество указателей на функцию после него, в зависимости от среды). За ним идет последовательность из нуля или более функций - указателей на конструкторы (или деструкторы), заканчивающаяся указателем на функцию, содержащим ноль.

В зависимости от операционной системы и формата исполняемого файла, " crtstuff.c " или " libgcc2.c " просматривает эти списки в момент запуска и выхода. Конструкторы вызваются в порядке, обратном порядку в списке; деструкторы - в прямом порядке.

Самый лучший способ обработки статических конструкторов работает только для форматов объектного файла, которые поддерживают произвольно названные разделы. Разделы определяются отдельно для списка конструкторов и для списка деструкторов.Традиционно они называются ".ctors " и ".dtors ". Каждый объектный файл, который определяет функцию инициализации, также помещает слово в раздел конструктора, чтобы указать на эту функцию. Компоновщик собирает все эти слова в один ".ctors" раздел. Функции завершения обрабатываются аналогично.

Чтобы использовать этот метод, необходимо определить макрокоманды " ASM_OUTPUT_CONSTRUCTOR " и " ASM_OUTPUT_DESTRUCTOR ". Обычно можно получить их, включая " svr4.h ".

Если доступны произвольные разделы, имеется два варианта, в зависимости от того, как вызывается код в " crtstuff.c ". В системах, которые поддерживают "init" раздел, который выполняется при запуске программы, части " crtstuff.c " компилируются в этот раздел. Программа, компонуется " gcc " драйвером примерно так:

  ld -o OUTPUT_FILE crtbegin.o ... crtend.o -lgcc

Заголовок функции (" __ do_global_ctors ") появляется в init разделе " crtbegin.o "; остаток функции появляется в init разделе " crtend.o ". Компоновщик соединит две эти части раздела вместе, создавая целую функцию. Если какие-то из пользовательских объектных файлов скомпоновались в середину этого кода, то этот код будет выполняться как часть тела " __ do_global_ctors ".

Чтобы использовать этот вариант, нужно соответственно определить макрокоманду " INIT_SECTION_ASM_OP ".

Если никакой init раздел не доступен, " INIT_SECTION_ASM_OP " не определяется. Затем " __ do_global_ctors" встраивается в текст раздела подобно всем другим функциям и располагается в " libgcc.a ". Когда GCC компилирует произвольную функцию, называемую " main ", он вставляет вызов процедуры " __main " как первый выполнимый код после пролога функции. Функция " __main ", также определенная в " libgcc2.c ", просто вызывает " __ do_global_ctors ".

В форматах файла, которые не поддерживают произвольные разделы, cнова имеется два варианта. В самом простом варианте должны использоваться GNU компоновщик (GNU " ld ") и формат " a.out ". В этом случае " ASM_OUTPUT_CONSTRUCTOR " определяется так, чтобы производить ".stabs" вход типа " N_SETT ", ссылаясь на имя " __CTOR_LIST__ ", и с адресом void функции, содержащей код инициализации как значение. GNU компоновщик распознает это как запрос, чтобы добавить значение к "set"; значения накапливаются и,в конечном счете, помещаются в выполняемый файл как вектор в формате, описанном выше, со счетчиком (игнорируемым) в начале и конечным элементом ноль. " ASM_OUTPUT_DESTRUCTOR " обрабатываеся аналогично. Так как нет доступного init раздела, отсутствие " INIT_SECTION_ASM_OP " заставляет трансляцию " main " вызывать "__ main " как выше, начиная процесс инициализации.

Последний вариант не использует ни произвольные разделы, ни GNU компоновщик. Он предпочтителен, когда требуется динамическая компоновка и когда используются форматы файла, которые GNU компоновщик не поддерживает, типа " ECOFF ". В этом случае, " ASM_OUTPUT_CONSTRUCTOR " не генерирует " N_SETT " символ; функции инициализации и завершения распознаются просто по своим именам. Это требует дополнительной программы на шаге компоновки, которая называется " collect2 ". Эта программа эмулирует компоновщик для использования GNU CC; она работает, запуская обычным компоновщиком, но также упорядочивает включение векторов функций инициализации и завершения. Эти функции вызываются через " __ main ", как описано выше.

Выбор из этих опций конфигурации упрощается набором файлов, зависимых от операционной системы, в каталоге " config ". Эти файлы определяют все существенные параметры. Обычно достаточно включать один из них в файл машинно-зависимой конфигурации. Это следующие файлы:

" aoutos.h "

Для операционных систем, использующих формат ` a.out '.

" next.h "

Для операционных систем, использующих формат ` MachO '.

" svr3.h "

Для Системы V выпуска 3 и подобных систем, использующих формат ` COFF '.

" svr4.h "

Для Системы V выпуска 4 и подобных систем, использующих формат ` ELF '.

" vms.h "

Для операционной системы VMS.

Следующий раздел описывает конкретные макрокоманды, которые управляют и настраивают обработку функций завершения и инициализации.

Макрокоманды, управляющие программами инициализации

Вот макрокоманды, управляющие обработкой транслятором функций инициализации и завершения:

" INIT_SECTION_ASM_OP "

Если она определена, это строковая константа C для операции ассемблера, чтобы идентифицировать следующие данные как код инициализации. Если не определена, GNU CC считает, что такого раздела не существует. Когда Вы используете специальные разделы для функций инициализации и завершения, эта макрокоманда также управляет тем, как " crtstuff.c " и " Libgcc2.c " приспосабливаются для запуска функций инициализации.

" HAS_INIT_SECTION "

Если она определена, " main " не будет вызывать " __ main ", как описано выше. Эта макрокоманда должна определяться для систем, которые управляют содержанием init раздела на посимвольной основе, типа OSF/1, и не должна определяться явно для систем ,которые поддерживают " INIT_SECTION_ASM_OP ".

" LD_INIT_SWITCH "

Если определена, это строковая константа С для переключателя, который сообщает компоновщику, что следующий символ - подпрограмма инициализации.

" LD_FINI_SWITCH "

Если определена, это строковая константа С для переключателя, который сообщает компоновщику, что следующий символ - подпрограмма завершения.

" INVOKE __ main "

Если определено, " main " будет вызывать " __main ", несмотря на присутствие " INIT_SECTION_ASM_OP ". Эта макрокоманда должна быть определена для систем, где init раздел фактически не выполняется автоматически, но полезен для составления списков конструкторов и деструкторов.

" ASM_OUTPUT_CONSTRUCTOR (STREAM, NAME) "

Эта макрокоманда определяется как оператор C для вывода в поток STREAM кода ассемблера для приспособления вызова функции NAME во время инициализации.

Предположим, что NAME - имя функции C, сгенерированной автоматически транслятором. Эта функция не имеет параметров. Используйте функцию " assemble_name " для вывода имени NAME; она выполняет любые специфические для системы синтаксические преобразования, такие как добавление подчеркивания.

Если Вы не определяете эту макрокоманду, ничего специального не выводится для упорядочивания вызова функции. Это корректно, когда функция вызывается другим способом - например, посредством программы " collect2 ", которая просматривает таблицу символов, чтобы найти эти функции по их именам.

" ASM_OUTPUT_DESTRUCTOR (STREAM, NAME) "

Похоже на " ASM_OUTPUT_CONSTRUCTOR ", но используется скорее для функций завершения чем функций инициализации.

Если ваша система использует " collect2 " как средство обработки конструкторов, то эта программа обычно использует " nm ", для поиска в объектном файле функций конструктора, которые нужно вызвать. На некоторых видах систем эти макрокоманды могут определяться, чтобы выполнять работу " collect2 " быстрее (и, в некоторых случаях, заставить ее работать вообще):

" OBJECT_FORMAT_COFF "

Определите эту макрокоманду, если система использует формат COFF (Common Object File Format) объектных файлов, чтобы " collect2 " мог распознать этот формат и просматривать объектные файлы непосредственно для поиска динамических функций конструктора/деструктора.

" OBJECT_FORMAT_ROSE "

Определите эту макрокоманду, если система использует формат ROSE объектных файлов, чтобы " collect2 " мог распознать этот формат и просматривать объектные файлы непосредственно для поиска динамических функций конструктора/деструктора.

Эти макрокоманды имеют эффект только для "родного" компилятора; " collect2 " как часть кросс-компилятора всегда использует " nm " для целевой машины.

" REAL_NM_FILE_NAME "

Определите эту макракоманду как строковую константу С, содержащую имя файла, используемого, чтобы выполнить " nm ". По умолчанию ищется путь, обычный для " nm ".

Если система поддерживает общедоступнные библиотеки и имеет программу, чтобы внести в список динамические зависимости данной библиотеки или выполнимой программы, можно определить эти макрокоманды, чтобы разрешить поддержку запуска функций инициализации и завершения в общедоступнных библиотеках:

" LDD_SUFFIX "

Эта макрокоманда определяется как строковая константа C, содержащая имя программы, которая вносит в список динамические зависимости, такие как " "ldd" " под SunOS 4.

" PARSE_LDD_OUTPUT (PTR) "

Эта макрокоманда определяется как C код, который извлекает имена файлов из вывода программы, обозначенной " LDD_SUFFIX ". PTR - переменная типа " char * ", которая указывает на начало строки вывода из " LDD_SUFFIX ". Если строка вносит в список динамическую зависимость, код должен передвинуть PTR к началу имени файла на этой строке. Иначе он должен установить PTR на " NULL ".

Вывод Команд Ассемблера

Здесь описывается вывод команд ассемблера.

" REGISTER_NAMES "

Инициализатор С, содержащий ассемблерные имена для машинных регистров, каждое из которых - строковая константа C. Она транслирует количество регистров в трансляторе в язык ассемблера.

" ADDITIONAL_REGISTER_NAMES "

Если определено,то это C инициализатор для массива структур, содержащих имя и номер регистра. Эта макрокоманда определяет дополнительные имена для аппаратных регистров, таким образом разрешая опцию " asm " в объявлениях для ссылки на регистры с использованием альтернативных имен.

" ASM_OUTPUT_OPCODE (STREAM, PTR) "

Определите эту макрокоманду, если используется нестандартный ассемблер, который требует различные имена для машинных команд.

Определение - оператор или операторы C, которые выводят код операции команды ассемблера в stdio поток STREAM. Операнд PTR - переменная типа " char * ", которая указывает на имя кода операции во "внутренней" форме - форме, которая описана в машинном описании. Это определение должно вывести имя кода операции в STREAM, выполняя любую нужную трансляцию, и увеличить переменную PTR, чтобы она указывала на конец кода операции, чтобы он не выводился дважды.

Фактически,ваше определение макрокоманды может обрабатывать меньше или больше, чем все имя кода операции; но если Вы хотите обработать текст, который включает "%"-последовательности для подстановки операндов, Вы должны позаботиться о подстановке самостоятельно. Вам только надо быть уверенными, что PTR увеличивается для любого текста, который не должен выводиться нормально.

Если надо рассмотреть значения операнда, они могут быть найдены как элементы " recog_operand ".

Если макрокоманда ничего не определяет, команда выводится обычным способом.

" FINAL_PRESCAN_INSN (INSN, OPVEC, NOPERANDS) "

Если определено, это оператор C, который будет выполнен прямо перед выводом кода ассемблера для INSN, чтобы изменить извлеченные операнды так, чтобы они выводились по-разному.

Параметром OPVEC является вектор, содержащий операнды, взятые из INSN, и NOPERANDS - число элементов вектора, которые содержат значимые данные для insn. Содержание этого вектора - то, что будет использоваться, для преобразования шаблона insn в код ассемблера, так что можно изменять ассемблерный вывод, изменяя содержание вектора.

Эта макрокоманда полезна, когда разные синтаксисы ассемблера используют один файл образцов инструкций; определяя эту мак- рокоманду иначе, можно заставить большой класс команд выводиться по-разному (например, с переставленными операндами). Конечно, изменения в синтаксисе ассемблера, воздействующие на индивидуальные образцы insn, должны быть обработаны при записи условных программ вывода в этих образцах.

Если эта макрокоманда не определена, она эквивалентна пустому оператору.

" PRINT_OPERAND (STREAM, X, CODE) "

Составной операторы С, чтобы вывести в stdio поток STREAM синтаксис ассемблера для операнда команды X. X - выражение RTL.

CODE - значение, которое может использоваться для определения одного из нескольких способов печати операнда. Используется, когда идентичные операнды должны печататься по-разному в зависимости от контекста. CODE исходит из "%" спецификации, которая использовалась, чтобы запросить печать операнда. Если спецификация была только " %DIGIT ", то CODE - 0; Если спецификация была " %LTR DIGIT ", то CODE - ASCII код для LTR.

Если X - регистр, эта макрокоманда напечатает имя регистра. Имена могут быть найдены в массиве " reg_names ", тип которого - "char *[] ". " reg_names " инициализируется из " REGISTER_NAMES ".

Когда машинное описание имеет спецификацию " %PUNCT " (за "%" следует символ пунктуации), эта макрокоманда вызывается с нулевым указателем для X и символом пунктуации для CODE.

" PRINT_OPERAND_PUNCT_VALID_P (CODE) "

Выражение C, которое истинно, если CODE - допустимый символ пунктуации для использования в макрокоманде " PRINT_OPERAND ". Если " PRINT_OPERAND_PUNCT_VALID_P " не определена, это означает, что символы пунктуации (кроме стандартного, "%") не используются таким образом.

" PRINT_OPERAND_ADDRESS (STREAM, X) "

Составной оператор C для вывода в stdio поток STREAM синтаксиса ассемблера для операнда команды, который является ссылкой памяти, чей адрес - X. X - выражение RTL.

На некоторых машинах синтаксис для символического адреса зависит от раздел, на который адрес ссылается. На этих машинах определите макрокоманду " ENCODE_SECTION_INFO ", чтобы сохранить информацию в " symbol_ref ", и затем проверяют ее здесь. * См.: Формат Ассемблера::.

" DBR_OUTPUT_SEQEND (FILE) "

Оператор C, который должен быть выполнен после того, как были выведены все инструкции заполнения слотов. В случае необходимости вызовите "dbr_sequence_length ", чтобы определить число слотов, заполненных последовательно (ноль, если в настоящее время не выводится последовательность), чтобы решить, сколько вывести пустых команд.

Не определяйте эту макрокоманду, если ей нечего делать, но она полезна при чтении вывода, если размер последовательности задержек указан явно (например с пропуском).

Обратите внимание, что программы вывода для команд со слотами задержки должны быть подготовлены, чтобы иметь дело не обязательно с частью последовательности (то есть когда проход планирования не запускался, или когда заполнители слотов не были найдены). Переменная " final_sequence " равна нулю, если последовательность не обрабатывается, иначе она содержит выводимую " sequence " rtx.

" REGISTER_PREFIX "

" LOCAL_LABEL_PREFIX "

" USER_LABEL_PREFIX "

" IMMEDIATE_PREFIX "

Если определены, то это строковые выражения С для использования для " %R ", " %L "," %U ", и " %I " опций " asm_fprintf " (см. " final.c "). Они полезны, когда одиночный " md " файл должен поддерживать несколько форматов ассемблера. В этом случае различные " tm.h " файлы могут определять эти макрокоманды по разному.

" ASSEMBLER_DIALECT "

Если целевая машина поддерживает различные варианты языка ассемблера, (такие, как различные коды операций), определите эту макрокоманду как выражение C, которое дает числовой индекс варианта языка ассемблера для использования, ноль - первый вариант.

Если эта макрокоманда определена, Вы можете использовать конструкции " {option0|option1|option2...} " в шаблонах вывода образцов (*См.: Шаблоны Вывода::.) или в первом параметре " asm_fprintf ". Эта конструкция выводит " option0 ", " option1 " или " оption2 ", и т.д., если значение " ASSEMBLER_DIALECT " равно нулю, один или два, и т.д. Все специальные символы внутри этих строк сохраняют свое обычное значение.

Если Вы не определяете эту макрокоманду, символы " {", " | " и "} " не имеют никакого специального значения, когда они используются в шаблонах или операндах для " asm_fprintf ".

Определите макрокоманды " REGISTER_PREFIX ", " LOCAL_LABEL_PREFIX ", " USER_LABEL_PREFIX " и " IMMEDIATE_PREFIX ", если Вы можете выразить изменения в синтаксисе языка ассемблера этим способом. Определите " ASSEMBLER_DIALECT " и используйте " {option0|option1} " синтаксис, если вариант синтаксиса больше и включает такие вещи, как различные коды операций или порядок операндов.

" ASM_OUTPUT_REG_PUSH (STREAM, REGNO) "

Выражение C для вывода в STREAM некоторого кода ассемблера, который поместит аппаратный регистр номер REGNO в стек. Код не обязательно должен быть оптимальным, так как эта макрокоманда используется только при профилировании.

" ASM_OUTPUT_REG_POP (STREAM, REGNO) "

Выражение C для вывода в STREAM некоторого кода ассемблера, который восстановит аппаратный регистр номер REGNO из стека. Код не обязательно должен быть оптимальным, так как эта макрокоманда используется только при профилировании.

Вывод Таблиц Распределения

Это касается таблиц распределения.

" ASM_OUTPUT_ADDR_DIFF_ELT (STREAM, VALUE, REL) "

Эту макрокоманду нужно определить на машинах, где адреса в таблицах распределения абсолютные.

Определение должно быть оператором C для вывода в stdio поток STREAM псевдоинструкции ассемблера для генерации различия между двумя метками. VALUE и REL - номера двух внутренних меток. Определения этих меток выводятся с использованием " ASM_OUTPUT_INTERNAL_LABEL ", и они должны печататься здесь таким же образом. Например,

  fprintf (STREAM, "\t.word L%d-L%d\n",
  VALUE, REL)
" ASM_OUTPUT_ADDR_VEC_ELT (STREAM, VALUE) "

Эту макрокоманду нужно определить на машинах, где адреса в таблицах распределения абсолютны.

Определение должно быть оператором C для вывода в stdio поток STREAM псевдо-инструкции ассемблера для генерации ссылки на метку. VALUE - номер внутренней метки, определение которой выводится с использованием " ASM_OUTPUT_INTERNAL_LABEL ". Например,

  fprintf (STREAM, "\t.word L%d\n", VALUE)
" ASM_OUTPUT_CASE_LABEL (STREAM, PREFIX, NUM, TABLE) "

Определите эту макрокоманду, если метка перед таблицей перехода должна выводиться отдельно. Первые три параметра - такие же, как для " ASM_OUTPUT_INTERNAL_LABEL "; четвертый параметр - таблица перехода, которая следует за ними(" jump_insn ", содержащий " addr_vec " или " addr_diff_vec ").

Эта особенность используется на системе V, для вывода оператора " swbeg " для таблицы.

Если эта макрокоманда не определена, эти метки выводятся " ASM_OUTPUT_INTERNAL_LABEL ".

" ASM_OUTPUT_CASE_END (STREAM, NUM, TABLE) "

Определите это, если что-нибудь специальное должно выводиться в конце таблицы перехода. Определением должен быть оператор C, который будет выполнен после того, как будет записан код ассемблера для таблицы. Оператор должен писать соответствующий код в stdio поток STREAM. Параметр TABLE является таблицей перехода insn, и NUM - номер предыдущей метки.

Если эта макрокоманда не определена, в конце таблицы перехода ничего специального не выводится.

Команды Ассемблера для Выравнивания

Здесь описываются команды для выравнивания.

" ASM_OUTPUT_ALIGN_CODE (FILE) "

Выражение C для вывода текста, чтобы выровнять текущий счетчик способом, который является желательным в участке кода, который может быть достигнут только при помощи перехода.

Эту макрокоманду не обязательно определять, если в данный момент не нужно никакого специального выравнивания. Большинство машинных описаний машины сейчас не определяет эту макрокоманду.

" ASM_OUTPUT_LOOP_ALIGN (FILE) "

Выражение C, для вывода текста, чтобы выровнять текущий счетчик, который является желательным в начале цикла.

Эту макрокоманду не обязательно определять, если в данный момент не нужно никакого специального выравнивания. Большинство машинных описаний машины сейчас не определяет эту макрокоманду.

" ASM_OUTPUT_SKIP (STREAM, NBYTES) "

Оператор C для вывода в stdio поток STREAM команды ассемблера, чтобы увеличить расположение счетчика ячеек на NBYTES байт. Эти байты должны равняться нулю при загрузке. NBYTES - выражение C типа " int ".

" ASM_NO_SKIP_IN_TEXT "

Определите эту макрокоманду, если " ASM_OUTPUT_SKIP " не будет использоваться в текстовом разделе, потому что она не может поместить нули в байты, которые пропущены. Это так во многих Unix системах, где псевдооператоры пропуска байтов генерируют скорее пустые команды, чем нули, когда они используются в текстовом разделе.

" ASM_OUTPUT_ALIGN (STREAM, POWER) "

Оператор C, служащий для вывода в stdio поток STREAM команды ассемблера для того, чтобы увеличить счетчик ячеек до кратного 2 в степени POWER байт. POWER должно быть выражением C типа " int ".

6.17 Управление Информационным Форматом отладки

Здесь описывается, как определять отладочную информацию.

Макрокоманды, которые воздействуют на все отладочные форматы

Эти макрокоманды воздействуют на все отладочные форматы.

" DBX_REGISTER_NUMBER (REGNO) "

Выражение C, которое возвращает номер регистра DBX для номера регистра транслятора REGNO. В простейших случаях значение этого выражения может быть самим REGNO. Но иногда имеются регистры, о которых транслятор знает, а DBX - нет, или наоборот. В таких случаях некоторые регистры должны иметь один номер для транслятора и другой - для DBX.

Если два регистра имеют последовательные номера внутри GNU CC, и они могут использоваться как пара, чтобы содержать значение из нескольких слов, то они *должны* иметь последовательные номера после перенумерации " DBX_REGISTER_NUMBER ". Иначе, отладчики не смогут обратиться к такой паре, потому что они ожидают, что регистровые пары будут последовательными в их собственной схеме нумерации.

Если Вы определяете " DBX_REGISTER_NUMBER " способом, который не сохраняет пары регистров, то Вы должны вместо этого переопределить фактическую схему нумерации регистров.

" DEBUGGER_AUTO_OFFSET (X) "

Выражение C, которое возвращает целочисленное значение смещения для автоматической переменной, имеющей адрес X (выражение RTL). Вычисление по умолчанию предполагает, что X отсчитывается от указателя кадра и дает смещение от указателя кадра. Это требуется для целевых машин, которые производят вывод отладки для DBX или COFF-форматный вывод отладки для SDB и позволяет удалять указатель кадра, когда используются " -g " опции.

" DEBUGGER_ARG_OFFSET (OFFSET, X) "

Выражение C, которое возвращает целочисленное значение смещения для параметра, имеющего адрес X (выражение RTL). Номинальное смещение - OFFSET.

" PREFERRED_DEBUGGING_TYPE "

Выражение C, которое возвращает тип вывода отладки, который GNU CC производит, если пользователь указывает " -g " или " -ggdb ". Определите его, если Вы приспособили GNU CC, чтобы поддерживать более чем один формат отладки вывода. В настоящее время допустимые значения - " DBX_DEBUG "," SDB_DEBUG ", " DWARF_DEBUG " и " XCOFF_DEBUG ".

Значение этой макрокоманды воздействует только на отладочный вывод по умолчанию; пользователь может всегда получать конкретный тип вывода, используя " -gstabs ", " -gcoff ", " -gdwarf ", или " -gxcoff ".

Специфические Опции для Вывода DBX

Вот специфические опции для вывода DBX.

" DBX_DEBUGGING_INFO "

Определите эту макрокоманду, если GNU CC произвел вывод отладки для DBX в ответ на опцию ` -g '.

" XCOFF_DEBUGGING_INFO "

Определите эту макрокоманду, если GNU CC произвел вывод отладки формата XCOFF в ответ на опцию ` -g '. Это - вариант DBX формата.

" DEFAULT_GDB_EXTENSIONS "

Определите эту макрокоманду, чтобы контролировать, будет ли GNU CC по умолчанию генерировать расширенную версию GDB об отладочной информации DBX (считая, что отладочная информация DBX-формата вообще разрешена). Если Вы не определяете эту макрокоманду, значение по умолчанию - 1: всегда генерируется расширенную информацию, если для этого имеется возможность.

" DEBUG_SYMS_TEXT "

Определите эту макрокоманду, если все ".stabs " команды должны быть выведены в текстовом разделе.

" ASM_STABS_OP "

Строковая константа С, содержащая имя ассемблерного псевдооператора, которое можно использовать вместо ".stabs", чтобы определить обычный символ отладки. Если Вы не определяете эту макрокоманду, используется ".stabs". Эта макрокоманда применяется только для DBX-формата информации об отладке.

" ASM_STABD_OP "

Строковая константа С, содержащая имя ассемблерного псевдооператора, которое можно использовать вместо ".stabd", чтобы определить отладочный символ,значением которого является текущее расположение. Если Вы не определяете эту макрокоманду, используется ".stabd". Эта макрокоманда применяется только для DBX-формата информации об отладке.

" ASM_STABN_OP "

Строковая константа С, содержащая имя ассемблерного псевдооператора, которое можно использовать вместо ".stabn", чтобы определить безымянный отладочный символ. Если Вы не определяете эту макрокоманду, используется ".stabn". Эта макрокоманда применяется только для DBX-формата информации об отладке.

" DBX_NO_XREFS "

Определите эту макрокоманду, если DBX на вашей системе не поддерживает конструкцию " xsTAGNAME ". В некоторых системах эта конструкция используется для описания прямой ссылки на структуру, называемую TAGNAME. В других системах, эта конструкция не поддерживается вообще.

" DBX_CONTIN_LENGTH "

Символьное имя в информации об отладке DBX-формата обычно продолжается (расщепляясь на две отдельных ".stabs" директивы), когда оно превышает соответствующую длину (по умолчанию 80 символов). В некоторых операционных системах DBX требует этого расщепления; в других расщепление не должно выполняться. Вы можете запретить расщепление определением этой макрокоманды значением ноль. Вы можете изменить заданную по умолчанию длину расщепления, определяя эту макрокоманду как выражение для длины, которая Вам требуется.

" DBX_CONTIN_CHAR "

Обычно продолжение определяется добавлением символа "\" к концу ".stabs" строки, когда продолжение следует.Для использования вместо него другого символа, определите эту макрокоманду как символьную константу для символа, который Вы хотите использовать. Не определяйте эту макрокоманду, если наклонная черта влево подходит для вашей системы.

" DBX_STATIC_STAB_DATA_SECTION "

Определите эту макрокоманду, если необходимо перейти к разделу данных перед выведением ".stabs" псевдооператора для неглобальной статической переменной.

" DBX_TYPE_DECL_STABS_CODE "

Значение для использования в поле "code" директивы ".stabs" для определения типа. Значение по умолчанию - " N_LSYM ".

" DBX_STATIC_CONST_VAR_CODE "

Значение для использования в поле "code" директивы ".stabs" для статической переменной, размещаемой в текстовом разделе. Формат DBX не обеспечивает никакого "правильный" способа сделать это. Значение по умолчанию - " N_FUN ".

" DBX_REGPARM_STABS_CODE "

Значение для использования в поле "code" директивы ".stabs" для параметра, передаваемого в регистрах. Формат DBX не обеспечивает никакого "правильного" способа сделать это. Значение по умолчанию - " N_RSYM ".

" DBX_REGPARM_STABS_LETTER "

Буква для использования в символьных данных DBX для идентификации символа как параметра, передаваемого в регистрах. Формат DBX обычно не обеспечивает какого-нибудь способа сделать это. Значение по умолчанию - " "P".

" DBX_MEMPARM_STABS_LETTER "

Буква для использования в символьных данных DBX для идентификации символа как параметра стека. Значение по умолчанию - " "p" ".

" DBX_FUNCTION_FIRST "

Определите эту макрокоманду, если DBX информация для функции и ее аргументов должна предшествовать коду ассемблера для этой функции. Обычно, в формате DBX, информация об отладке полностью следует за кодом ассемблера.

" DBX_LBRAC_FIRST "

Определите эту макрокоманду, если " N_LBRAC " символ для блока должен предшествовать информации об отладке для переменных и функций, определенных в этом блоке. Обычно, в формате DBX, " N_LBRAC " символ идет первым.

" DBX_BLOCKS_FUNCTION_RELATIVE "

Определите эту макрокоманду если значение символа, описывающего область блока (" N_LBRAC " или " N_RBRAC "), должно быть относительно начала вложенной функции. Обычно GNU C использует абсолютный адрес.

Открытые Ловушки для Формата DBX

Вот ловушки для формата DBX.

" DBX_OUTPUT_LBRAC (STREAM, NAME) "

Определите эту макрокоманду, чтобы сказать, как выводить в STREAM отладочную информацию для начала области для имен переменных. Параметр NAME - это имя символа ассемблера (для использования с " assemble_name "), значение которого - адрес начала области.

" DBX_OUTPUT_RBRAC (STREAM, NAME) "

Подобно " DBX_OUTPUT_LBRAC ", но для конца области.

" DBX_OUTPUT_ENUM (STREAM, TYPE) "

Определите эту макрокоманду, если целевая машина требует специальной обработки для вывода типа перечисления. Это определение должно быть C оператором (без точки с запятой) для вывода соответствующей информации в STREAM для типа TYPE.

" DBX_OUTPUT_FUNCTION_END (STREAM, FUNCTION) "

Определите эту макрокоманду, если целевая машина требует специального вывода в конце информации об отладке для функции. Определение должно быть оператором C (без точки с запятой) для вывода приспособленной информации в STREAM. FUNCTION - это " FUNCTION_DECL " узел для функции.

" DBX_OUTPUT_STANDARD_TYPES (SYMS) "

Определите эту макрокоманду, если вам нужно контролировать порядок вывода стандартных типов данных в начале компиляции. Параметр SYMS - "дерево", которое является цепочкой всей предопределенных глобальных символов, включая имена типов данных.

Обычно DBX вывод начинается с определений типов для целых чисел и символов, дальше следуют все другие предопределенные типы специфического языка, но не в специфическом порядке.

На некоторых машинах, необходимо сначала вывести различные конкретные типы. Чтобы сделать это, определите " DBX_OUTPUT_STANDARD_TYPES ", чтобы она выводила эти символы в необходимом порядке. Все предопределенные типы, которые Вы явно не выводите, будут выводиться позже без специфического порядка.

Будьте внимательным, чтобы не определить эту макрокоманду так, чтобы она работала только для C. Нет никаких глобальных переменных для доступа к большинству встроенных типов, потому что другой язык может иметь другой набор типов. Способ вывода данного типа состоит в том, чтобы просмотреть SYMS, чтобы увидеть, можете ли Вы его найти. Вот пример:

           {
             tree decl;
             for (decl = syms; decl; decl = TREE_CHAIN (decl))
               if (!strcmp (IDENTIFIER_POINTER (DECL_NAME (decl)),
                            "long int"))
                 dbxout_symbol (decl);
             ...
           }
Эта программа ничего не делает, если ожидаемый тип не существует.

См. функцию " init_decl_processing " в " c-decl.c ", чтобы найти имена, используемые для всех встроенных типов C.

Вотдругой путь нахождения данного типа:

           {
             tree decl;
             for (decl = syms; decl; decl = TREE_CHAIN (decl))
               if (TREE_CODE (decl) == TYPE_DECL
                   && (TREE_CODE (TREE_TYPE (decl))
                       == INTEGER_CST)
                   && TYPE_PRECISION (TREE_TYPE (decl)) == 16
                   && TYPE_UNSIGNED (TREE_TYPE (decl)))
           /* This must be `unsigned short'.  */
                 dbxout_symbol (decl);
             ...
           }

Имена Файлов в Формате DBX

Здесь описываются имена файла в формате DBX.

" DBX_WORKING_DIRECTORY "

Определите это, если DBX хочет, чтобы текущий каталог был записан в каждый объектный файл.

Обратите внимание, что рабочий каталог всегда записывается, если включены расширения GDB.

" DBX_OUTPUT_MAIN_SOURCE_FILENAME (STREAM, NAME) "

Оператор C для вывода DBX информации об отладке в stdio поток STREAM, который определяет, что файл NAME - основной файл источника - этот файл указывается как входной файл для компиляции. Эта макрокоманда вызывается только однажды, в начале трансляции.

Эта макрокоманда не нуждается в определении, если стандартная форма вывода для DBX отладочной информации является подходящей.

" DBX_OUTPUT_MAIN_SOURCE_DIRECTORY (STREAM, NAME) "

Оператор C для выводя DBX информации об отладке в stdio поток STREAM, который указывает, что текущий каталог в течение трансляции называется NAME.

Эта макрокоманда не нуждается в определении, если стандартная форма вывода для DBX отладочной информации является подходящей.

" DBX_OUTPUT_MAIN_SOURCE_FILE_END (STREAM, NAME) "

Оператор C для вывода DBX информации об отладке в конец трансляции основного файла источника NAME.

Если Вы не определяете эту макрокоманду, ничего специального не выводится в конце трансляции, что является правильным для большинства машин.

" DBX_OUTPUT_SOURCE_FILENAME (STREAM, NAME) "

Оператор C для вывода DBX информации об отладке в stdio поток STREAM, который определяет, что файла NAME - текущий файл источника. Этот вывод генерируется каждый раз, когда ввод перемещается на другой исходный файл в результате " #include ", конца включенного файла или команды " #line ".

Эта макрокоманда не нуждается в определении, если стандартная форма вывода для DBX отладочной информации является подходящей.

Макрокоманды для SDB и Вывода DWARF

Вот макрокоманды для вывода DWARF и SDB.

" SDB_DEBUGGING_INFO "

Определите эту макрокоманду, если GNU CC должен вывести вывод отладки в coff-формате для SDB в ответ на опцию ` -g '.

" DWARF_DEBUGGING_INFO "

Определите эту макрокоманду, если GNU CC должен вывести вывод отладки в DWARF формате в ответ на опцию ` -g '.

" PUT_SDB_... "

Определите эти макрокоманды, чтобы изменить синтаксис ассемблера для специальных SDB директив ассемблера. См. " sdbout.c " для списка этих макрокоманд и их параметров. Если используетя стандартный синтаксис, Вам не нужно определять их самостоятельно.

" SDB_DELIM "

Некоторые ассемблеры не поддерживают точку с запятой как разделитель, даже между SDB директивами ассемблера. В этом случае определите эту макрокоманду как используемый разделитель (обычно " \n "). Не обязательно определять новый набор " PUT_SDB_OP " макрокоманд, если это - единственое требуемое изменение.

" SDB_GENERATE_FAKE "

Определите эту макрокоманду, чтобы изменить обычный метод построения dummy имени для анонимной структуры и типов объединения. См. " sdbout.c " для большей информации.

" SDB_ALLOW_UNKNOWN_REFERENCES "

Определите эту макрокоманду, чтобы разрешить выделение ссылок на структуры, объединения и перечисления, которые еще не встечались. Стандарт COFF не позволяет обработку неизвестных ссылок, а MIPS ECOFF поддерживает их.

" SDB_ALLOW_FORWARD_REFERENCES "

Определите эту макрокоманду, чтобы разрешить обработку ссылок на структуры, объединения и перечисления, которые еще не встечались. Некоторые ассемблеры не поддерживают забегания вперед, в то время как некоторые требуют его.

6.18 Кросс-трансляция и числа с плавающей точкой

В то время как все современные машины используют одинаковое представление для целых чисел, существует множество представлений чисел с плавающей точкой. Это значит, что при перекрестной трансляции представление чисел с плавающей точкой (вещественных чисел) в компилируемой программе может быть отлично от представления на машине, на которой происходит трансляция.

Т.к. различные системы представлений могут использовать числа с разными размерами и разной точность, то перекрестная компиляция не может использовать вещественную арифметику главной машины. Следовательно, вещественные константы должны представляться в формате целевой машины. Это означает, что в фазе перекрестной компиляций нельзя использовать `atof' для анализирования вещественных констант. Вместо этого должна использоваться специальная подпрограмма. Свертка констант так же должна эмулировать арифметику целевой машины (или свертка констант не должна производиться вообще).

Макрокоманды из следующей таблицы должны быть определены только если Вы производите перекрестную компиляцию между машинами с различными форматами чисел с плавающей точкой.

Иначе, не определяйте их совсем. В этом случае будут установлены значения по умолчанию, использующие тип данных `double' и `==' для проверки равенства, и т.д.

Вам не нужно беспокоиться, как много раз Вы используете операнд любой из этих макрокоманд. Транслятор никогда не использует операнды которые имеют побочный эффект.

`REAL_VALUE_TYPE'

Макрокоманда для типа данных C, который нужно использовать, чтобы держать вещественное (с плавающей точкой) значение в формате целевой машины. Обычно этот тип должен быть `struct', содержащая массив `int'.

`REAL_VALUES_EQUAL (X, Y)'

Макрокоманда для выражения на C, которое проверяет равенство двух значения, X и Y, оба типа `REAL_VALUE_TYPE'.

`REAL_VALUES_LESS (X, Y)'

Макрокоманда для выражения на С, которое проверяет является ли X меньше чем Y, оба значения типа `REAL_VALUE_TYPE' и интерпретируются как числа с плавающей точкой в формате целевой машины.

`REAL_VALUE_LDEXP (X, SCALE)'

Макрокоманда для выражения на C, которое выполняет стандартную библиотечную функцию `ldexp', но использует представление плавающей точки в формате целевой машины. Как X, так и значение выражения имеют тип `REAL_VALUE_TYPE'. Второй параметр, SCALE - целое число.

`REAL_VALUE_FIX (X)'

Макрокоманда, которая определяется, как выражение на С, преобразующее значение Х в вещественном формате целевой машины к целому знаковому числу. Х имеет тип `REAL_VALUE_TYPE'.

`REAL_VALUE_UNSIGNED_FIX (X)'

Макрокоманда, которая определяется, как выражение на С, преобразующее значение Х в вещественном формате целевой машины к целому беззнаковому числу. Х имеет тип `REAL_VALUE_TYPE'.

`REAL_VALUE_RNDZINT (X)'

Макрокоманда, которая определяется, как выражение на С, округляющее значение Х в вещественном формате целевой машины в сторону нуля к целому числу (но при этом тип остается вещественным). Х имеет тип `REAL_VALUE_TYPE'.

`REAL_VALUE_UNSIGNED_RNDZINT (X)'

Макрокоманда, которая определяется, как выражение на С, округляющее значение Х в вещественном формате целевой машины в сторону нуля к целому беззнаковому числу (но при этом тип остается вещественным). Х имеет тип `REAL_VALUE_TYPE'.

`REAL_VALUE_ATOF (STRING, MODE)'

Макрокоманда, для выражения на С, которое преобразует выражение типа char* - STRING в вещественное число в формате целевой машины, представленное типом MODE. Х имеет тип `REAL_VALUE_TYPE'.

`REAL_INFINITY'

Определите эту макрокоманду, если возможно бесконечное вещественно значение. В таком случае деление на ноль является корректной операцией.

`REAL_VALUE_ISINF (X)'

Макрокоманда, для выражения на С, которое определяет является ли вещественное число Х бесконечностью. Значение имеет тип `int'. По умолчанию она вызывает `isinf'.

`REAL_VALUE_ISNAN (X)'

Макрокоманда, для выражения на С, которое определяет является ли вещественное число "nan" (not-a-number [не число]). Значение имеет тип `int'. По умолчанию, это определено, чтобы вызвать `isnan'.

Определите следующие дополнительные макрокоманды, если Вы хотите чтобы во время перекрестной трансляции происходило сворачивание вещественных констант. Если Вы их не определите, то перекрестная трансляция все еще возможна, но свертывания вещественных константы не будет.
`REAL_ARITHMETIC (OUTPUT, CODE, X, Y)'

Макрокоманда, для выражения на С, которое вычисляет результат арифметической операции над над двумя значениями с плавающей точкой. X и Y типа `REAL_VALUE_TYPE`, представленного в формате целевой машины. Результат будет иметь тот же тип и такое же представление типа. Результат сохраняется в OUTPUT (OUTPUT должен быть переменной).

Операция, которую нужно выполнить определяется CODE - кодом, который всегда один из следующих: `PLUS_EXPR', `MINUS_EXPR', `MULT_EXPR', `RDIV_EXPR', `MAX_EXPR' или `MIN_EXPR'.

Расширение этой макрокоманды ответственно за проверку переполнения. Если случается переполнение, макрорасширение должно выполнить оператор `return 0;', который указывает на неспособность выполнить запрошенную арифметическую операцию.

`REAL_VALUE_NEGATE (X)'

Макрокоманда, для выражения на С, которое возвращает вещественное значение Х с измененным знаком. Как Х, так и значение выражения имеют тип `REAL_VALUE_TYPE' и представлены в формате целевой машины.

В этой макрокоманде не предусмотрен механизм сообщения о переполнение, т.к. переполнение невозможно.

`REAL_VALUE_TRUNCATE (MODE, X)'

Макрокоманда, для выражения на С, которое преобразовывает вещественное значение Х в тип MODE.

Как Х, так и значение выражения представлены в формате целевой машины и имеют тип `REAL_VALUE_TYPE'. Тем не менее, значение должно иметь соответствующий битовый образец, чтобы его можно было корректно выводить как плавающую константу, чей тип в точности согласуется с типом MODE.

В этой макрокоманде не предусмотрен механизм сообщения о переполнение.

`REAL_VALUE_TO_INT (LOW, HIGH, X)'

Макрокоманда, для выражения на С, которое преобразовывает вещественное число Х в целое число двойной точности, которое затем сохраняется в двух переменных типа INT - LOW и HIGH.

`REAL_VALUE_FROM_INT (X, LOW, HIGH)'

Макрокоманда, для выражения на С, которое преобразовывает целое число двойной точности, расположенное в двух переменных типа INT - LOW и HIGH, в вещественное число, которое затем записывается в Х.

6.19 Смешанные параметры

Здесь представлено несколько смешанных параметров.

`PREDICATE_CODES'

Определите его, если Вы предварительно определили специальные предикаты в файле `MACHINE.c'. Эта макрокоманда вызывается в инициализаторе массива структур. Первое поле в структуре - имя предиката, второе - массив кодов RTL. Для каждого предиката существует список всех кодов RTL, которые могут встречаться в выражениях, соответствующих предикату. Элементы этого списка должны разделяться запятыми. Вот пример двух списков типичных для RISC машины:

           #define PREDICATE_CODES \
             {"gen_reg_rtx_operand", {SUBREG, REG}},  \
             {"reg_or_short_cint_operand", {SUBREG, REG, CONST_INT}},
Определение этой макрокоманды не повлияет на сгенерированный код (тем не менее, некорректные определения, в которых пропущен ЫЫЫ код, которому может быть поставлен в соответствие предикат, могут привести к ошибке транслятора). Вместо этого оно сделает таблицу, построенную с помощью `genrecog', более компактной и эффективной. И это ускорит транслятор. Важнее всего включить в список, определяемый этой макрокомандой, предикаты, используемые в большинстве insn.

`CASE_VECTOR_MODE'

Псевдоним для имени типа. Это тип, который должны иметь элементы таблицы переходов.

`CASE_VECTOR_PC_RELATIVE'

Определите эту макрокоманду, если таблицы переходов содержат относительные адреса.

`CASE_DROPS_THROUGH'

Определите эту макрокоманду, если выход значения указателя за разрешенные пределы приводит к потере управления над 'case' insn. Это означает, что определенная по умолчанию метка в действительности игнорируется 'case' insn-ом.

`CASE_VALUES_THRESHOLD'

Определите эту макрокоманду, как наименьшее число, при котором лучше использовать таблицу переходов, чем дерево условных ветвей. По умолчанию она равна четырем для машин с `casesi' инструкциями, и пять для всех остальных. Это самое лучшее для большинства машин значение.

`WORD_REGISTER_OPERATIONS'

Определите эту макрокоманду, чтобы операции между регистрами с интегральным режимом (типом) размера меньше, чем размер слова, всегда выполнялись на всем регистре. Большинство RISC машин имеют такую возможность, а большинство CISC машин нет.

`LOAD_EXTEND_OP (MODE)'

Определите эту макрокоманду, как выражение на C, указывающее, когда insns, читающие из памяти тип MODE - интегральный тип уже чем слово, делают либо знаковое расширение, либо расширение нулем, устанавливая биты вне MODE. Для тех типов MODE, которые надо расширять нулем макрокоманда должна возвратить `ZERO_EXTEND', для типов знакового расширения - `SIGN_EXTEND', и `NIL' для остальных.

Эта макрокоманда не вызывается если MODE не интегральный тип, или если размер MODE больше или равен, чем `BITS_PER_WORD', поэтому в таких случаях Ваша макрокоманда может возвращать что угодно. Не определяйте эту макрокоманду если она всегда будет возвращать 'NIL'. На машинах, на которых эта макрокоманда определена, Вы обычно будете определять ее как константу `SIGN_EXTEND', либо как константу `ZERO_EXTEND'.

`IMPLICIT_FIX_EXPR'

Псевдоним для tree кода, который следует использовать по умолчанию для преобразования вещественных значений в значения с фиксированной точкой. Обычно используется `FIX_ROUND_EXPR'.

`FIXUNS_TRUNC_LIKE_FIX_TRUNC'

Определите эту макрокоманду, если те же самые команды, которые преобразовывают вещественное число в число с плавающей точкой, так же правильно преобразовывают в беззнаковое.

`EASY_DIV_EXPR'

Псевдоним для tree кода, который в общем случае является наиболее простым видом деления для компиляции кода. Он может быть `TRUNC_DIV_EXPR', `FLOOR_DIV_EXPR', `CEIL_DIV_EXPR' или `ROUND_DIV_EXPR'. Эти четыре оператора деления различаются тем, как они округляют результаты до целого. `EASY_DIV_EXPR' используется, когда разрешимо использовать любой из этих операторов и выбор должен быть сделан исходя из их сравнительной эффективности.

`MOVE_MAX'

Максимальное число байтов, которые одна команда может быстро переместить из памяти в память.

`MAX_MOVE_MAX'

Максимальное число байтов, которые одна команда может быстро переместить из памяти в память. Если она не определена, то по умолчанию берется `MOVE_MAX'. Иначе, это - постоянное значение, которое является самым большим из значений, которые принимает 'MOVE_MAX'.

`SHIFT_COUNT_TRUNCATED'

Выражение на C, которое не равно нулю, если на этой машине число битов, фактически используемых для счета операции сдвига, равно числу битов, которое требуется для представления перемещаемого объекта.

Когда эта макрокоманда не ноль, транслятор исходит из предположения, что безопаснее опустить знако-расширяющие, нуль-расширяющие и некоторые выполняющие побитовое "и" инструкции, которые усекают размер сдвига. На машинах, имеющих инструкции, которые действуют на битовые поля в различных позициях, которые могут включать в себя инструкции `bit test', ненулевой `SHIFT_COUNT_TRUNCATED' также осуществляет уничтожение усеканий значений, которые служат аргументами для инструкций битовых полей.

Если оба типа инструкций усекают размер (сдвигов) и позицию (для операций битовых полей), или если не существует инструкций битовых полей с переменной позицией, Вам следует определить эту макрокоманду.

Тем не менее, на некоторых машинах, таких как 80386 и 680x0, усечение работает только с операциями сдвига и не работает с (реальными или симулируемыми) операциями битовых полей. Определите для таких машин значение `SHIFT_COUNT_TRUNCATED' равным нулю. Вместо этого добавьте образцы в файл `md', который включает подразумеваемые усечения инструкций сдвигов.

Вы можете не определять эту макрокоманду если она всегда будет иметь значение ноль.

`TRULY_NOOP_TRUNCATION (OUTPREC, INPREC)'

Выражение на С, которое не является нулем, если на этой машине безопасно "преобразовывать" целое число размером INPREC бит в целое размером OUTPREC (где OUTPREC меньше чем INPREC) простым обращением с ним, как если бы оно имело только OUTPREC биты.

На многих машинах, это выражение может быть 1.

Когда `TRULY_NOOP_TRUNCATION' возвращает 1 для пары размеров типов, для которых `MODES_TIEABLE_P' равен 0, может быть сгенерирован неоптимальный код. В таком случае назначение `TRULY_NOOP_TRUNCATION' нулём для таких ситуаций может улучшить положение.

`STORE_FLAG_VALUE'

Выражение на C, которое описывает значение, возвращенное оператором сравнения с интегральным типом и сохраненное командой сохранения флага (`sCOND') когда условие истинно. Это описание должно прилагаться ко *всем* `sCOND' образцам, и ко всем операторам сравнения, чьи результаты имеют тип `MODE_INT'.

Значение 1 или -1 означает, что инструкция, содержащая сравнение, возвращает соответственно 1 или -1, когда сравнение - истина и 0, когда сравнение - ложь. Другое значение указывает какие биты результата гарантированно равны 1, когда сравнение - истина. Это значение интерпретируется в типе операции сравнения, который определяется типом первого операнда в `sCOND' образце. Будет установлен либо нижний, либо знаковый бит `STORE_FLAG_VALUE'. Транслятором используются только эти биты.

Если `STORE_FLAG_VALUE' ни 1 ни -1, то транслятор сгенерирует код, зависящий только от определенного бита. Он так же может заменить операторы сравнения на эквивалентные операции, даже если они действуют только на эти особенные биты и оставляют другие биты неопределенными. Например, на машинах, чьи операторы сравнения возвращают значение типа `SImode' и где `STORE_FLAG_VALUE' определен как `0x80000000', т.е. только знаковый бит имеет значение, выражение:

           (ne:SI (and:SI X (const_int POWER-OF-2)) (const_int 0))
может быть преобразовано к

           (ashift:SI X (const_int N))
где N подходящий размер операции сдвига для перемещения проверяемого бита в знаковый бит.

Не существует способа описать машину, которая всегда устанавливает бит младшего разряда для значения истина, но не гарантирует значения никаких других битов, но мы не знаем таких машин. Если Вы пытаетесь установить GNU CC на такой машине, включите инструкцию, выполняющую логическое "и" с 1 в образце для операторов сравнения и дайте нам знать (см. Как вывести сообщение об ошибке).

Часто машина будет иметь много инструкций, которые получают значения от сравнений (или кодов условия). Вот правила для выбора значения для `STORE_FLAG_VALUE', и следовательно инструкций, которые нужно использовать:

  • Используйте самую короткую последовательность, которая дает определение для `STORE_FLAG_VALUE'. Для транслятора более эффективно "нормализовать" значение самому (преобразовать его, к примеру, в 1 или 0), чем это будут делать сравнения, т.к. у транслятора может быть возможность соединить нормализацию с другими операциями.
  • Для последовательностей одинаковой длины используйте значение 1 или -1, причем на машинах с долгими переходами немного предпочтительнее -1, а на других машинах предпочтительнее 1.
  • Вы можете так же выбрать значение `0x80000001' если существуют инструкции, устанавливающие бит знака и младший бит, но не определяющие значения остальных.
  • В другом случае используйте значение `0x80000000'.
Многие машины могут генерировать значение, выбранное для `STORE_FLAG_VALUE', и его отрицание в таком же числе инструкций. На таких машинах Вам следует так же определить образец для этих случаев, например, образец, соответствующий

           (set A (neg:M (ne:M B C)))
Некоторые машины могут так же выполнять операции `and' или `plus' над значениями кода условия и с меньшим количеством инструкций, чем соответствующий insn `sCOND', сопровождаемый `and' или `plus'. На этих машинах Вам следует определить нужные образцы. Используйте имена `incscc' и `decscc' соответственно, для образцов, которые выполняют операции `plus' или `minus' над значениями кода условия. Для примеров смотрите `rs6000.md'. Вы можете использовать GNU Superoptizer, что бы найти такие последовательности инструкций на других машинах.

Вам не нужно определять `STORE_FLAG_VALUE', если машина не имеет инструкций сохранения флага.

`FLOAT_STORE_FLAG_VALUE'

Выражение на C, которое дает ненулевое вещественное значение, возвращаемое, когда операция сравнения с вещественным результатом истина. Определите эту макрокоманду на машине, если она имеет операции сравнения, возвращающие значение с плавающей точкой. Если же таких команд нет, то определять эту макрокоманду не надо.

`Pmode'

Псевдоним для машинного режима указателей. На большинстве машин, эта макрокоманда определяется как целочисленным режимом, соответствующий ширине аппаратного указателя; `SImode' на 32-битных машинах и `DImode' на 64-битных. На некоторых машинах эта макрокоманда должна быть одним из частичных целых типов, таких как `PSImode'.

Ширина `Pmode' должна быть по крайней мере такого же размера, как значение `POINTER_SIZE'. Если она не равна, то Вы должны определить макрокоманду `POINTERS_EXTEND_UNSIGNED' чтобы определить, как расширить указатель до `Pmode'.

`FUNCTION_MODE'

Псевдоним для типа, используемого для ссылок на функции, вызываемые в RTL выражениях вызова. На большинстве машин этот тип должен быть `QImode'.

`INTEGRATE_THRESHOLD (DECL)'

Выражение на С для максимального числа инструкций, для которых функцию DECL можно сделать inline. DECL есть узел `FUNCTION_DECL'.

Значение этой макрокоманды по умолчанию равно 64 плюс число аргументов, которое понимает функция, умноженное на 8. Некоторые люди полагают, что на RISC машинах следует использовать большее пороговое значение.

`SCCS_DIRECTIVE'

Определите ее, если препроцессору следует игнорировать директивы `#sccs', и не выдавать сообщения об ошибках.

`NO_IMPLICIT_EXTERN_C'

Определите эту макрокоманду, если системные файлы описания поддерживают С++ так же, как и С. Эта макрокоманда отключает обычный метод использования системных файлов описания, симулирующий, что содержимое файлов заключено в `extern "C" {...}'.

`HANDLE_PRAGMA (STREAM)'

Определите эту макрокоманду, если Вы хотите вставлять какие-нибудь прагмы. Если она определена, то выражение, выполняющееся, когда замечена `#pragma', должно быть выражением на С. Аргумент STREAM есть входной поток stdio из которого читается текст источника.

Идея использования новых `#pragma' как правило плохая идея. Единственная причина определить эту макрокоманду - для совместимости с другими трансляторами, поддерживающими `#pragma' ради уже существующих программ юзера, которые ее используют.

`VALID_MACHINE_DECL_ATTRIBUTE (DECL, ATTRIBUTES, IDENTIFIER, ARGS)'

Если определен, то это выражение на С, чье значение не ноль, если IDENTIFIER с аргументами ARGS есть специфичный корректный машинный атрибут для DECL. Атрибуты в ATTRIBUTES были предварительно назначены для DECL.

`VALID_MACHINE_TYPE_ATTRIBUTE (TYPE, ATTRIBUTES, IDENTIFIER, ARGS)'

Если определен, то это выражение на С, чье значение не ноль, если IDENTIFIER с аргументами ARGS есть специфичный корректный машинный атрибут для TYPE. Атрибуты в ATTRIBUTES были предварительно назначены для TYPE.

`COMP_TYPE_ATTRIBUTES (TYPE1, TYPE2)'

Если определен, то это выражение на С, чье значение ноль, если атрибуты на TYPE1 и TYPE2 несовместимы, один если совместимы, и два если они почти совместимы (в этом случае выдастся warning).

`SET_DEFAULT_TYPE_ATTRIBUTES (TYPE)'

Если определена, утверждение C, которое назначает заданные по умолчанию атрибуты к недавно определенному ТИПУ.

`DOLLARS_IN_IDENTIFIERS'

Определите эту макрокоманду, что бы контролировать использование символа '$' в именах идентификатора. Значение должно быть 0, 1 или 2. 0 значит, что по умолчанию '$' не позволен; 1 значит, что позволен, если используется `-traditional'; 2 значит, что позволен, если `-ansi' не используется. По умолчанию 1. В этом случае нет надобности определят эту макрокоманду.

`NO_DOLLAR_IN_LABEL'

Определите эту макрокоманду, если ассемблер не принимает меткам с именами, содержащими символ '$'. По умолчанию в именах конструкторов и деструкторов в G ++ содержится символ '$'. Если эта макрокоманда определена, то вместо '$' используется `.'.

`NO_DOT_IN_LABEL'

Определите эту макрокоманду, если ассемблер не принимает меткам с именами, содержащими символ '.'. По умолчанию в именах конструкторов и деструкторов в G ++ содержится символ '.'. Если эта макрокоманда определена, то вместо имена переделываются, что бы избежать этого символа.

`DEFAULT_MAIN_RETURN'

Определите эту макрокоманду, если целевая система считает, что функция `main' каждой программы по умолчанию возвратит стандартное значение "успеха" (если никакое другое значение явно не возвращено).

Определение должно быть оператором на С (с ';'), генерирующем соответствующие rtl команды. Оно используется только при компилировании конца `main'.

`HAVE_ATEXIT'

Определите ее, если целевая система поддерживает функцию `atexit' из ANSI C стандарт. Если она не определена, и не определен `INIT_SECTION_ASM_OP', то `exit' функция, заданная по умолчанию, будет поддерживать C ++.

`EXIT_BODY'

Определите ее, если ваша `exit' функция должна делать что-нибудь кроме вызова внешней функции `_cleanup' перед завершением с `_exit'. Макрокоманда `EXIT_BODY' необходим только, если не определены ни 'HAVE_ATEXIT' ни 'INIT_SECTION_ASM_OP'.

`INSN_SETS_ARE_DELAYED (INSN)'

Определите эту макрокоманду как выражение на C, которое отлично от нуля, если планировщик слота задержки может безопасно, поместить команды в слот задержки INSN, даже если их появление устанавливает или уничтожпет ресурсы в INSN. INSN - всегда или 'jump_insn' или 'insn'; GNU CC знает, что каждый 'call_insn' ведет себя так. На машинах, на которых некоторые 'insn' или 'jump_insn' действительно являются вызовами функции и следовательно имеют такое поведение, Вы должны определить эту макрокоманду.

Вам не надо определять эту макрокоманду если она всегда будет возвращать ноль.

`INSN_REFERENCES_ARE_DELAYED (INSN)'

Определите эту макрокоманду как выражение на C, которое отлично от нуля, если планировщик слота задержки может безопасно, поместить команды в слот задержки INSN, даже если их появление устанавливает или уничтожает ресурсы в INSN. INSN - всегда или 'jump_insn' или 'insn'. На некоторых машинах, на которых `insn' или `jump_insn' есть настояшие вызовы функции и их операнды - регистры, которые фактический используют в вызвающей подпрограмме, Вы должны определить эту макрокоманду. Такое выполнение позволяет планировщику слота задержки перемещать команды, копирующие параметры в регистры аргументов в слоте задержки INSN.

Вы были не должны определять эту макрокоманду, если она всегда возвращает ноль.

`MACHINE_DEPENDENT_REORG (INSN)'

В редких случаях(ящиках), корректная генерация объектного кода требует дополнительной машинно-зависимо обработки между вторым проходом оптимизации переходов и отсроченным планированием перехода. На таких машинах, определите эту макрокоманду как оператор на C, чтобы действовать на код, начинающийся в INSN.


Вперед Назад Содержание