1 /* Generate from machine description: 2 - some #define configuration flags. 3 Copyright (C) 1987-2013 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 22 #include "bconfig.h" 23 #include "system.h" 24 #include "coretypes.h" 25 #include "tm.h" 26 #include "rtl.h" 27 #include "errors.h" 28 #include "gensupport.h" 29 30 31 /* flags to determine output of machine description dependent #define's. */ 32 static int max_recog_operands; /* Largest operand number seen. */ 33 static int max_dup_operands; /* Largest number of match_dup in any insn. */ 34 static int max_clobbers_per_insn; 35 static int have_cc0_flag; 36 static int have_cmove_flag; 37 static int have_cond_exec_flag; 38 static int have_lo_sum_flag; 39 static int have_peephole_flag; 40 static int have_peephole2_flag; 41 42 /* Maximum number of insns seen in a split. */ 43 static int max_insns_per_split = 1; 44 45 /* Maximum number of input insns for peephole2. */ 46 static int max_insns_per_peep2; 47 48 static int clobbers_seen_this_insn; 49 static int dup_operands_seen_this_insn; 50 51 static void walk_insn_part (rtx, int, int); 52 static void gen_insn (rtx); 53 static void gen_expand (rtx); 54 static void gen_split (rtx); 55 static void gen_peephole (rtx); 56 static void gen_peephole2 (rtx); 57 58 /* RECOG_P will be nonzero if this pattern was seen in a context where it will 59 be used to recognize, rather than just generate an insn. 60 61 NON_PC_SET_SRC will be nonzero if this pattern was seen in a SET_SRC 62 of a SET whose destination is not (pc). */ 63 64 static void 65 walk_insn_part (rtx part, int recog_p, int non_pc_set_src) 66 { 67 int i, j; 68 RTX_CODE code; 69 const char *format_ptr; 70 71 if (part == 0) 72 return; 73 74 code = GET_CODE (part); 75 switch (code) 76 { 77 case CLOBBER: 78 clobbers_seen_this_insn++; 79 break; 80 81 case MATCH_OPERAND: 82 if (XINT (part, 0) > max_recog_operands) 83 max_recog_operands = XINT (part, 0); 84 return; 85 86 case MATCH_OP_DUP: 87 case MATCH_PAR_DUP: 88 ++dup_operands_seen_this_insn; 89 case MATCH_SCRATCH: 90 case MATCH_PARALLEL: 91 case MATCH_OPERATOR: 92 if (XINT (part, 0) > max_recog_operands) 93 max_recog_operands = XINT (part, 0); 94 /* Now scan the rtl's in the vector inside the MATCH_OPERATOR or 95 MATCH_PARALLEL. */ 96 break; 97 98 case LABEL_REF: 99 if (GET_CODE (XEXP (part, 0)) == MATCH_OPERAND 100 || GET_CODE (XEXP (part, 0)) == MATCH_DUP) 101 break; 102 return; 103 104 case MATCH_DUP: 105 ++dup_operands_seen_this_insn; 106 if (XINT (part, 0) > max_recog_operands) 107 max_recog_operands = XINT (part, 0); 108 return; 109 110 case CC0: 111 if (recog_p) 112 have_cc0_flag = 1; 113 return; 114 115 case LO_SUM: 116 if (recog_p) 117 have_lo_sum_flag = 1; 118 return; 119 120 case SET: 121 walk_insn_part (SET_DEST (part), 0, recog_p); 122 walk_insn_part (SET_SRC (part), recog_p, 123 GET_CODE (SET_DEST (part)) != PC); 124 return; 125 126 case IF_THEN_ELSE: 127 /* Only consider this machine as having a conditional move if the 128 two arms of the IF_THEN_ELSE are both MATCH_OPERAND. Otherwise, 129 we have some specific IF_THEN_ELSE construct (like the doz 130 instruction on the RS/6000) that can't be used in the general 131 context we want it for. */ 132 133 if (recog_p && non_pc_set_src 134 && GET_CODE (XEXP (part, 1)) == MATCH_OPERAND 135 && GET_CODE (XEXP (part, 2)) == MATCH_OPERAND) 136 have_cmove_flag = 1; 137 break; 138 139 case COND_EXEC: 140 if (recog_p) 141 have_cond_exec_flag = 1; 142 break; 143 144 case REG: case CONST_INT: case SYMBOL_REF: 145 case PC: 146 return; 147 148 default: 149 break; 150 } 151 152 format_ptr = GET_RTX_FORMAT (GET_CODE (part)); 153 154 for (i = 0; i < GET_RTX_LENGTH (GET_CODE (part)); i++) 155 switch (*format_ptr++) 156 { 157 case 'e': 158 case 'u': 159 walk_insn_part (XEXP (part, i), recog_p, non_pc_set_src); 160 break; 161 case 'E': 162 if (XVEC (part, i) != NULL) 163 for (j = 0; j < XVECLEN (part, i); j++) 164 walk_insn_part (XVECEXP (part, i, j), recog_p, non_pc_set_src); 165 break; 166 } 167 } 168 169 static void 170 gen_insn (rtx insn) 171 { 172 int i; 173 174 /* Walk the insn pattern to gather the #define's status. */ 175 clobbers_seen_this_insn = 0; 176 dup_operands_seen_this_insn = 0; 177 if (XVEC (insn, 1) != 0) 178 for (i = 0; i < XVECLEN (insn, 1); i++) 179 walk_insn_part (XVECEXP (insn, 1, i), 1, 0); 180 181 if (clobbers_seen_this_insn > max_clobbers_per_insn) 182 max_clobbers_per_insn = clobbers_seen_this_insn; 183 if (dup_operands_seen_this_insn > max_dup_operands) 184 max_dup_operands = dup_operands_seen_this_insn; 185 } 186 187 /* Similar but scan a define_expand. */ 188 189 static void 190 gen_expand (rtx insn) 191 { 192 int i; 193 194 /* Walk the insn pattern to gather the #define's status. */ 195 196 /* Note that we don't bother recording the number of MATCH_DUPs 197 that occur in a gen_expand, because only reload cares about that. */ 198 if (XVEC (insn, 1) != 0) 199 for (i = 0; i < XVECLEN (insn, 1); i++) 200 { 201 /* Compute the maximum SETs and CLOBBERS 202 in any one of the sub-insns; 203 don't sum across all of them. */ 204 clobbers_seen_this_insn = 0; 205 206 walk_insn_part (XVECEXP (insn, 1, i), 0, 0); 207 208 if (clobbers_seen_this_insn > max_clobbers_per_insn) 209 max_clobbers_per_insn = clobbers_seen_this_insn; 210 } 211 } 212 213 /* Similar but scan a define_split. */ 214 215 static void 216 gen_split (rtx split) 217 { 218 int i; 219 220 /* Look through the patterns that are matched 221 to compute the maximum operand number. */ 222 for (i = 0; i < XVECLEN (split, 0); i++) 223 walk_insn_part (XVECEXP (split, 0, i), 1, 0); 224 /* Look at the number of insns this insn could split into. */ 225 if (XVECLEN (split, 2) > max_insns_per_split) 226 max_insns_per_split = XVECLEN (split, 2); 227 } 228 229 static void 230 gen_peephole (rtx peep) 231 { 232 int i; 233 234 /* Look through the patterns that are matched 235 to compute the maximum operand number. */ 236 for (i = 0; i < XVECLEN (peep, 0); i++) 237 walk_insn_part (XVECEXP (peep, 0, i), 1, 0); 238 } 239 240 static void 241 gen_peephole2 (rtx peep) 242 { 243 int i, n; 244 245 /* Look through the patterns that are matched 246 to compute the maximum operand number. */ 247 for (i = XVECLEN (peep, 0) - 1; i >= 0; --i) 248 walk_insn_part (XVECEXP (peep, 0, i), 1, 0); 249 250 /* Look at the number of insns this insn can be matched from. */ 251 for (i = XVECLEN (peep, 0) - 1, n = 0; i >= 0; --i) 252 if (GET_CODE (XVECEXP (peep, 0, i)) != MATCH_DUP 253 && GET_CODE (XVECEXP (peep, 0, i)) != MATCH_SCRATCH) 254 n++; 255 if (n > max_insns_per_peep2) 256 max_insns_per_peep2 = n; 257 } 258 259 int 260 main (int argc, char **argv) 261 { 262 rtx desc; 263 264 progname = "genconfig"; 265 266 if (!init_rtx_reader_args (argc, argv)) 267 return (FATAL_EXIT_CODE); 268 269 puts ("/* Generated automatically by the program `genconfig'"); 270 puts (" from the machine description file `md'. */\n"); 271 puts ("#ifndef GCC_INSN_CONFIG_H"); 272 puts ("#define GCC_INSN_CONFIG_H\n"); 273 274 /* Allow at least 30 operands for the sake of asm constructs. */ 275 /* ??? We *really* ought to reorganize things such that there 276 is no fixed upper bound. */ 277 max_recog_operands = 29; /* We will add 1 later. */ 278 max_dup_operands = 1; 279 280 /* Read the machine description. */ 281 282 while (1) 283 { 284 int line_no, insn_code_number = 0; 285 286 desc = read_md_rtx (&line_no, &insn_code_number); 287 if (desc == NULL) 288 break; 289 290 switch (GET_CODE (desc)) 291 { 292 case DEFINE_INSN: 293 gen_insn (desc); 294 break; 295 296 case DEFINE_EXPAND: 297 gen_expand (desc); 298 break; 299 300 case DEFINE_SPLIT: 301 gen_split (desc); 302 break; 303 304 case DEFINE_PEEPHOLE2: 305 have_peephole2_flag = 1; 306 gen_peephole2 (desc); 307 break; 308 309 case DEFINE_PEEPHOLE: 310 have_peephole_flag = 1; 311 gen_peephole (desc); 312 break; 313 314 default: 315 break; 316 } 317 } 318 319 printf ("#define MAX_RECOG_OPERANDS %d\n", max_recog_operands + 1); 320 printf ("#define MAX_DUP_OPERANDS %d\n", max_dup_operands); 321 322 /* This is conditionally defined, in case the user writes code which emits 323 more splits than we can readily see (and knows s/he does it). */ 324 printf ("#ifndef MAX_INSNS_PER_SPLIT\n"); 325 printf ("#define MAX_INSNS_PER_SPLIT %d\n", max_insns_per_split); 326 printf ("#endif\n"); 327 328 if (have_cc0_flag) 329 { 330 printf ("#define HAVE_cc0 1\n"); 331 printf ("#define CC0_P(X) ((X) == cc0_rtx)\n"); 332 } 333 else 334 { 335 /* We output CC0_P this way to make sure that X is declared 336 somewhere. */ 337 printf ("#define CC0_P(X) ((X) ? 0 : 0)\n"); 338 } 339 340 if (have_cmove_flag) 341 printf ("#define HAVE_conditional_move 1\n"); 342 343 if (have_cond_exec_flag) 344 printf ("#define HAVE_conditional_execution 1\n"); 345 346 if (have_lo_sum_flag) 347 printf ("#define HAVE_lo_sum 1\n"); 348 349 if (have_peephole_flag) 350 printf ("#define HAVE_peephole 1\n"); 351 352 if (have_peephole2_flag) 353 { 354 printf ("#define HAVE_peephole2 1\n"); 355 printf ("#define MAX_INSNS_PER_PEEP2 %d\n", max_insns_per_peep2); 356 } 357 358 puts("\n#endif /* GCC_INSN_CONFIG_H */"); 359 360 if (ferror (stdout) || fflush (stdout) || fclose (stdout)) 361 return FATAL_EXIT_CODE; 362 363 return SUCCESS_EXIT_CODE; 364 } 365