gccint: Insn Canonicalizations

1 
1 17.14 Canonicalization of Instructions
1 ======================================
1 
1 There are often cases where multiple RTL expressions could represent an
1 operation performed by a single machine instruction.  This situation is
1 most commonly encountered with logical, branch, and multiply-accumulate
1 instructions.  In such cases, the compiler attempts to convert these
1 multiple RTL expressions into a single canonical form to reduce the
1 number of insn patterns required.
1 
1  In addition to algebraic simplifications, following canonicalizations
1 are performed:
1 
1    * For commutative and comparison operators, a constant is always made
1      the second operand.  If a machine only supports a constant as the
1      second operand, only patterns that match a constant in the second
1      operand need be supplied.
1 
1    * For associative operators, a sequence of operators will always
1      chain to the left; for instance, only the left operand of an
1      integer 'plus' can itself be a 'plus'.  'and', 'ior', 'xor',
1      'plus', 'mult', 'smin', 'smax', 'umin', and 'umax' are associative
1      when applied to integers, and sometimes to floating-point.
1 
1    * For these operators, if only one operand is a 'neg', 'not', 'mult',
1      'plus', or 'minus' expression, it will be the first operand.
1 
1    * In combinations of 'neg', 'mult', 'plus', and 'minus', the 'neg'
1      operations (if any) will be moved inside the operations as far as
1      possible.  For instance, '(neg (mult A B))' is canonicalized as
1      '(mult (neg A) B)', but '(plus (mult (neg B) C) A)' is
1      canonicalized as '(minus A (mult B C))'.
1 
1    * For the 'compare' operator, a constant is always the second operand
1      if the first argument is a condition code register or '(cc0)'.
1 
1    * For instructions that inherently set a condition code register, the
1      'compare' operator is always written as the first RTL expression of
1      the 'parallel' instruction pattern.  For example,
1 
1           (define_insn ""
1             [(set (reg:CCZ FLAGS_REG)
1           	(compare:CCZ
1           	  (plus:SI
1           	    (match_operand:SI 1 "register_operand" "%r")
1           	    (match_operand:SI 2 "register_operand" "r"))
1           	  (const_int 0)))
1              (set (match_operand:SI 0 "register_operand" "=r")
1           	(plus:SI (match_dup 1) (match_dup 2)))]
1             ""
1             "addl %0, %1, %2")
1 
1    * An operand of 'neg', 'not', 'mult', 'plus', or 'minus' is made the
1      first operand under the same conditions as above.
1 
1    * '(ltu (plus A B) B)' is converted to '(ltu (plus A B) A)'.
1      Likewise with 'geu' instead of 'ltu'.
1 
1    * '(minus X (const_int N))' is converted to '(plus X (const_int
1      -N))'.
1 
1    * Within address computations (i.e., inside 'mem'), a left shift is
1      converted into the appropriate multiplication by a power of two.
1 
1    * De Morgan's Law is used to move bitwise negation inside a bitwise
1      logical-and or logical-or operation.  If this results in only one
1      operand being a 'not' expression, it will be the first one.
1 
1      A machine that has an instruction that performs a bitwise
1      logical-and of one operand with the bitwise negation of the other
1      should specify the pattern for that instruction as
1 
1           (define_insn ""
1             [(set (match_operand:M 0 ...)
1                   (and:M (not:M (match_operand:M 1 ...))
1                                (match_operand:M 2 ...)))]
1             "..."
1             "...")
1 
1      Similarly, a pattern for a "NAND" instruction should be written
1 
1           (define_insn ""
1             [(set (match_operand:M 0 ...)
1                   (ior:M (not:M (match_operand:M 1 ...))
1                                (not:M (match_operand:M 2 ...))))]
1             "..."
1             "...")
1 
1      In both cases, it is not necessary to include patterns for the many
1      logically equivalent RTL expressions.
1 
1    * The only possible RTL expressions involving both bitwise
1      exclusive-or and bitwise negation are '(xor:M X Y)' and '(not:M
1      (xor:M X Y))'.
1 
1    * The sum of three items, one of which is a constant, will only
1      appear in the form
1 
1           (plus:M (plus:M X Y) CONSTANT)
1 
1    * Equality comparisons of a group of bits (usually a single bit) with
1      zero will be written using 'zero_extract' rather than the
1      equivalent 'and' or 'sign_extract' operations.
1 
1    * '(sign_extend:M1 (mult:M2 (sign_extend:M2 X) (sign_extend:M2 Y)))'
1      is converted to '(mult:M1 (sign_extend:M1 X) (sign_extend:M1 Y))',
1      and likewise for 'zero_extend'.
1 
1    * '(sign_extend:M1 (mult:M2 (ashiftrt:M2 X S) (sign_extend:M2 Y)))'
1      is converted to '(mult:M1 (sign_extend:M1 (ashiftrt:M2 X S))
1      (sign_extend:M1 Y))', and likewise for patterns using 'zero_extend'
1      and 'lshiftrt'.  If the second operand of 'mult' is also a shift,
1      then that is extended also.  This transformation is only applied
1      when it can be proven that the original operation had sufficient
1      precision to prevent overflow.
1 
1  Further canonicalization rules are defined in the function
1 'commutative_operand_precedence' in 'gcc/rtlanal.c'.
1