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
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062 #include "defs.h"
00063 #include "config.h"
00064 #include "config_asm.h"
00065 #include "config_debug.h"
00066 #include "config_targ_opt.h"
00067 #include "config_opt.h"
00068 #include "erglob.h"
00069 #include "tracing.h"
00070 #include "mtypes.h"
00071 #include "stab.h"
00072 #include "targ_sim.h"
00073
00074 #if defined(FRONT_END_C) || defined(FRONT_END_CPLUSPLUS)
00075 typedef unsigned char an_integer_kind;
00076 #include "c_int_model.h"
00077 #endif
00078
00079
00080
00081 BOOL ARCH_generate_nor = FALSE;
00082 BOOL ARCH_mask_shift_counts = FALSE;
00083
00084
00085 TARGET_ABI Target_ABI = ABI_UNDEF;
00086 TARGET_PROCESSOR Target = TARGET_UNDEF;
00087 TARGET_ISA Target_ISA = TARGET_ISA_UNDEF;
00088
00089
00090
00091
00092 CLASS_INDEX Spill_Int_Mtype = 0;
00093 CLASS_INDEX Spill_Float_Mtype = 0;
00094
00095
00096
00097
00098 CLASS_INDEX Max_Int_Mtype = 0;
00099 CLASS_INDEX Max_Uint_Mtype = 0;
00100 CLASS_INDEX Def_Int_Mtype = 0;
00101 CLASS_INDEX Def_Uint_Mtype = 0;
00102
00103
00104 BOOL Use_32_Bit_Pointers = FALSE;
00105
00106
00107 INT Pointer_Size;
00108 CLASS_INDEX Pointer_Mtype;
00109 CLASS_INDEX Pointer_Mtype2;
00110
00111
00112 TYPE_ID Pointer_type;
00113 TYPE_ID Pointer_type2;
00114 TYPE_ID Boolean_type;
00115 TYPE_ID Boolean_type2;
00116 TYPE_ID Integer_type;
00117
00118
00119 INT Comparison_Result_Size;
00120 CLASS_INDEX Comparison_Result_Mtype;
00121
00122
00123
00124
00125 char *AS_ADDRESS;
00126 char *AS_ADDRESS_UNALIGNED;
00127
00128
00129 BOOL Char_Type_Is_Signed = FALSE;
00130
00131
00132 static BOOL Target_int64;
00133
00134
00135 #define FPX_DEF EXC_ALL
00136 INT16 FP_Exception_Enable_Max = FPX_DEF;
00137 INT16 FP_Exception_Enable_Min = 0;
00138
00139 INT32 Align_Instructions = 0;
00140 BOOL Avoid_TFP_blikely_bug = FALSE;
00141 BOOL Avoid_TFP_blikely_bug_overridden = FALSE;
00142
00143
00144 BOOL Force_IEEE_Comparisons = TRUE;
00145
00146
00147
00148 BOOL WHIRL_Return_Val_On = TRUE;
00149 BOOL WHIRL_Mldid_Mstid_On = TRUE;
00150 BOOL WHIRL_Return_Info_On = TRUE;
00151
00152
00153
00154
00155
00156
00157
00158
00159
00160
00161
00162
00163
00164
00165 INT16 Symbolic_Debug_Mode;
00166 INT16 Max_Symbolic_Debug_Mode;
00167
00168
00169
00170
00171
00172
00173
00174
00175
00176
00177 BOOL Allow_Word_Aligned_Doubles = FALSE;
00178
00179
00180 BOOL Generate_Position_Independent_Code = FALSE;
00181
00182
00183 BOOL Split_64_Bit_Int_Ops = FALSE;
00184
00185
00186 BOOL Split_Quad_Ops = TRUE;
00187
00188
00189 BOOL Simulate_32_Bit_Interface = FALSE;
00190
00191
00192 BOOL No_Quad_Aligned_Branch = FALSE;
00193
00194
00195 BOOL Only_Unsigned_64_Bit_Ops = TRUE;
00196
00197 BOOL Has_GP_Groups = FALSE;
00198
00199
00200
00201
00202 BOOL Use_Load_Store_Offset = FALSE;
00203
00204 #if defined (FRONT_END_C) || defined (FRONT_END_CPLUSPLUS)
00205
00206 PREG_NUM Map_Reg_To_Preg [] = {
00207
00208 0x000, 0x001, 0x002, 0x003, 0x004, 0x005, 0x006, 0x007,
00209 0x008, 0x009, 0x00a, 0x00b, 0x00c, 0x00d, 0x00e, 0x00f,
00210 0x010, 0x011, 0x012, 0x013, 0x014, 0x015, 0x016, 0x017,
00211 0x018, 0x019, 0x01a, 0x01b, 0x01c, 0x01d, 0x01e, 0x01f,
00212 0x020, 0x021, 0x022, 0x023, 0x024, 0x025, 0x026, 0x027,
00213 0x028, 0x029, 0x02a, 0x02b, 0x02c, 0x02d, 0x02e, 0x02f,
00214 0x030, 0x031, 0x032, 0x033, 0x034, 0x035, 0x036, 0x037,
00215 0x038, 0x039, 0x03a, 0x03b, 0x03c, 0x03d, 0x03e, 0x03f,
00216 0x040, 0x041, 0x042, 0x043, 0x044, 0x045, 0x046, 0x047,
00217 0x048, 0x049, 0x04a, 0x04b, 0x04c, 0x04d, 0x04e, 0x04f,
00218 0x050, 0x051, 0x052, 0x053, 0x054, 0x055, 0x056, 0x057,
00219 0x058, 0x059, 0x05a, 0x05b, 0x05c, 0x05d, 0x05e, 0x05f,
00220 0x060, 0x061, 0x062, 0x063, 0x064, 0x065, 0x066, 0x067,
00221 0x068, 0x069, 0x06a, 0x06b, 0x06c, 0x06d, 0x06e, 0x06f,
00222 0x070, 0x071, 0x072, 0x073, 0x074, 0x075, 0x076, 0x077,
00223 0x078, 0x079, 0x07a, 0x07b, 0x07c, 0x07d, 0x07e, 0x07f,
00224
00225 0x080, 0x081, 0x082, 0x083, 0x084, 0x085, 0x086, 0x087,
00226 0x088, 0x089, 0x08a, 0x08b, 0x08c, 0x08d, 0x08e, 0x08f,
00227 0x090, 0x091, 0x092, 0x093, 0x094, 0x095, 0x096, 0x097,
00228 0x098, 0x099, 0x09a, 0x09b, 0x09c, 0x09d, 0x09e, 0x09f,
00229 0x0a0, 0x0a1, 0x0a2, 0x0a3, 0x0a4, 0x0a5, 0x0a6, 0x0a7,
00230 0x0a8, 0x0a9, 0x0aa, 0x0ab, 0x0ac, 0x0ad, 0x0ae, 0x0af,
00231 0x0b0, 0x0b1, 0x0b2, 0x0b3, 0x0b4, 0x0b5, 0x0b6, 0x0b7,
00232 0x0b8, 0x0b9, 0x0ba, 0x0bb, 0x0bc, 0x0bd, 0x0be, 0x0bf,
00233 0x0c0, 0x0c1, 0x0c2, 0x0c3, 0x0c4, 0x0c5, 0x0c6, 0x0c7,
00234 0x0c8, 0x0c9, 0x0ca, 0x0cb, 0x0cc, 0x0cd, 0x0ce, 0x0cf,
00235 0x0d0, 0x0d1, 0x0d2, 0x0d3, 0x0d4, 0x0d5, 0x0d6, 0x0d7,
00236 0x0d8, 0x0d9, 0x0da, 0x0db, 0x0dc, 0x0dd, 0x0de, 0x0df,
00237 0x0e0, 0x0e1, 0x0e2, 0x0e3, 0x0e4, 0x0e5, 0x0e6, 0x0e7,
00238 0x0e8, 0x0e9, 0x0ea, 0x0eb, 0x0ec, 0x0ed, 0x0ee, 0x0ef,
00239 0x0f0, 0x0f1, 0x0f2, 0x0f3, 0x0f4, 0x0f5, 0x0f6, 0x0f7,
00240 0x0f8, 0x0f9, 0x0fa, 0x0fb, 0x0fc, 0x0fd, 0x0fe, 0x0ff,
00241
00242 -1, -1, -1, -1, -1, -1, -1, -1,
00243 -1, -1, -1, -1, -1, -1, -1, -1,
00244 -1, -1, -1, -1, -1, -1, -1, -1,
00245 -1, -1, -1, -1, -1, -1, -1, -1,
00246 -1, -1, -1, -1, -1, -1, -1, -1,
00247 -1, -1, -1, -1, -1, -1, -1, -1,
00248 -1, -1, -1, -1, -1, -1, -1, -1,
00249 -1, -1, -1, -1, -1, -1, -1, -1,
00250
00251 0x100, 0x101, 0x102, 0x103, 0x104, 0x105, 0x106, 0x107,
00252
00253 0x07f, 0x07e, 0x07d, 0x07c, 0x07b, 0x07a, 0x079, 0x078,
00254
00255 -1
00256 };
00257
00258 #endif
00259
00260
00261
00262
00263
00264
00265
00266
00267
00268
00269
00270 static struct bnm {
00271 char name[16];
00272 } bnb[4];
00273 static INT16 bnb_used = 0;
00274
00275 #ifndef MONGOOSE_BE
00276 char *
00277 Abi_Name ( TARGET_ABI b)
00278 {
00279 char *r;
00280
00281 switch ( b ) {
00282 case ABI_I32: return "i32";
00283 case ABI_I64: return "i64";
00284 default:
00285 r = bnb[bnb_used].name;
00286 bnb_used = (bnb_used + 1) % 4;
00287 sprintf (r, "ABI_%d", b);
00288 return r;
00289 }
00290 }
00291 #endif
00292
00293 char *
00294 Isa_Name ( TARGET_ISA b)
00295 {
00296 char *r;
00297
00298 switch ( b ) {
00299 default:
00300 r = bnb[bnb_used].name;
00301 bnb_used = (bnb_used + 1) % 4;
00302 sprintf (r, "ISA_%d", b);
00303 return r;
00304 }
00305 }
00306
00307 char *
00308 Targ_Name ( TARGET_PROCESSOR b)
00309 {
00310 char *r;
00311
00312 switch ( b ) {
00313 case TARGET_ITANIUM: return "Itanium";
00314 case TARGET_ITANIUM2: return "Itanium2";
00315 default:
00316 r = bnb[bnb_used].name;
00317 bnb_used = (bnb_used + 1) % 4;
00318 sprintf (r, "PROCESSOR_%d", b);
00319 return r;
00320 }
00321 }
00322
00323
00324
00325
00326
00327
00328
00329
00330
00331
00332 void
00333 Preconfigure_Target ( void )
00334 {
00335 #if defined(linux)
00336 Target_Byte_Sex = LITTLE_ENDIAN;
00337 #else
00338 Target_Byte_Sex = BIG_ENDIAN;
00339 #endif
00340 Same_Byte_Sex = ( Target_Byte_Sex == Host_Byte_Sex );
00341
00342 return;
00343 }
00344
00345
00346
00347
00348
00349
00350
00351
00352
00353
00354
00355
00356
00357
00358
00359
00360
00361
00362
00363
00364 static void
00365 Prepare_Target ( void )
00366 {
00367 TARGET_ISA isa_default = TARGET_ISA_UNDEF;
00368 TARGET_PROCESSOR targ_default = TARGET_UNDEF;
00369
00370
00371 if ( ABI_Name != NULL ) {
00372 if ( strcmp ( ABI_Name, "i32" ) == 0 ) {
00373 Target_ABI = ABI_I32;
00374 isa_default = TARGET_ISA_I1;
00375 targ_default = TARGET_ITANIUM2;
00376 } else if ( strcmp ( ABI_Name, "i64" ) == 0 ) {
00377 Target_ABI = ABI_I64;
00378 isa_default = TARGET_ISA_I1;
00379 targ_default = TARGET_ITANIUM2;
00380 } else {
00381 ErrMsg ( EC_Inv_TARG, "abi", ABI_Name );
00382 }
00383 }
00384
00385
00386 if ( ISA_Name != NULL ) {
00387 TARGET_ISA isa;
00388
00389 if ( strcasecmp ( ISA_Name, "intel1" ) == 0 ) {
00390 isa = TARGET_ISA_I1;
00391 targ_default = TARGET_ITANIUM2;
00392 } else
00393 {
00394 ErrMsg ( EC_Inv_TARG, "isa", ISA_Name );
00395 }
00396
00397
00398 if ( Target_ISA != TARGET_ISA_UNDEF && Target_ISA != isa ) {
00399 ErrMsg ( EC_Incons_TARG, "isa", ISA_Name,
00400 "isa", Isa_Name(Target_ISA) );
00401 }
00402 Target_ISA = isa;
00403 }
00404
00405
00406
00407
00408 switch ( Target_ISA ) {
00409 case TARGET_ISA_UNDEF:
00410 Target_ISA = isa_default;
00411 break;
00412 }
00413
00414
00415 if ( Processor_Name != NULL ) {
00416 TARGET_PROCESSOR targ;
00417
00418 if ( strcasecmp ( Processor_Name, "itanium" ) == 0 ) {
00419 targ = TARGET_ITANIUM;
00420 } else if (strcasecmp (Processor_Name, "itanium2")) {
00421 targ = TARGET_ITANIUM2;
00422 } else {
00423 ErrMsg ( EC_Inv_TARG, "processor", Processor_Name );
00424 targ = TARGET_UNDEF;
00425 }
00426
00427
00428 if ( Target != TARGET_UNDEF && Target != targ ) {
00429 ErrMsg ( EC_Incons_TARG, "processor", Processor_Name,
00430 "processor", Targ_Name(Target) );
00431 }
00432 Target = targ;
00433 }
00434
00435
00436
00437
00438 switch ( Target ) {
00439 case TARGET_ITANIUM:
00440 Target_ABI = ABI_I64;
00441 Target_ISA = TARGET_ISA_I1;
00442 Target = TARGET_ITANIUM;
00443 break;
00444
00445 case TARGET_ITANIUM2:
00446 Target_ABI = ABI_I64;
00447 Target_ISA = TARGET_ISA_I1;
00448 Target = TARGET_ITANIUM2;
00449 break;
00450
00451 case TARGET_UNDEF:
00452 Target = targ_default;
00453 if ( Target == TARGET_UNDEF ) {
00454
00455 Target_ABI = ABI_I64;
00456 Target_ISA = TARGET_ISA_I1;
00457 Target = TARGET_ITANIUM2;
00458 }
00459 break;
00460 }
00461
00462
00463 switch ( Target_FPRs ) {
00464 default:
00465 ErrMsg ( EC_Inv_FPRs, Target_FPRs );
00466
00467 case 0:
00468 Target_FPRs = 128;
00469 break;
00470 case 16:
00471 ErrMsg ( EC_FPR_16 );
00472 break;
00473 case 32:
00474 ErrMsg ( EC_FPR_32 );
00475 break;
00476 }
00477
00478
00479 Target_int64 = TRUE;
00480 Use_32_Bit_Pointers = (Target_ABI == ABI_I32);
00481 #if defined(FRONT_END_C) || defined(FRONT_END_CPLUSPLUS)
00482 Target_Int_Model = ( Target_ABI == ABI_I64 ) ? TARGET_INT_LP64
00483 : TARGET_INT_ILP32;
00484 Make_Int_Model_Consistent ();
00485 #endif
00486 }
00487
00488
00489
00490
00491
00492
00493
00494
00495
00496
00497 void
00498 Configure_Target ( void )
00499 {
00500
00501 #if defined(linux)
00502 Target_Byte_Sex = LITTLE_ENDIAN;
00503 #else
00504 Target_Byte_Sex = BIG_ENDIAN;
00505 #endif
00506 Same_Byte_Sex = ( Target_Byte_Sex == Host_Byte_Sex );
00507
00508 Gen_PIC_Calls = FALSE;
00509 GP_Is_Preserved = FALSE;
00510
00511
00512 Prepare_Target ();
00513
00514
00515 if (OPT_unroll_times > 0 && !OPT_unroll_times_overridden)
00516 OPT_unroll_times = 4;
00517
00518
00519 switch ( Target_ISA ) {
00520 case TARGET_ITANIUM:
00521 case TARGET_ITANIUM2:
00522 Spill_Int_Mtype = MTYPE_I8;
00523 Spill_Float_Mtype = MTYPE_F16;
00524 Max_Int_Mtype = Def_Int_Mtype = MTYPE_I8;
00525 Max_Uint_Mtype = Def_Uint_Mtype = MTYPE_U8;
00526 Boolean_type = MTYPE_I4;
00527 Boolean_type2 = MTYPE_I4;
00528 Integer_type = MTYPE_I4;
00529
00530 Split_Quad_Ops = TRUE;
00531 Split_64_Bit_Int_Ops = FALSE;
00532 break;
00533 }
00534
00535 #if defined(FRONT_END_C) || defined(FRONT_END_CPLUSPLUS)
00536 #ifndef EDG_FORTRAN
00537 Make_Int_Model_Consistent();
00538 #endif
00539 #endif
00540
00541
00542
00543 if ( Use_32_Bit_Pointers ) {
00544 Pointer_Size = 4;
00545 Pointer_Mtype = WHIRL_Mtype_A_On ? MTYPE_A4 : MTYPE_U4;
00546 Pointer_type = Pointer_Mtype;
00547 Pointer_Mtype2 = MTYPE_U4;
00548 Pointer_type2 = MTYPE_U4;
00549 } else {
00550 Pointer_Size = 8;
00551 Pointer_Mtype = WHIRL_Mtype_A_On ? MTYPE_A8: MTYPE_U8;
00552 Pointer_type = Pointer_Mtype;
00553 Pointer_Mtype2 = MTYPE_U8;
00554 Pointer_type2 = MTYPE_U8;
00555 }
00556
00557 if ( Use_32_Bit_Pointers ) {
00558 AS_ADDRESS = AS_WORD;
00559 AS_ADDRESS_UNALIGNED = AS_WORD;
00560 } else {
00561 AS_ADDRESS = AS_DWORD;
00562 AS_ADDRESS_UNALIGNED = AS_DWORD_UNALIGNED;
00563 }
00564
00565
00566
00567
00568
00569
00570
00571
00572
00573 if ( Aggregate_Alignment > 0 ) {
00574 INT32 i = 1;
00575 while ( i < Aggregate_Alignment ) i <<= 1;
00576 Aggregate_Alignment = i;
00577
00578 if (Aggregate_Alignment < (Target_int64 ? 8 : 4))
00579 {
00580 Align_Object = FALSE;
00581 }
00582 }
00583
00584 #if defined(BACK_END)
00585 Init_Targ_Sim();
00586 #endif
00587
00588 #define IS_POW2(n) (((n) & ((n)-1))==0)
00589 FmtAssert (IS_POW2(Align_Instructions),
00590 ("-OPT:align_instructions=<n> must equal power of two"));
00591
00592 return;
00593 }
00594
00595
00596
00597
00598
00599
00600
00601
00602
00603
00604 void
00605 IPA_Configure_Target (void)
00606 {
00607 if (Target_ABI == ABI_I32) {
00608 Pointer_Size = 4;
00609 Pointer_Mtype = WHIRL_Mtype_A_On ? MTYPE_A4 : MTYPE_U4;
00610 Pointer_type = Pointer_Mtype;
00611 Pointer_Mtype2 = MTYPE_U4;
00612 Pointer_type2 = MTYPE_U4;
00613 } else {
00614 Pointer_Size = 8;
00615 Pointer_Mtype = WHIRL_Mtype_A_On ? MTYPE_A8 : MTYPE_U8;
00616 Pointer_type = Pointer_Mtype;
00617 Pointer_Mtype2 = MTYPE_U8;
00618 Pointer_type2 = MTYPE_U8;
00619 }
00620
00621 Integer_type = MTYPE_I4;
00622 Boolean_type = MTYPE_I4;
00623 Boolean_type2 = MTYPE_I4;
00624
00625 }
00626
00627
00628
00629
00630
00631
00632
00633
00634
00635
00636 void
00637 Configure_Source_Target ( char * )
00638 {
00639 char *option;
00640
00641
00642
00643 Indexed_Loads_Allowed = FALSE;
00644
00645
00646 if ( Kernel_Code ) {
00647 Zeroinit_in_bss = FALSE;
00648 }
00649
00650
00651 if ( FP_Excp_Max != NULL ) {
00652 FP_Exception_Enable_Max = 0;
00653 option = FP_Excp_Max;
00654 while ( *option ) {
00655 switch ( *option ) {
00656 case 'I': FP_Exception_Enable_Max |= FPX_I; break;
00657 case 'U': FP_Exception_Enable_Max |= FPX_U; break;
00658 case 'O': FP_Exception_Enable_Max |= FPX_O; break;
00659 case 'Z': FP_Exception_Enable_Max |= FPX_Z; break;
00660 case 'V': FP_Exception_Enable_Max |= FPX_V; break;
00661 }
00662 option++;
00663 }
00664 }
00665 if ( FP_Excp_Min != NULL ) {
00666 FP_Exception_Enable_Min = 0;
00667 option = FP_Excp_Min;
00668 while ( *option ) {
00669 switch ( *option ) {
00670 case 'I': FP_Exception_Enable_Min |= FPX_I; break;
00671 case 'U': FP_Exception_Enable_Min |= FPX_U; break;
00672 case 'O': FP_Exception_Enable_Min |= FPX_O; break;
00673 case 'Z': FP_Exception_Enable_Min |= FPX_Z; break;
00674 case 'V': FP_Exception_Enable_Min |= FPX_V; break;
00675 }
00676 option++;
00677 }
00678 }
00679
00680 if ( DEBUG_Trap_Uv )
00681 FP_Exception_Enable_Min |= FPX_V;
00682
00683
00684 if (Gen_PIC_Call_Shared)
00685 Gen_PIC_Call_Shared = FALSE;
00686
00687 return;
00688 }
00689
00690
00691 extern BOOL
00692 Set_Target_ABI (BOOL is_64bit, INT isa)
00693 {
00694 if (is_64bit) {
00695 switch (Target_ABI) {
00696 case ABI_UNDEF:
00697 Target_ABI = ABI_I64;
00698 break;
00699 case ABI_I64:
00700 break;
00701 default:
00702 return FALSE;
00703 }
00704 } else {
00705 switch (Target_ABI) {
00706 case ABI_UNDEF:
00707 Target_ABI = ABI_I32;
00708 break;
00709 case ABI_I32:
00710 break;
00711 default:
00712 return FALSE;
00713 }
00714 }
00715
00716 if (Target_ISA == TARGET_ISA_UNDEF) {
00717 Target_ISA = TARGET_ISA_I1;
00718 }
00719
00720 return TRUE;
00721 }