6.47.3.1 Простые ограничения ¶
Простейший вид ограничения — строка, заполненная буквами, каждая из которых описывает один тип операнда, который разрешён. Вот разрешённые буквы:
- пробелы
-
Символы пробелов игнорируются и могут быть вставлены в любом месте, кроме первого. Это позволяет визуально выравнивать каждую альтернативу для разных операндов в описании машины, даже если у них разное количество ограничений и модификаторов.
- ‘m’ ¶
-
Разрешён операнд памяти с любым типом адреса, который поддерживается машиной в целом. Обратите внимание, что букву, используемую для общего ограничения памяти, можно переопределить на заднем плане, используя макрос
TARGET_MEM_CONSTRAINT. - ‘o’ ¶
-
Разрешён операнд памяти, но только если адрес является смещаемым. Это означает, что к адресу можно добавить небольшое целое число (фактически, ширину операнда в байтах, определённую его машинным режимом), и результат также будет допустимым адресом памяти.
Например, адрес, который является константой, является смещаемым; так же, как и адрес, который является суммой регистра и константы (при условии, что несколько большая константа также находится в диапазоне поддерживаемых машиной смещений адреса); но адрес с автоматическим инкрементом или декрементом не смещаем. Более сложные косвенные/индексированные адреса могут быть или не быть смещаемыми в зависимости от других режимов адресации, которые поддерживает машина.
Обратите внимание, что в выходном операнде, который может быть сопоставлен с другим операндом, буква ограничения ‘o’ допустима только в сопровождении ‘<’ (если у целевой машины есть адресация с преддекрементом) и ‘>’ (если у целевой машины есть адресация с преинкрементом).
- ‘V’ ¶
-
Операнд памяти, который не смещаем. Другими словами, всё, что подходит для ограничения ‘m’, но не для ограничения ‘o’.
- ‘<’ ¶
-
Разрешён операнд памяти с адресацией автодекремента (преддекремент или постдекремент). Встроенном
asm, это ограничение разрешено только в том случае, если операнд используется ровно один раз в инструкции, которая может обрабатывать побочные эффекты. Отсутствие операнда с ‘<’ в строке ограничения в шаблоне встроенногоasm, или использование его в нескольких инструкциях недопустимо, потому что побочные эффекты не будут выполняться или будут выполняться более одного раза. Кроме того, на некоторых целевых платформах операнд с ‘<’ в строке ограничения должен сопровождаться специальными суффиксами инструкций, такими как суффикс инструкции%U0на PowerPC или%P0на IA-64. - ‘>’ ¶
-
Разрешён операнд памяти с адресацией автоинкремента (преинкремент или постинкеремент). Встроенном
asm, применяются те же ограничения, что и для ‘<’. - ‘r’ ¶
-
Разрешён операнд регистра, при условии, что он находится в общем регистре.
- ‘i’ ¶
-
Разрешен целочисленный операнд со значением константы (с постоянным значением). Это включает символические константы, значения которых будут известны только во время сборки или позже.
- ‘n’ ¶
-
Разрешён целочисленный операнд со значением константы, имеющий известное числовое значение. Многие системы не могут поддерживать константы времени сборки для операндов меньше ширины слова.
Ограничения для таких операндов должны использовать ‘n’ вместо ‘i’.
- ‘I’, ‘J’, ‘K’, … ‘P’ ¶
-
Другие буквы в диапазоне от ‘I’ до ‘P’ могут быть определены в зависимости от машины, чтобы разрешить целочисленные операнды со значениями констант в заданных диапазонах. Например, на 68000 ‘I’ определено как диапазон значений от 1 до 8. Это диапазон, разрешённый в качестве сдвига в инструкциях сдвига.
- ‘E’ ¶
-
Разрешён операнд с плавающей точкой со значением константы (код выражения
const_double), но только если формат плавающей точки целевой машины совпадает с форматом хост-машины (на которой работает компилятор). - ‘F’ ¶
-
Разрешен операнд с плавающей точкой со значением константы (код выражения
const_doubleилиconst_vector). - ‘G’, ‘H’ ¶
-
‘G’ и ‘H’ могут быть определены в зависимости от машины, чтобы разрешить операнды с плавающей точкой в определённых диапазонах значений.
- ‘s’ ¶
-
Разрешен целочисленный операнд со значением константы, значение которого не является явным целым числом.
Это может показаться странным; если инструкция позволяет использовать операнд с константой, значение которой неизвестно во время компиляции, она определённо должна позволить любое известное значение. Так почему используется ‘s’ вместо ‘i’? Иногда это позволяет сгенерировать лучший код.
Например, на 68000 в инструкции с полным словом можно использовать операнд со значением константы; но если значение константы находится в диапазоне от -128 до 127, для генерации лучшего кода загружается значение в регистр и используется регистр. Это происходит потому, что загрузка в регистр может быть выполнена с помощью инструкции ‘moveq’. Мы организуем это, определив букву ‘K’ как означающую «любое целое число вне диапазона от -128 до 127», а затем указав ‘Ks’ в ограничениях операнда.
- ‘g’ ¶
-
Разрешены любые операнды регистра, памяти или целочисленных констант, кроме регистров, которые не являются общими регистрами.
- ‘X’ ¶
-
Разрешён любой операнд.
- ‘0’, ‘1’, ‘2’, … ‘9’ ¶
-
Разрешён операнд, который соответствует указанному номеру операнда. Если цифра используется вместе с буквами в той же альтернативе, цифра должна стоять последней.
Это число может быть больше одной цифры. Если встречаются несколько цифр подряд, они интерпретируются как одно десятичное целое число. Вероятность неоднозначности невелика, так как до сих пор не было необходимости, чтобы ‘10’ интерпретировалось как сопоставление либо операнда 1, либо операнда 0. Если это необходимо, можно использовать несколько альтернатив.
Это называется ограничением сопоставления, и на самом деле это означает, что у ассемблера только один операнд, который выполняет две роли, которые
asmотличает. Например, инструкция сложения использует два входных операнда и один выходной операнд, но на большинстве машин CISC инструкция сложения фактически имеет только два операнда, один из которых — входно-выходной операнд:addl #35,r12
В таких случаях используются ограничения сопоставления. Точнее, два операнда, которые сопоставляются, должны включать один только входной операнд и один только выходной операнд. Кроме того, цифра должна быть меньше номера операнда, который использует её в ограничении.
- ‘p’ ¶
-
Разрешён операнд, являющийся допустимым адресом памяти. Это для инструкций «загрузка адреса» и «загрузка адреса в стек».
‘p’ в ограничении должно сопровождаться
address_operandв качестве предиката вmatch_operand. Этот предикат интерпретирует режим, указанный вmatch_operand, как режим обращения к памяти, для которого адрес будет действительным. - other-letters ¶
Другие буквы могут быть определены в зависимости от машины, чтобы обозначать определённые классы регистров или другие произвольные типы операндов. ‘d’, ‘a’ и ‘f’ определены на 68000/68020 как обозначения для регистров данных, адресов и с плавающей точкой.
© Free Software Foundation
Licensed under the GNU Free Documentation License, Version 1.3.
https://gcc.gnu.org/onlinedocs/gcc-10.5.0/gcc/Simple-Constraints.html