recog.h (alternative_class): New function.
[platform/upstream/gcc.git] / gcc / recog.h
1 /* Declarations for interface to insn recognizer and insn-output.c.
2    Copyright (C) 1987-2014 Free Software Foundation, Inc.
3
4 This file is part of GCC.
5
6 GCC is free software; you can redistribute it and/or modify it under
7 the terms of the GNU General Public License as published by the Free
8 Software Foundation; either version 3, or (at your option) any later
9 version.
10
11 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
12 WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
14 for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with GCC; see the file COPYING3.  If not see
18 <http://www.gnu.org/licenses/>.  */
19
20 #ifndef GCC_RECOG_H
21 #define GCC_RECOG_H
22
23 /* Random number that should be large enough for all purposes.  Also define
24    a type that has at least MAX_RECOG_ALTERNATIVES + 1 bits, with the extra
25    bit giving an invalid value that can be used to mean "uninitialized".  */
26 #define MAX_RECOG_ALTERNATIVES 30
27 typedef unsigned int alternative_mask;
28
29 /* A mask of all alternatives.  */
30 #define ALL_ALTERNATIVES ((alternative_mask) -1)
31
32 /* A mask containing just alternative X.  */
33 #define ALTERNATIVE_BIT(X) ((alternative_mask) 1 << (X))
34
35 /* Types of operands.  */
36 enum op_type {
37   OP_IN,
38   OP_OUT,
39   OP_INOUT
40 };
41
42 struct operand_alternative
43 {
44   /* Pointer to the beginning of the constraint string for this alternative,
45      for easier access by alternative number.  */
46   const char *constraint;
47
48   /* The register class valid for this alternative (possibly NO_REGS).  */
49   enum reg_class cl;
50
51   /* "Badness" of this alternative, computed from number of '?' and '!'
52      characters in the constraint string.  */
53   unsigned int reject;
54
55   /* -1 if no matching constraint was found, or an operand number.  */
56   int matches;
57   /* The same information, but reversed: -1 if this operand is not
58      matched by any other, or the operand number of the operand that
59      matches this one.  */
60   int matched;
61
62   /* Nonzero if '&' was found in the constraint string.  */
63   unsigned int earlyclobber:1;
64   /* Nonzero if TARGET_MEM_CONSTRAINT was found in the constraint
65      string.  */
66   unsigned int memory_ok:1;
67   /* Nonzero if 'o' was found in the constraint string.  */
68   unsigned int offmem_ok:1;
69   /* Nonzero if 'V' was found in the constraint string.  */
70   unsigned int nonoffmem_ok:1;
71   /* Nonzero if '<' was found in the constraint string.  */
72   unsigned int decmem_ok:1;
73   /* Nonzero if '>' was found in the constraint string.  */
74   unsigned int incmem_ok:1;
75   /* Nonzero if 'p' was found in the constraint string.  */
76   unsigned int is_address:1;
77   /* Nonzero if 'X' was found in the constraint string, or if the constraint
78      string for this alternative was empty.  */
79   unsigned int anything_ok:1;
80 };
81
82 /* Return the class for operand I of alternative ALT, taking matching
83    constraints into account.  */
84
85 static inline enum reg_class
86 alternative_class (const operand_alternative *alt, int i)
87 {
88   return alt[i].matches >= 0 ? alt[alt[i].matches].cl : alt[i].cl;
89 }
90
91 extern void init_recog (void);
92 extern void init_recog_no_volatile (void);
93 extern int check_asm_operands (rtx);
94 extern int asm_operand_ok (rtx, const char *, const char **);
95 extern bool validate_change (rtx, rtx *, rtx, bool);
96 extern bool validate_unshare_change (rtx, rtx *, rtx, bool);
97 extern bool canonicalize_change_group (rtx insn, rtx x);
98 extern int insn_invalid_p (rtx, bool);
99 extern int verify_changes (int);
100 extern void confirm_change_group (void);
101 extern int apply_change_group (void);
102 extern int num_validated_changes (void);
103 extern void cancel_changes (int);
104 extern int constrain_operands (int);
105 extern int constrain_operands_cached (int);
106 extern int memory_address_addr_space_p (enum machine_mode, rtx, addr_space_t);
107 #define memory_address_p(mode,addr) \
108         memory_address_addr_space_p ((mode), (addr), ADDR_SPACE_GENERIC)
109 extern int strict_memory_address_addr_space_p (enum machine_mode, rtx,
110                                                addr_space_t);
111 #define strict_memory_address_p(mode,addr) \
112         strict_memory_address_addr_space_p ((mode), (addr), ADDR_SPACE_GENERIC)
113 extern int validate_replace_rtx_subexp (rtx, rtx, rtx, rtx *);
114 extern int validate_replace_rtx (rtx, rtx, rtx);
115 extern int validate_replace_rtx_part (rtx, rtx, rtx *, rtx);
116 extern int validate_replace_rtx_part_nosimplify (rtx, rtx, rtx *, rtx);
117 extern void validate_replace_rtx_group (rtx, rtx, rtx);
118 extern void validate_replace_src_group (rtx, rtx, rtx);
119 extern bool validate_simplify_insn (rtx insn);
120 extern int num_changes_pending (void);
121 #ifdef HAVE_cc0
122 extern int next_insn_tests_no_inequality (rtx);
123 #endif
124 extern bool reg_fits_class_p (const_rtx, reg_class_t, int, enum machine_mode);
125
126 extern int offsettable_memref_p (rtx);
127 extern int offsettable_nonstrict_memref_p (rtx);
128 extern int offsettable_address_addr_space_p (int, enum machine_mode, rtx,
129                                              addr_space_t);
130 #define offsettable_address_p(strict,mode,addr) \
131         offsettable_address_addr_space_p ((strict), (mode), (addr), \
132                                           ADDR_SPACE_GENERIC)
133 extern bool mode_dependent_address_p (rtx, addr_space_t);
134
135 extern int recog (rtx, rtx, int *);
136 #ifndef GENERATOR_FILE
137 static inline int recog_memoized (rtx insn);
138 #endif
139 extern void add_clobbers (rtx, int);
140 extern int added_clobbers_hard_reg_p (int);
141 extern void insn_extract (rtx);
142 extern void extract_insn (rtx);
143 extern void extract_constrain_insn_cached (rtx);
144 extern void extract_insn_cached (rtx);
145 extern void preprocess_constraints (void);
146 extern rtx peep2_next_insn (int);
147 extern int peep2_regno_dead_p (int, int);
148 extern int peep2_reg_dead_p (int, rtx);
149 #ifdef CLEAR_HARD_REG_SET
150 extern rtx peep2_find_free_register (int, int, const char *,
151                                      enum machine_mode, HARD_REG_SET *);
152 #endif
153 extern rtx peephole2_insns (rtx, rtx, int *);
154
155 extern int store_data_bypass_p (rtx, rtx);
156 extern int if_test_bypass_p (rtx, rtx);
157
158 #ifndef GENERATOR_FILE
159 /* Try recognizing the instruction INSN,
160    and return the code number that results.
161    Remember the code so that repeated calls do not
162    need to spend the time for actual rerecognition.
163
164    This function is the normal interface to instruction recognition.
165    The automatically-generated function `recog' is normally called
166    through this one.  */
167
168 static inline int
169 recog_memoized (rtx insn)
170 {
171   if (INSN_CODE (insn) < 0)
172     INSN_CODE (insn) = recog (PATTERN (insn), insn, 0);
173   return INSN_CODE (insn);
174 }
175 #endif
176
177 /* Skip chars until the next ',' or the end of the string.  This is
178    useful to skip alternatives in a constraint string.  */
179 static inline const char *
180 skip_alternative (const char *p)
181 {
182   const char *r = p;
183   while (*r != '\0' && *r != ',')
184     r++;
185   if (*r == ',')
186     r++;
187   return r;
188 }
189
190 /* Nonzero means volatile operands are recognized.  */
191 extern int volatile_ok;
192
193 /* Set by constrain_operands to the number of the alternative that
194    matched.  */
195 extern int which_alternative;
196
197 /* The following vectors hold the results from insn_extract.  */
198
199 struct recog_data_d
200 {
201   /* It is very tempting to make the 5 operand related arrays into a
202      structure and index on that.  However, to be source compatible
203      with all of the existing md file insn constraints and output
204      templates, we need `operand' as a flat array.  Without that
205      member, making an array for the rest seems pointless.  */
206
207   /* Gives value of operand N.  */
208   rtx operand[MAX_RECOG_OPERANDS];
209
210   /* Gives location where operand N was found.  */
211   rtx *operand_loc[MAX_RECOG_OPERANDS];
212
213   /* Gives the constraint string for operand N.  */
214   const char *constraints[MAX_RECOG_OPERANDS];
215
216   /* Nonzero if operand N is a match_operator or a match_parallel.  */
217   char is_operator[MAX_RECOG_OPERANDS];
218
219   /* Gives the mode of operand N.  */
220   enum machine_mode operand_mode[MAX_RECOG_OPERANDS];
221
222   /* Gives the type (in, out, inout) for operand N.  */
223   enum op_type operand_type[MAX_RECOG_OPERANDS];
224
225   /* Gives location where the Nth duplicate-appearance of an operand
226      was found.  This is something that matched MATCH_DUP.  */
227   rtx *dup_loc[MAX_DUP_OPERANDS];
228
229   /* Gives the operand number that was duplicated in the Nth
230      duplicate-appearance of an operand.  */
231   char dup_num[MAX_DUP_OPERANDS];
232
233   /* ??? Note that these are `char' instead of `unsigned char' to (try to)
234      avoid certain lossage from K&R C, wherein `unsigned char' default
235      promotes to `unsigned int' instead of `int' as in ISO C.  As of 1999,
236      the most common places to bootstrap from K&R C are SunOS and HPUX,
237      both of which have signed characters by default.  The only other
238      supported natives that have both K&R C and unsigned characters are
239      ROMP and Irix 3, and neither have been seen for a while, but do
240      continue to consider unsignedness when performing arithmetic inside
241      a comparison.  */
242
243   /* The number of operands of the insn.  */
244   char n_operands;
245
246   /* The number of MATCH_DUPs in the insn.  */
247   char n_dups;
248
249   /* The number of alternatives in the constraints for the insn.  */
250   char n_alternatives;
251
252   /* True if insn is ASM_OPERANDS.  */
253   bool is_asm;
254
255   /* Specifies whether an insn alternative is enabled using the `enabled'
256      attribute in the insn pattern definition.  For back ends not using
257      the `enabled' attribute the bits are always set to 1 in expand_insn.
258      Bits beyond the last alternative are also set to 1.  */
259   alternative_mask enabled_alternatives;
260
261   /* In case we are caching, hold insn data was generated for.  */
262   rtx insn;
263 };
264
265 extern struct recog_data_d recog_data;
266
267 extern struct operand_alternative recog_op_alt[MAX_RECOG_OPERANDS
268                                                * MAX_RECOG_ALTERNATIVES];
269
270 /* Return a pointer to an array in which index OP describes the constraints
271    on operand OP of the current instruction alternative (which_alternative).
272    Only valid after calling preprocess_constraints and constrain_operands.  */
273
274 inline static const operand_alternative *
275 which_op_alt ()
276 {
277   gcc_checking_assert (IN_RANGE (which_alternative, 0,
278                                  recog_data.n_alternatives - 1));
279   return &recog_op_alt[which_alternative * recog_data.n_operands];
280 }
281
282 /* A table defined in insn-output.c that give information about
283    each insn-code value.  */
284
285 typedef int (*insn_operand_predicate_fn) (rtx, enum machine_mode);
286 typedef const char * (*insn_output_fn) (rtx *, rtx);
287
288 struct insn_gen_fn
289 {
290   typedef rtx (*f0) (void);
291   typedef rtx (*f1) (rtx);
292   typedef rtx (*f2) (rtx, rtx);
293   typedef rtx (*f3) (rtx, rtx, rtx);
294   typedef rtx (*f4) (rtx, rtx, rtx, rtx);
295   typedef rtx (*f5) (rtx, rtx, rtx, rtx, rtx);
296   typedef rtx (*f6) (rtx, rtx, rtx, rtx, rtx, rtx);
297   typedef rtx (*f7) (rtx, rtx, rtx, rtx, rtx, rtx, rtx);
298   typedef rtx (*f8) (rtx, rtx, rtx, rtx, rtx, rtx, rtx, rtx);
299   typedef rtx (*f9) (rtx, rtx, rtx, rtx, rtx, rtx, rtx, rtx, rtx);
300   typedef rtx (*f10) (rtx, rtx, rtx, rtx, rtx, rtx, rtx, rtx, rtx, rtx);
301   typedef rtx (*f11) (rtx, rtx, rtx, rtx, rtx, rtx, rtx, rtx, rtx, rtx, rtx);
302   typedef rtx (*f12) (rtx, rtx, rtx, rtx, rtx, rtx, rtx, rtx, rtx, rtx, rtx, rtx);
303   typedef rtx (*f13) (rtx, rtx, rtx, rtx, rtx, rtx, rtx, rtx, rtx, rtx, rtx, rtx, rtx);
304   typedef rtx (*f14) (rtx, rtx, rtx, rtx, rtx, rtx, rtx, rtx, rtx, rtx, rtx, rtx, rtx, rtx);
305   typedef rtx (*f15) (rtx, rtx, rtx, rtx, rtx, rtx, rtx, rtx, rtx, rtx, rtx, rtx, rtx, rtx, rtx);
306   typedef rtx (*f16) (rtx, rtx, rtx, rtx, rtx, rtx, rtx, rtx, rtx, rtx, rtx, rtx, rtx, rtx, rtx, rtx);
307
308   typedef f0 stored_funcptr;
309
310   rtx operator () (void) const { return ((f0)func) (); }
311   rtx operator () (rtx a0) const { return ((f1)func) (a0); }
312   rtx operator () (rtx a0, rtx a1) const { return ((f2)func) (a0, a1); }
313   rtx operator () (rtx a0, rtx a1, rtx a2) const { return ((f3)func) (a0, a1, a2); }
314   rtx operator () (rtx a0, rtx a1, rtx a2, rtx a3) const { return ((f4)func) (a0, a1, a2, a3); }
315   rtx operator () (rtx a0, rtx a1, rtx a2, rtx a3, rtx a4) const { return ((f5)func) (a0, a1, a2, a3, a4); }
316   rtx operator () (rtx a0, rtx a1, rtx a2, rtx a3, rtx a4, rtx a5) const { return ((f6)func) (a0, a1, a2, a3, a4, a5); }
317   rtx operator () (rtx a0, rtx a1, rtx a2, rtx a3, rtx a4, rtx a5, rtx a6) const { return ((f7)func) (a0, a1, a2, a3, a4, a5, a6); }
318   rtx operator () (rtx a0, rtx a1, rtx a2, rtx a3, rtx a4, rtx a5, rtx a6, rtx a7) const { return ((f8)func) (a0, a1, a2, a3, a4, a5, a6, a7); }
319   rtx operator () (rtx a0, rtx a1, rtx a2, rtx a3, rtx a4, rtx a5, rtx a6, rtx a7, rtx a8) const { return ((f9)func) (a0, a1, a2, a3, a4, a5, a6, a7, a8); }
320   rtx operator () (rtx a0, rtx a1, rtx a2, rtx a3, rtx a4, rtx a5, rtx a6, rtx a7, rtx a8, rtx a9) const { return ((f10)func) (a0, a1, a2, a3, a4, a5, a6, a7, a8, a9); }
321   rtx operator () (rtx a0, rtx a1, rtx a2, rtx a3, rtx a4, rtx a5, rtx a6, rtx a7, rtx a8, rtx a9, rtx a10) const { return ((f11)func) (a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10); }
322   rtx operator () (rtx a0, rtx a1, rtx a2, rtx a3, rtx a4, rtx a5, rtx a6, rtx a7, rtx a8, rtx a9, rtx a10, rtx a11) const { return ((f12)func) (a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11); }
323   rtx operator () (rtx a0, rtx a1, rtx a2, rtx a3, rtx a4, rtx a5, rtx a6, rtx a7, rtx a8, rtx a9, rtx a10, rtx a11, rtx a12) const { return ((f13)func) (a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12); }
324   rtx operator () (rtx a0, rtx a1, rtx a2, rtx a3, rtx a4, rtx a5, rtx a6, rtx a7, rtx a8, rtx a9, rtx a10, rtx a11, rtx a12, rtx a13) const { return ((f14)func) (a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13); }
325   rtx operator () (rtx a0, rtx a1, rtx a2, rtx a3, rtx a4, rtx a5, rtx a6, rtx a7, rtx a8, rtx a9, rtx a10, rtx a11, rtx a12, rtx a13, rtx a14) const { return ((f15)func) (a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14); }
326   rtx operator () (rtx a0, rtx a1, rtx a2, rtx a3, rtx a4, rtx a5, rtx a6, rtx a7, rtx a8, rtx a9, rtx a10, rtx a11, rtx a12, rtx a13, rtx a14, rtx a15) const { return ((f16)func) (a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15); }
327
328   // This is for compatibility of code that invokes functions like
329   //   (*funcptr) (arg)
330   insn_gen_fn operator * (void) const { return *this; }
331
332   // The wrapped function pointer must be public and there must not be any
333   // constructors.  Otherwise the insn_data_d struct initializers generated
334   // by genoutput.c will result in static initializer functions, which defeats
335   // the purpose of the generated insn_data_d array.
336   stored_funcptr func;
337 };
338
339 struct insn_operand_data
340 {
341   const insn_operand_predicate_fn predicate;
342
343   const char *const constraint;
344
345   ENUM_BITFIELD(machine_mode) const mode : 16;
346
347   const char strict_low;
348
349   const char is_operator;
350
351   const char eliminable;
352
353   const char allows_mem;
354 };
355
356 /* Legal values for insn_data.output_format.  Indicate what type of data
357    is stored in insn_data.output.  */
358 #define INSN_OUTPUT_FORMAT_NONE         0       /* abort */
359 #define INSN_OUTPUT_FORMAT_SINGLE       1       /* const char * */
360 #define INSN_OUTPUT_FORMAT_MULTI        2       /* const char * const * */
361 #define INSN_OUTPUT_FORMAT_FUNCTION     3       /* const char * (*)(...) */
362
363 struct insn_data_d
364 {
365   const char *const name;
366 #if HAVE_DESIGNATED_UNION_INITIALIZERS
367   union {
368     const char *single;
369     const char *const *multi;
370     insn_output_fn function;
371   } output;
372 #else
373   struct {
374     const char *single;
375     const char *const *multi;
376     insn_output_fn function;
377   } output;
378 #endif
379   const insn_gen_fn genfun;
380   const struct insn_operand_data *const operand;
381
382   const char n_generator_args;
383   const char n_operands;
384   const char n_dups;
385   const char n_alternatives;
386   const char output_format;
387 };
388
389 extern const struct insn_data_d insn_data[];
390 extern int peep2_current_count;
391
392 #ifndef GENERATOR_FILE
393 #include "insn-codes.h"
394
395 /* Target-dependent globals.  */
396 struct target_recog {
397   bool x_initialized;
398   alternative_mask x_enabled_alternatives[LAST_INSN_CODE];
399 };
400
401 extern struct target_recog default_target_recog;
402 #if SWITCHABLE_TARGET
403 extern struct target_recog *this_target_recog;
404 #else
405 #define this_target_recog (&default_target_recog)
406 #endif
407
408 alternative_mask get_enabled_alternatives (rtx);
409
410 void recog_init ();
411 #endif
412
413 #endif /* GCC_RECOG_H */