00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047 #include <string.h>
00048 #include <stdlib.h>
00049 #if !defined(_WIN32)
00050 #include <sys/utsname.h>
00051 #endif
00052 #include <unistd.h>
00053 #include "cmplrs/rcodes.h"
00054 #include "opt_actions.h"
00055 #include "options.h"
00056 #include "option_names.h"
00057 #include "option_seen.h"
00058 #include "lang_defs.h"
00059 #include "errors.h"
00060 #include "file_utils.h"
00061 #include "file_names.h"
00062 #include "string_utils.h"
00063 #include "get_options.h"
00064 #include "objects.h"
00065 #include "pathscale_defs.h"
00066 #include "phases.h"
00067 #include "run.h"
00068 #include "profile_type.h"
00069
00070
00071 typedef struct toggle_name_struct {
00072 int *address;
00073 char *name;
00074 } toggle_name;
00075 #define MAX_TOGGLES 50
00076 static toggle_name toggled_names[MAX_TOGGLES];
00077 static int last_toggle_index = 0;
00078 static int inline_on_seen = FALSE;
00079 int inline_t = UNDEFINED;
00080 #ifdef KEY
00081
00082
00083 int run_inline;
00084 int malloc_algorithm = UNDEFINED;
00085 #endif
00086 boolean dashdash_flag = FALSE;
00087 boolean read_stdin = FALSE;
00088 boolean xpg_flag = FALSE;
00089 #if defined(TARG_NVISA)
00090
00091 int default_olevel = 3;
00092 #else
00093 int default_olevel = 2;
00094 #endif
00095 static int default_isa = UNDEFINED;
00096 static int default_proc = UNDEFINED;
00097 int instrumentation_invoked = UNDEFINED;
00098 int profile_type = 0;
00099 boolean ftz_crt = FALSE;
00100
00101 int proc = UNDEFINED;
00102 #ifdef TARG_X8664
00103 static int target_supported_abi = UNDEFINED;
00104 static boolean target_supports_mmx = FALSE;
00105 static boolean target_supports_sse = FALSE;
00106 static boolean target_supports_sse2 = FALSE;
00107 static boolean target_prefers_sse3 = FALSE;
00108 static boolean target_supports_sse4a = FALSE;
00109 #endif
00110
00111 extern boolean parsing_default_options;
00112 extern boolean drop_option;
00113
00114 static void set_cpu(char *name, m_flag flag_type);
00115
00116 #ifdef KEY
00117 void set_memory_model(char *model);
00118 static int get_platform_abi();
00119 #endif
00120
00121 #ifdef TARG_X8664
00122 static void Get_x86_ISA();
00123 static boolean Get_x86_ISA_extensions();
00124 #endif
00125
00126
00127
00128
00129
00130
00131
00132
00133
00134
00135
00136
00137
00138
00139
00140 int ofast = UNDEFINED;
00141
00142
00143 static void
00144 add_toggle_name (int *obj, char *name)
00145 {
00146 int i;
00147 for (i = 0; i < last_toggle_index; i++) {
00148 if (obj == toggled_names[i].address) {
00149 break;
00150 }
00151 }
00152 if (i == last_toggle_index) {
00153 if (last_toggle_index >= MAX_TOGGLES) {
00154 internal_error("too many toggle names\n");
00155 } else {
00156 last_toggle_index++;
00157 }
00158 }
00159 toggled_names[i].address = obj;
00160 toggled_names[i].name = string_copy(option_name);
00161 }
00162
00163 static char *
00164 get_toggle_name (int *obj)
00165 {
00166 int i;
00167 for (i = 0; i < last_toggle_index; i++) {
00168 if (obj == toggled_names[i].address) {
00169 return toggled_names[i].name;
00170 }
00171 }
00172 internal_error("no previously toggled name?");
00173 return "<unknown>";
00174 }
00175
00176
00177 boolean
00178 is_toggled (int obj)
00179 {
00180 return (obj != UNDEFINED);
00181 }
00182
00183
00184 void
00185 toggle (int *obj, int value)
00186 {
00187
00188
00189 if (parsing_default_options &&
00190 is_toggled(*obj)) {
00191 drop_option = TRUE;
00192 return;
00193 }
00194
00195 if (*obj != UNDEFINED && *obj != value) {
00196 warning ("%s conflicts with %s; using latter value (%s)",
00197 get_toggle_name(obj), option_name, option_name);
00198 }
00199 *obj = value;
00200 add_toggle_name(obj, option_name);
00201 }
00202
00203
00204
00205
00206
00207
00208
00209
00210
00211
00212
00213
00214 static char *
00215 Get_Group_Option_Value (
00216 char *arg,
00217 char *name,
00218 char *abbrev)
00219 {
00220 char *endc = arg;
00221 int n;
00222
00223 while ( TRUE ) {
00224 n = strcspn ( arg, ":=" );
00225 if ( strncasecmp ( arg, abbrev, strlen(abbrev) ) == 0
00226 && strncasecmp ( arg, name, n ) == 0 )
00227 {
00228 endc += n;
00229 if ( *endc == '=' ) {
00230
00231 char *result = strdup ( endc+1 );
00232
00233 * ( result + strcspn ( result, ":=" ) ) = 0;
00234 return result;
00235 } else {
00236
00237 return "";
00238 }
00239 }
00240 if ( ( endc = strchr ( arg, ':' ) ) == NULL ) return NULL;
00241 arg = ++endc;
00242 }
00243
00244
00245
00246 }
00247
00248
00249
00250
00251
00252
00253
00254
00255
00256
00257
00258 static boolean
00259 Bool_Group_Value ( char *val )
00260 {
00261 if ( *val == 0 ) {
00262
00263 return TRUE;
00264 }
00265
00266 if ( strcasecmp ( val, "OFF" ) == 0
00267 || strcasecmp ( val, "NO" ) == 0
00268 || strcasecmp ( val, "FALSE" ) == 0
00269 || strcasecmp ( val, "0" ) == 0 )
00270 {
00271 return FALSE;
00272 } else {
00273 return TRUE;
00274 }
00275 }
00276 #ifdef KEY
00277
00278
00279
00280
00281
00282
00283
00284
00285 char *f90_module_dir = 0;
00286
00287 void
00288 Process_module ( char *dirname )
00289 {
00290 if (0 != f90_module_dir)
00291 {
00292 error("Only one -module option allowed");
00293 }
00294 strcat(
00295 strcpy(
00296 f90_module_dir = malloc(sizeof "-J" + strlen(dirname)),
00297 "-J"),
00298 dirname);
00299 }
00300 #endif
00301
00302
00303
00304
00305
00306
00307
00308
00309
00310
00311
00312 void
00313 Process_Ofast ( char *ipname )
00314 {
00315 int flag;
00316 char *suboption;
00317
00318
00319 if (!Gen_feedback) {
00320 O3_flag = TRUE;
00321 toggle ( &olevel, 3 );
00322 add_option_seen ( O_O3 );
00323
00324 #ifdef TARG_IA64
00325 ftz_crt = TRUE;
00326 #endif
00327
00328
00329 toggle ( &fmath_errno, 0);
00330 add_option_seen (O_fno_math_errno);
00331
00332
00333 toggle ( &ffast_math, 1);
00334 add_option_seen (O_ffast_math);
00335
00336
00337 toggle ( &ipa, TRUE );
00338 add_option_seen ( O_IPA );
00339
00340
00341
00342
00343
00344
00345 toggle ( &ofast, TRUE );
00346 suboption = concat_strings ( "Ofast=", ipname );
00347 flag = add_string_option ( O_OPT_, suboption );
00348 add_option_seen ( flag );
00349 } else {
00350 suboption = concat_strings ( "platform=", ipname );
00351 flag = add_string_option ( O_TARG_, suboption );
00352 add_option_seen ( flag );
00353 }
00354 }
00355
00356
00357
00358
00359
00360
00361
00362
00363
00364
00365
00366
00367
00368
00369 void
00370 Process_Opt_Group ( char *opt_args )
00371 {
00372 char *optval = NULL;
00373
00374 if ( debug ) {
00375 fprintf ( stderr, "Process_Opt_Group: %s\n", opt_args );
00376 }
00377
00378
00379 optval = Get_Group_Option_Value ( opt_args, "instrument", "instr");
00380 if (optval != NULL) {
00381 instrumentation_invoked = TRUE;
00382 }
00383
00384
00385 optval = Get_Group_Option_Value ( opt_args, "reorg_common", "reorg");
00386 if ( optval != NULL && Bool_Group_Value(optval)) {
00387 #ifndef KEY
00388
00389 add_option_seen ( O_split_common );
00390 add_option_seen ( O_ivpad );
00391 #endif
00392 }
00393
00394 #ifdef KEY
00395
00396 optval = Get_Group_Option_Value(opt_args, "malloc_algorithm", "malloc_alg");
00397 if (optval != NULL &&
00398 atoi(optval) > 0) {
00399 #ifdef TARG_X8664 // Option available only for x86-64. Bug 12431.
00400 malloc_algorithm = atoi(optval);
00401 #else
00402 warning("ignored -OPT:malloc_algorithm because option not supported on"
00403 " this architecture");
00404 #endif
00405 }
00406 #endif
00407 }
00408
00409 void
00410 Process_Default_Group (char *default_args)
00411 {
00412 char *s;
00413 int i;
00414
00415 if ( debug ) {
00416 fprintf ( stderr, "Process_Default_Group: %s\n", default_args );
00417 }
00418
00419
00420 s = Get_Group_Option_Value ( default_args, "isa", "isa");
00421 if (s != NULL && same_string_prefix (s, "mips")) {
00422 default_isa = atoi(s + strlen("mips"));
00423 }
00424
00425 s = Get_Group_Option_Value ( default_args, "opt", "opt");
00426 if (s != NULL) {
00427 default_olevel = atoi(s);
00428 }
00429
00430 s = Get_Group_Option_Value ( default_args, "arith", "arith");
00431 if (s != NULL) {
00432 i = add_string_option (O_OPT_, concat_strings("IEEE_arith=", s));
00433 add_option_seen (i);
00434 }
00435 }
00436
00437
00438
00439
00440
00441
00442
00443
00444
00445
00446
00447
00448
00449
00450
00451
00452
00453
00454
00455
00456
00457
00458
00459
00460 void
00461 Process_Targ_Group ( char *targ_args )
00462 {
00463 char *cp = targ_args;
00464 char *cpeq;
00465 char *ftz;
00466
00467 if ( debug ) {
00468 fprintf ( stderr, "Process_Targ_Group: %s\n", targ_args );
00469 }
00470
00471 ftz = Get_Group_Option_Value ( targ_args, "flush_to_zero", "flush_to_zero");
00472 if ( ftz != NULL && Bool_Group_Value(ftz)) {
00473
00474 ftz_crt = TRUE;
00475 }
00476
00477 while ( *cp != 0 ) {
00478 switch ( *cp ) {
00479 case '3':
00480 #ifdef TARG_X8664
00481 if (!strncasecmp(cp, "3dnow=on", 9)) {
00482 add_option_seen(O_m3dnow);
00483 toggle(&m3dnow, TRUE);
00484 } else if (!strncasecmp(cp, "3dnow=off", 10)) {
00485 add_option_seen(O_mno_3dnow);
00486 toggle(&m3dnow, FALSE);
00487 }
00488 break;
00489 #endif
00490
00491 case 'a':
00492 if ( strncasecmp ( cp, "abi", 3 ) == 0 && *(cp+3) == '=' ) {
00493 #ifdef TARG_MIPS
00494 if ( strncasecmp ( cp+4, "n32", 3 ) == 0 ) {
00495 add_option_seen ( O_n32 );
00496 toggle ( &abi, ABI_N32 );
00497 }
00498 #ifndef TARG_SL
00499 else if ( strncasecmp ( cp+4, "64", 2 ) == 0 ) {
00500 add_option_seen ( O_m64 );
00501 toggle ( &abi, ABI_64 );
00502 }
00503 #endif
00504 #endif
00505 #ifdef TARG_X8664
00506
00507
00508
00509
00510 if ( strncasecmp ( cp+4, "n32", 3 ) == 0 ) {
00511 add_option_seen ( O_m32 );
00512 toggle ( &abi, ABI_N32 );
00513 } else if ( strncasecmp ( cp+4, "n64", 3 ) == 0 ) {
00514 add_option_seen ( O_m64 );
00515 toggle ( &abi, ABI_64 );
00516 }
00517 #endif
00518 #if defined(TARG_NVISA)
00519 if ( strncasecmp ( cp+4, "w64", 3 ) == 0 ) {
00520 add_option_seen ( O_w64 );
00521 toggle ( &abi, ABI_W64 );
00522 }
00523 #endif
00524 }
00525 break;
00526
00527 #if 0
00528 case 'e':
00529 if ( strncasecmp ( cp, "exc_enable", 10 ) == 0 && *(cp+10) == '=' ) {
00530 int flag;
00531 buffer_t buf;
00532 int mask = 0;
00533 cp += 11;
00534 while ( *cp != 0 && *cp != ':' ) {
00535 switch (*cp) {
00536 case 'I': mask |= (1 << 5); break;
00537 case 'U': mask |= (1 << 4); break;
00538 case 'O': mask |= (1 << 3); break;
00539 case 'Z': mask |= (1 << 2); break;
00540 case 'D': mask |= (1 << 1); break;
00541 case 'V': mask |= (1 << 0); break;
00542 }
00543 ++cp;
00544 }
00545 flag = add_string_option(O_WlC, "-defsym,_IEEE_ENABLE_DEFINED=1");
00546 add_option_seen (flag);
00547 sprintf(buf, "-defsym,_IEEE_ENABLE=%#x", mask);
00548 flag = add_string_option(O_WlC, buf);
00549 add_option_seen (flag);
00550 }
00551 break;
00552 #endif
00553
00554 case 'i':
00555
00556
00557
00558
00559 if ( strncasecmp ( cp, "isa", 3 ) != 0 || *(cp+3) != '=' ) {
00560 break;
00561 } else {
00562 cp += 4;
00563 }
00564
00565
00566 case 'm':
00567 #ifdef TARG_MIPS
00568 if ( strncasecmp ( cp, "mips", 4 ) == 0 ) {
00569 if ( '1' <= *(cp+4) && *(cp+4) <= '6' ) {
00570 toggle ( &isa, *(cp+4) - '0' );
00571 #ifndef TARG_SL
00572 switch ( isa ) {
00573 case 1: add_option_seen ( O_mips1 );
00574 break;
00575 case 2: add_option_seen ( O_mips2 );
00576 break;
00577 case 3: add_option_seen ( O_mips3 );
00578 break;
00579 case 4: add_option_seen ( O_mips4 );
00580 break;
00581 default: error ( "invalid ISA: %s", cp );
00582 break;
00583 }
00584 #endif
00585 }
00586 }
00587 #endif
00588 break;
00589
00590 case 'p':
00591 #ifdef KEY
00592 if (!strncasecmp(cp, "processor=", 10)) {
00593 char *target = cp + 10;
00594 set_cpu (target, M_ARCH);
00595 }
00596 #endif
00597 break;
00598
00599 case 's':
00600 #ifdef TARG_X8664
00601 if (!strncasecmp(cp, "mmx=on", 7)) {
00602 add_option_seen(O_mmmx);
00603 toggle(&mmx, TRUE);
00604 } else if (!strncasecmp(cp, "mmx=off", 8)) {
00605 add_option_seen(O_mno_mmx);
00606 toggle(&mmx, FALSE);
00607 } else if (!strncasecmp(cp, "sse=on", 7)) {
00608 add_option_seen(O_msse);
00609 toggle(&sse, TRUE);
00610 } else if (!strncasecmp(cp, "sse=off", 8)) {
00611 add_option_seen(O_mno_sse);
00612 toggle(&sse, FALSE);
00613 } else if (!strncasecmp(cp, "sse2=on", 8)) {
00614 add_option_seen(O_msse2);
00615 toggle(&sse2, TRUE);
00616 } else if (!strncasecmp(cp, "sse2=off", 9)) {
00617 add_option_seen(O_mno_sse2);
00618 toggle(&sse2, FALSE);
00619 } else if (!strncasecmp(cp, "sse3=on", 8)) {
00620 add_option_seen(O_msse3);
00621 toggle(&sse3, TRUE);
00622 } else if (!strncasecmp(cp, "sse3=off", 9)) {
00623 add_option_seen(O_mno_sse3);
00624 toggle(&sse3, FALSE);
00625 }else if (!strncasecmp(cp, "sse4a=on", 9)){
00626 add_option_seen(O_mno_sse4a);
00627 toggle(&sse4a, TRUE);
00628 }else if (!strncasecmp(cp, "sse4a=off", 10)){
00629 add_option_seen(O_mno_sse4a);
00630 toggle(&sse4a, FALSE);
00631 }
00632 #endif
00633 break;
00634 }
00635
00636
00637 while ( *cp != 0 && *cp != ':' ) ++cp;
00638 if ( *cp == ':' ) ++cp;
00639 }
00640 }
00641
00642
00643
00644
00645
00646
00647
00648
00649
00650
00651
00652 void
00653 Check_Target ( void )
00654 {
00655 int opt_id;
00656 int opt_val;
00657
00658 if ( debug ) {
00659 fprintf ( stderr, "Check_Target ABI=%d ISA=%d Processor=%d\n",
00660 abi, isa, proc );
00661 }
00662
00663 #ifdef TARG_X8664
00664 if (target_cpu == NULL) {
00665 set_cpu ("auto", M_ARCH);
00666 }
00667
00668
00669 Get_x86_ISA();
00670 #endif
00671
00672 if (abi == UNDEFINED) {
00673 #ifdef TARG_IA64
00674 toggle(&abi, ABI_I64);
00675 add_option_seen ( O_i64 );
00676 #elif TARG_IA32
00677 toggle(&abi, ABI_IA32);
00678 add_option_seen ( O_ia32 );
00679 #elif TARG_SL
00680 toggle(&abi, ABI_N32);
00681 add_option_seen ( O_n32 );
00682 #elif TARG_MIPS
00683 toggle(&abi, ABI_64);
00684 add_option_seen ( O_64 );
00685 #elif TARG_X8664
00686
00687 if (target_supported_abi == ABI_N32) {
00688 abi = ABI_N32;
00689 } else if (target_supported_abi == ABI_64) {
00690 abi = (get_platform_abi() == ABI_N32) ?
00691 ABI_N32 : target_supported_abi;
00692 } else if (target_supported_abi == UNDEFINED) {
00693 abi = (get_platform_abi() == ABI_64) ? ABI_64 : ABI_N32;
00694 } else {
00695 internal_error ("illegal target_supported_abi");
00696 }
00697
00698 if (abi == ABI_64)
00699 add_option_seen (O_m64);
00700 else
00701 add_option_seen (O_m32);
00702 #elif TARG_NVISA
00703 abi = get_platform_abi();
00704 if (abi == ABI_64)
00705 add_option_seen (O_m64);
00706 else if (abi == ABI_W64)
00707 add_option_seen (O_w64);
00708 else
00709 add_option_seen (O_m32);
00710 #else
00711 warning("abi should have been specified by driverwrap");
00712
00713 toggle ( &abi, ABI_N32 );
00714 add_option_seen ( O_n32 );
00715 #endif
00716 }
00717
00718 #ifdef TARG_X8664
00719
00720 if (!Get_x86_ISA_extensions())
00721 return;
00722 #endif
00723
00724
00725 if ( isa != UNDEFINED ) {
00726 switch ( abi ) {
00727 #if defined(TARG_MIPS) && !defined(TARG_SL)
00728 case ABI_N32:
00729 if ( isa < ISA_MIPS3 ) {
00730 add_option_seen ( O_mips3 );
00731 warning ( "ABI specification %s conflicts with ISA "
00732 "specification %s: defaulting ISA to mips3",
00733 get_toggle_name (&abi),
00734 get_toggle_name (&isa) );
00735 option_name = get_option_name ( O_mips3 );
00736 isa = UNDEFINED;
00737 toggle ( &isa, ISA_MIPS3 );
00738 }
00739 break;
00740
00741 case ABI_64:
00742 if ( isa < ISA_MIPS3 ) {
00743
00744 if ( proc == UNDEFINED || proc >= PROC_R5K ) {
00745 opt_id = O_mips4;
00746 opt_val = ISA_MIPS4;
00747 add_option_seen ( O_mips4 );
00748 } else {
00749 opt_id = O_mips3;
00750 opt_val = ISA_MIPS3;
00751 add_option_seen ( O_mips3 );
00752 }
00753 warning ( "ABI specification %s conflicts with ISA "
00754 "specification %s: defaulting ISA to mips%d",
00755 get_toggle_name (&abi),
00756 get_toggle_name (&isa),
00757 opt_val );
00758 option_name = get_option_name ( opt_id );
00759 isa = UNDEFINED;
00760 toggle ( &isa, opt_val );
00761 }
00762 break;
00763 #endif
00764 }
00765
00766 } else {
00767
00768
00769 switch ( abi ) {
00770 #ifdef TARG_SL
00771 case ABI_N32:
00772 case ABI_64:
00773 opt_val = ISA_MIPS4;
00774 opt_id = O_mips4;
00775 toggle ( &isa, opt_val );
00776 add_option_seen ( opt_id );
00777 option_name = get_option_name ( opt_id );
00778 break;
00779 #elif TARG_MIPS
00780 case ABI_N32:
00781 case ABI_64:
00782 if (default_isa == ISA_MIPS3) {
00783 opt_val = ISA_MIPS3;
00784 opt_id = O_mips3;
00785 }
00786 else if (default_isa == ISA_MIPS4) {
00787 opt_val = ISA_MIPS4;
00788 opt_id = O_mips4;
00789 }
00790 else {
00791 opt_val = ISA_MIPS64;
00792 opt_id = O_mips64;
00793 }
00794 toggle ( &isa, opt_val );
00795 add_option_seen ( opt_id );
00796 option_name = get_option_name ( opt_id );
00797 break;
00798 #elif TARG_X8664
00799 case ABI_N32:
00800 case ABI_64:
00801 opt_val = ISA_X8664;
00802 toggle ( &isa, opt_val );
00803 break;
00804 #elif TARG_NVISA
00805 case ABI_N32:
00806 case ABI_64:
00807 case ABI_W64:
00808 opt_val = ISA_COMPUTE_10;
00809 toggle ( &isa, opt_val );
00810 break;
00811 #endif
00812 case ABI_I32:
00813 case ABI_I64:
00814 opt_val = ISA_IA641;
00815 toggle ( &isa, opt_val );
00816 break;
00817 case ABI_IA32:
00818 opt_val = ISA_IA32;
00819 toggle ( &isa, opt_val );
00820 break;
00821 }
00822 }
00823 if (isa == UNDEFINED) {
00824 internal_error ("isa should have been defined by now");
00825 }
00826
00827
00828 if ( proc != UNDEFINED ) {
00829 switch ( abi ) {
00830 #ifdef TARG_MIPS
00831 case ABI_N32:
00832 case ABI_64:
00833 #ifndef TARG_SL
00834 if ( proc < PROC_R4K ) {
00835 warning ( "ABI specification %s conflicts with processor "
00836 "specification %s: defaulting processor to r10000",
00837 get_toggle_name (&abi),
00838 get_toggle_name (&proc) );
00839 option_name = get_option_name ( O_r10000 );
00840 proc = UNDEFINED;
00841 add_option_seen ( O_r10000 );
00842 toggle ( &proc, PROC_R10K );
00843 }
00844 #endif
00845 break;
00846 #endif
00847 }
00848 }
00849
00850
00851 if ( proc != UNDEFINED ) {
00852 switch ( isa ) {
00853 #if defined(TARG_MIPS) && !defined(TARG_SL)
00854 case ISA_MIPS1:
00855
00856 break;
00857
00858 case ISA_MIPS2:
00859 case ISA_MIPS3:
00860 if ( proc < PROC_R4K ) {
00861 warning ( "ISA specification %s conflicts with processor "
00862 "specification %s: defaulting processor to r10000",
00863 get_toggle_name (&isa),
00864 get_toggle_name (&proc) );
00865 add_option_seen ( O_r10000 );
00866 proc = UNDEFINED;
00867 option_name = get_option_name ( O_r10000 );
00868 toggle ( &proc, PROC_R10K );
00869 }
00870 break;
00871
00872 case ISA_MIPS4:
00873 if ( proc < PROC_R5K ) {
00874 warning ( "ISA specification %s conflicts with processor "
00875 "specification %s: defaulting processor to r10000",
00876 get_toggle_name (&isa),
00877 get_toggle_name (&proc) );
00878 add_option_seen ( O_r10000 );
00879 proc = UNDEFINED;
00880 option_name = get_option_name ( O_r10000 );
00881 toggle ( &proc, PROC_R10K );
00882 }
00883 break;
00884 #endif
00885 }
00886 }
00887 else if (default_proc != UNDEFINED) {
00888
00889 opt_id = 0;
00890 #if defined(TARG_MIPS) && !defined(TARG_SL)
00891 switch (default_proc) {
00892 case PROC_R4K:
00893 if (isa <= ISA_MIPS3) {
00894 opt_id = O_r4000;
00895 }
00896 break;
00897 case PROC_R5K:
00898 opt_id = O_r5000;
00899 break;
00900 case PROC_R8K:
00901 opt_id = O_r8000;
00902 break;
00903 case PROC_R10K:
00904 opt_id = O_r10000;
00905 break;
00906 }
00907 #endif
00908 if (abi == ABI_I64 || abi == ABI_IA32) {
00909 opt_id = 0;
00910 }
00911 if (opt_id != 0) {
00912 add_option_seen ( opt_id );
00913 option_name = get_option_name ( opt_id );
00914 toggle ( &proc, default_proc);
00915 }
00916 }
00917
00918 if ( debug ) {
00919 fprintf ( stderr, "Check_Target done; ABI=%d ISA=%d Processor=%d\n",
00920 abi, isa, proc );
00921 }
00922 }
00923
00924
00925
00926
00927
00928
00929
00930
00931
00932
00933 static void
00934 toggle_inline_normal(void)
00935 {
00936 if (inline_t == UNDEFINED)
00937 inline_t = TRUE;
00938 }
00939
00940
00941
00942 void
00943 toggle_inline_on(void)
00944 {
00945 if (inline_t == FALSE) {
00946 warning ("-noinline or -INLINE:=off has been seen, %s ignored",
00947 option_name);
00948 }
00949 else {
00950
00951 inline_t = TRUE;
00952 inline_on_seen = TRUE;
00953 }
00954 }
00955
00956
00957
00958 static void
00959 toggle_inline_off(void)
00960 {
00961 if (inline_on_seen == TRUE) {
00962 warning ("Earlier request for inline processing has been overridden by %s",
00963 option_name);
00964 }
00965 inline_t = FALSE;
00966 }
00967
00968 void
00969 Process_Profile_Arcs( void )
00970 {
00971 if (strncmp (option_name, "-fprofile-arcs", 14) == 0)
00972 add_string_option (O_OPT_, "profile_arcs=true");
00973 }
00974
00975 void
00976 Process_Test_Coverage( void )
00977 {
00978 if (strncmp (option_name, "-ftest-coverage", 15) == 0)
00979 add_string_option (O_CG_, "test_coverage=true");
00980 }
00981
00982
00983 void
00984 Process_Inline ( void )
00985 {
00986 int more_symbols = TRUE;
00987 char *args = option_name+7;
00988
00989 if (strncmp (option_name, "-noinline", 9) == 0
00990 #ifdef KEY
00991 || strncmp (option_name, "-fno-inline", 11) == 0
00992 #endif
00993 )
00994 toggle_inline_off();
00995 else if (*args == '\0'
00996 #ifdef KEY
00997 || strncmp (option_name, "-finline", 8) == 0
00998 #endif
00999 )
01000
01001 toggle_inline_on();
01002 else do {
01003 char *endc;
01004 *args = ':';
01005 if ((endc = strchr(++args, ':')) == NULL)
01006 more_symbols = FALSE;
01007 else
01008 *endc = '\0';
01009 if (strcasecmp(args, "=off") == 0)
01010 toggle_inline_off();
01011 else if (strcasecmp(args, "=on") == 0)
01012 toggle_inline_on();
01013 else
01014 toggle_inline_normal();
01015 args = endc;
01016 }
01017 while (more_symbols);
01018 }
01019
01020
01021
01022
01023
01024 void dash_F_option(void)
01025 {
01026 if (invoked_lang == L_f77) {
01027 last_phase=earliest_phase(P_ratfor,last_phase);
01028 } else if (invoked_lang == L_CC) {
01029 error("-F is not supported: cannot generate intermediate C code");
01030 } else {
01031 parse_error("-F", "unknown flag");
01032 }
01033 }
01034
01035
01036 void
01037 untoggle (int *obj, int value)
01038
01039 {
01040 *obj = UNDEFINED;
01041 }
01042
01043
01044 static void
01045 change_phase_path (char *arg)
01046 {
01047 char *dir;
01048 char *s;
01049 for (s = arg; s != NULL && *s != NIL && *s != ','; s++)
01050 ;
01051 if (s == NULL || *s == NIL) {
01052 parse_error(option_name, "bad syntax for -Y option");
01053 return;
01054 }
01055 dir = s+1;
01056 if (dir[0] == '~' && (dir[1] == '/' || dir[1] == '\0')) {
01057 char *home = getenv("HOME");
01058 if (home)
01059 dir = concat_strings(home, dir+1);
01060 }
01061 if (!is_directory(dir))
01062 parse_error(option_name, "not a directory");
01063 for (s = arg; *s != ','; s++) {
01064
01065 if (get_phase(*s) == P_NONE) {
01066 parse_error(option_name, "bad phase for -Y option");
01067 } else {
01068 set_phase_dir(get_phase_mask(get_phase(*s)), dir);
01069 #ifdef KEY
01070
01071
01072
01073 if (get_phase(*s) == P_any_fe)
01074 set_phase_dir(get_phase_mask(P_wgen), dir);
01075 #endif
01076 }
01077 }
01078 }
01079
01080
01081
01082 static void
01083 change_last_phase (char *s)
01084 {
01085 phases_t phase;
01086 if (s == NULL || *s == NIL) {
01087 warn_ignored("-H");
01088 } else if ( *(s+1)!=NIL) {
01089 parse_error(option_name, "bad syntax for -H option");
01090 } else if ((phase=get_phase(*s)) == P_NONE) {
01091 parse_error(option_name, "bad phase for -H option");
01092 } else {
01093 last_phase=earliest_phase(phase, last_phase);
01094 }
01095 }
01096
01097 void
01098 save_name (char **obj, char *value)
01099 {
01100 *obj = string_copy(value);
01101 }
01102
01103 static void
01104 check_output_name (char *name)
01105 {
01106 if (name == NULL) return;
01107 #if defined(TARG_NVISA)
01108
01109 if (get_source_kind(name) == S_s)
01110 return;
01111
01112 if (option_was_seen(O_multicore) && get_source_kind(name) == S_c)
01113 return;
01114 #endif
01115 if (get_source_kind(name) != S_o && file_exists(name)) {
01116 warning("%s %s will overwrite a file that has a source-file suffix", option_name, name);
01117 }
01118 }
01119
01120 #ifdef KEY
01121
01122 void
01123 check_convert_name(char *name)
01124 {
01125 static char *legal_names[] = {
01126 "big_endian",
01127 "big-endian",
01128 "little_endian",
01129 "little-endian",
01130 "native"
01131 };
01132 int i;
01133 for (i = 0; i < ((sizeof legal_names) / (sizeof *legal_names));
01134 i += 1) {
01135 if (0 == strcmp(name, legal_names[i])) {
01136 return;
01137 }
01138 }
01139 parse_error(option_name, "bad conversion name");
01140 }
01141 #endif
01142
01143 void check_opt_tls_model(char* model)
01144 {
01145 if ( strcmp("global-dynamic", model) == 0 ||
01146 strcmp("local-dynamic", model) == 0 ||
01147 strcmp("initial-exec", model) == 0 ||
01148 strcmp("local-exec", model) == 0 )
01149 return;
01150 else
01151 error("`-ftls-model=%s': unknown tls-model option", model);
01152 }
01153
01154 void
01155 check_dashdash (void)
01156 {
01157 #ifndef KEY // Silently ignore dashdash options in case pathcc is called as
01158
01159 if(xpg_flag)
01160 dashdash_flag = 1;
01161 else
01162 error("%s not allowed in non XPG4 environment", option_name);
01163 #endif
01164 }
01165
01166 static char *
01167 Get_Binary_Name ( char *name)
01168 {
01169 char *new;
01170 int len, i;
01171 new = string_copy(name);
01172 len = strlen(new);
01173 for ( i=0; i<len; i++ ) {
01174 if (strncmp(&new[i], ".x.Counts", 9) == 0) {
01175 new[i] = 0;
01176 break;
01177 }
01178 }
01179 return new;
01180 }
01181
01182 void
01183 Process_fbuse ( char *fname )
01184 {
01185 static boolean is_first_count_file = TRUE;
01186 Use_feedback = TRUE;
01187 add_string (count_files, fname);
01188 if (is_first_count_file && (prof_file == NULL))
01189 prof_file = Get_Binary_Name(drop_path(fname));
01190 is_first_count_file = FALSE;
01191 }
01192
01193 void
01194 Process_fb_type ( char* typename )
01195 {
01196 char str[10];
01197 int flag, tmp;
01198 fb_type = string_copy(typename);
01199 sprintf(str,"fb_type=%s",fb_type);
01200 flag = add_string_option (O_OPT_, str);
01201 add_option_seen(flag);
01202
01203 sscanf (typename, "%d", &tmp);
01204 profile_type |= tmp;
01205 }
01206
01207
01208 void
01209 Process_fb_create ( char *fname )
01210 {
01211 int flag;
01212 fb_file = string_copy(fname);
01213
01214 if (instrumentation_invoked == TRUE) {
01215
01216 flag = add_string_option (O_OPT_, "instr_unique_output=on");
01217 }
01218 else {
01219 toggle ( &instrumentation_invoked, TRUE );
01220 flag = add_string_option (O_OPT_, "instr=on:instr_unique_output=on");
01221 }
01222 add_option_seen (flag);
01223 }
01224
01225
01226 void
01227 Process_fb_phase(char *phase)
01228 {
01229 char str[10];
01230 int flag;
01231 fb_phase = string_copy(phase);
01232 sprintf(str,"fb_phase=%s",fb_phase);
01233 flag = add_string_option (O_OPT_, str);
01234 add_option_seen(flag);
01235 }
01236
01237
01238 void
01239 Process_fb_opt ( char *fname )
01240 {
01241 opt_file = string_copy(fname);
01242 toggle ( &instrumentation_invoked, FALSE);
01243 }
01244
01245
01246 void
01247 Process_fbexe ( char *fname )
01248 {
01249 prof_file = string_copy(fname);
01250 }
01251
01252 void
01253 Process_fb_xdir ( char *fname )
01254 {
01255 fb_xdir = string_copy(fname);
01256 }
01257
01258 void
01259 Process_fb_cdir ( char *fname )
01260 {
01261 fb_cdir = string_copy(fname);
01262 }
01263
01264 #ifndef KEY // -dsm no longer supported. Bug 4406.
01265 typedef enum {
01266 DSM_UNDEFINED,
01267 DSM_OFF,
01268 DSM_ON
01269 } DSM_OPTION;
01270
01271 static DSM_OPTION dsm_option=DSM_UNDEFINED;
01272 static DSM_OPTION dsm_clone=DSM_UNDEFINED;
01273 static DSM_OPTION dsm_check=DSM_UNDEFINED;
01274
01275 void
01276 set_dsm_default_options (void)
01277 {
01278 if (dsm_option==DSM_UNDEFINED) dsm_option=DSM_ON;
01279 if (dsm_clone==DSM_UNDEFINED && invoked_lang != L_CC) dsm_clone=DSM_ON;
01280 if (dsm_check==DSM_UNDEFINED) dsm_check=DSM_OFF;
01281 }
01282
01283 void
01284 reset_dsm_default_options (void)
01285 {
01286 dsm_option=DSM_OFF;
01287 dsm_clone=DSM_OFF;
01288 dsm_check=DSM_OFF;
01289 }
01290
01291 void
01292 set_dsm_options (void)
01293 {
01294
01295 if (dsm_option==DSM_ON) {
01296 add_option_seen(O_dsm);
01297 } else {
01298 reset_dsm_default_options();
01299 if (option_was_seen(O_dsm))
01300 set_option_unseen(O_dsm);
01301 }
01302
01303 if (dsm_clone==DSM_ON)
01304 add_option_seen(O_dsm_clone);
01305 else
01306 if (option_was_seen(O_dsm_clone))
01307 set_option_unseen(O_dsm_clone);
01308 if (dsm_check==DSM_ON)
01309 add_option_seen(O_dsm_check);
01310 else
01311 if (option_was_seen(O_dsm_check))
01312 set_option_unseen(O_dsm_check);
01313 }
01314
01315
01316
01317
01318
01319
01320
01321
01322
01323
01324
01325
01326
01327
01328 void
01329 Process_Mp_Group ( char *mp_args )
01330 {
01331 char *cp = mp_args;
01332
01333 if ( debug ) {
01334 fprintf ( stderr, "Process_Mp_Group: %s\n", mp_args );
01335 }
01336
01337 while ( *cp != 0 ) {
01338 switch ( *cp ) {
01339 case 'd':
01340 if ( strncasecmp ( cp, "dsm", 3 ) == 0 &&
01341 (*(cp+3)==':' || *(cp+3)=='\0'))
01342 set_dsm_default_options();
01343 else if ( strncasecmp ( cp, "dsm=on", 6 ) == 0 )
01344 set_dsm_default_options();
01345 else if ( strncasecmp ( cp, "dsm=off", 7 ) == 0 )
01346 reset_dsm_default_options();
01347 else if ( strncasecmp ( cp, "dsm=true", 8 ) == 0 )
01348 set_dsm_default_options();
01349 else if ( strncasecmp ( cp, "dsm=false", 9 ) == 0 )
01350 reset_dsm_default_options();
01351 else
01352 parse_error(option_name, "Unknown -MP: option");
01353 break;
01354 case 'c':
01355 if ( strncasecmp ( cp, "clone", 5 ) == 0) {
01356 if ( *(cp+5) == '=' ) {
01357 if ( strncasecmp ( cp+6, "on", 2 ) == 0 )
01358 dsm_clone=DSM_ON;
01359 else if ( strncasecmp ( cp+6, "off", 3 ) == 0 )
01360 dsm_clone=DSM_OFF;
01361 } else if ( *(cp+5) == ':' || *(cp+5) == '\0' ) {
01362 dsm_clone=DSM_ON;
01363 } else
01364 parse_error(option_name, "Unknown -MP: option");
01365 } else if ( strncasecmp ( cp, "check_reshape", 13 ) == 0) {
01366 if ( *(cp+13) == '=' ) {
01367 if ( strncasecmp ( cp+14, "on", 2 ) == 0 ) {
01368 dsm_check=DSM_ON;
01369 } else if ( strncasecmp ( cp+14, "off", 3 ) == 0 ) {
01370 dsm_check=DSM_OFF;
01371 }
01372 } else if ( *(cp+13) == ':' || *(cp+13) == '\0' ) {
01373 dsm_check=DSM_ON;
01374 } else
01375 parse_error(option_name, "Unknown -MP: option");
01376 }
01377 else
01378 parse_error(option_name, "Unknown -MP: option");
01379 break;
01380 case 'm':
01381 if (strncasecmp (cp, "manual=off", 10) == 0) {
01382 set_option_unseen (O_mp);
01383 reset_dsm_default_options ();
01384 }
01385 else
01386 parse_error(option_name, "Unknown -MP: option");
01387 break;
01388 case 'o':
01389 if (strncasecmp (cp, "open_mp=off", 11) == 0) {
01390 Disable_open_mp = TRUE;
01391 } else if (strncasecmp (cp, "old_mp=off", 10) == 0) {
01392 Disable_old_mp = TRUE;
01393 } else if ((strncasecmp (cp, "open_mp=on", 10) == 0) ||
01394 (strncasecmp (cp, "old_mp=on", 9) == 0)) {
01395
01396 } else {
01397 parse_error(option_name, "Unknown -MP: option");
01398 }
01399 break;
01400 default:
01401 parse_error(option_name, "Unknown -MP: option");
01402 }
01403
01404
01405 while ( *cp != 0 && *cp != ':' ) ++cp;
01406 if ( *cp == ':' ) ++cp;
01407 }
01408
01409 if ( debug ) {
01410 fprintf ( stderr, "Process_Dsm_Group done\n" );
01411 }
01412 }
01413
01414 void
01415 Process_Mp ( void )
01416 {
01417
01418 if ( debug ) {
01419 fprintf ( stderr, "Process_Mp\n" );
01420 }
01421
01422 if (!option_was_seen (O_mp)) {
01423
01424 add_option_seen (O_mp);
01425 }
01426 set_dsm_default_options();
01427
01428 if ( debug ) {
01429 fprintf ( stderr, "Process_Mp done\n" );
01430 }
01431 }
01432
01433 void Process_Cray_Mp (void) {
01434
01435 if (invoked_lang == L_f90) {
01436
01437
01438
01439 }
01440 else error ("-cray_mp applicable only to f90");
01441 }
01442 #endif
01443
01444 void
01445 Process_Promp ( void )
01446 {
01447
01448 if ( debug ) {
01449 fprintf ( stderr, "Process_Promp\n" );
01450 }
01451
01452
01453
01454
01455 if (invoked_lang == L_f77 || invoked_lang == L_f90) {
01456 add_option_seen ( O_promp );
01457 add_option_seen(add_string_option(O_FE_, "endloop_marker=1"));
01458 } else if (invoked_lang == L_cc) {
01459
01460 add_option_seen ( O_promp );
01461 }
01462 if ( debug ) {
01463 fprintf ( stderr, "Process_Promp done\n" );
01464 }
01465 }
01466
01467 void
01468 Process_Tenv_Group ( char *opt_args )
01469 {
01470 if ( debug ) {
01471 fprintf ( stderr, "Process_TENV_Group: %s\n", opt_args );
01472 }
01473
01474
01475 if (strncmp (opt_args, "mcmodel=", 8) == 0) {
01476 set_memory_model (opt_args + 8);
01477 }
01478 }
01479
01480 static int
01481 print_magic_path(const char *base, const char *fname)
01482 {
01483 int m32 = check_for_saved_option("-m32");
01484 char *slash;
01485 char *path;
01486
01487 if (m32) {
01488 char *sfx;
01489
01490 asprintf(&path, "%s/32/%s", base, fname);
01491
01492 if (file_exists(path))
01493 goto good;
01494
01495 if (ends_with(base, "/lib64")) {
01496 asprintf(&path, "%.*s/%s", (int)strlen(base) - 2, base, fname);
01497
01498 if (file_exists(path))
01499 goto good;
01500 }
01501
01502 sfx = get_suffix(fname);
01503
01504 if (sfx != NULL &&
01505 (!strcmp(sfx, "a") || !strcmp(sfx, "o") || !strcmp(sfx, "so")))
01506 goto bad;
01507
01508 if ((slash = strrchr(path, '/')) && strstr(slash, ".so."))
01509 goto bad;
01510 }
01511
01512 asprintf(&path, "%s/%s", base, fname);
01513
01514 if (file_exists(path))
01515 goto good;
01516
01517 bad:
01518 return 0;
01519
01520 good:
01521 puts(path);
01522 return 1;
01523 }
01524
01525 static int
01526 print_phase_path(phases_t phase, const char *fname)
01527 {
01528 return print_magic_path(get_phase_dir(phase), fname);
01529 }
01530
01531 static int print_relative_path(const char *s, const char *fname)
01532 {
01533 char *root_prefix = directory_path(get_executable_dir());
01534 char *base;
01535
01536 asprintf(&base, "%s/%s", root_prefix, s);
01537 return print_magic_path(base, fname);
01538 }
01539
01540
01541
01542 void
01543 print_file_path (char *fname, int exe)
01544 {
01545
01546
01547
01548
01549
01550
01551 #ifdef PSC_TO_OPEN64
01552 if (print_relative_path("lib/" OPEN64_FULL_VERSION, fname))
01553 #endif
01554 return;
01555
01556 if (print_phase_path(P_be, fname))
01557 return;
01558
01559 if (print_phase_path(P_library, fname))
01560 return;
01561
01562 if (print_phase_path(P_gcpp, fname))
01563 return;
01564
01565 if (print_phase_path(P_gas, fname))
01566 return;
01567
01568 if (print_phase_path(P_alt_library, fname))
01569 return;
01570
01571
01572 int m32 = check_for_saved_option("-m32");
01573 char *argv[4];
01574 argv[0] = "gcc";
01575 argv[1] = m32 ? "-m32" : "-m64";
01576 asprintf(&argv[2], "-print-%s-name=%s", exe ? "prog" : "file", fname);
01577 argv[3] = NULL;
01578
01579 execlp(argv[0], argv[1], argv[2], NULL);
01580 fprintf(stderr, "could not execute %s: %m\n", argv[0]);
01581 exit(1);
01582 }
01583
01584 void
01585 print_multi_lib ()
01586 {
01587 char *argv[3];
01588 argv[0] = "gcc";
01589 asprintf(&argv[1], "-print-multi-lib");
01590 argv[2] = NULL;
01591
01592 execlp(argv[0], argv[1], NULL);
01593 fprintf(stderr, "could not execute %s: %m\n", argv[0]);
01594 exit(1);
01595 }
01596
01597 mem_model_t mem_model = M_SMALL;
01598 char *mem_model_name = NULL;
01599
01600 void
01601 set_memory_model(char *model)
01602 {
01603 if (strcmp(model, "small") == 0) {
01604 mem_model = M_SMALL;
01605 mem_model_name = "small";
01606 }
01607 else if (strcmp(model, "medium") == 0) {
01608 mem_model = M_MEDIUM;
01609 mem_model_name = "medium";
01610 }
01611 else if (strcmp(model, "large") == 0) {
01612 mem_model = M_LARGE;
01613 mem_model_name = "large";
01614 }
01615 else if (strcmp(model, "kernel") == 0) {
01616 mem_model = M_KERNEL;
01617 mem_model_name = "kernel";
01618 } else {
01619 error("unknown memory model \"%s\"", model);
01620 mem_model_name = NULL;
01621 }
01622 }
01623
01624 static struct
01625 {
01626 char *cpu_name;
01627 char *target_name;
01628 int abi;
01629 boolean supports_sse2;
01630 boolean prefers_sse3;
01631 boolean supports_sse4a;
01632 } supported_cpu_types[] = {
01633 { "any_64bit_x86", "anyx86", ABI_64, TRUE, FALSE, FALSE},
01634 { "any_32bit_x86", "anyx86", ABI_N32, FALSE, FALSE, FALSE},
01635 { "i386", "anyx86", ABI_N32, FALSE, FALSE, FALSE},
01636 { "i486", "anyx86", ABI_N32, FALSE, FALSE, FALSE},
01637 { "i586", "anyx86", ABI_N32, FALSE, FALSE, FALSE},
01638 { "athlon", "athlon", ABI_N32, FALSE, FALSE, FALSE},
01639 { "athlon-mp", "athlon", ABI_N32, FALSE, FALSE, FALSE},
01640 { "athlon-xp", "athlon", ABI_N32, FALSE, FALSE, FALSE},
01641 { "athlon64", "athlon64", ABI_64, TRUE, FALSE, FALSE},
01642 { "athlon64fx", "opteron", ABI_64, TRUE, FALSE, FALSE},
01643 { "turion", "athlon64", ABI_64, TRUE, FALSE, FALSE},
01644 { "i686", "pentium4", ABI_N32, FALSE, FALSE, FALSE},
01645 { "ia32", "pentium4", ABI_N32, TRUE, FALSE, FALSE},
01646 { "k7", "athlon", ABI_N32, FALSE, FALSE, FALSE},
01647 { "k8", "opteron", ABI_64, TRUE, FALSE, FALSE},
01648 { "opteron", "opteron", ABI_64, TRUE, FALSE, FALSE},
01649 { "pentium4", "pentium4", ABI_N32, TRUE, FALSE, FALSE},
01650 { "xeon", "xeon", ABI_N32, TRUE, FALSE, FALSE},
01651 { "em64t", "em64t", ABI_64, TRUE, TRUE, FALSE},
01652 { "core", "core", ABI_64, TRUE, TRUE, FALSE},
01653 { "wolfdale", "wolfdale", ABI_64, TRUE, TRUE, FALSE},
01654 { "barcelona","barcelona", ABI_64, TRUE, TRUE, TRUE},
01655 { NULL, NULL, },
01656 };
01657
01658 char *target_cpu = NULL;
01659
01660
01661 static int
01662 get_platform_abi()
01663 {
01664 #ifdef _WIN32
01665 #ifdef WIN64
01666 return ABI_W64;
01667 #endif
01668 #endif
01669
01670 struct utsname u;
01671
01672 uname(&u);
01673 if (!strcmp(u.machine, "x86_64"))
01674 return ABI_64;
01675 return ABI_N32;
01676 }
01677
01678
01679 static int
01680 get_num_after_colon (char *str)
01681 {
01682 char *p;
01683 int num;
01684
01685 p = strchr(str, ':');
01686 if (p == NULL) {
01687 error ("cannot parse /proc/cpuinfo: missing colon");
01688 }
01689 p++;
01690 if (sscanf(p, "%d", &num) == 0) {
01691 error ("cannot parse /proc/cpuinfo: missing number after colon");
01692 }
01693 return num;
01694 }
01695
01696
01697
01698 static char *
01699 get_default_cpu_name (char *msg)
01700 {
01701 char *cpu_name = NULL;
01702 char *abi_name = NULL;
01703
01704 if (get_platform_abi() == ABI_64) {
01705 cpu_name = "anyx86";
01706 abi_name = "64-bit";
01707 } else {
01708 cpu_name = "anyx86";
01709 abi_name = "32-bit";
01710 }
01711
01712
01713 if (msg != NULL)
01714 warning("%s, defaulting to basic %s x86.", msg, abi_name);
01715
01716 return cpu_name;
01717 }
01718
01719
01720
01721 char *
01722 get_auto_cpu_name ()
01723 {
01724 FILE *f;
01725 char buf[256];
01726 char *cpu_name = NULL;
01727 char *cpu_name_64bit = NULL;
01728 int cpu_family = -1;
01729 int model = -1;
01730 boolean amd = FALSE;
01731 boolean intel = FALSE;
01732
01733 f = fopen("/proc/cpuinfo", "r");
01734 if (f == NULL) {
01735 return get_default_cpu_name("cannot read /proc/cpuinfo");
01736 }
01737
01738
01739 while (fgets(buf, 256, f) != NULL) {
01740
01741 if (!strncmp("vendor_id", buf, 9)) {
01742 if (strstr(buf, "AuthenticAMD")) {
01743 amd = TRUE;
01744 } else if (strstr(buf, "GenuineIntel")) {
01745 intel = TRUE;
01746 } else {
01747 return get_default_cpu_name("unsupported vendor_id in /proc/cpuinfo");
01748 }
01749
01750
01751 } else if (!strncmp("cpu family", buf, 10)) {
01752 cpu_family = get_num_after_colon(buf);
01753
01754
01755 } else if (!strncmp("model\t", buf, 6) ||
01756 !strncmp("model ", buf, 8)) {
01757 model = get_num_after_colon(buf);
01758
01759
01760 } else if (!strncmp("model name", buf, 10)) {
01761 if (strstr(buf, "Opteron")) {
01762 cpu_name = "opteron";
01763 } else if (strstr(buf, "Athlon")) {
01764 if (strstr(buf, "64"))
01765 cpu_name = "athlon64";
01766 else if (strstr(buf, "MP"))
01767 cpu_name = "athlon-mp";
01768 else
01769 cpu_name = "athlon";
01770 } else if (strstr(buf, "Turion")) {
01771 cpu_name = "turion";
01772 } else if (strstr(buf, "Pentium") &&
01773 strstr(buf, "4")) {
01774 cpu_name = "pentium4";
01775 } else if (strstr(buf, "Xeon")) {
01776 cpu_name = "xeon";
01777 cpu_name_64bit = "em64t";
01778 }
01779 } else if (strstr(buf, "GenuineIntel")) {
01780 intel = TRUE;
01781 } else if (strstr(buf, "AuthenticAMD")) {
01782 amd = TRUE;
01783 }
01784 }
01785
01786 fclose(f);
01787
01788
01789
01790
01791 if (cpu_name == NULL ||
01792
01793 !strcmp(cpu_name, "xeon")) {
01794 char *abi_name;
01795 if (intel == TRUE) {
01796 switch (cpu_family) {
01797 case 4:
01798 case 5:
01799 return "i386";
01800
01801 case 6:
01802 if (model == 23)
01803 return "wolfdale";
01804
01805 if (model == 15)
01806 return "core";
01807
01808
01809
01810 return "i386";
01811
01812 case 15:
01813 cpu_name = "xeon";
01814 cpu_name_64bit = "em64t";
01815 break;
01816 }
01817
01818 } else if (amd == TRUE) {
01819 switch (cpu_family) {
01820 case 4:
01821 case 5:
01822 case 6:
01823 return "athlon";
01824 case 15:
01825 return "opteron";
01826 case 16:
01827 return "barcelona";
01828 }
01829 }
01830
01831 if (cpu_name == NULL) {
01832 return get_default_cpu_name("cannot deduce a supported CPU name"
01833 " from /proc/cpuinfo");
01834 }
01835 }
01836
01837 if (cpu_name == NULL) {
01838 error("cpu_name NULL");
01839 return NULL;
01840 }
01841
01842
01843 if (cpu_name_64bit != NULL) {
01844 if (get_platform_abi() == ABI_64) {
01845 cpu_name = cpu_name_64bit;
01846 }
01847 }
01848
01849 return cpu_name;
01850 }
01851
01852
01853 static void
01854 set_cpu(char *name, m_flag flag_type)
01855 {
01856
01857
01858 if (parsing_default_options &&
01859 target_cpu != NULL) {
01860 drop_option = TRUE;
01861 return;
01862 }
01863
01864
01865
01866
01867 if (target_cpu != NULL &&
01868 strcmp(target_cpu, name)) {
01869 warning("CPU target %s conflicts with %s; using latter (%s)",
01870 get_toggle_name((int*)&target_cpu), name, name);
01871
01872
01873 target_cpu = NULL;
01874 }
01875 target_cpu = name;
01876 add_toggle_name((int*)&target_cpu, name);
01877 }
01878
01879 #ifdef TARG_X8664
01880 static void
01881 Get_x86_ISA ()
01882 {
01883 char *name = NULL;
01884
01885
01886 if (!strcmp(target_cpu, "auto")) {
01887 target_cpu = get_auto_cpu_name();
01888 if (target_cpu == NULL)
01889 return;
01890 }
01891 if (!strcmp(target_cpu, "anyx86")) {
01892
01893 if (abi == UNDEFINED) {
01894 if (get_platform_abi() == ABI_64) {
01895 abi = ABI_64;
01896 add_option_seen(O_m64);
01897 } else {
01898 abi = ABI_N32;
01899 add_option_seen(O_m32);
01900 }
01901 }
01902 switch (abi) {
01903 case ABI_N32: name = "any_32bit_x86"; break;
01904 case ABI_64: name = "any_64bit_x86"; break;
01905 default: internal_error("illegal ABI");
01906 }
01907 } else
01908 name = target_cpu;
01909
01910 for (int i = 0; supported_cpu_types[i].cpu_name; i++) {
01911 if (strcmp(name, supported_cpu_types[i].cpu_name) == 0) {
01912 target_cpu = supported_cpu_types[i].target_name;
01913 target_supported_abi = supported_cpu_types[i].abi;
01914 target_supports_sse2 = supported_cpu_types[i].supports_sse2;
01915 target_prefers_sse3 = supported_cpu_types[i].prefers_sse3;
01916 target_supports_sse4a = supported_cpu_types[i].supports_sse4a;
01917 break;
01918 }
01919 }
01920
01921 if (target_cpu == NULL) {
01922 error("unknown CPU type \"%s\"", name);
01923 }
01924 }
01925
01926
01927 static boolean
01928 Get_x86_ISA_extensions ()
01929 {
01930
01931
01932 if (sse2 == TRUE &&
01933 !target_supports_sse2) {
01934 error("Target processor does not support SSE2.");
01935 return FALSE;
01936 }
01937
01938 if (sse4a == TRUE &&
01939 !target_supports_sse4a) {
01940 error("Target processor does not support SSE4a.");
01941 return FALSE;
01942 }
01943
01944 if (abi == UNDEFINED) {
01945 internal_error("Get_x86_ISA_extensions: ABI undefined\n");
01946 return FALSE;
01947 }
01948
01949
01950 if (abi == ABI_64) {
01951 if (sse2 == FALSE) {
01952 warning("SSE2 required for 64-bit ABI; enabling SSE2.");
01953 }
01954 sse2 = TRUE;
01955 } else {
01956
01957 if (sse2 == UNDEFINED &&
01958 target_supports_sse2) {
01959 sse2 = TRUE;
01960 }
01961 }
01962
01963
01964 if (target_prefers_sse3 &&
01965 sse2 != FALSE &&
01966 sse3 != FALSE) {
01967 sse2 = TRUE;
01968 sse3 = TRUE;
01969 }
01970
01971 #if 0 //temporarily disable it until we have assembler and linker support for
01972
01973
01974 if (target_supports_sse4a &&
01975 sse2 != FALSE &&
01976 sse4a != FALSE){
01977 sse2 = TRUE;
01978 sse4a = TRUE;
01979 }
01980 #endif
01981
01982
01983 return TRUE;
01984 }
01985 #endif
01986
01987 #ifdef KEY
01988 static void
01989 accumulate_isystem(char *optargs)
01990 {
01991 if (!isystem_dirs) {
01992 isystem_dirs = init_string_list();
01993 }
01994 # define INCLUDE_EQ "-include="
01995 char *temp = malloc(strlen(optargs) + sizeof INCLUDE_EQ);
01996 add_string(isystem_dirs, strcat(strcpy(temp, INCLUDE_EQ), optargs));
01997 }
01998 #endif
01999
02000 #include "opt_action.i"