diff options
Diffstat (limited to 'gcc/config')
-rw-r--r-- | gcc/config/i386/driver-i386.c | 5 | ||||
-rw-r--r-- | gcc/config/i386/i386-c.c | 7 | ||||
-rw-r--r-- | gcc/config/i386/i386.c | 128 | ||||
-rw-r--r-- | gcc/config/i386/i386.h | 3 | ||||
-rw-r--r-- | gcc/config/i386/i386.md | 2 | ||||
-rw-r--r-- | gcc/config/i386/i386.opt | 2 |
6 files changed, 131 insertions, 16 deletions
diff --git a/gcc/config/i386/driver-i386.c b/gcc/config/i386/driver-i386.c index efd4372..ecd8958 100644 --- a/gcc/config/i386/driver-i386.c +++ b/gcc/config/i386/driver-i386.c @@ -499,6 +499,8 @@ const char *host_detect_local_cpu (int argc, const char **argv) if (name == SIG_GEODE) processor = PROCESSOR_GEODE; + else if (has_bmi) + processor = PROCESSOR_BDVER2; else if (has_xop) processor = PROCESSOR_BDVER1; else if (has_sse4a && has_ssse3) @@ -664,6 +666,9 @@ const char *host_detect_local_cpu (int argc, const char **argv) case PROCESSOR_BDVER1: cpu = "bdver1"; break; + case PROCESSOR_BDVER2: + cpu = "bdver2"; + break; case PROCESSOR_BTVER1: cpu = "btver1"; break; diff --git a/gcc/config/i386/i386-c.c b/gcc/config/i386/i386-c.c index 5676548..5cbcfd5 100644 --- a/gcc/config/i386/i386-c.c +++ b/gcc/config/i386/i386-c.c @@ -110,6 +110,10 @@ ix86_target_macros_internal (int isa_flag, def_or_undef (parse_in, "__bdver1"); def_or_undef (parse_in, "__bdver1__"); break; + case PROCESSOR_BDVER2: + def_or_undef (parse_in, "__bdver2"); + def_or_undef (parse_in, "__bdver2__"); + break; case PROCESSOR_BTVER1: def_or_undef (parse_in, "__btver1"); def_or_undef (parse_in, "__btver1__"); @@ -198,6 +202,9 @@ ix86_target_macros_internal (int isa_flag, case PROCESSOR_BDVER1: def_or_undef (parse_in, "__tune_bdver1__"); break; + case PROCESSOR_BDVER2: + def_or_undef (parse_in, "__tune_bdver2__"); + break; case PROCESSOR_BTVER1: def_or_undef (parse_in, "__tune_btver1__"); break; diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c index 4ca95ab..e75e1b1 100644 --- a/gcc/config/i386/i386.c +++ b/gcc/config/i386/i386.c @@ -1338,6 +1338,93 @@ struct processor_costs bdver1_cost = { 1, /* cond_not_taken_branch_cost. */ }; +struct processor_costs bdver2_cost = { + COSTS_N_INSNS (1), /* cost of an add instruction */ + COSTS_N_INSNS (1), /* cost of a lea instruction */ + COSTS_N_INSNS (1), /* variable shift costs */ + COSTS_N_INSNS (1), /* constant shift costs */ + {COSTS_N_INSNS (4), /* cost of starting multiply for QI */ + COSTS_N_INSNS (4), /* HI */ + COSTS_N_INSNS (4), /* SI */ + COSTS_N_INSNS (6), /* DI */ + COSTS_N_INSNS (6)}, /* other */ + 0, /* cost of multiply per each bit set */ + {COSTS_N_INSNS (19), /* cost of a divide/mod for QI */ + COSTS_N_INSNS (35), /* HI */ + COSTS_N_INSNS (51), /* SI */ + COSTS_N_INSNS (83), /* DI */ + COSTS_N_INSNS (83)}, /* other */ + COSTS_N_INSNS (1), /* cost of movsx */ + COSTS_N_INSNS (1), /* cost of movzx */ + 8, /* "large" insn */ + 9, /* MOVE_RATIO */ + 4, /* cost for loading QImode using movzbl */ + {5, 5, 4}, /* cost of loading integer registers + in QImode, HImode and SImode. + Relative to reg-reg move (2). */ + {4, 4, 4}, /* cost of storing integer registers */ + 2, /* cost of reg,reg fld/fst */ + {5, 5, 12}, /* cost of loading fp registers + in SFmode, DFmode and XFmode */ + {4, 4, 8}, /* cost of storing fp registers + in SFmode, DFmode and XFmode */ + 2, /* cost of moving MMX register */ + {4, 4}, /* cost of loading MMX registers + in SImode and DImode */ + {4, 4}, /* cost of storing MMX registers + in SImode and DImode */ + 2, /* cost of moving SSE register */ + {4, 4, 4}, /* cost of loading SSE registers + in SImode, DImode and TImode */ + {4, 4, 4}, /* cost of storing SSE registers + in SImode, DImode and TImode */ + 2, /* MMX or SSE register to integer */ + /* On K8: + MOVD reg64, xmmreg Double FSTORE 4 + MOVD reg32, xmmreg Double FSTORE 4 + On AMDFAM10: + MOVD reg64, xmmreg Double FADD 3 + 1/1 1/1 + MOVD reg32, xmmreg Double FADD 3 + 1/1 1/1 */ + 16, /* size of l1 cache. */ + 2048, /* size of l2 cache. */ + 64, /* size of prefetch block */ + /* New AMD processors never drop prefetches; if they cannot be performed + immediately, they are queued. We set number of simultaneous prefetches + to a large constant to reflect this (it probably is not a good idea not + to limit number of prefetches at all, as their execution also takes some + time). */ + 100, /* number of parallel prefetches */ + 2, /* Branch cost */ + COSTS_N_INSNS (6), /* cost of FADD and FSUB insns. */ + COSTS_N_INSNS (6), /* cost of FMUL instruction. */ + COSTS_N_INSNS (42), /* cost of FDIV instruction. */ + COSTS_N_INSNS (2), /* cost of FABS instruction. */ + COSTS_N_INSNS (2), /* cost of FCHS instruction. */ + COSTS_N_INSNS (52), /* cost of FSQRT instruction. */ + + /* BDVER2 has optimized REP instruction for medium sized blocks, but for + very small blocks it is better to use loop. For large blocks, libcall + can do nontemporary accesses and beat inline considerably. */ + {{libcall, {{6, loop}, {14, unrolled_loop}, {-1, rep_prefix_4_byte}}}, + {libcall, {{16, loop}, {8192, rep_prefix_8_byte}, {-1, libcall}}}}, + {{libcall, {{8, loop}, {24, unrolled_loop}, + {2048, rep_prefix_4_byte}, {-1, libcall}}}, + {libcall, {{48, unrolled_loop}, {8192, rep_prefix_8_byte}, {-1, libcall}}}}, + 6, /* scalar_stmt_cost. */ + 4, /* scalar load_cost. */ + 4, /* scalar_store_cost. */ + 6, /* vec_stmt_cost. */ + 0, /* vec_to_scalar_cost. */ + 2, /* scalar_to_vec_cost. */ + 4, /* vec_align_load_cost. */ + 4, /* vec_unalign_load_cost. */ + 4, /* vec_store_cost. */ + 2, /* cond_taken_branch_cost. */ + 1, /* cond_not_taken_branch_cost. */ +}; + struct processor_costs btver1_cost = { COSTS_N_INSNS (1), /* cost of an add instruction */ COSTS_N_INSNS (2), /* cost of a lea instruction */ @@ -1813,8 +1900,10 @@ const struct processor_costs *ix86_cost = &pentium_cost; #define m_ATHLON_K8 (m_K8 | m_ATHLON) #define m_AMDFAM10 (1<<PROCESSOR_AMDFAM10) #define m_BDVER1 (1<<PROCESSOR_BDVER1) +#define m_BDVER2 (1<<PROCESSOR_BDVER2) #define m_BTVER1 (1<<PROCESSOR_BTVER1) -#define m_AMD_MULTIPLE (m_K8 | m_ATHLON | m_AMDFAM10 | m_BDVER1 | m_BTVER1) +#define m_BDVER (m_BDVER1 | m_BDVER2) +#define m_AMD_MULTIPLE (m_ATHLON_K8 | m_AMDFAM10 | m_BDVER | m_BTVER1) #define m_GENERIC32 (1<<PROCESSOR_GENERIC32) #define m_GENERIC64 (1<<PROCESSOR_GENERIC64) @@ -1856,7 +1945,7 @@ static unsigned int initial_ix86_tune_features[X86_TUNE_LAST] = { ~m_386, /* X86_TUNE_USE_SAHF */ - m_ATOM | m_PPRO | m_K6_GEODE | m_K8 | m_AMDFAM10 | m_BDVER1 | m_BTVER1 + m_ATOM | m_PPRO | m_K6_GEODE | m_K8 | m_AMDFAM10 | m_BDVER | m_BTVER1 | m_PENT4 | m_NOCONA | m_CORE2I7 | m_GENERIC, /* X86_TUNE_MOVX: Enable to zero extend integer registers to avoid @@ -1959,17 +2048,17 @@ static unsigned int initial_ix86_tune_features[X86_TUNE_LAST] = { shows that disabling this option on P4 brings over 20% SPECfp regression, while enabling it on K8 brings roughly 2.4% regression that can be partly masked by careful scheduling of moves. */ - m_ATOM | m_PENT4 | m_NOCONA | m_PPRO | m_CORE2I7 | m_GENERIC - | m_AMDFAM10 | m_BDVER1, + m_ATOM | m_PENT4 | m_NOCONA | m_PPRO | m_CORE2I7 | m_GENERIC | m_AMDFAM10 + | m_BDVER, /* X86_TUNE_SSE_UNALIGNED_LOAD_OPTIMAL */ - m_AMDFAM10 | m_BDVER1 | m_BTVER1 | m_COREI7, + m_AMDFAM10 | m_BDVER | m_BTVER1 | m_COREI7, /* X86_TUNE_SSE_UNALIGNED_STORE_OPTIMAL */ - m_BDVER1 | m_COREI7, + m_BDVER | m_COREI7, /* X86_TUNE_SSE_PACKED_SINGLE_INSN_OPTIMAL */ - m_BDVER1, + m_BDVER , /* X86_TUNE_SSE_SPLIT_REGS: Set for machines where the type and dependencies are resolved on SSE register parts instead of whole registers, so we may @@ -2002,7 +2091,7 @@ static unsigned int initial_ix86_tune_features[X86_TUNE_LAST] = { ~(m_AMD_MULTIPLE | m_GENERIC), /* X86_TUNE_INTER_UNIT_CONVERSIONS */ - ~(m_AMDFAM10 | m_BDVER1), + ~(m_AMDFAM10 | m_BDVER ), /* X86_TUNE_FOUR_JUMP_LIMIT: Some CPU cores are not able to predict more than 4 branch instructions in the 16 byte window. */ @@ -2041,11 +2130,11 @@ static unsigned int initial_ix86_tune_features[X86_TUNE_LAST] = { /* X86_TUNE_SLOW_IMUL_IMM32_MEM: Imul of 32-bit constant and memory is vector path on AMD machines. */ - m_K8 | m_CORE2I7_64 | m_GENERIC64 | m_AMDFAM10 | m_BDVER1 | m_BTVER1, + m_K8 | m_CORE2I7_64 | m_GENERIC64 | m_AMDFAM10 | m_BDVER | m_BTVER1, /* X86_TUNE_SLOW_IMUL_IMM8: Imul of 8-bit constant is vector path on AMD machines. */ - m_K8 | m_CORE2I7_64 | m_GENERIC64 | m_AMDFAM10 | m_BDVER1 | m_BTVER1, + m_K8 | m_CORE2I7_64 | m_GENERIC64 | m_AMDFAM10 | m_BDVER | m_BTVER1, /* X86_TUNE_MOVE_M1_VIA_OR: On pentiums, it is faster to load -1 via OR than a MOV. */ @@ -2071,7 +2160,7 @@ static unsigned int initial_ix86_tune_features[X86_TUNE_LAST] = { /* X86_TUNE_FUSE_CMP_AND_BRANCH: Fuse a compare or test instruction with a subsequent conditional jump instruction into a single compare-and-branch uop. */ - m_BDVER1, + m_BDVER , /* X86_TUNE_OPT_AGU: Optimize for Address Generation Unit. This flag will impact LEA instruction selection. */ @@ -2088,7 +2177,7 @@ static unsigned int initial_ix86_tune_features[X86_TUNE_LAST] = { /* X86_TUNE_AVX128_OPTIMAL: Enable 128-bit AVX instruction generation for the auto-vectorizer. */ - m_BDVER1 + m_BDVER }; /* Feature tests against the various architecture variations. */ @@ -2125,7 +2214,7 @@ static const unsigned int x86_avx256_split_unaligned_load = m_COREI7 | m_GENERIC; static const unsigned int x86_avx256_split_unaligned_store - = m_COREI7 | m_BDVER1 | m_GENERIC; + = m_COREI7 | m_BDVER | m_GENERIC; /* In case the average insn count for single function invocation is lower than this constant, emit fast (but longer) prologue and @@ -2508,6 +2597,7 @@ static const struct ptt processor_target_table[PROCESSOR_max] = {&generic64_cost, 16, 10, 16, 10, 16}, {&amdfam10_cost, 32, 24, 32, 7, 32}, {&bdver1_cost, 32, 24, 32, 7, 32}, + {&bdver2_cost, 32, 24, 32, 7, 32}, {&btver1_cost, 32, 24, 32, 7, 32}, {&atom_cost, 16, 7, 16, 7, 16} }; @@ -2538,6 +2628,7 @@ static const char *const cpu_names[TARGET_CPU_DEFAULT_max] = "k8", "amdfam10", "bdver1", + "bdver2", "btver1" }; @@ -2939,6 +3030,12 @@ ix86_option_override_internal (bool main_args_p) | PTA_SSE4A | PTA_CX16 | PTA_ABM | PTA_SSSE3 | PTA_SSE4_1 | PTA_SSE4_2 | PTA_AES | PTA_PCLMUL | PTA_AVX | PTA_FMA4 | PTA_XOP | PTA_LWP}, + {"bdver2", PROCESSOR_BDVER2, CPU_BDVER2, + PTA_64BIT | PTA_MMX | PTA_SSE | PTA_SSE2 | PTA_SSE3 + | PTA_SSE4A | PTA_CX16 | PTA_ABM | PTA_SSSE3 | PTA_SSE4_1 + | PTA_SSE4_2 | PTA_AES | PTA_PCLMUL | PTA_AVX + | PTA_XOP | PTA_LWP | PTA_BMI | PTA_TBM | PTA_F16C + | PTA_FMA}, {"btver1", PROCESSOR_BTVER1, CPU_GENERIC64, PTA_64BIT | PTA_MMX | PTA_SSE | PTA_SSE2 | PTA_SSE3 | PTA_SSSE3 | PTA_SSE4A |PTA_ABM | PTA_CX16}, @@ -21878,6 +21975,7 @@ ix86_issue_rate (void) case PROCESSOR_GENERIC32: case PROCESSOR_GENERIC64: case PROCESSOR_BDVER1: + case PROCESSOR_BDVER2: case PROCESSOR_BTVER1: return 3; @@ -22066,6 +22164,7 @@ ix86_adjust_cost (rtx insn, rtx link, rtx dep_insn, int cost) case PROCESSOR_K8: case PROCESSOR_AMDFAM10: case PROCESSOR_BDVER1: + case PROCESSOR_BDVER2: case PROCESSOR_BTVER1: case PROCESSOR_ATOM: case PROCESSOR_GENERIC32: @@ -34534,7 +34633,8 @@ do_dispatch (rtx insn, int mode) static bool has_dispatch (rtx insn, int action) { - if (ix86_tune == PROCESSOR_BDVER1 && flag_dispatch_scheduler) + if ((ix86_tune == PROCESSOR_BDVER1 || ix86_tune == PROCESSOR_BDVER2) + && flag_dispatch_scheduler) switch (action) { default: diff --git a/gcc/config/i386/i386.h b/gcc/config/i386/i386.h index 8cef4e7..f532bad 100644 --- a/gcc/config/i386/i386.h +++ b/gcc/config/i386/i386.h @@ -242,6 +242,7 @@ extern const struct processor_costs ix86_size_cost; #define TARGET_GENERIC (TARGET_GENERIC32 || TARGET_GENERIC64) #define TARGET_AMDFAM10 (ix86_tune == PROCESSOR_AMDFAM10) #define TARGET_BDVER1 (ix86_tune == PROCESSOR_BDVER1) +#define TARGET_BDVER2 (ix86_tune == PROCESSOR_BDVER2) #define TARGET_BTVER1 (ix86_tune == PROCESSOR_BTVER1) #define TARGET_ATOM (ix86_tune == PROCESSOR_ATOM) @@ -585,6 +586,7 @@ enum target_cpu_default TARGET_CPU_DEFAULT_k8, TARGET_CPU_DEFAULT_amdfam10, TARGET_CPU_DEFAULT_bdver1, + TARGET_CPU_DEFAULT_bdver2, TARGET_CPU_DEFAULT_btver1, TARGET_CPU_DEFAULT_max @@ -2031,6 +2033,7 @@ enum processor_type PROCESSOR_GENERIC64, PROCESSOR_AMDFAM10, PROCESSOR_BDVER1, + PROCESSOR_BDVER2, PROCESSOR_BTVER1, PROCESSOR_ATOM, PROCESSOR_max diff --git a/gcc/config/i386/i386.md b/gcc/config/i386/i386.md index a52941b..d6026c8 100644 --- a/gcc/config/i386/i386.md +++ b/gcc/config/i386/i386.md @@ -369,7 +369,7 @@ ;; Processor type. (define_attr "cpu" "none,pentium,pentiumpro,geode,k6,athlon,k8,core2,corei7, - atom,generic64,amdfam10,bdver1,btver1" + atom,generic64,amdfam10,bdver1,bdver2,btver1" (const (symbol_ref "ix86_schedule"))) ;; A basic instruction type. Refinements due to arguments to be diff --git a/gcc/config/i386/i386.opt b/gcc/config/i386/i386.opt index 8dea93e..5e6b5df 100644 --- a/gcc/config/i386/i386.opt +++ b/gcc/config/i386/i386.opt @@ -384,7 +384,7 @@ the function. mdispatch-scheduler Target RejectNegative Var(flag_dispatch_scheduler) -Do dispatch scheduling if processor is bdver1 and Haifa scheduling +Do dispatch scheduling if processor is bdver1 or bdver2 and Haifa scheduling is selected. mprefer-avx128 |