genconfig.c revision 169690
1139969Simp/* Generate from machine description: 21556Srgrimes - some #define configuration flags. 31556Srgrimes Copyright (C) 1987, 1991, 1997, 1998, 1999, 2000, 2003, 2004 41556Srgrimes Free Software Foundation, Inc. 51556Srgrimes 61556SrgrimesThis file is part of GCC. 71556Srgrimes 81556SrgrimesGCC is free software; you can redistribute it and/or modify it under 91556Srgrimesthe terms of the GNU General Public License as published by the Free 101556SrgrimesSoftware Foundation; either version 2, or (at your option) any later 111556Srgrimesversion. 121556Srgrimes 131556SrgrimesGCC is distributed in the hope that it will be useful, but WITHOUT ANY 141556SrgrimesWARRANTY; without even the implied warranty of MERCHANTABILITY or 151556SrgrimesFITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 161556Srgrimesfor more details. 171556Srgrimes 181556SrgrimesYou should have received a copy of the GNU General Public License 191556Srgrimesalong with GCC; see the file COPYING. If not, write to the Free 201556SrgrimesSoftware Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 211556Srgrimes02110-1301, USA. */ 221556Srgrimes 231556Srgrimes 241556Srgrimes#include "bconfig.h" 251556Srgrimes#include "system.h" 261556Srgrimes#include "coretypes.h" 271556Srgrimes#include "tm.h" 281556Srgrimes#include "rtl.h" 291556Srgrimes#include "errors.h" 301556Srgrimes#include "gensupport.h" 311556Srgrimes 321556Srgrimes 33114433Sobrien/* flags to determine output of machine description dependent #define's. */ 341556Srgrimesstatic int max_recog_operands; /* Largest operand number seen. */ 3520420Sstevestatic int max_dup_operands; /* Largest number of match_dup in any insn. */ 361556Srgrimesstatic int max_clobbers_per_insn; 371556Srgrimesstatic int have_cc0_flag; 381556Srgrimesstatic int have_cmove_flag; 391556Srgrimesstatic int have_cond_exec_flag; 401556Srgrimesstatic int have_lo_sum_flag; 4136049Scharnierstatic int have_peephole_flag; 42114433Sobrienstatic int have_peephole2_flag; 4336049Scharnier 4492974Sobrien/* Maximum number of insns seen in a split. */ 4592974Sobrienstatic int max_insns_per_split = 1; 461556Srgrimes 47149790Scsjp/* Maximum number of input insns for peephole2. */ 48149790Scsjpstatic int max_insns_per_peep2; 491556Srgrimes 501556Srgrimesstatic int clobbers_seen_this_insn; 511556Srgrimesstatic int dup_operands_seen_this_insn; 521556Srgrimes 5331664Seivindstatic void walk_insn_part (rtx, int, int); 541556Srgrimesstatic void gen_insn (rtx); 551556Srgrimesstatic void gen_expand (rtx); 561556Srgrimesstatic void gen_split (rtx); 571556Srgrimesstatic void gen_peephole (rtx); 5890644Simpstatic void gen_peephole2 (rtx); 5977409Simp 6096806Sjmallett/* RECOG_P will be nonzero if this pattern was seen in a context where it will 6190644Simp be used to recognize, rather than just generate an insn. 621556Srgrimes 631556Srgrimes NON_PC_SET_SRC will be nonzero if this pattern was seen in a SET_SRC 641556Srgrimes of a SET whose destination is not (pc). */ 6550544Smharo 661556Srgrimesstatic void 671556Srgrimeswalk_insn_part (rtx part, int recog_p, int non_pc_set_src) 68174935Sdds{ 69174935Sdds int i, j; 70174935Sdds RTX_CODE code; 71239951Sjhb const char *format_ptr; 721556Srgrimes 73180604Sdelphij if (part == 0) 74180604Sdelphij return; 75180604Sdelphij 76180604Sdelphij code = GET_CODE (part); 77196841Strasz switch (code) 78196841Strasz { 791556Srgrimes case CLOBBER: 801556Srgrimes clobbers_seen_this_insn++; 8190110Simp break; 821556Srgrimes 8391085Smarkm case MATCH_OPERAND: 8491085Smarkm if (XINT (part, 0) > max_recog_operands) 8590114Simp max_recog_operands = XINT (part, 0); 861556Srgrimes return; 871556Srgrimes 8877409Simp case MATCH_OP_DUP: 891556Srgrimes case MATCH_PAR_DUP: 90239951Sjhb ++dup_operands_seen_this_insn; 911556Srgrimes case MATCH_SCRATCH: 92239951Sjhb case MATCH_PARALLEL: 93239951Sjhb case MATCH_OPERATOR: 94239951Sjhb if (XINT (part, 0) > max_recog_operands) 951556Srgrimes max_recog_operands = XINT (part, 0); 9614154Swosch /* Now scan the rtl's in the vector inside the MATCH_OPERATOR or 9792935Sobrien MATCH_PARALLEL. */ 981556Srgrimes break; 991556Srgrimes 1001556Srgrimes case LABEL_REF: 10192935Sobrien if (GET_CODE (XEXP (part, 0)) == MATCH_OPERAND 1021556Srgrimes || GET_CODE (XEXP (part, 0)) == MATCH_DUP) 10392935Sobrien break; 10492935Sobrien return; 10592935Sobrien 10692935Sobrien case MATCH_DUP: 10750544Smharo ++dup_operands_seen_this_insn; 10850544Smharo if (XINT (part, 0) > max_recog_operands) 10950544Smharo max_recog_operands = XINT (part, 0); 1101556Srgrimes return; 1111556Srgrimes 1121556Srgrimes case CC0: 11314305Swosch if (recog_p) 1141556Srgrimes have_cc0_flag = 1; 1151556Srgrimes return; 1161556Srgrimes 1171556Srgrimes case LO_SUM: 1181556Srgrimes if (recog_p) 1191556Srgrimes have_lo_sum_flag = 1; 1201556Srgrimes return; 1211556Srgrimes 1221556Srgrimes case SET: 1231556Srgrimes walk_insn_part (SET_DEST (part), 0, recog_p); 1241556Srgrimes walk_insn_part (SET_SRC (part), recog_p, 125284916Sjilles GET_CODE (SET_DEST (part)) != PC); 1261556Srgrimes return; 1271556Srgrimes 1281556Srgrimes case IF_THEN_ELSE: 129239951Sjhb /* Only consider this machine as having a conditional move if the 130239951Sjhb two arms of the IF_THEN_ELSE are both MATCH_OPERAND. Otherwise, 131239951Sjhb we have some specific IF_THEN_ELSE construct (like the doz 132239951Sjhb instruction on the RS/6000) that can't be used in the general 133239951Sjhb context we want it for. */ 134239951Sjhb 135239951Sjhb if (recog_p && non_pc_set_src 136239951Sjhb && GET_CODE (XEXP (part, 1)) == MATCH_OPERAND 137239951Sjhb && GET_CODE (XEXP (part, 2)) == MATCH_OPERAND) 138239951Sjhb have_cmove_flag = 1; 139239951Sjhb break; 1401556Srgrimes 14136785Simp case COND_EXEC: 14236785Simp if (recog_p) 1431556Srgrimes have_cond_exec_flag = 1; 1441556Srgrimes break; 1451556Srgrimes 14636383Ssteve case REG: case CONST_INT: case SYMBOL_REF: 14736383Ssteve case PC: 14836383Ssteve return; 14936383Ssteve 1501556Srgrimes default: 15111298Sbde break; 15211298Sbde } 15311298Sbde 15411298Sbde format_ptr = GET_RTX_FORMAT (GET_CODE (part)); 15511298Sbde 15611298Sbde for (i = 0; i < GET_RTX_LENGTH (GET_CODE (part)); i++) 15711298Sbde switch (*format_ptr++) 15811298Sbde { 15911298Sbde case 'e': 16011298Sbde case 'u': 16177409Simp walk_insn_part (XEXP (part, i), recog_p, non_pc_set_src); 1621556Srgrimes break; 1631556Srgrimes case 'E': 1641556Srgrimes if (XVEC (part, i) != NULL) 16576878Skris for (j = 0; j < XVECLEN (part, i); j++) 1661556Srgrimes walk_insn_part (XVECEXP (part, i, j), recog_p, non_pc_set_src); 1671556Srgrimes break; 1681556Srgrimes } 1691556Srgrimes} 1701556Srgrimes 1711556Srgrimesstatic void 1721556Srgrimesgen_insn (rtx insn) 173180604Sdelphij{ 174180604Sdelphij int i; 1751556Srgrimes 1761556Srgrimes /* Walk the insn pattern to gather the #define's status. */ 17729933Swosch clobbers_seen_this_insn = 0; 1781556Srgrimes dup_operands_seen_this_insn = 0; 1791556Srgrimes if (XVEC (insn, 1) != 0) 1801556Srgrimes for (i = 0; i < XVECLEN (insn, 1); i++) 1811556Srgrimes walk_insn_part (XVECEXP (insn, 1, i), 1, 0); 1821556Srgrimes 1831556Srgrimes if (clobbers_seen_this_insn > max_clobbers_per_insn) 1841556Srgrimes max_clobbers_per_insn = clobbers_seen_this_insn; 1851556Srgrimes if (dup_operands_seen_this_insn > max_dup_operands) 18614166Swosch max_dup_operands = dup_operands_seen_this_insn; 18714166Swosch} 18814166Swosch 18914305Swosch/* Similar but scan a define_expand. */ 19014305Swosch 19114166Swoschstatic void 19230106Swoschgen_expand (rtx insn) 19330106Swosch{ 1941556Srgrimes int i; 19592935Sobrien 19692935Sobrien /* Walk the insn pattern to gather the #define's status. */ 19792935Sobrien 19892935Sobrien /* Note that we don't bother recording the number of MATCH_DUPs 19992935Sobrien that occur in a gen_expand, because only reload cares about that. */ 20030106Swosch if (XVEC (insn, 1) != 0) 2011556Srgrimes for (i = 0; i < XVECLEN (insn, 1); i++) 202243072Seadler { 2031556Srgrimes /* Compute the maximum SETs and CLOBBERS 20430106Swosch in any one of the sub-insns; 2051556Srgrimes don't sum across all of them. */ 20676878Skris clobbers_seen_this_insn = 0; 20776878Skris 2081556Srgrimes walk_insn_part (XVECEXP (insn, 1, i), 0, 0); 2091556Srgrimes 2101556Srgrimes if (clobbers_seen_this_insn > max_clobbers_per_insn) 21129933Swosch max_clobbers_per_insn = clobbers_seen_this_insn; 21229933Swosch } 21329933Swosch} 21430106Swosch 21530106Swosch/* Similar but scan a define_split. */ 2161556Srgrimes 21730106Swoschstatic void 2181556Srgrimesgen_split (rtx split) 2191556Srgrimes{ 220174935Sdds int i; 221174935Sdds 222174935Sdds /* Look through the patterns that are matched 223174935Sdds to compute the maximum operand number. */ 224174935Sdds for (i = 0; i < XVECLEN (split, 0); i++) 22550544Smharo walk_insn_part (XVECEXP (split, 0, i), 1, 0); 22650544Smharo /* Look at the number of insns this insn could split into. */ 22750544Smharo if (XVECLEN (split, 2) > max_insns_per_split) 2281556Srgrimes max_insns_per_split = XVECLEN (split, 2); 22950544Smharo} 2301556Srgrimes 23131664Seivindstatic void 23231664Seivindgen_peephole (rtx peep) 23377409Simp{ 23431664Seivind int i; 235127272Spjd 236127272Spjd /* Look through the patterns that are matched 237127272Spjd to compute the maximum operand number. */ 238127272Spjd for (i = 0; i < XVECLEN (peep, 0); i++) 239127272Spjd walk_insn_part (XVECEXP (peep, 0, i), 1, 0); 240127272Spjd} 24131664Seivind 24231664Seivindstatic void 243127272Spjdgen_peephole2 (rtx peep) 244127272Spjd{ 245127272Spjd int i, n; 246174935Sdds 247127272Spjd /* Look through the patterns that are matched 248127272Spjd to compute the maximum operand number. */ 249127272Spjd for (i = XVECLEN (peep, 0) - 1; i >= 0; --i) 250127272Spjd walk_insn_part (XVECEXP (peep, 0, i), 1, 0); 251127272Spjd 252127272Spjd /* Look at the number of insns this insn can be matched from. */ 253127272Spjd for (i = XVECLEN (peep, 0) - 1, n = 0; i >= 0; --i) 25431664Seivind if (GET_CODE (XVECEXP (peep, 0, i)) != MATCH_DUP 25531664Seivind && GET_CODE (XVECEXP (peep, 0, i)) != MATCH_SCRATCH) 2561556Srgrimes n++; 2571556Srgrimes if (n > max_insns_per_peep2) 2581556Srgrimes max_insns_per_peep2 = n; 2591556Srgrimes} 2601556Srgrimes 2611556Srgrimesint 2621556Srgrimesmain (int argc, char **argv) 2631556Srgrimes{ 2641556Srgrimes rtx desc; 26562963Sdwmalone 2661556Srgrimes progname = "genconfig"; 2671556Srgrimes 2681556Srgrimes if (init_md_reader_args (argc, argv) != SUCCESS_EXIT_CODE) 2691556Srgrimes return (FATAL_EXIT_CODE); 2701556Srgrimes 2711556Srgrimes puts ("/* Generated automatically by the program `genconfig'"); 2721556Srgrimes puts (" from the machine description file `md'. */\n"); 273180604Sdelphij puts ("#ifndef GCC_INSN_CONFIG_H"); 274180604Sdelphij puts ("#define GCC_INSN_CONFIG_H\n"); 2751556Srgrimes 276277645Sjilles /* Allow at least 30 operands for the sake of asm constructs. */ 277225954Sivoras /* ??? We *really* ought to reorganize things such that there 278225954Sivoras is no fixed upper bound. */ 27923525Sguido max_recog_operands = 29; /* We will add 1 later. */ 28090114Simp max_dup_operands = 1; 281268129Sdelphij 2821556Srgrimes /* Read the machine description. */ 2831556Srgrimes 284225954Sivoras while (1) 2851556Srgrimes { 2861556Srgrimes int line_no, insn_code_number = 0; 287225954Sivoras 288225954Sivoras desc = read_md_rtx (&line_no, &insn_code_number); 289225954Sivoras if (desc == NULL) 29023525Sguido break; 29123525Sguido 29223525Sguido switch (GET_CODE (desc)) 29323525Sguido { 29423525Sguido case DEFINE_INSN: 295225954Sivoras gen_insn (desc); 2961556Srgrimes break; 2971556Srgrimes 2981556Srgrimes case DEFINE_EXPAND: 29976878Skris gen_expand (desc); 30076878Skris break; 301225954Sivoras 3021556Srgrimes case DEFINE_SPLIT: 3031556Srgrimes gen_split (desc); 3041556Srgrimes break; 305225954Sivoras 3061556Srgrimes case DEFINE_PEEPHOLE2: 3071556Srgrimes have_peephole2_flag = 1; 3081556Srgrimes gen_peephole2 (desc); 3091556Srgrimes break; 3101556Srgrimes 3111556Srgrimes case DEFINE_PEEPHOLE: 3121556Srgrimes have_peephole_flag = 1; 31323525Sguido gen_peephole (desc); 31423525Sguido break; 31537245Sbde 31637245Sbde default: 31723525Sguido break; 31823525Sguido } 31923525Sguido } 32023525Sguido 32123525Sguido printf ("#define MAX_RECOG_OPERANDS %d\n", max_recog_operands + 1); 32223525Sguido printf ("#define MAX_DUP_OPERANDS %d\n", max_dup_operands); 32323525Sguido 324196841Strasz /* This is conditionally defined, in case the user writes code which emits 325196841Strasz more splits than we can readily see (and knows s/he does it). */ 326149790Scsjp printf ("#ifndef MAX_INSNS_PER_SPLIT\n"); 327149790Scsjp printf ("#define MAX_INSNS_PER_SPLIT %d\n", max_insns_per_split); 328174935Sdds printf ("#endif\n"); 329149790Scsjp 330149790Scsjp if (have_cc0_flag) 331196841Strasz { 332149790Scsjp printf ("#define HAVE_cc0 1\n"); 33363680Ssada printf ("#define CC0_P(X) ((X) == cc0_rtx)\n"); 33463680Ssada } 33563680Ssada else 33663680Ssada { 33763680Ssada /* We output CC0_P this way to make sure that X is declared 33863680Ssada somewhere. */ 33963680Ssada printf ("#define CC0_P(X) ((X) ? 0 : 0)\n"); 340268129Sdelphij } 341268129Sdelphij 342268129Sdelphij if (have_cmove_flag) 343268129Sdelphij printf ("#define HAVE_conditional_move 1\n"); 344268129Sdelphij 345268129Sdelphij if (have_cond_exec_flag) 346268129Sdelphij printf ("#define HAVE_conditional_execution 1\n"); 347268129Sdelphij 348268129Sdelphij if (have_lo_sum_flag) 349268129Sdelphij printf ("#define HAVE_lo_sum 1\n"); 350268129Sdelphij 351268129Sdelphij if (have_peephole_flag) 3521556Srgrimes printf ("#define HAVE_peephole 1\n"); 353277645Sjilles 354277645Sjilles if (have_peephole2_flag) 355280386Sjilles { 3561556Srgrimes printf ("#define HAVE_peephole2 1\n"); 3571556Srgrimes printf ("#define MAX_INSNS_PER_PEEP2 %d\n", max_insns_per_peep2); 3581556Srgrimes } 3591556Srgrimes 3601556Srgrimes puts("\n#endif /* GCC_INSN_CONFIG_H */"); 3611556Srgrimes 3621556Srgrimes if (ferror (stdout) || fflush (stdout) || fclose (stdout)) 3631556Srgrimes return FATAL_EXIT_CODE; 3641556Srgrimes 3651556Srgrimes return SUCCESS_EXIT_CODE; 3661556Srgrimes} 36750544Smharo