Next: C Constraint Interface, Previous: Machine Constraints, Up: Constraints
机器特定的约束分为两类:寄存器约束和非寄存器约束。在后者中, 如果约束允许所有可能的内存或地址操作数,则应该被专门标记出来, 以便给reload
更多信息。
机器特定的约束可以给定任意长度的名字,但是它们全部由字母,数字, 下划线(‘_’)和三角括号(‘< >’)组成。跟C标识符类似, 它们必须起始于字母或者下划线。
为了避免操作数约束字符串的混淆,约束的名字不能起始于任何其它约束的名字。 例如,如果x
被定义为一个约束名,则不可以定义xy
,反之依然。 按照这个规则,所有约束都不能起始于通用约束字母:‘E F V X g i m n o p r s’。
寄存器约束直接对应于寄存器类别。参见Register Classes。 因此它们的定义没有太多的灵活性。
这三个参数都是字符串常量。name为约束的名字, 将在
match_operand
表达式中出现。如果name为多个字母的约束, 则它的长度应该与所有起始与同一字母的约束相同。 regclass可以为相应的寄存器类别的名字(参见Register Classes), 或者一个C表达式,其值为合适的寄存器类别。如果为表达式,其必须不具有副作用, 并且不能查看操作数。通常使用表达式是为了当寄存器类别对于给定的子体系结构无效时, 将一些寄存器约束映射为NO_REGS
。docstring为一条语句,介绍了约束的含义。这将在下面做进一步的解释。
非寄存器的约束更加像断言:约束定义给出一个布尔表达式,其指示是否约束匹配。
name和docstring参数与
define_register_constraint
的相同, 但是注意docstring直接跟随name之后。exp为一个RTL表达式, 遵循在断言定义中相同的规则。详情参见Defining Predicates。如果求得为真, 则约束匹配;如果求得为假,则不匹配。约束表达式应该指示出它们可能匹配的RTL, 就像断言表达式一样。C表达式
match_test
,可以访问下列变量:
- op
- 定义操作数的RTL对象。
- mode
- op的机器模式。
- ival
- ‘INTVAL (op)’, 如果op为
const_int
。- hval
- ‘CONST_DOUBLE_HIGH (op)’, 如果op为整数
const_double
。- lval
- ‘CONST_DOUBLE_LOW (op)’, 如果op为整数
const_double
。- rval
- ‘CONST_DOUBLE_REAL_VALUE (op)’, 如果op为浮点
const_double
。变量*val应该只在表达式的其它部分已经验证了op为合适类型的RTL对象时, 才被使用。
大多数非寄存器约束应该使用define_constraint
来定义。 其余的两个定义表达式只适合当约束匹配失败时,应该由reload
单独处理的约束。
使用该表达式来定义匹配所有内存操作数的子集的约束:也就是,
reload
能够通过将操作数转换为‘(mem (reg X))’的形式使得它们 匹配。其中X为基址寄存器(通过BASE_REG_CLASS
指定的寄存器类别,参见Register Classes)。例如,在S/390上,一些指令不接受任意的内存引用,只接受那些不使用索引寄存器的。 约束字母‘Q’被定义用来表示这个类型的内存地址。 如果‘Q’使用
define_memory_constraint
定义, 则‘Q’约束可以处理任意内存操作数,因为reload
知道在需要的时候, 它可以简单的将内存地址复制到基址寄存器中。 这与‘o’约束可以处理任意内存操作数的方式类似。语法和语义在其它方面都与
define_constraint
相同。
使用该表达式来定义匹配所有地址操作数的子集的约束:也就是,
reload
能够通过将操作数转换为‘(reg X)’的形式使得它们匹配。 同样X为基址寄存器。使用
define_address_constraint
定义的约束只能用于address_operand
断言 ,或者机器特定的同样方式的断言。它们与通用的‘p’约束类似。语法和语义在其它方面都与
define_constraint
相同。
由于历史的原因,
起始于字母‘G H’的名字被保留为只匹配const_double
的约束,
起始与字母‘I J K L M N O P’被保留为只匹配const_int
的约束。
这在将来可能会改变。暂时的,这些名字的约束必须使用固定形式来书写,
以便genpreds
能够辨别出你在做正确的事情:
(define_constraint "[GHIJKLMNOP]..." "doc..." (and (match_code "const_int") ;const_double
for G/H condition...)) ; usually amatch_test
可以使用起始于其它字母的名字来定义匹配const_double
或const_int
的约束。
在约束定义中的每个docstring应该是一条或多条完整的语句,使用Texinfo格式来标记。
它们目前没有被使用。在将来,它们将被复制到 GCC手册中,在机器约束这一章节,
用来替换手工维护的表格。而且,将来编译器可以使用其来给出更多有帮助的诊断信息,
当过少的asm
约束选择造成重载失败时。
如果你在docstring的起始出放入伪Texinfo指令‘@internal’,
则(在将来)其将只出现在internals手册版本的机器特定约束表中。
这可以用于不应该出现在asm
语句中的约束。