Next: Constant Attributes, Previous: Attr Example, Up: Insn Attributes
许多机器提供了多种类型的分支指令,针对于不同长度的分支位移。多数情况下,
汇编器会选择使用正确的指令。但是,当汇编器无法做到的时候,如果一个特殊的属性,
length
属性,被定义,则可以由GCC来完成。
该属性必须通过在它的define_attr
中指定一个空字符串,
从而被定义成具有数字值。
对于length
属性,在test表达式中允许两个额外形式的算术术语:
(match_dup
n)
label_ref
。
(pc)
对于通常的insn,长度将由length
属性的值来确定。
对于addr_vec
和addr_diff_vec
的insn模式,
长度通过向量数乘于每个向量的大小来计算获得。
长度按照可寻址的存储单元(字节)来度量。
ADJUST_INSN_LENGTH (
insn,
length)
该宏通常并不需要。一种使用它的情况为ROMP。在这个机器上,
一个addr_vec
insn的大小必须被加2用于补偿可能需要的指令对齐。
返回get_attr_length
(length
属性的值)的程序,
可以被输出程序用来确定将要写入的分支指令的形式,正如下面的例子。
作为一个指定可变长度分支的例子,可以考虑一下IBM360。 如果我们采用寄存器将被设为函数起始地址这样的约定, 我们则可以使用一个4字节的指令来跳转到4K范围的标号。 否则,我们需要一个6字节的序列来从内存加载地址并然后分支到那里。
对于这样的机器,可以按照如下的方式来指定一个分支指令模式:
(define_insn "jump" [(set (pc) (label_ref (match_operand 0 "" "")))] "" { return (get_attr_length (insn) == 4 ? "b %l0" : "l r15,=a(%l0); br r15"); } [(set (attr "length") (if_then_else (lt (match_dup 0) (const_int 4096)) (const_int 4) (const_int 6)))])