[Contents]   [Back]   [Prev]   [Up]   [Next]   [Forward]

## Canonicalization of Instructions

There are often cases where multiple RTL expressions could represent an operation performed by a single machine instruction. This situation is most commonly encountered with logical, branch, and multiply-accumulate instructions. In such cases, the compiler attempts to convert these multiple RTL expressions into a single canonical form to reduce the number of insn patterns required.

In addition to algebraic simplifications, following canonicalizations are performed:

• For commutative and comparison operators, a constant is always made the second operand. If a machine only supports a constant as the second operand, only patterns that match a constant in the second operand need be supplied. For these operators, if only one operand is a `neg`, `not`, `mult`, `plus`, or `minus` expression, it will be the first operand.
• For the `compare` operator, a constant is always the second operand on machines where `cc0` is used (see section Defining Jump Instruction Patterns). On other machines, there are rare cases where the compiler might want to construct a `compare` with a constant as the first operand. However, these cases are not common enough for it to be worthwhile to provide a pattern matching a constant as the first operand unless the machine actually has such an instruction. An operand of `neg`, `not`, `mult`, `plus`, or `minus` is made the first operand under the same conditions as above.
• `(minus x (const_int n))` is converted to `(plus x (const_int -n))`.
• Within address computations (i.e., inside `mem`), a left shift is converted into the appropriate multiplication by a power of two.
• De`Morgan's Law is used to move bitwise negation inside a bitwise logical-and or logical-or operation. If this results in only one operand being a `not` expression, it will be the first one. A machine that has an instruction that performs a bitwise logical-and of one operand with the bitwise negation of the other should specify the pattern for that instruction as
```(define_insn ""
[(set (match_operand:m 0 ...)
(and:m (not:m (match_operand:m 1 ...))
(match_operand:m 2 ...)))]
"..."
"...")
```
Similarly, a pattern for a "NAND" instruction should be written
```(define_insn ""
[(set (match_operand:m 0 ...)
(ior:m (not:m (match_operand:m 1 ...))
(not:m (match_operand:m 2 ...))))]
"..."
"...")
```
In both cases, it is not necessary to include patterns for the many logically equivalent RTL expressions.
• The only possible RTL expressions involving both bitwise exclusive-or and bitwise negation are `(xor:m x y)` and `(not:m (xor:m x y))`.
• The sum of three items, one of which is a constant, will only appear in the form
```(plus:m (plus:m x y) constant)
```
• On machines that do not use `cc0`, `(compare x (const_int 0))` will be converted to x.
• Equality comparisons of a group of bits (usually a single bit) with zero will be written using `zero_extract` rather than the equivalent `and` or `sign_extract` operations.

[Contents]   [Back]   [Prev]   [Up]   [Next]   [Forward]