Next: Disable Insn Alternatives, Previous: Class Preferences, Up: Constraints
当编译器修订操作数来满足约束时, 它需要知道哪些操作数为指令的输入以及哪些为它的输出。‘=’表示一个输出; ‘+’表示一个操作数同时为输入和输出;所有其它操作数将被认为只是输入。
如果你指定了‘=’或者‘+’,你要将它作为约束字符串的第一个字符。
‘&’只应用于其所在的可选项。在具有多个可选项的约束中, 有时一个可选项需要‘&’,而其它的不需要。例如,参见68000的‘movdf’ insn。
一个输入操作数可以被限定为一个earlyclobber操作数, 如果它唯一的作为输入的使用发生在早期结果被写出之前。 增加这种形式的可选项经常可以允许GCC来产生更好的代码, 当只有一些输出可以被earlyclobber影响时。例如,参见ARM的‘mulsi3’ insn。
‘&’不排除对‘=’的需要。
(define_insn "addhi3" [(set (match_operand:HI 0 "general_operand" "=m,r") (plus:HI (match_operand:HI 1 "general_operand" "%0,0") (match_operand:HI 2 "general_operand" "di,g")))] ...)
GCC只能处理在asm中的一个可交换对;如果你有更多的,编译器将会失败。
注意如果两个可选项严格相同,则不需要使用该修饰符;这只会在重载过程浪费时间。
该修饰符在寄存器分配之后,是不可操作的,
所以在重载之后执行的define_peephole2
和define_split
的结果不能依赖
‘%’来进行insn匹配。
这里有一个例子:68000有一条指令,用于在数据寄存器中符号扩展一个半字, 并且还可以通过将其复制到一个地址寄存器中来符号扩展一个值。 当每种寄存器都可以被接受时,对于地址寄存器的约束相对不是很严格, 所以最好是寄存器分配将地址寄存器作为其目标。 因此,‘*’被使用,以至于‘d’约束字母(数据寄存器)被忽略, 当计算寄存器优先时。
(define_insn "extendhisi2" [(set (match_operand:SI 0 "general_operand" "=*d,a") (sign_extend:SI (match_operand:HI 1 "general_operand" "0,g")))] ...)