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