]> git.ipfire.org Git - thirdparty/gcc.git/blame - gcc/doc/gccint/machine-descriptions/canonicalization-of-instructions.rst
sphinx: add missing trailing newline
[thirdparty/gcc.git] / gcc / doc / gccint / machine-descriptions / canonicalization-of-instructions.rst
CommitLineData
c63539ff
ML
1..
2 Copyright 1988-2022 Free Software Foundation, Inc.
3 This is part of the GCC manual.
4 For copying conditions, see the copyright.rst file.
5
6.. index:: canonicalization of instructions, insn canonicalization
7
8.. _insn-canonicalizations:
9
10Canonicalization of Instructions
11********************************
12
13There are often cases where multiple RTL expressions could represent an
14operation performed by a single machine instruction. This situation is
15most commonly encountered with logical, branch, and multiply-accumulate
16instructions. In such cases, the compiler attempts to convert these
17multiple RTL expressions into a single canonical form to reduce the
18number of insn patterns required.
19
20In addition to algebraic simplifications, following canonicalizations
21are performed:
22
23* For commutative and comparison operators, a constant is always made the
24 second operand. If a machine only supports a constant as the second
25 operand, only patterns that match a constant in the second operand need
26 be supplied.
27
28* For associative operators, a sequence of operators will always chain
29 to the left; for instance, only the left operand of an integer ``plus``
30 can itself be a ``plus``. ``and``, ``ior``, ``xor``,
31 ``plus``, ``mult``, ``smin``, ``smax``, ``umin``, and
32 ``umax`` are associative when applied to integers, and sometimes to
33 floating-point.
34
35.. index:: neg, canonicalization of, not, canonicalization of, mult, canonicalization of, plus, canonicalization of, minus, canonicalization of
36
37* For these operators, if only one operand is a ``neg``, ``not``,
38 ``mult``, ``plus``, or ``minus`` expression, it will be the
39 first operand.
40
41* In combinations of ``neg``, ``mult``, ``plus``, and
42 ``minus``, the ``neg`` operations (if any) will be moved inside
43 the operations as far as possible. For instance,
44 ``(neg (mult A B))`` is canonicalized as ``(mult (neg A) B)``, but
45 ``(plus (mult (neg B) C) A)`` is canonicalized as
46 ``(minus A (mult B C))``.
47
48 .. index:: compare, canonicalization of
49
50* For the ``compare`` operator, a constant is always the second operand
51 if the first argument is a condition code register.
52
53* For instructions that inherently set a condition code register, the
54 ``compare`` operator is always written as the first RTL expression of
55 the ``parallel`` instruction pattern. For example,
56
57 .. code-block::
58
59 (define_insn ""
60 [(set (reg:CCZ FLAGS_REG)
61 (compare:CCZ
62 (plus:SI
63 (match_operand:SI 1 "register_operand" "%r")
64 (match_operand:SI 2 "register_operand" "r"))
65 (const_int 0)))
66 (set (match_operand:SI 0 "register_operand" "=r")
67 (plus:SI (match_dup 1) (match_dup 2)))]
68 ""
69 "addl %0, %1, %2")
70
71* An operand of ``neg``, ``not``, ``mult``, ``plus``, or
72 ``minus`` is made the first operand under the same conditions as
73 above.
74
75* ``(ltu (plus ab) b)`` is converted to
76 ``(ltu (plus ab) a)``. Likewise with ``geu`` instead
77 of ``ltu``.
78
79* ``(minus x (const_int n))`` is converted to
80 ``(plus x (const_int -n))``.
81
82* Within address computations (i.e., inside ``mem``), a left shift is
83 converted into the appropriate multiplication by a power of two.
84
85 .. index:: ior, canonicalization of, and, canonicalization of, De Morgan's law
86
87* De Morgan's Law is used to move bitwise negation inside a bitwise
88 logical-and or logical-or operation. If this results in only one
89 operand being a ``not`` expression, it will be the first one.
90
91 A machine that has an instruction that performs a bitwise logical-and of one
92 operand with the bitwise negation of the other should specify the pattern
93 for that instruction as
94
95 .. code-block::
96
97 (define_insn ""
98 [(set (match_operand:m 0 ...)
99 (and:m (not:m (match_operand:m 1 ...))
100 (match_operand:m 2 ...)))]
101 "..."
102 "...")
103
104 Similarly, a pattern for a 'NAND' instruction should be written
105
106 .. code-block::
107
108 (define_insn ""
109 [(set (match_operand:m 0 ...)
110 (ior:m (not:m (match_operand:m 1 ...))
111 (not:m (match_operand:m 2 ...))))]
112 "..."
113 "...")
114
115 In both cases, it is not necessary to include patterns for the many
116 logically equivalent RTL expressions.
117
118 .. index:: xor, canonicalization of
119
120* The only possible RTL expressions involving both bitwise exclusive-or
121 and bitwise negation are ``(xor:mxy)``
122 and ``(not:m (xor:mxy))``.
123
124* The sum of three items, one of which is a constant, will only appear in
125 the form
126
127 .. code-block:: c++
128
129 (plus:m (plus:m x y) constant)
130
131 .. index:: zero_extract, canonicalization of, sign_extract, canonicalization of
132
133* Equality comparisons of a group of bits (usually a single bit) with zero
134 will be written using ``zero_extract`` rather than the equivalent
135 ``and`` or ``sign_extract`` operations.
136
137 .. index:: mult, canonicalization of
138
139* ``(sign_extend:m1 (mult:m2 (sign_extend:m2x)
140 (sign_extend:m2y)))`` is converted to ``(mult:m1
141 (sign_extend:m1x) (sign_extend:m1y))``, and likewise
142 for ``zero_extend``.
143
144* ``(sign_extend:m1 (mult:m2 (ashiftrt:m2xs) (sign_extend:m2y)))`` is converted
145 to ``(mult:m1 (sign_extend:m1 (ashiftrt:m2xs)) (sign_extend:m1y))``, and likewise for
146 patterns using ``zero_extend`` and ``lshiftrt``. If the second
147 operand of ``mult`` is also a shift, then that is extended also.
148 This transformation is only applied when it can be proven that the
149 original operation had sufficient precision to prevent overflow.
150
151Further canonicalization rules are defined in the function
3ed1b4ce 152``commutative_operand_precedence`` in :samp:`gcc/rtlanal.cc`.