gccint: Modifiers
1
1 17.8.4 Constraint Modifier Characters
1 -------------------------------------
1
1 Here are constraint modifier characters.
1
1 '='
1 Means that this operand is written to by this instruction: the
1 previous value is discarded and replaced by new data.
1
1 '+'
1 Means that this operand is both read and written by the
1 instruction.
1
1 When the compiler fixes up the operands to satisfy the constraints,
1 it needs to know which operands are read by the instruction and
1 which are written by it. '=' identifies an operand which is only
1 written; '+' identifies an operand that is both read and written;
1 all other operands are assumed to only be read.
1
1 If you specify '=' or '+' in a constraint, you put it in the first
1 character of the constraint string.
1
1 '&'
1 Means (in a particular alternative) that this operand is an
1 "earlyclobber" operand, which is written before the instruction is
1 finished using the input operands. Therefore, this operand may not
1 lie in a register that is read by the instruction or as part of any
1 memory address.
1
1 '&' applies only to the alternative in which it is written. In
1 constraints with multiple alternatives, sometimes one alternative
1 requires '&' while others do not. See, for example, the 'movdf'
1 insn of the 68000.
1
1 A operand which is read by the instruction can be tied to an
1 earlyclobber operand if its only use as an input occurs before the
1 early result is written. Adding alternatives of this form often
1 allows GCC to produce better code when only some of the read
1 operands can be affected by the earlyclobber. See, for example,
1 the 'mulsi3' insn of the ARM.
1
1 Furthermore, if the "earlyclobber" operand is also a read/write
1 operand, then that operand is written only after it's used.
1
1 '&' does not obviate the need to write '=' or '+'. As
1 "earlyclobber" operands are always written, a read-only
1 "earlyclobber" operand is ill-formed and will be rejected by the
1 compiler.
1
1 '%'
1 Declares the instruction to be commutative for this operand and the
1 following operand. This means that the compiler may interchange
1 the two operands if that is the cheapest way to make all operands
1 fit the constraints. '%' applies to all alternatives and must
1 appear as the first character in the constraint. Only read-only
1 operands can use '%'.
1
1 This is often used in patterns for addition instructions that
1 really have only two operands: the result must go in one of the
1 arguments. Here for example, is how the 68000 halfword-add
1 instruction is defined:
1
1 (define_insn "addhi3"
1 [(set (match_operand:HI 0 "general_operand" "=m,r")
1 (plus:HI (match_operand:HI 1 "general_operand" "%0,0")
1 (match_operand:HI 2 "general_operand" "di,g")))]
1 ...)
1 GCC can only handle one commutative pair in an asm; if you use
1 more, the compiler may fail. Note that you need not use the
1 modifier if the two alternatives are strictly identical; this would
1 only waste time in the reload pass. The modifier is not
1 operational after register allocation, so the result of
1 'define_peephole2' and 'define_split's performed after reload
1 cannot rely on '%' to make the intended insn match.
1
1 '#'
1 Says that all following characters, up to the next comma, are to be
1 ignored as a constraint. They are significant only for choosing
1 register preferences.
1
1 '*'
1 Says that the following character should be ignored when choosing
1 register preferences. '*' has no effect on the meaning of the
1 constraint as a constraint, and no effect on reloading. For LRA
1 '*' additionally disparages slightly the alternative if the
1 following character matches the operand.
1
1 Here is an example: the 68000 has an instruction to sign-extend a
1 halfword in a data register, and can also sign-extend a value by
1 copying it into an address register. While either kind of register
1 is acceptable, the constraints on an address-register destination
1 are less strict, so it is best if register allocation makes an
1 address register its goal. Therefore, '*' is used so that the 'd'
1 constraint letter (for data register) is ignored when computing
1 register preferences.
1
1 (define_insn "extendhisi2"
1 [(set (match_operand:SI 0 "general_operand" "=*d,a")
1 (sign_extend:SI
1 (match_operand:HI 1 "general_operand" "0,g")))]
1 ...)
1