Previous: Define Constraints, Up: Constraints


16.8.8 从C中测试约束

有时从C代码中测试约束要比隐式的通过match_operand中的约束字符串有用处。 生成文件tm_p.h声明了一些接口,用于机器特定的约束。 这些接口都没有用于在Simple Constraints中描述的通用约束。 这在将来可能会有所改变。

警告:tm_p.h可能声明了其它操作约束的函数,除了在这里列的以外。 不要在机器独立的代码中使用那些函数。它们只是为了实现旧的约束接口。 它们在将来将会有变动或者消失。

一些有效的约束名字不是有效的C标志符, 所以这里有一个mangling框架用于从C中引用它们。 不包含三角括号或者下划线的约束名保持不变。下划线改写成两次, 每个‘<’被‘_l’替换,每个‘>’被‘_g’替换。这里有些例子:

     

Original Mangled
x x
P42x P42x
P4_x P4__x
P4>x P4_gx
P4>> P4_g_g
P4_g> P4__g_g

在该章节中,变量c或者为一个抽象的约束, 或者为来自enum constraint_num的常量; 变量m为一个mangled约束名字(通常作为一个大标志符的一部分)。

— Enum: constraint_num

对于每个机器特定的约束,有一个对应的枚举常量: ‘CONSTRAINT_’加上约束的mangled名字。 函数接受一个enum constraint_num作为参数。

机器独立的约束不具有相关的常量。这在将来可能会有改变。

— Function: inline bool satisfies_constraint_m (rtx exp)

对于每个机器特定的,非寄存器约束m,有一个这样函数;其返回true, 如果exp满足约束。 这些函数只有当rtl.h被包含在tm_p.h之前时才可见。

— Function: bool constraint_satisfied_p (rtx exp, enum constraint_num c)

类似satisfies_constraint_m函数,只是被测试的约束作为参数给出, c。如果c指定一个寄存器约束,该函数将总是返回false

— Function: enum reg_class regclass_for_constraint (enum constraint_num c)

返回与c关联的寄存器类别。如果c不是寄存器约束, 或者那些寄存器对于当前选择的子target无效,则返回NO_REGS

这里有一个使用satisfies_constraint_m的例子。 在窥孔优化(参见Peephole Definitions)中,操作数约束字符串将被忽略, 所以如果有相应的约束,它们必须在C条件中被测试。在例子中,如果操作数2不满足‘K’约束,优化将被采用。 (这是从 i386机器描述中的窥孔定义简化的版本。)

     (define_peephole2
       [(match_scratch:SI 3 "r")
        (set (match_operand:SI 0 "register_operand" "")
             (mult:SI (match_operand:SI 1 "memory_operand" "")
                      (match_operand:SI 2 "immediate_operand" "")))]
     
       "!satisfies_constraint_K (operands[2])"
     
       [(set (match_dup 3) (match_dup 1))
        (set (match_dup 0) (mult:SI (match_dup 3) (match_dup 2)))]
     
       "")