0
|
1 /* Declarations for interface to insn recognizer and insn-output.c.
|
|
2 Copyright (C) 1987, 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004,
|
|
3 2005, 2006, 2007, 2008, 2009 Free Software Foundation, Inc.
|
|
4
|
|
5 This file is part of GCC.
|
|
6
|
|
7 GCC is free software; you can redistribute it and/or modify it under
|
|
8 the terms of the GNU General Public License as published by the Free
|
|
9 Software Foundation; either version 3, or (at your option) any later
|
|
10 version.
|
|
11
|
|
12 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
|
|
13 WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
14 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
|
15 for more details.
|
|
16
|
|
17 You should have received a copy of the GNU General Public License
|
|
18 along with GCC; see the file COPYING3. If not see
|
|
19 <http://www.gnu.org/licenses/>. */
|
|
20
|
|
21 /* Random number that should be large enough for all purposes. */
|
|
22 #define MAX_RECOG_ALTERNATIVES 30
|
|
23
|
|
24 /* Types of operands. */
|
|
25 enum op_type {
|
|
26 OP_IN,
|
|
27 OP_OUT,
|
|
28 OP_INOUT
|
|
29 };
|
|
30
|
|
31 struct operand_alternative
|
|
32 {
|
|
33 /* Pointer to the beginning of the constraint string for this alternative,
|
|
34 for easier access by alternative number. */
|
|
35 const char *constraint;
|
|
36
|
|
37 /* The register class valid for this alternative (possibly NO_REGS). */
|
|
38 enum reg_class cl;
|
|
39
|
|
40 /* "Badness" of this alternative, computed from number of '?' and '!'
|
|
41 characters in the constraint string. */
|
|
42 unsigned int reject;
|
|
43
|
|
44 /* -1 if no matching constraint was found, or an operand number. */
|
|
45 int matches;
|
|
46 /* The same information, but reversed: -1 if this operand is not
|
|
47 matched by any other, or the operand number of the operand that
|
|
48 matches this one. */
|
|
49 int matched;
|
|
50
|
|
51 /* Nonzero if '&' was found in the constraint string. */
|
|
52 unsigned int earlyclobber:1;
|
|
53 /* Nonzero if TARGET_MEM_CONSTRAINT was found in the constraint
|
|
54 string. */
|
|
55 unsigned int memory_ok:1;
|
|
56 /* Nonzero if 'o' was found in the constraint string. */
|
|
57 unsigned int offmem_ok:1;
|
|
58 /* Nonzero if 'V' was found in the constraint string. */
|
|
59 unsigned int nonoffmem_ok:1;
|
|
60 /* Nonzero if '<' was found in the constraint string. */
|
|
61 unsigned int decmem_ok:1;
|
|
62 /* Nonzero if '>' was found in the constraint string. */
|
|
63 unsigned int incmem_ok:1;
|
|
64 /* Nonzero if 'p' was found in the constraint string. */
|
|
65 unsigned int is_address:1;
|
|
66 /* Nonzero if 'X' was found in the constraint string, or if the constraint
|
|
67 string for this alternative was empty. */
|
|
68 unsigned int anything_ok:1;
|
|
69 };
|
|
70
|
|
71
|
|
72 extern void init_recog (void);
|
|
73 extern void init_recog_no_volatile (void);
|
|
74 extern int check_asm_operands (rtx);
|
|
75 extern int asm_operand_ok (rtx, const char *, const char **);
|
|
76 extern bool validate_change (rtx, rtx *, rtx, bool);
|
|
77 extern bool validate_unshare_change (rtx, rtx *, rtx, bool);
|
|
78 extern bool canonicalize_change_group (rtx insn, rtx x);
|
|
79 extern int insn_invalid_p (rtx);
|
|
80 extern int verify_changes (int);
|
|
81 extern void confirm_change_group (void);
|
|
82 extern int apply_change_group (void);
|
|
83 extern int num_validated_changes (void);
|
|
84 extern void cancel_changes (int);
|
|
85 extern int constrain_operands (int);
|
|
86 extern int constrain_operands_cached (int);
|
|
87 extern int memory_address_p (enum machine_mode, rtx);
|
|
88 extern int strict_memory_address_p (enum machine_mode, rtx);
|
|
89 extern int validate_replace_rtx (rtx, rtx, rtx);
|
|
90 extern int validate_replace_rtx_part (rtx, rtx, rtx *, rtx);
|
|
91 extern int validate_replace_rtx_part_nosimplify (rtx, rtx, rtx *, rtx);
|
|
92 extern void validate_replace_rtx_group (rtx, rtx, rtx);
|
|
93 extern void validate_replace_src_group (rtx, rtx, rtx);
|
|
94 extern bool validate_simplify_insn (rtx insn);
|
|
95 extern int num_changes_pending (void);
|
|
96 #ifdef HAVE_cc0
|
|
97 extern int next_insn_tests_no_inequality (rtx);
|
|
98 #endif
|
|
99 extern int reg_fits_class_p (rtx, enum reg_class, int, enum machine_mode);
|
|
100
|
|
101 extern int offsettable_memref_p (rtx);
|
|
102 extern int offsettable_nonstrict_memref_p (rtx);
|
|
103 extern int offsettable_address_p (int, enum machine_mode, rtx);
|
|
104 extern int mode_dependent_address_p (rtx);
|
|
105
|
|
106 extern int recog (rtx, rtx, int *);
|
|
107 #ifndef GENERATOR_FILE
|
|
108 static inline int recog_memoized (rtx insn);
|
|
109 #endif
|
|
110 extern void add_clobbers (rtx, int);
|
|
111 extern int added_clobbers_hard_reg_p (int);
|
|
112 extern void insn_extract (rtx);
|
|
113 extern void extract_insn (rtx);
|
|
114 extern void extract_constrain_insn_cached (rtx);
|
|
115 extern void extract_insn_cached (rtx);
|
|
116 extern void preprocess_constraints (void);
|
|
117 extern rtx peep2_next_insn (int);
|
|
118 extern int peep2_regno_dead_p (int, int);
|
|
119 extern int peep2_reg_dead_p (int, rtx);
|
|
120 #ifdef CLEAR_HARD_REG_SET
|
|
121 extern rtx peep2_find_free_register (int, int, const char *,
|
|
122 enum machine_mode, HARD_REG_SET *);
|
|
123 #endif
|
|
124 extern rtx peephole2_insns (rtx, rtx, int *);
|
|
125
|
|
126 extern int store_data_bypass_p (rtx, rtx);
|
|
127 extern int if_test_bypass_p (rtx, rtx);
|
|
128
|
|
129 #ifndef GENERATOR_FILE
|
|
130 /* Try recognizing the instruction INSN,
|
|
131 and return the code number that results.
|
|
132 Remember the code so that repeated calls do not
|
|
133 need to spend the time for actual rerecognition.
|
|
134
|
|
135 This function is the normal interface to instruction recognition.
|
|
136 The automatically-generated function `recog' is normally called
|
|
137 through this one. */
|
|
138
|
|
139 static inline int
|
|
140 recog_memoized (rtx insn)
|
|
141 {
|
|
142 if (INSN_CODE (insn) < 0)
|
|
143 INSN_CODE (insn) = recog (PATTERN (insn), insn, 0);
|
|
144 return INSN_CODE (insn);
|
|
145 }
|
|
146 #endif
|
|
147
|
|
148 /* Skip chars until the next ',' or the end of the string. This is
|
|
149 useful to skip alternatives in a constraint string. */
|
|
150 static inline const char *
|
|
151 skip_alternative (const char *p)
|
|
152 {
|
|
153 const char *r = p;
|
|
154 while (*r != '\0' && *r != ',')
|
|
155 r++;
|
|
156 if (*r == ',')
|
|
157 r++;
|
|
158 return r;
|
|
159 }
|
|
160
|
|
161 /* Nonzero means volatile operands are recognized. */
|
|
162 extern int volatile_ok;
|
|
163
|
|
164 /* Set by constrain_operands to the number of the alternative that
|
|
165 matched. */
|
|
166 extern int which_alternative;
|
|
167
|
|
168 /* The following vectors hold the results from insn_extract. */
|
|
169
|
|
170 struct recog_data
|
|
171 {
|
|
172 /* It is very tempting to make the 5 operand related arrays into a
|
|
173 structure and index on that. However, to be source compatible
|
|
174 with all of the existing md file insn constraints and output
|
|
175 templates, we need `operand' as a flat array. Without that
|
|
176 member, making an array for the rest seems pointless. */
|
|
177
|
|
178 /* Gives value of operand N. */
|
|
179 rtx operand[MAX_RECOG_OPERANDS];
|
|
180
|
|
181 /* Gives location where operand N was found. */
|
|
182 rtx *operand_loc[MAX_RECOG_OPERANDS];
|
|
183
|
|
184 /* Gives the constraint string for operand N. */
|
|
185 const char *constraints[MAX_RECOG_OPERANDS];
|
|
186
|
|
187 /* Gives the mode of operand N. */
|
|
188 enum machine_mode operand_mode[MAX_RECOG_OPERANDS];
|
|
189
|
|
190 /* Gives the type (in, out, inout) for operand N. */
|
|
191 enum op_type operand_type[MAX_RECOG_OPERANDS];
|
|
192
|
|
193 /* Gives location where the Nth duplicate-appearance of an operand
|
|
194 was found. This is something that matched MATCH_DUP. */
|
|
195 rtx *dup_loc[MAX_DUP_OPERANDS];
|
|
196
|
|
197 /* Gives the operand number that was duplicated in the Nth
|
|
198 duplicate-appearance of an operand. */
|
|
199 char dup_num[MAX_DUP_OPERANDS];
|
|
200
|
|
201 /* ??? Note that these are `char' instead of `unsigned char' to (try to)
|
|
202 avoid certain lossage from K&R C, wherein `unsigned char' default
|
|
203 promotes to `unsigned int' instead of `int' as in ISO C. As of 1999,
|
|
204 the most common places to bootstrap from K&R C are SunOS and HPUX,
|
|
205 both of which have signed characters by default. The only other
|
|
206 supported natives that have both K&R C and unsigned characters are
|
|
207 ROMP and Irix 3, and neither have been seen for a while, but do
|
|
208 continue to consider unsignedness when performing arithmetic inside
|
|
209 a comparison. */
|
|
210
|
|
211 /* The number of operands of the insn. */
|
|
212 char n_operands;
|
|
213
|
|
214 /* The number of MATCH_DUPs in the insn. */
|
|
215 char n_dups;
|
|
216
|
|
217 /* The number of alternatives in the constraints for the insn. */
|
|
218 char n_alternatives;
|
|
219
|
|
220 /* Specifies whether an insn alternative is enabled using the
|
|
221 `enabled' attribute in the insn pattern definition. For back
|
|
222 ends not using the `enabled' attribute the array fields are
|
|
223 always set to `true' in expand_insn. */
|
|
224 bool alternative_enabled_p [MAX_RECOG_ALTERNATIVES];
|
|
225
|
|
226 /* In case we are caching, hold insn data was generated for. */
|
|
227 rtx insn;
|
|
228 };
|
|
229
|
|
230 extern struct recog_data recog_data;
|
|
231
|
|
232 /* Contains a vector of operand_alternative structures for every operand.
|
|
233 Set up by preprocess_constraints. */
|
|
234 extern struct operand_alternative recog_op_alt[MAX_RECOG_OPERANDS][MAX_RECOG_ALTERNATIVES];
|
|
235
|
|
236 /* A table defined in insn-output.c that give information about
|
|
237 each insn-code value. */
|
|
238
|
|
239 typedef int (*insn_operand_predicate_fn) (rtx, enum machine_mode);
|
|
240 typedef const char * (*insn_output_fn) (rtx *, rtx);
|
|
241 typedef rtx (*insn_gen_fn) (rtx, ...);
|
|
242
|
|
243 struct insn_operand_data
|
|
244 {
|
|
245 const insn_operand_predicate_fn predicate;
|
|
246
|
|
247 const char *const constraint;
|
|
248
|
|
249 ENUM_BITFIELD(machine_mode) const mode : 16;
|
|
250
|
|
251 const char strict_low;
|
|
252
|
|
253 const char eliminable;
|
|
254 };
|
|
255
|
|
256 /* Legal values for insn_data.output_format. Indicate what type of data
|
|
257 is stored in insn_data.output. */
|
|
258 #define INSN_OUTPUT_FORMAT_NONE 0 /* abort */
|
|
259 #define INSN_OUTPUT_FORMAT_SINGLE 1 /* const char * */
|
|
260 #define INSN_OUTPUT_FORMAT_MULTI 2 /* const char * const * */
|
|
261 #define INSN_OUTPUT_FORMAT_FUNCTION 3 /* const char * (*)(...) */
|
|
262
|
|
263 struct insn_data
|
|
264 {
|
|
265 const char *const name;
|
|
266 #if HAVE_DESIGNATED_INITIALIZERS
|
|
267 union {
|
|
268 const char *single;
|
|
269 const char *const *multi;
|
|
270 insn_output_fn function;
|
|
271 } output;
|
|
272 #else
|
|
273 struct {
|
|
274 const char *single;
|
|
275 const char *const *multi;
|
|
276 insn_output_fn function;
|
|
277 } output;
|
|
278 #endif
|
|
279 const insn_gen_fn genfun;
|
|
280 const struct insn_operand_data *const operand;
|
|
281
|
|
282 const char n_operands;
|
|
283 const char n_dups;
|
|
284 const char n_alternatives;
|
|
285 const char output_format;
|
|
286 };
|
|
287
|
|
288 extern const struct insn_data insn_data[];
|
|
289 extern int peep2_current_count;
|