Previous: Machine-Independent Predicates, Up: Predicates
许多机器对操作数的要求无法使用通用的predicate来精确表达。
你可以使用表达式define_predicate
和define_special_predicate
来定义 额外的predicate。这些表达式具有三个操作数:
match_operand
或match_operator
表达式中被引用。
MATCH_OPERAND
MATCH_OPERAND
在predicate允许op时为真。
操作数编号和constraint被忽略。由于genrecog中的限制,
你只能用于引用通用的predicate和已经被定义的predicate。
MATCH_CODE
该表达式的第一个操作数为一个字符串常量,
包含了逗号分割的RTX代码名字(小写形式)列表。这些是MATCH_CODE
为真的代码。
第二个操作数为一个字符串常量,其指示op的什么子表达式需要被检查。
如果没有或者为空字符串,则检查op本身。
否则,字符串常量必须为一个数字和/或小写字母的序列。
每个字符指示从当前表达式中抽取的子表达式;
第一个字符为op,第二个和后续字符,其为先前字符的结果。
数字n用于抽取‘XEXP (e, n)’;
字母l抽取‘XVECEXP (e, 0, n)’,
其中n为l的字母顺序(0为`a',1为'b',等等)。
MATCH_CODE
然后检查完整字符串所抽取的子表达式的RTX代码。
MATCH_TEST
MATCH_TEST
为真。
MATCH_TEST
表达式必须不具有副作用。
AND
IOR
NOT
IF_THEN_ELSE
AND
或IOR
表达式任意数目的参数;
这跟写成两个参数的AND
或IOR
表达式链具有相同的效果。
如果代码块存在于predicate定义中,则对于predicate允许的操作数, RTL表达式必须求值为true并且代码块必须执行‘return true’。 RTL表达式被首先求值,不要重复检查代码块中的在RTL表达式中曾经被检查过的任何事情。
程序genrecog扫描define_predicate
和
define_special_predicate
表达式来决定什么RTX代码可能被允许。
你应该使其在RTL predicate表达式中总是显式的,
使用MATCH_OPERAND
和MATCH_CODE
。
这里有一个简单的定义predicate的例子,来自IA64机器描述:
;; True if op is a SYMBOL_REF
which refers to the sdata section.
(define_predicate "small_addr_symbolic_operand"
(and (match_code "symbol_ref")
(match_test "SYMBOL_REF_SMALL_ADDR_P (op)")))
另一个例子,展示了C块的使用。
;; True if op is a register operand that is (or could be) a GR reg. (define_predicate "gr_register_operand" (match_operand 0 "register_operand") { unsigned int regno; if (GET_CODE (op) == SUBREG) op = SUBREG_REG (op); regno = REGNO (op); return (regno >= FIRST_PSEUDO_REGISTER || GENERAL_REGNO_P (regno)); })
使用define_predicate
编写的predicate会自动包含一个测试,
用来测试mode为VOIDmode
,
或者op具有与mode相同的机器模式,
或者op为CONST_INT
或CONST_DOUBLE
。
它们不专门检查整数CONST_DOUBLE
,
也不测试每种常量的值是否适合所需求的机器模式。
这是因为接受常量的目标机特定的predicate,通常必须做更严厉的值检查。
如果你需要确切的通用predicate提供的对CONST_INT
或
CONST_DOUBLE
的对待,
则可以使用MATCH_OPERAND
子表达式来调用const_int_operand
,
const_double_operand
或者immediate_operand
。
使用define_special_predicate
编写的predicate不做任何自动的机器模式检查,
并且genrecog将其作为具有特定的机器模式处理来对待。
程序genpreds负责生成代码来测试predicate。 其还编写了一个包含所有机器特定predicate的函数声明的头文件。 所以不需要在cpu-protos.h中声明这些predicate。