2.2. Output condition part of instruction defining patterns
Following genconditions will generate array insn_conditions which contains conditional test part of instrucitons description patterns. This array will be used to help optimizing the generation of backend functionalities, as we will see in later sections.
main (continued, genconditions)
199 /* Read the machine description. */
200
201 while (1)
202 {
203 desc = read_md_rtx (&pattern_lineno, &code);
204 if (desc == NULL)
205 break ;
206
207 /* N.B. define_insn_and_split, define_cond_exec are handled
208 entirely within read_md_rtx; we never see them. */
209 switch (GET_CODE (desc))
210 {
211 default :
212 break ;
213
214 case DEFINE_INSN:
215 case DEFINE_EXPAND:
216 add_condition (XSTR (desc, 2));
217 /* except.h needs to know whether there is an eh_return
218 pattern in the machine description. */
219 if (!strcmp (XSTR (desc, 0), "eh_return"))
220 saw_eh_return = 1;
221 break ;
222
223 case DEFINE_SPLIT:
224 case DEFINE_PEEPHOLE:
225 case DEFINE_PEEPHOLE2:
226 add_condition (XSTR (desc, 1));
227 break ;
228 }
229 }
230
231 write_header ();
232 write_conditions ();
233
234 fflush (stdout);
235 return (ferror (stdout) != 0 ? FATAL_EXIT_CODE : SUCCESS_EXIT_CODE);
236 }
Here, at line 203, read_md_rtx nearly does nothing, as insn_elision_unavailable is 1 – we just creating it. read_md_rtx just returns rtx object from define_attr_queue , define_insn_queue , or other_queue accordingly.
52 static void
53 add_condition (const char *expr) in genconditions.c
54 {
55 struct c_test *test;
56
57 if (expr[0] == 0)
58 return ;
59
60 test = xmalloc (sizeof (struct c_test));
61 test->expr = expr;
62
63 *(htab_find_slot (condition_table , test, INSERT)) = test;
64 }
All patterns will be put into hash table of condition_table via funciton add_condition . Pay attention to the parameter passed to add_condition , it is the condition part of the pattern. At line 231, write_header just outputs the constant part of the output file.
163 static void
164 write_conditions (void) in genconditions.c
165 {
166 puts ("/
167 /* This table lists each condition found in the machine description./n/
168 Each condition is mapped to its truth value (0 or 1), or -1 if that/n/
169 cannot be calculated at compile time. *//n/
170 /n/
171 const struct c_test insn_conditions[] = {");
172
173 htab_traverse (condition_table , write_one_condition , 0);
174
175 puts ("};/n");
176
177 printf ("const size_t n_insn_conditions = %lu;/n",
178 (unsigned long) htab_elements (condition_table ));
179 puts ("const int insn_elision_unavailable = 0;");
180 }
Above, at line 173, htab_traverse will invoke write_one_condition for every member in the condition_table . Here the function constructs the array of insn_conditions . And notice that at line 179, when creating insn-recog.c, maybe_eval_c_test will do the evaluation as now insn_elision_unavailable is zero.
140 static int
141 write_one_condition (void **slot, void *dummy ATTRIBUTE_UNUSED) in genconditions.c
142 {
143 const struct c_test *test = * (const struct c_test **) slot;
144 const char *p;
145
146 fputs (" { /"", stdout);
147 for (p = test->expr; *p; p++)
148 {
149 if (*p == '/n')
150 fputs ("//n///n", stdout);
151 else if (*p == '"')
152 fputs ("///"", stdout);
153 else
154 putchar (*p);
155 }
156
157 printf ("/",/n MAYBE_EVAL (%s) },/n", test->expr);
158 return 1;
159 }
Above at line 157, MAYBE_EVAL has definition as below. It also appears in the generated file insn-conditions.c (output by write_header ).
#if (GCC_VERSION >= 3001) || ((GCC_VERSION == 3000) && !__OPTIMIZE__)
# define MAYBE_EVAL(expr) (__builtin_constant_p(expr) ? (int) (expr) : -1)
#else
# define MAYBE_EVAL(expr) -1
#endif
__builtin_constant_p is the builtin function provided by GCC after release V3.0.1, it returns 1 if the expr is constant known at the time of compilation, otherwise returns 0. So MAYBE_EVAL returns the value of expression if it is constant; or -1 if it is not. This macro is used heavily with insn-conditions for other tools as we see later. It does helpful to reduce the size of generated code and save the processing time as the tools can skip those patterns known unmatched during handling at certain point of time.