]>
Commit | Line | Data |
---|---|---|
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:: constant definitions, define_constants | |
7 | ||
8 | .. _constant-definitions: | |
9 | ||
10 | Constant Definitions | |
11 | ******************** | |
12 | ||
13 | Using literal constants inside instruction patterns reduces legibility and | |
14 | can be a maintenance problem. | |
15 | ||
16 | To overcome this problem, you may use the ``define_constants`` | |
17 | expression. It contains a vector of name-value pairs. From that | |
18 | point on, wherever any of the names appears in the MD file, it is as | |
19 | if the corresponding value had been written instead. You may use | |
20 | ``define_constants`` multiple times; each appearance adds more | |
21 | constants to the table. It is an error to redefine a constant with | |
22 | a different value. | |
23 | ||
24 | To come back to the a29k load multiple example, instead of | |
25 | ||
26 | .. code-block:: | |
27 | ||
28 | (define_insn "" | |
29 | [(match_parallel 0 "load_multiple_operation" | |
30 | [(set (match_operand:SI 1 "gpc_reg_operand" "=r") | |
31 | (match_operand:SI 2 "memory_operand" "m")) | |
32 | (use (reg:SI 179)) | |
33 | (clobber (reg:SI 179))])] | |
34 | "" | |
35 | "loadm 0,0,%1,%2") | |
36 | ||
37 | You could write: | |
38 | ||
39 | .. code-block:: | |
40 | ||
41 | (define_constants [ | |
42 | (R_BP 177) | |
43 | (R_FC 178) | |
44 | (R_CR 179) | |
45 | (R_Q 180) | |
46 | ]) | |
47 | ||
48 | (define_insn "" | |
49 | [(match_parallel 0 "load_multiple_operation" | |
50 | [(set (match_operand:SI 1 "gpc_reg_operand" "=r") | |
51 | (match_operand:SI 2 "memory_operand" "m")) | |
52 | (use (reg:SI R_CR)) | |
53 | (clobber (reg:SI R_CR))])] | |
54 | "" | |
55 | "loadm 0,0,%1,%2") | |
56 | ||
57 | The constants that are defined with a define_constant are also output | |
58 | in the insn-codes.h header file as #defines. | |
59 | ||
60 | .. index:: enumerations, define_c_enum | |
61 | ||
62 | You can also use the machine description file to define enumerations. | |
63 | Like the constants defined by ``define_constant``, these enumerations | |
64 | are visible to both the machine description file and the main C code. | |
65 | ||
66 | The syntax is as follows: | |
67 | ||
68 | .. code-block:: | |
69 | ||
70 | (define_c_enum "name" [ | |
71 | value0 | |
72 | value1 | |
73 | (value32 32) | |
74 | value33 | |
75 | ... | |
76 | valuen | |
77 | ]) | |
78 | ||
79 | This definition causes the equivalent of the following C code to appear | |
80 | in :samp:`insn-constants.h`: | |
81 | ||
82 | .. code-block:: c++ | |
83 | ||
84 | enum name { | |
85 | value0 = 0, | |
86 | value1 = 1, | |
87 | value32 = 32, | |
88 | value33 = 33, | |
89 | ... | |
90 | valuen = n | |
91 | }; | |
92 | #define NUM_cname_VALUES (n + 1) | |
93 | ||
94 | where :samp:`{cname}` is the capitalized form of :samp:`{name}`. | |
95 | It also makes each :samp:`{valuei}` available in the machine description | |
96 | file, just as if it had been declared with: | |
97 | ||
98 | .. code-block:: | |
99 | ||
100 | (define_constants [(valuei i)]) | |
101 | ||
102 | Each :samp:`{valuei}` is usually an upper-case identifier and usually | |
103 | begins with :samp:`{cname}`. | |
104 | ||
105 | You can split the enumeration definition into as many statements as | |
106 | you like. The above example is directly equivalent to: | |
107 | ||
108 | .. code-block:: | |
109 | ||
110 | (define_c_enum "name" [value0]) | |
111 | (define_c_enum "name" [value1]) | |
112 | ... | |
113 | (define_c_enum "name" [valuen]) | |
114 | ||
115 | Splitting the enumeration helps to improve the modularity of each | |
116 | individual ``.md`` file. For example, if a port defines its | |
117 | synchronization instructions in a separate :samp:`sync.md` file, | |
118 | it is convenient to define all synchronization-specific enumeration | |
119 | values in :samp:`sync.md` rather than in the main :samp:`.md` file. | |
120 | ||
121 | Some enumeration names have special significance to GCC: | |
122 | ||
123 | ``unspecv`` | |
124 | ||
125 | .. index:: unspec_volatile | |
126 | ||
127 | If an enumeration called ``unspecv`` is defined, GCC will use it | |
128 | when printing out ``unspec_volatile`` expressions. For example: | |
129 | ||
130 | .. code-block:: | |
131 | ||
132 | (define_c_enum "unspecv" [ | |
133 | UNSPECV_BLOCKAGE | |
134 | ]) | |
135 | ||
136 | causes GCC to print :samp:`(unspec_volatile ... 0)` as: | |
137 | ||
138 | .. code-block:: c++ | |
139 | ||
140 | (unspec_volatile ... UNSPECV_BLOCKAGE) | |
141 | ||
142 | ``unspec`` | |
143 | ||
144 | .. index:: unspec | |
145 | ||
146 | If an enumeration called ``unspec`` is defined, GCC will use | |
147 | it when printing out ``unspec`` expressions. GCC will also use | |
148 | it when printing out ``unspec_volatile`` expressions unless an | |
149 | ``unspecv`` enumeration is also defined. You can therefore | |
150 | decide whether to keep separate enumerations for volatile and | |
151 | non-volatile expressions or whether to use the same enumeration | |
152 | for both. | |
153 | ||
154 | .. index:: define_enum | |
155 | ||
156 | .. _define_enum: | |
157 | ||
158 | Another way of defining an enumeration is to use ``define_enum`` : | |
159 | ||
160 | .. code-block:: | |
161 | ||
162 | (define_enum "name" [ | |
163 | value0 | |
164 | value1 | |
165 | ... | |
166 | valuen | |
167 | ]) | |
168 | ||
169 | This directive implies: | |
170 | ||
171 | .. code-block:: | |
172 | ||
173 | (define_c_enum "name" [ | |
174 | cname_cvalue0 | |
175 | cname_cvalue1 | |
176 | ... | |
177 | cname_cvaluen | |
178 | ]) | |
179 | ||
180 | .. index:: define_enum_attr | |
181 | ||
182 | where :samp:`{cvaluei}` is the capitalized form of :samp:`{valuei}`. | |
183 | However, unlike ``define_c_enum``, the enumerations defined | |
184 | by ``define_enum`` can be used in attribute specifications | |
3ed1b4ce | 185 | (see :ref:`define_enum_attr`). |