| 1 | 684 | jeremybenn | /* 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, 2010 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 |  |  | #ifndef GCC_RECOG_H
 | 
      
         | 22 |  |  | #define GCC_RECOG_H
 | 
      
         | 23 |  |  |  
 | 
      
         | 24 |  |  | /* Random number that should be large enough for all purposes.  */
 | 
      
         | 25 |  |  | #define MAX_RECOG_ALTERNATIVES 30
 | 
      
         | 26 |  |  |  
 | 
      
         | 27 |  |  | /* Types of operands.  */
 | 
      
         | 28 |  |  | enum op_type {
 | 
      
         | 29 |  |  |   OP_IN,
 | 
      
         | 30 |  |  |   OP_OUT,
 | 
      
         | 31 |  |  |   OP_INOUT
 | 
      
         | 32 |  |  | };
 | 
      
         | 33 |  |  |  
 | 
      
         | 34 |  |  | struct operand_alternative
 | 
      
         | 35 |  |  | {
 | 
      
         | 36 |  |  |   /* Pointer to the beginning of the constraint string for this alternative,
 | 
      
         | 37 |  |  |      for easier access by alternative number.  */
 | 
      
         | 38 |  |  |   const char *constraint;
 | 
      
         | 39 |  |  |  
 | 
      
         | 40 |  |  |   /* The register class valid for this alternative (possibly NO_REGS).  */
 | 
      
         | 41 |  |  |   enum reg_class cl;
 | 
      
         | 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;
 | 
      
         | 56 |  |  |   /* Nonzero if TARGET_MEM_CONSTRAINT was found in the constraint
 | 
      
         | 57 |  |  |      string.  */
 | 
      
         | 58 |  |  |   unsigned int memory_ok:1;
 | 
      
         | 59 |  |  |   /* Nonzero if 'o' was found in the constraint string.  */
 | 
      
         | 60 |  |  |   unsigned int offmem_ok:1;
 | 
      
         | 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;
 | 
      
         | 67 |  |  |   /* Nonzero if 'p' was found in the constraint string.  */
 | 
      
         | 68 |  |  |   unsigned int is_address:1;
 | 
      
         | 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 |  |  |  
 | 
      
         | 75 |  |  | extern void init_recog (void);
 | 
      
         | 76 |  |  | extern void init_recog_no_volatile (void);
 | 
      
         | 77 |  |  | extern int check_asm_operands (rtx);
 | 
      
         | 78 |  |  | extern int asm_operand_ok (rtx, const char *, const char **);
 | 
      
         | 79 |  |  | extern bool validate_change (rtx, rtx *, rtx, bool);
 | 
      
         | 80 |  |  | extern bool validate_unshare_change (rtx, rtx *, rtx, bool);
 | 
      
         | 81 |  |  | extern bool canonicalize_change_group (rtx insn, rtx x);
 | 
      
         | 82 |  |  | extern int insn_invalid_p (rtx);
 | 
      
         | 83 |  |  | extern int verify_changes (int);
 | 
      
         | 84 |  |  | extern void confirm_change_group (void);
 | 
      
         | 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);
 | 
      
         | 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)
 | 
      
         | 97 |  |  | extern int validate_replace_rtx_subexp (rtx, rtx, rtx, rtx *);
 | 
      
         | 98 |  |  | extern int validate_replace_rtx (rtx, rtx, rtx);
 | 
      
         | 99 |  |  | extern int validate_replace_rtx_part (rtx, rtx, rtx *, rtx);
 | 
      
         | 100 |  |  | extern int validate_replace_rtx_part_nosimplify (rtx, rtx, rtx *, rtx);
 | 
      
         | 101 |  |  | extern void validate_replace_rtx_group (rtx, rtx, rtx);
 | 
      
         | 102 |  |  | extern void validate_replace_src_group (rtx, rtx, rtx);
 | 
      
         | 103 |  |  | extern bool validate_simplify_insn (rtx insn);
 | 
      
         | 104 |  |  | extern int num_changes_pending (void);
 | 
      
         | 105 |  |  | #ifdef HAVE_cc0
 | 
      
         | 106 |  |  | extern int next_insn_tests_no_inequality (rtx);
 | 
      
         | 107 |  |  | #endif
 | 
      
         | 108 |  |  | extern bool reg_fits_class_p (const_rtx, reg_class_t, int, enum machine_mode);
 | 
      
         | 109 |  |  |  
 | 
      
         | 110 |  |  | extern int offsettable_memref_p (rtx);
 | 
      
         | 111 |  |  | extern int offsettable_nonstrict_memref_p (rtx);
 | 
      
         | 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)
 | 
      
         | 117 |  |  | extern bool mode_dependent_address_p (rtx);
 | 
      
         | 118 |  |  |  
 | 
      
         | 119 |  |  | extern int recog (rtx, rtx, int *);
 | 
      
         | 120 |  |  | #ifndef GENERATOR_FILE
 | 
      
         | 121 |  |  | static inline int recog_memoized (rtx insn);
 | 
      
         | 122 |  |  | #endif
 | 
      
         | 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);
 | 
      
         | 133 |  |  | #ifdef CLEAR_HARD_REG_SET
 | 
      
         | 134 |  |  | extern rtx peep2_find_free_register (int, int, const char *,
 | 
      
         | 135 |  |  |                                      enum machine_mode, HARD_REG_SET *);
 | 
      
         | 136 |  |  | #endif
 | 
      
         | 137 |  |  | extern rtx peephole2_insns (rtx, rtx, int *);
 | 
      
         | 138 |  |  |  
 | 
      
         | 139 |  |  | extern int store_data_bypass_p (rtx, rtx);
 | 
      
         | 140 |  |  | extern int if_test_bypass_p (rtx, rtx);
 | 
      
         | 141 |  |  |  
 | 
      
         | 142 |  |  | #ifndef GENERATOR_FILE
 | 
      
         | 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
 | 
      
         | 150 |  |  |    through this one.  */
 | 
      
         | 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 |  |  | }
 | 
      
         | 159 |  |  | #endif
 | 
      
         | 160 |  |  |  
 | 
      
         | 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 |  |  |  
 | 
      
         | 174 |  |  | /* Nonzero means volatile operands are recognized.  */
 | 
      
         | 175 |  |  | extern int volatile_ok;
 | 
      
         | 176 |  |  |  
 | 
      
         | 177 |  |  | /* Set by constrain_operands to the number of the alternative that
 | 
      
         | 178 |  |  |    matched.  */
 | 
      
         | 179 |  |  | extern int which_alternative;
 | 
      
         | 180 |  |  |  
 | 
      
         | 181 |  |  | /* The following vectors hold the results from insn_extract.  */
 | 
      
         | 182 |  |  |  
 | 
      
         | 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.  */
 | 
      
         | 190 |  |  |  
 | 
      
         | 191 |  |  |   /* Gives value of operand N.  */
 | 
      
         | 192 |  |  |   rtx operand[MAX_RECOG_OPERANDS];
 | 
      
         | 193 |  |  |  
 | 
      
         | 194 |  |  |   /* Gives location where operand N was found.  */
 | 
      
         | 195 |  |  |   rtx *operand_loc[MAX_RECOG_OPERANDS];
 | 
      
         | 196 |  |  |  
 | 
      
         | 197 |  |  |   /* Gives the constraint string for operand N.  */
 | 
      
         | 198 |  |  |   const char *constraints[MAX_RECOG_OPERANDS];
 | 
      
         | 199 |  |  |  
 | 
      
         | 200 |  |  |   /* Nonzero if operand N is a match_operator or a match_parallel.  */
 | 
      
         | 201 |  |  |   char is_operator[MAX_RECOG_OPERANDS];
 | 
      
         | 202 |  |  |  
 | 
      
         | 203 |  |  |   /* Gives the mode of operand N.  */
 | 
      
         | 204 |  |  |   enum machine_mode operand_mode[MAX_RECOG_OPERANDS];
 | 
      
         | 205 |  |  |  
 | 
      
         | 206 |  |  |   /* Gives the type (in, out, inout) for operand N.  */
 | 
      
         | 207 |  |  |   enum op_type operand_type[MAX_RECOG_OPERANDS];
 | 
      
         | 208 |  |  |  
 | 
      
         | 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];
 | 
      
         | 212 |  |  |  
 | 
      
         | 213 |  |  |   /* Gives the operand number that was duplicated in the Nth
 | 
      
         | 214 |  |  |      duplicate-appearance of an operand.  */
 | 
      
         | 215 |  |  |   char dup_num[MAX_DUP_OPERANDS];
 | 
      
         | 216 |  |  |  
 | 
      
         | 217 |  |  |   /* ??? Note that these are `char' instead of `unsigned char' to (try to)
 | 
      
         | 218 |  |  |      avoid certain lossage from K&R C, wherein `unsigned char' default
 | 
      
         | 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 |  |  |  
 | 
      
         | 227 |  |  |   /* The number of operands of the insn.  */
 | 
      
         | 228 |  |  |   char n_operands;
 | 
      
         | 229 |  |  |  
 | 
      
         | 230 |  |  |   /* The number of MATCH_DUPs in the insn.  */
 | 
      
         | 231 |  |  |   char n_dups;
 | 
      
         | 232 |  |  |  
 | 
      
         | 233 |  |  |   /* The number of alternatives in the constraints for the insn.  */
 | 
      
         | 234 |  |  |   char n_alternatives;
 | 
      
         | 235 |  |  |  
 | 
      
         | 236 |  |  |   /* True if insn is ASM_OPERANDS.  */
 | 
      
         | 237 |  |  |   bool is_asm;
 | 
      
         | 238 |  |  |  
 | 
      
         | 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 |  |  |  
 | 
      
         | 245 |  |  |   /* In case we are caching, hold insn data was generated for.  */
 | 
      
         | 246 |  |  |   rtx insn;
 | 
      
         | 247 |  |  | };
 | 
      
         | 248 |  |  |  
 | 
      
         | 249 |  |  | extern struct recog_data recog_data;
 | 
      
         | 250 |  |  |  
 | 
      
         | 251 |  |  | /* Contains a vector of operand_alternative structures for every operand.
 | 
      
         | 252 |  |  |    Set up by preprocess_constraints.  */
 | 
      
         | 253 |  |  | extern struct operand_alternative recog_op_alt[MAX_RECOG_OPERANDS][MAX_RECOG_ALTERNATIVES];
 | 
      
         | 254 |  |  |  
 | 
      
         | 255 |  |  | /* A table defined in insn-output.c that give information about
 | 
      
         | 256 |  |  |    each insn-code value.  */
 | 
      
         | 257 |  |  |  
 | 
      
         | 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, ...);
 | 
      
         | 261 |  |  |  
 | 
      
         | 262 |  |  | struct insn_operand_data
 | 
      
         | 263 |  |  | {
 | 
      
         | 264 |  |  |   const insn_operand_predicate_fn predicate;
 | 
      
         | 265 |  |  |  
 | 
      
         | 266 |  |  |   const char *const constraint;
 | 
      
         | 267 |  |  |  
 | 
      
         | 268 |  |  |   ENUM_BITFIELD(machine_mode) const mode : 16;
 | 
      
         | 269 |  |  |  
 | 
      
         | 270 |  |  |   const char strict_low;
 | 
      
         | 271 |  |  |  
 | 
      
         | 272 |  |  |   const char is_operator;
 | 
      
         | 273 |  |  |  
 | 
      
         | 274 |  |  |   const char eliminable;
 | 
      
         | 275 |  |  |  
 | 
      
         | 276 |  |  |   const char allows_mem;
 | 
      
         | 277 |  |  | };
 | 
      
         | 278 |  |  |  
 | 
      
         | 279 |  |  | /* Legal values for insn_data.output_format.  Indicate what type of data
 | 
      
         | 280 |  |  |    is stored in insn_data.output.  */
 | 
      
         | 281 |  |  | #define INSN_OUTPUT_FORMAT_NONE         0        /* abort */
 | 
      
         | 282 |  |  | #define INSN_OUTPUT_FORMAT_SINGLE       1       /* const char * */
 | 
      
         | 283 |  |  | #define INSN_OUTPUT_FORMAT_MULTI        2       /* const char * const * */
 | 
      
         | 284 |  |  | #define INSN_OUTPUT_FORMAT_FUNCTION     3       /* const char * (*)(...) */
 | 
      
         | 285 |  |  |  
 | 
      
         | 286 |  |  | struct insn_data_d
 | 
      
         | 287 |  |  | {
 | 
      
         | 288 |  |  |   const char *const name;
 | 
      
         | 289 |  |  | #if HAVE_DESIGNATED_UNION_INITIALIZERS
 | 
      
         | 290 |  |  |   union {
 | 
      
         | 291 |  |  |     const char *single;
 | 
      
         | 292 |  |  |     const char *const *multi;
 | 
      
         | 293 |  |  |     insn_output_fn function;
 | 
      
         | 294 |  |  |   } output;
 | 
      
         | 295 |  |  | #else
 | 
      
         | 296 |  |  |   struct {
 | 
      
         | 297 |  |  |     const char *single;
 | 
      
         | 298 |  |  |     const char *const *multi;
 | 
      
         | 299 |  |  |     insn_output_fn function;
 | 
      
         | 300 |  |  |   } output;
 | 
      
         | 301 |  |  | #endif
 | 
      
         | 302 |  |  |   const insn_gen_fn genfun;
 | 
      
         | 303 |  |  |   const struct insn_operand_data *const operand;
 | 
      
         | 304 |  |  |  
 | 
      
         | 305 |  |  |   const char n_generator_args;
 | 
      
         | 306 |  |  |   const char n_operands;
 | 
      
         | 307 |  |  |   const char n_dups;
 | 
      
         | 308 |  |  |   const char n_alternatives;
 | 
      
         | 309 |  |  |   const char output_format;
 | 
      
         | 310 |  |  | };
 | 
      
         | 311 |  |  |  
 | 
      
         | 312 |  |  | extern const struct insn_data_d insn_data[];
 | 
      
         | 313 |  |  | extern int peep2_current_count;
 | 
      
         | 314 |  |  |  
 | 
      
         | 315 |  |  | #endif /* GCC_RECOG_H */
 |