6.11.3.1 Простые ограничения
Самый простой вид ограничения — это строка, состоящая из букв, каждая из которых обозначает один тип допустимого операнда. Ниже перечислены допустимые буквы:
- пробельные символы
-
Пробельные символы игнорируются и могут быть вставлены в любое место, кроме начала. Благодаря этому альтернативы для разных операндов можно визуально выровнять в описании машины, даже если они содержат разное количество ограничений и модификаторов.
- ‘m’
-
Допускается операнд-память с любым типом адреса, который поддерживается машиной в целом. Обратите внимание, что буква, используемая для общего ограничения памяти, может быть переопределена бэкендом с помощью макроса
TARGET_MEM_CONSTRAINT. - ‘o’
-
Допускается операнд-память, но только если адрес является смещаемым. Это означает, что к адресу можно прибавить небольшое целое число (фактически ширину операнда в байтах, определяемую его машинным режимом), и полученный результат также будет допустимым адресом памяти.
Например, постоянный адрес является смещаемым; смещаемым является и адрес, представляющий собой сумму регистра и константы (если немного большая константа также находится в диапазоне поддерживаемых машиной смещений адреса); однако адрес с автоинкрементом или автодекрементом не является смещаемым. Более сложные косвенные адреса и адреса с индексированием могут быть или не быть смещаемыми в зависимости от других режимов адресации, поддерживаемых машиной.
Обратите внимание: в выходном операнде, который может совпадать с другим операндом, буква ограничения ‘o’ допустима только в сочетании с ‘<’ (если целевая машина поддерживает адресацию с предварительным декрементом) и ‘>’ (если целевая машина поддерживает адресацию с предварительным инкрементом).
- ‘V’
-
Операнд-память, который не является смещаемым. Иными словами, любой операнд, подходящий под ограничение ‘m’, но не подходящий под ограничение ‘o’.
- ‘<’
-
Допускается операнд-память с адресацией автодекремента (как с предварительным, так и с последующим декрементом). В inline
asmэто ограничение допустимо только в том случае, если операнд используется ровно один раз в инструкции, которая может обработать побочные эффекты. Не использовать операнд с ‘<’ в строке ограничений в шаблоне inlineasmили использовать его в нескольких инструкциях недопустимо, поскольку побочные эффекты либо не будут выполнены, либо будут выполнены более одного раза. Кроме того, на некоторых целевых платформах операнд с ‘<’ в строке ограничений должен сопровождаться специальными суффиксами инструкции, такими как суффикс инструкции%U0на PowerPC или%P0на IA-64. - ‘>’
-
Допускается операнд-память с адресацией автоинкремента (как с предварительным, так и с последующим инкрементом). В inline
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, как режим ссылки на память, для которого адрес был бы допустим. - ‘:’
-
Это ограничение, допустимое только для входных операндов, указывает, что шаблон inline
asmзадаёт символ функции или переменной. Ограничение не следует смешивать с другими ограничениями для того же операнда; операнд должен быть адресом функции или неавтоматической переменной. Лучше всего использовать его с модификатором ‘cc’ при выводе операнда, чтобы он печатался как метка даже в позиционно-независимом коде.void foo (void); asm (".globl %cc0; %cc0: ret" : : ":" (foo)); - другие-буквы
Другие буквы можно определять в зависимости от машины для обозначения определённых классов регистров или других произвольных типов операндов. На 68000/68020 буквы ‘d’, ‘a’ и ‘f’ обозначают регистры данных, адреса и числа с плавающей точкой соответственно.
© Free Software Foundation
Licensed under the GNU Free Documentation License, Version 1.3.
https://gcc.gnu.org/onlinedocs/gcc-15.3.0/gcc/Simple-Constraints.html