1# Copyright (C) 2003,2004,2005,2006,2007,2008, 2010, 2011 2# Free Software Foundation, Inc. 3# Contributed by Kelley Cook, June 2004. 4# Original code from Neil Booth, May 2003. 5# 6# This program is free software; you can redistribute it and/or modify it 7# under the terms of the GNU General Public License as published by the 8# Free Software Foundation; either version 3, or (at your option) any 9# later version. 10# 11# This program is distributed in the hope that it will be useful, 12# but WITHOUT ANY WARRANTY; without even the implied warranty of 13# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14# GNU General Public License for more details. 15# 16# You should have received a copy of the GNU General Public License 17# along with this program; see the file COPYING3. If not see 18# <http://www.gnu.org/licenses/>. 19 20# This Awk script reads in the option records generated from 21# opt-gather.awk, combines the flags of duplicate options and generates a 22# C header file. 23# 24# This program uses functions from opt-functions.awk and code from 25# opt-read.awk. 26# Usage: awk -f opt-functions.awk -f opt-read.awk -f opth-gen.awk \ 27# < inputfile > options.h 28 29# Dump out an enumeration into a .h file. 30# Combine the flags of duplicate options. 31END { 32print "/* This file is auto-generated by opth-gen.awk. */" 33print "" 34print "#ifndef OPTIONS_H" 35print "#define OPTIONS_H" 36print "" 37print "#include \"flag-types.h\"" 38print "" 39 40if (n_extra_h_includes > 0) { 41 for (i = 0; i < n_extra_h_includes; i++) { 42 print "#include " quote extra_h_includes[i] quote 43 } 44 print "" 45} 46 47print "#if !defined(IN_LIBGCC2) && !defined(IN_TARGET_LIBS) && !defined(IN_RTS)" 48print "#ifndef GENERATOR_FILE" 49print "#if !defined(IN_LIBGCC2) && !defined(IN_TARGET_LIBS)" 50print "struct GTY(()) gcc_options" 51print "#else" 52print "struct gcc_options" 53print "#endif" 54print "{" 55print "#endif" 56 57for (i = 0; i < n_extra_vars; i++) { 58 var = extra_vars[i] 59 sub(" *=.*", "", var) 60 orig_var = var 61 name = var 62 type = var 63 type_after = var 64 sub("^.*[ *]", "", name) 65 sub("\\[.*\\]$", "", name) 66 sub("\\[.*\\]$", "", type) 67 sub(" *" name "$", "", type) 68 sub("^.*" name, "", type_after) 69 var_seen[name] = 1 70 print "#ifdef GENERATOR_FILE" 71 print "extern " orig_var ";" 72 print "#else" 73 print " " type " x_" name type_after ";" 74 print "#define " name " global_options.x_" name 75 print "#endif" 76} 77 78for (i = 0; i < n_opts; i++) { 79 if (flag_set_p("Save", flags[i])) 80 have_save = 1; 81 82 name = var_name(flags[i]); 83 if (name == "") 84 continue; 85 86 if (name in var_seen) 87 continue; 88 89 var_seen[name] = 1; 90 print "#ifdef GENERATOR_FILE" 91 print "extern " var_type(flags[i]) name ";" 92 print "#else" 93 print " " var_type(flags[i]) "x_" name ";" 94 print "#define " name " global_options.x_" name 95 print "#endif" 96} 97for (i = 0; i < n_opts; i++) { 98 name = static_var(opts[i], flags[i]); 99 if (name != "") { 100 print "#ifndef GENERATOR_FILE" 101 print " " var_type(flags[i]) "x_" name ";" 102 print "#define x_" name " do_not_use" 103 print "#endif" 104 } 105} 106for (i = 0; i < n_opts; i++) { 107 if (flag_set_p("SetByCombined", flags[i])) { 108 print "#ifndef GENERATOR_FILE" 109 print " bool frontend_set_" var_name(flags[i]) ";" 110 print "#endif" 111 } 112} 113print "#ifndef GENERATOR_FILE" 114print "};" 115print "extern struct gcc_options global_options;" 116print "extern const struct gcc_options global_options_init;" 117print "extern struct gcc_options global_options_set;" 118print "#define target_flags_explicit global_options_set.x_target_flags" 119print "#endif" 120print "#endif" 121print "" 122 123# All of the optimization switches gathered together so they can be saved and restored. 124# This will allow attribute((cold)) to turn on space optimization. 125 126# Change the type of normal switches from int to unsigned char to save space. 127# Also, order the structure so that pointer fields occur first, then int 128# fields, and then char fields to provide the best packing. 129 130print "#if !defined(IN_LIBGCC2) && !defined(IN_TARGET_LIBS) && !defined(IN_RTS)" 131print "" 132print "/* Structure to save/restore optimization and target specific options. */"; 133print "struct GTY(()) cl_optimization"; 134print "{"; 135 136n_opt_char = 2; 137n_opt_short = 0; 138n_opt_int = 0; 139n_opt_enum = 1; 140n_opt_other = 0; 141var_opt_char[0] = "unsigned char x_optimize"; 142var_opt_char[1] = "unsigned char x_optimize_size"; 143var_opt_enum[0] = "enum fp_contract_mode x_flag_fp_contract_mode"; 144 145for (i = 0; i < n_opts; i++) { 146 if (flag_set_p("Optimization", flags[i])) { 147 name = var_name(flags[i]) 148 if(name == "") 149 continue; 150 151 if(name in var_opt_seen) 152 continue; 153 154 var_opt_seen[name]++; 155 otype = var_type_struct(flags[i]); 156 if (otype ~ "^((un)?signed +)?int *$") 157 var_opt_int[n_opt_int++] = otype "x_" name; 158 159 else if (otype ~ "^((un)?signed +)?short *$") 160 var_opt_short[n_opt_short++] = otype "x_" name; 161 162 else if (otype ~ "^((un)?signed +)?char *$") 163 var_opt_char[n_opt_char++] = otype "x_" name; 164 165 else if (otype ~ ("^enum +[_" alnum "]+ *$")) 166 var_opt_enum[n_opt_enum++] = otype "x_" name; 167 168 else 169 var_opt_other[n_opt_other++] = otype "x_" name; 170 } 171} 172 173for (i = 0; i < n_opt_other; i++) { 174 print " " var_opt_other[i] ";"; 175} 176 177for (i = 0; i < n_opt_int; i++) { 178 print " " var_opt_int[i] ";"; 179} 180 181for (i = 0; i < n_opt_enum; i++) { 182 print " " var_opt_enum[i] ";"; 183} 184 185for (i = 0; i < n_opt_short; i++) { 186 print " " var_opt_short[i] ";"; 187} 188 189for (i = 0; i < n_opt_char; i++) { 190 print " " var_opt_char[i] ";"; 191} 192 193print "};"; 194print ""; 195 196# Target and optimization save/restore/print functions. 197print "/* Structure to save/restore selected target specific options. */"; 198print "struct GTY(()) cl_target_option"; 199print "{"; 200 201n_target_char = 0; 202n_target_short = 0; 203n_target_int = 0; 204n_target_enum = 0; 205n_target_other = 0; 206 207for (i = 0; i < n_target_save; i++) { 208 if (target_save_decl[i] ~ "^((un)?signed +)?int +[_" alnum "]+$") 209 var_target_int[n_target_int++] = target_save_decl[i]; 210 211 else if (target_save_decl[i] ~ "^((un)?signed +)?short +[_" alnum "]+$") 212 var_target_short[n_target_short++] = target_save_decl[i]; 213 214 else if (target_save_decl[i] ~ "^((un)?signed +)?char +[_ " alnum "]+$") 215 var_target_char[n_target_char++] = target_save_decl[i]; 216 217 else if (target_save_decl[i] ~ ("^enum +[_" alnum "]+ +[_" alnum "]+$")) { 218 var_target_enum[n_target_enum++] = target_save_decl[i]; 219 } 220 else 221 var_target_other[n_target_other++] = target_save_decl[i]; 222} 223 224if (have_save) { 225 for (i = 0; i < n_opts; i++) { 226 if (flag_set_p("Save", flags[i])) { 227 name = var_name(flags[i]) 228 if(name == "") 229 name = "target_flags"; 230 231 if(name in var_save_seen) 232 continue; 233 234 var_save_seen[name]++; 235 otype = var_type_struct(flags[i]) 236 if (otype ~ "^((un)?signed +)?int *$") 237 var_target_int[n_target_int++] = otype "x_" name; 238 239 else if (otype ~ "^((un)?signed +)?short *$") 240 var_target_short[n_target_short++] = otype "x_" name; 241 242 else if (otype ~ "^((un)?signed +)?char *$") 243 var_target_char[n_target_char++] = otype "x_" name; 244 245 else if (otype ~ ("^enum +[_" alnum "]+ +[_" alnum "]+")) 246 var_target_enum[n_target_enum++] = otype "x_" name; 247 248 else 249 var_target_other[n_target_other++] = otype "x_" name; 250 } 251 } 252} else { 253 var_target_int[n_target_int++] = "int x_target_flags"; 254} 255 256for (i = 0; i < n_target_other; i++) { 257 print " " var_target_other[i] ";"; 258} 259 260for (i = 0; i < n_target_enum; i++) { 261 print " " var_target_enum[i] ";"; 262} 263 264for (i = 0; i < n_target_int; i++) { 265 print " " var_target_int[i] ";"; 266} 267 268for (i = 0; i < n_target_short; i++) { 269 print " " var_target_short[i] ";"; 270} 271 272for (i = 0; i < n_target_char; i++) { 273 print " " var_target_char[i] ";"; 274} 275 276print "};"; 277print ""; 278print ""; 279print "/* Save optimization variables into a structure. */" 280print "extern void cl_optimization_save (struct cl_optimization *, struct gcc_options *);"; 281print ""; 282print "/* Restore optimization variables from a structure. */"; 283print "extern void cl_optimization_restore (struct gcc_options *, struct cl_optimization *);"; 284print ""; 285print "/* Print optimization variables from a structure. */"; 286print "extern void cl_optimization_print (FILE *, int, struct cl_optimization *);"; 287print ""; 288print "/* Save selected option variables into a structure. */" 289print "extern void cl_target_option_save (struct cl_target_option *, struct gcc_options *);"; 290print ""; 291print "/* Restore selected option variables from a structure. */" 292print "extern void cl_target_option_restore (struct gcc_options *, struct cl_target_option *);"; 293print ""; 294print "/* Print target option variables from a structure. */"; 295print "extern void cl_target_option_print (FILE *, int, struct cl_target_option *);"; 296print "#endif"; 297print ""; 298 299for (i = 0; i < n_opts; i++) { 300 name = opt_args("Mask", flags[i]) 301 vname = var_name(flags[i]) 302 mask = "MASK_" 303 mask_1 = "1" 304 if (vname != "") { 305 mask = "OPTION_MASK_" 306 if (host_wide_int[vname] == "yes") 307 mask_1 = "HOST_WIDE_INT_1" 308 } 309 if (name != "" && !flag_set_p("MaskExists", flags[i])) 310 print "#define " mask name " (" mask_1 " << " masknum[vname]++ ")" 311} 312for (i = 0; i < n_extra_masks; i++) { 313 print "#define MASK_" extra_masks[i] " (1 << " masknum[""]++ ")" 314} 315 316for (var in masknum) { 317 if (var != "" && host_wide_int[var] == "yes") { 318 print" #if defined(HOST_BITS_PER_WIDE_INT) && " masknum[var] " >= HOST_BITS_PER_WIDE_INT" 319 print "#error too many masks for " var 320 print "#endif" 321 } 322 else if (masknum[var] > 31) { 323 if (var == "") 324 print "#error too many target masks" 325 else 326 print "#error too many masks for " var 327 } 328} 329print "" 330 331for (i = 0; i < n_opts; i++) { 332 name = opt_args("Mask", flags[i]) 333 vname = var_name(flags[i]) 334 macro = "OPTION_" 335 mask = "OPTION_MASK_" 336 if (vname == "") { 337 vname = "target_flags" 338 macro = "TARGET_" 339 mask = "MASK_" 340 } 341 if (name != "" && !flag_set_p("MaskExists", flags[i])) 342 print "#define " macro name \ 343 " ((" vname " & " mask name ") != 0)" 344} 345for (i = 0; i < n_extra_masks; i++) { 346 print "#define TARGET_" extra_masks[i] \ 347 " ((target_flags & MASK_" extra_masks[i] ") != 0)" 348} 349print "" 350 351for (i = 0; i < n_opts; i++) { 352 opt = opt_args("InverseMask", flags[i]) 353 if (opt ~ ",") { 354 vname = var_name(flags[i]) 355 macro = "OPTION_" 356 mask = "OPTION_MASK_" 357 if (vname == "") { 358 vname = "target_flags" 359 macro = "TARGET_" 360 mask = "MASK_" 361 } 362 print "#define " macro nth_arg(1, opt) \ 363 " ((" vname " & " mask nth_arg(0, opt) ") == 0)" 364 } 365} 366print "" 367 368for (i = 0; i < n_langs; i++) { 369 macros[i] = "CL_" langs[i] 370 gsub( "[^" alnum "_]", "X", macros[i] ) 371 s = substr(" ", length (macros[i])) 372 print "#define " macros[i] s " (1U << " i ")" 373 } 374print "#define CL_LANG_ALL ((1U << " n_langs ") - 1)" 375 376print "" 377print "enum opt_code" 378print "{" 379 380for (i = 0; i < n_opts; i++) 381 back_chain[i] = "N_OPTS"; 382 383enum_value = 0 384for (i = 0; i < n_opts; i++) { 385 # Combine the flags of identical switches. Switches 386 # appear many times if they are handled by many front 387 # ends, for example. 388 while( i + 1 != n_opts && opts[i] == opts[i + 1] ) { 389 flags[i + 1] = flags[i] " " flags[i + 1]; 390 i++; 391 } 392 393 len = length (opts[i]); 394 enum = opt_enum(opts[i]) 395 enum_string = enum " = " enum_value "," 396 397 # Aliases do not get enumeration names. 398 if ((flag_set_p("Alias.*", flags[i]) \ 399 && !flag_set_p("SeparateAlias", flags[i])) \ 400 || flag_set_p("Ignore", flags[i])) { 401 enum_string = "/* " enum_string " */" 402 } 403 404 # If this switch takes joined arguments, back-chain all 405 # subsequent switches to it for which it is a prefix. If 406 # a later switch S is a longer prefix of a switch T, T 407 # will be back-chained to S in a later iteration of this 408 # for() loop, which is what we want. 409 if (flag_set_p("Joined.*", flags[i])) { 410 for (j = i + 1; j < n_opts; j++) { 411 if (substr (opts[j], 1, len) != opts[i]) 412 break; 413 back_chain[j] = enum; 414 } 415 } 416 417 s = substr(" ", 418 length (enum_string)) 419 420 if (help[i] == "") 421 hlp = "0" 422 else 423 hlp = "N_(\"" help[i] "\")"; 424 425 print " " enum_string s "/* -" opts[i] " */" 426 enum_value++ 427} 428 429print " N_OPTS," 430print " OPT_SPECIAL_unknown," 431print " OPT_SPECIAL_ignore," 432print " OPT_SPECIAL_program_name," 433print " OPT_SPECIAL_input_file" 434print "};" 435print "" 436print "#endif /* OPTIONS_H */" 437} 438