Next: , Previous: Defining Attributes, Up: Insn Attributes


16.19.2 属性表达式

用于定义属性的RTL表达式,除了使用上面描述的代码外,还使用了下面要 讨论的一些细节。属性值表达式必须为下列形式之一:

(const_int i)
整数 i 指定了一个数字属性的值。 i 必须为非负的。

数字属性的值可以被指定为一个 const_int,或者一个在 const_string, eq_attr (参见下面), attr, symbol_ref, 简单算术表达式, 和特定指令上的 set_attr (参见Tagging Insns)中,作为字符串来表示的整数,


(const_string value)
字符串指定了一个常量属性值。如果 value 使用 ‘"*"’ 指定, 则表示包含该表达式的insn将使用属性的缺省值。显然 ‘"*"’ 不能用 于 define_attrdefault 表达式。

如果属性值被指定为数值的,value 必须为一个字符串,包含了一个 非负整数(通常这种情况下会使用 const_int)。否则,其必须包含 一个有效的属性值。


(if_then_else test true-value false-value)
test 指定了一个属性测试,其格式在下面定义。如果 test 为 真时,该表达式的值为 true-value,否则为 false-value


(cond [test1 value1 ...] default)
该表达式的第一个操作数为一个向量,包含了偶数个表达式并且由 testvalue 表达式对组成。表达式 cond 的值为对应于第一个为 真的 test 表达式的 value。如果没有 test 表达式为真, 则 cond 表达式的值为 default 表达式。

test表达式可以具有下列形式:

(const_int i)
该测试为真,如果i非零,否则为假。


(not test)
(ior test1 test2)
(and test1 test2)
这些测试为真,如果所表示的逻辑函数为真。


(match_operand:m n pred constraints)
该测试为真,如果insn的操作数n,其属性值被确定具有机器模式m(如果mVOIDmode,则这部分测试被忽略),并且被字符串pred指定的函数,当传递操作数n和机器模式m时,返回一个非零值(如果pred为空字符串,则这部分测试被忽略)。

constraints操作数被忽略并且应该为空字符串。


(le arith1 arith2)
(leu arith1 arith2)
(lt arith1 arith2)
(ltu arith1 arith2)
(gt arith1 arith2)
(gtu arith1 arith2)
(ge arith1 arith2)
(geu arith1 arith2)
(ne arith1 arith2)
(eq arith1 arith2)
这些测试为真,如果所表示的对两个算术表达式的比较为真。算术表达式的形式为 plus, minus, mult, div, mod, abs, neg, and, ior, xor, not, ashift, lshiftrtashiftrt表达式。

const_intsymbol_ref总为有效(其它的形式,参见Insn Lengths)。symbol_ref为一个字符串,表示当使用‘get_attr_...’程序求解时,可以生成一个int的C表达式。其通常应该为一个全局变量。


(eq_attr name value)
name为一个字符串,指定了属性的名字。

value为一个字符串,或者为一个该属性name的有效值,由逗号分隔的值列表,或者为‘!’,后面跟随一个值或者列表。如果value不是起始于‘!’,则该测试为真,如果当前insn的name属性的值在值列表中。如果value起始于‘!’,则该测试为真,如果属性值不在指定的列表中。

例如,

          (eq_attr "type" "load,store")

等价于

          (ior (eq_attr "type" "load") (eq_attr "type" "store"))

如果name指定了属性‘alternative’,则它是指的编译器变量which_alternative的值(参见Output Statement),并且值必须为小整数。例如,

          (eq_attr "alternative" "2,3")

等价于

          (ior (eq (symbol_ref "which_alternative") (const_int 2))
               (eq (symbol_ref "which_alternative") (const_int 3)))

注意,对于大多数属性,当被测试的属性的值已知为匹配特定模式的所有insn时,eq_attr测试将被简化。这是迄今为止最常见的情况。


(attr_flag name)
表达式attr_flag的值为真,如果由name指定的标记对于当前被调度的insn为真。

name为一个字符串,指定了要测试的标记集合。测试标记forwardbackward可以确定条件分支的方向。测试标记very_likely, likely, very_unlikelyunlikely可以确定条件分支是否被接受。

如果very_likely为真,则likely标记也为真。同样对于very_unlikelyunlikely也是这样。

该例子描述了一个条件分支延迟槽,其对于被接受的(annul-true)forward分支或者没有被接受的(annul-false)的backward分支,可以置空(nullified),

          (define_delay (eq_attr "type" "cbranch")
            [(eq_attr "in_branch_delay" "true")
             (and (eq_attr "in_branch_delay" "true")
                  (attr_flag "forward"))
             (and (eq_attr "in_branch_delay" "true")
                  (attr_flag "backward"))])

标记forwardbackward为假,如果当前被调度的insn不是条件分支。

标记very_likelylikely为真,如果被调度的insn不是条件分支。标记very_unlikelyunlikely为假,如果被调度的attr_flag不是条件分支。

attr_flag只用于延迟槽调度阶段,并且跟编译器的其它过程没有关系。


(attr name)
返回另一个属性的值。这对于数值属性非常有用,因为eq_attrattr_flag可以产生比非数值属性更加有效的代码。