Регистры компилятора

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

- регистры компилятора (Compiler Registers), которые используются компилятором для собственных целей и должны содержать указанные в таблице значения. Не следует изменять значения этих регистров, так как компилятор предполагает, что эти регистры всегда имеют значения, приведенные в таблице. Дополнительно следует отметить, что все L-регистры (кроме L6 и L7) должны быть равны 0 в любой точке вызова процедуры и возврата из процедуры. Если какой-либо из L-регистров был модифицирован, то при вызове функции или возврате управления в вызывающую подпрограмму, его следует обнулить. Подпрограммы – обработчики прерываний должны сохранять (в памяти) и сбрасывать L-регистры в 0 до использования соответствующих им I-регистров для любых инструкций с пост-модификацией.

Регистр Значение Правило использования
M5, M13   Не модифицировать
M6, M14   Не модифицировать
M7, M15 -1 Не модифицировать
B6, B7 база стека Не модифицировать
L6, L7 длина стека Не модифицировать
L0, L1, L2, L3, L4, L5, L8, L9, L10, L11, L12, L13, L14, L15   Доступны для временного использования. После использования – восстановить

- регистры, зарегистрированные пользователем (User Registers), задание (перечисление) которых в опциях компилятора вынуждает компилятор отказаться от использования этих регистров. Если же компилятору не будет хватать регистров, он проигнорирует запрет на их использование. Следует заметить, что "заказ" регистра L, требует резервирования соответствующего I-регистра и наоборот, в противном случае возможны ошибки на этапе выполнения. Чем больше зарезервировано регистров для пользовательских целей, тем ниже может оказаться "качество" кода, сгенерированного компилятором;

Регистр Значение Правило использования
i0, n0, l0, m0, i1, b1, l1, m1, i8, b8, l8, m8, i9, b9, l9, m9, mrb, ustat1, ustat2, ustat3, ustat4 Задается пользователем Если не зарезервированы явно, то можно использовать для временного пользования, а по окончании восстановить прежние значения. Если явно зарезервированы под пользовательские цели в опциях компилятора, то можно использовать без ограничения.

- регистры, сохраняемые при вызове (Call Preserved Registers), представляют собой набор регистров, которые должны быть сохранены в "прологе" функции и затем восстановлены в "эпилоге" функции, если эта функция написана на ассемблере. Естественно, что если функция не изменяет регистры данной группы, то сохранять и восстанавливать их необязательно. При этом, если используется сохраняемый при вызове I-регистр, то необходимо сохранить (и затем восстановить) не только этот I-регистр, но и соответствующий ему L-регистр. Значительная часть библиотечных функций работает в предположении, что процессор работает в определенном режиме, определяемом, в частности, регистрами параметром и управления. Если эти значения будут изменены и затем выполнен вызов стандартной функции, то результат ее работы будет непредсказуем. Поэтому при необходимости изменения режимов работы процессора (регистры MODE1 и MODE2) "хорошим тоном" считается сохранение их старых значений и их восстановление при вызове другой функции и при возврате в вызывающую функцию.

B0, B1, B2, B3, B5, B8, B9, B10, B11, B14, B15
I0, I1, I2, I3, I5, I8, I9, I10, I11, I14, I15
MODE1, MODE2
MRB, MRF
M0, M1, M2, M3, M8, M9, M10, M11
R3, R5, R6, R7, R9, R10, R11, R13, R14, R15
USTAT1, USTAT2

По умолчанию run-time окружение С/С++ предполагает, что режим процессора определяется задается следующими установками (задача обеспечить эти установки ложится на инициализационный код):

а) не используется бит-реверсная адресация;

б) используется основной (не теневой) набор регистров;

в) используется точность.PRESICION=32 (32-битовые ПЗ-числа) и режим округления до ближайшего целого;

г) запрещено насыщение АЛУ (бит ALUSAT=0);

д) для ADSP-2116x разрешены циклические буферы (бит CBUFEN=1 в регистре MODE1);

- временные или рабочие регистры (Scratch Registers) не требуют сохранения и восстановления, изменение их содержимого при вызове функций или вставке ассемблерного кода не "волнует" компилятор. К таким регистрам относятся:

B4, B12, B13
R0, R1, R2, R4, R8, R12
I4, I12, I13
M4, M12
PX

Для процессора ADSP-2116x все регистры данных процессорного элемента PEy являются Scratch-регистрами;

- отдельный набор регистров (Stack Registers) резервируется и всегда используется для работы со стеком. Подпрограммы на ассемблере должны строго выполнять правила работы с ними, приведенные в таблице.

Регистр Значение Правило использования
I7 Указатель стека (Stack Pointer) Модифицируется при работе со стеком, восстановить при возврате из подпрограммы
I6 Указатель фрейма стека (Frame Pointer) Модифицируется при работе со стеком, восстановить при возврате из подпрограммы
I12 Адрес возврата Загружается адресом возврата при выходе из функции

- альтернативные регистры (Alternate Registers) не используются средой выполнения и доступны для использования в ассемблерных подпрограммах. Однако при их использовании следует учитывать, что при переключении регистров I6 и I7 (DAG1) на теневой набор может быть нарушена работа со стеком. Поэтому при использовании теневых регистров, особенно I6/I7 прерывания должны быть запрещены. Кроме того, самый быстрый диспетчер прерываний (super fast interrupt dispatcher) для переключения контекста сам использует теневые регистры вместо сохранения регистров в стеке среды выполнения. Поэтому во избежание конфликтов желательно не применять данный вид диспетчера прерываний при использовании теневых регистров в ассемблерных вставках.


Понравилась статья? Добавь ее в закладку (CTRL+D) и не забудь поделиться с друзьями:  



double arrow
Сейчас читают про: