Patchwork AMD bdver2 enablement.

login
register
mail settings
Submitter harsha.jagasia@amd.com
Date July 11, 2011, 6:38 p.m.
Message ID <20110711183826.4035.38768.sendpatchset@gccpike1.amd.com>
Download mbox | patch
Permalink /patch/104268/
State New
Headers show

Comments

harsha.jagasia@amd.com - July 11, 2011, 6:38 p.m.
Hi,

This patch does the basic enablement for AMD's upcoming bdver2 processor.
It defines -march=bdver2 and -mtune=bdver2, and lets -march=native correctly
recognizes bdver2. At the moment the tuning is mostly a copy of bdver1.
The patch passed bootstrap and the x86 tests. 
Is it OK to commit to trunk?

Thanks,
Harsha

2011-07-11  Harsha Jagasia  <harsha.jagasia@amd.com>

	AMD bdver2 Enablement
	* config.gcc (i[34567]86-*-linux* | ...): Add bdver2.
	(case ${target}): Add bdver2.
	* config/i386/driver-i386.c (host_detect_local_cpu): Let
	-march=native recognize bdver2 processors.
	* config/i386/i386-c.c (ix86_target_macros_internal): Add
	bdver2 def_and_undef
	* config/i386/i386.c (struct processor_costs bdver2_cost): New
	bdver2 cost table.
	(m_BDVER2): New definition.
	(m_AMD_MULTIPLE): Includes m_BDVER2.
	(initial_ix86_tune_features): Add bdver2 tuning.
	(processor_target_table): Add bdver2 entry.
	(static const char *const cpu_names): Add bdver2 entry.
	(ix86_option_override_internal): Add bdver2 instruction sets.
	(ix86_issue_rate): Add bdver2.
	(ix86_adjust_cost): Add bdver2.
	(has_dispatch): Add bdver2.
	* config/i386/i386.h (TARGET_BDVER2): New definition.
	(enum target_cpu_default): Add TARGET_CPU_DEFAULT_bdver2.
	(enum processor_type): Add PROCESSOR_BDVER2.
	* config/i386/i386.md (define_attr "cpu"): Add bdver2.
	* config/i386/i386.opt ( mdispatch-scheduler): Add bdver2 to
	description.
Gerald Pfeifer - July 15, 2011, 4:12 p.m.
On Mon, 11 Jul 2011, harsha.jagasia@amd.com wrote:
> Is it OK to commit to trunk?

Please also think of updating the release notes for GCC 4.7. :-)

Gerald

Patch

Index: gcc/config.gcc
===================================================================
--- gcc/config.gcc	(revision 175929)
+++ gcc/config.gcc	(working copy)
@@ -1283,7 +1283,7 @@  i[34567]86-*-linux* | i[34567]86-*-kfree
 			need_64bit_hwint=yes
 			need_64bit_isa=yes
 			case X"${with_cpu}" in
-			Xgeneric|Xatom|Xcore2|Xcorei7|Xcorei7-avx|Xnocona|Xx86-64|Xbdver1|Xbtver1|Xamdfam10|Xbarcelona|Xk8|Xopteron|Xathlon64|Xathlon-fx|Xathlon64-sse3|Xk8-sse3|Xopteron-sse3)
+			Xgeneric|Xatom|Xcore2|Xcorei7|Xcorei7-avx|Xnocona|Xx86-64|Xbdver2|Xbdver1|Xbtver1|Xamdfam10|Xbarcelona|Xk8|Xopteron|Xathlon64|Xathlon-fx|Xathlon64-sse3|Xk8-sse3|Xopteron-sse3)
 				;;
 			X)
 				if test x$with_cpu_64 = x; then
@@ -1292,7 +1292,7 @@  i[34567]86-*-linux* | i[34567]86-*-kfree
 				;;
 			*)
 				echo "Unsupported CPU used in --with-cpu=$with_cpu, supported values:" 1>&2
-				echo "generic atom core2 corei7 corei7-avx nocona x86-64 bdver1 btver1 amdfam10 barcelona k8 opteron athlon64 athlon-fx athlon64-sse3 k8-sse3 opteron-sse3" 1>&2
+				echo "generic atom core2 corei7 corei7-avx nocona x86-64 bdver2 bdver1 btver1 amdfam10 barcelona k8 opteron athlon64 athlon-fx athlon64-sse3 k8-sse3 opteron-sse3" 1>&2
 				exit 1
 				;;
 			esac
@@ -1392,7 +1392,7 @@  i[34567]86-*-solaris2*)
 		need_64bit_hwint=yes
 		need_64bit_isa=yes
 		case X"${with_cpu}" in
-		Xgeneric|Xatom|Xcore2|Xcorei7|Xcorei7-avx|Xnocona|Xx86-64|Xbdver1|Xbtver1|Xamdfam10|Xbarcelona|Xk8|Xopteron|Xathlon64|Xathlon-fx|Xathlon64-sse3|Xk8-sse3|Xopteron-sse3)
+		Xgeneric|Xatom|Xcore2|Xcorei7|Xcorei7-avx|Xnocona|Xx86-64|Xbdver2|Xbdver1|Xbtver1|Xamdfam10|Xbarcelona|Xk8|Xopteron|Xathlon64|Xathlon-fx|Xathlon64-sse3|Xk8-sse3|Xopteron-sse3)
 			;;
 		X)
 			if test x$with_cpu_64 = x; then
@@ -1401,7 +1401,7 @@  i[34567]86-*-solaris2*)
 			;;
 		*)
 			echo "Unsupported CPU used in --with-cpu=$with_cpu, supported values:" 1>&2
-			echo "generic atom core2 corei7 corei7-avx nocona x86-64 bdver1 btver1 amdfam10 barcelona k8 opteron athlon64 athlon-fx athlon64-sse3 k8-sse3 opteron-sse3" 1>&2
+			echo "generic atom core2 corei7 corei7-avx nocona x86-64 bdver2 bdver1 btver1 amdfam10 barcelona k8 opteron athlon64 athlon-fx athlon64-sse3 k8-sse3 opteron-sse3" 1>&2
 			exit 1
 			;;
 		esac
@@ -1471,7 +1471,7 @@  i[34567]86-*-mingw* | x86_64-*-mingw*)
 			if test x$enable_targets = xall; then
 				tm_defines="${tm_defines} TARGET_BI_ARCH=1"
 				case X"${with_cpu}" in
-				Xgeneric|Xatom|Xcore2|Xcorei7|Xcorei7-avx|Xnocona|Xx86-64|Xbdver1|Xbtver1|Xamdfam10|Xbarcelona|Xk8|Xopteron|Xathlon64|Xathlon-fx|Xathlon64-sse3|Xk8-sse3|Xopteron-sse3)
+				Xgeneric|Xatom|Xcore2|Xcorei7|Xcorei7-avx|Xnocona|Xx86-64|Xbdver2|Xbdver1|Xbtver1|Xamdfam10|Xbarcelona|Xk8|Xopteron|Xathlon64|Xathlon-fx|Xathlon64-sse3|Xk8-sse3|Xopteron-sse3)
 					;;
 				X)
 					if test x$with_cpu_64 = x; then
@@ -1480,7 +1480,7 @@  i[34567]86-*-mingw* | x86_64-*-mingw*)
 					;;
 				*)
 					echo "Unsupported CPU used in --with-cpu=$with_cpu, supported values:" 1>&2
-					echo "generic atom core2 corei7 Xcorei7-avx nocona x86-64 bdver1 btver1 amdfam10 barcelona k8 opteron athlon64 athlon-fx athlon64-sse3 k8-sse3 opteron-sse3" 1>&2
+					echo "generic atom core2 corei7 Xcorei7-avx nocona x86-64 bdver2 bdver1 btver1 amdfam10 barcelona k8 opteron athlon64 athlon-fx athlon64-sse3 k8-sse3 opteron-sse3" 1>&2
 					exit 1
 					;;
 				esac
@@ -2718,6 +2718,10 @@  case ${target} in
     ;;
   i686-*-* | i786-*-*)
     case ${target_noncanonical} in
+      bdver2-*)
+        arch=bdver2
+        cpu=bdver2
+        ;;
       bdver1-*)
 	arch=bdver1
 	cpu=bdver1
@@ -2811,6 +2815,10 @@  case ${target} in
     ;;
   x86_64-*-*)
     case ${target_noncanonical} in
+      bdver2-*)
+        arch=bdver2
+        cpu=bdver2
+        ;;
       bdver1-*)
 	arch=bdver1
 	cpu=bdver1
@@ -3246,8 +3254,9 @@  case "${target}" in
 				;;
 			"" | x86-64 | generic | native \
 			| k8 | k8-sse3 | athlon64 | athlon64-sse3 | opteron \
-			| opteron-sse3 | athlon-fx | bdver1 | btver1 | amdfam10 \
-			| barcelona | nocona | core2 | corei7 | corei7-avx | atom)
+			| opteron-sse3 | athlon-fx | bdver2 | bdver1 | btver1 \
+			| amdfam10 | barcelona | nocona | core2 | corei7 \
+			| corei7-avx | atom)
 				# OK
 				;;
 			*)
Index: gcc/config/i386/i386.h
===================================================================
--- gcc/config/i386/i386.h	(revision 175929)
+++ gcc/config/i386/i386.h	(working copy)
@@ -240,6 +240,7 @@  extern const struct processor_costs ix86
 #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)
 
@@ -583,6 +584,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
@@ -2020,6 +2022,7 @@  enum processor_type
   PROCESSOR_GENERIC64,
   PROCESSOR_AMDFAM10,
   PROCESSOR_BDVER1,
+  PROCESSOR_BDVER2,
   PROCESSOR_BTVER1,
   PROCESSOR_ATOM,
   PROCESSOR_max
Index: gcc/config/i386/i386.md
===================================================================
--- gcc/config/i386/i386.md	(revision 175929)
+++ gcc/config/i386/i386.md	(working copy)
@@ -369,7 +369,7 @@  (define_constants
 
 ;; 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
Index: gcc/config/i386/i386.opt
===================================================================
--- gcc/config/i386/i386.opt	(revision 175929)
+++ gcc/config/i386/i386.opt	(working copy)
@@ -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
Index: gcc/config/i386/i386-c.c
===================================================================
--- gcc/config/i386/i386-c.c	(revision 175929)
+++ gcc/config/i386/i386-c.c	(working copy)
@@ -110,6 +110,10 @@  ix86_target_macros_internal (int isa_fla
       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_fla
     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;
Index: gcc/config/i386/driver-i386.c
===================================================================
--- gcc/config/i386/driver-i386.c	(revision 175929)
+++ gcc/config/i386/driver-i386.c	(working copy)
@@ -499,6 +499,8 @@  const char *host_detect_local_cpu (int a
 
       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 a
     case PROCESSOR_BDVER1:
       cpu = "bdver1";
       break;
+    case PROCESSOR_BDVER2:
+      cpu = "bdver2";
+      break;
     case PROCESSOR_BTVER1:
       cpu = "btver1";
       break;
Index: gcc/config/i386/i386.c
===================================================================
--- gcc/config/i386/i386.c	(revision 175929)
+++ gcc/config/i386/i386.c	(working copy)
@@ -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
 #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,8 +1945,8 @@  static unsigned int initial_ix86_tune_fe
   ~m_386,
 
   /* X86_TUNE_USE_SAHF */
-  m_ATOM | m_PPRO | m_K6_GEODE | m_K8 | m_AMDFAM10 | m_BDVER1 | m_BTVER1
-  | m_PENT4 | m_NOCONA | m_CORE2I7 | m_GENERIC,
+  m_ATOM | m_PPRO | m_K6_GEODE | m_K8 | m_AMDFAM10 | m_BDVER1 | m_BDVER2
+  | m_BTVER1 | m_PENT4 | m_NOCONA | m_CORE2I7 | m_GENERIC,
 
   /* X86_TUNE_MOVX: Enable to zero extend integer registers to avoid
      partial dependencies.  */
@@ -1960,16 +2049,16 @@  static unsigned int initial_ix86_tune_fe
      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_AMDFAM10 | m_BDVER1 | m_BDVER2,
 
   /* X86_TUNE_SSE_UNALIGNED_LOAD_OPTIMAL */
-  m_AMDFAM10 | m_BDVER1 | m_BTVER1 | m_COREI7,
+  m_AMDFAM10 | m_BDVER1 | m_BDVER2 | m_BTVER1 | m_COREI7,
 
   /* X86_TUNE_SSE_UNALIGNED_STORE_OPTIMAL */
-  m_BDVER1 | m_COREI7,
+  m_BDVER1 | m_BDVER2 | m_COREI7,
 
   /* X86_TUNE_SSE_PACKED_SINGLE_INSN_OPTIMAL */
-  m_BDVER1,
+  m_BDVER1 | m_BDVER2 ,
 
   /* 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_fe
   ~(m_AMD_MULTIPLE | m_GENERIC),
 
   /* X86_TUNE_INTER_UNIT_CONVERSIONS */
-  ~(m_AMDFAM10 | m_BDVER1),
+  ~(m_AMDFAM10 | m_BDVER1 | m_BDVER2 ),
 
   /* 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,13 @@  static unsigned int initial_ix86_tune_fe
 
   /* 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_BDVER1 | m_BDVER2
+  | 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_BDVER1 | m_BDVER2
+  | m_BTVER1,
 
   /* X86_TUNE_MOVE_M1_VIA_OR: On pentiums, it is faster to load -1 via OR
      than a MOV.  */
@@ -2071,7 +2162,7 @@  static unsigned int initial_ix86_tune_fe
   /* 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_BDVER1 | m_BDVER2 ,
 
   /* X86_TUNE_OPT_AGU: Optimize for Address Generation Unit. This flag
      will impact LEA instruction selection. */
@@ -2088,7 +2179,7 @@  static unsigned int initial_ix86_tune_fe
 
   /* X86_TUNE_AVX128_OPTIMAL: Enable 128-bit AVX instruction generation for
      the auto-vectorizer.  */
-  m_BDVER1
+  m_BDVER1 | m_BDVER2 
 };
 
 /* Feature tests against the various architecture variations.  */
@@ -2125,7 +2216,7 @@  static const unsigned int x86_avx256_spl
   = m_COREI7 | m_GENERIC;
 
 static const unsigned int x86_avx256_split_unaligned_store
-  = m_COREI7 | m_BDVER1 | m_GENERIC;
+  = m_COREI7 | m_BDVER1 | m_BDVER2 | 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 +2599,7 @@  static const struct ptt processor_target
   {&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 +2630,7 @@  static const char *const cpu_names[TARGE
   "k8",
   "amdfam10",
   "bdver1",
+  "bdver2",
   "btver1"
 };
 
@@ -2939,6 +3032,12 @@  ix86_option_override_internal (bool main
 	| 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},
@@ -21869,6 +21968,7 @@  ix86_issue_rate (void)
     case PROCESSOR_GENERIC32:
     case PROCESSOR_GENERIC64:
     case PROCESSOR_BDVER1:
+    case PROCESSOR_BDVER2:
     case PROCESSOR_BTVER1:
       return 3;
 
@@ -22057,6 +22157,7 @@  ix86_adjust_cost (rtx insn, rtx link, rt
     case PROCESSOR_K8:
     case PROCESSOR_AMDFAM10:
     case PROCESSOR_BDVER1:
+    case PROCESSOR_BDVER2:
     case PROCESSOR_BTVER1:
     case PROCESSOR_ATOM:
     case PROCESSOR_GENERIC32:
@@ -34505,7 +34606,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: