Patchwork [i386] : AMD bdver3 enablement

login
register
mail settings
Submitter Gopalasubramanian, Ganesh
Date Nov. 14, 2012, 9:22 a.m.
Message ID <EB4625145972F94C9680D8CADD651615397836C9@sausexdag06.amd.com>
Download mbox | patch
Permalink /patch/198842/
State New
Headers show

Comments

Gopalasubramanian, Ganesh - Nov. 14, 2012, 9:22 a.m.
Hi Uros!

> sseshuf replaces sselog in some insn patterns, but should be handled in the same way in *existing* .md files.

Modifications done as per the comments. 
1. Sseshuf is added along with sselog in existing md files.
2. sseshuf is handled in a separate pattern in bdver3.md

Bootstrapping and "make -k check" passes.
Ok for trunk?

Regards
Ganesh

2012-11-14  Ganesh Gopalasubramanian  <Ganesh.Gopalasubramanian@amd.com>

	bdver3 Enablement
	* gcc/doc/extend.texi: Add details about bdver3.
	* gcc/doc/invoke.texi: Add details about bdver3.
	* config.gcc (i[34567]86-*-linux* | ...): Add bdver3.
	(case ${target}): Add bdver3.
	* config/i386/i386.h (TARGET_BDVER3): New definition.
	* config/i386/i386.md (define_attr "cpu"): Add bdver3.
	* config/i386/sse.md (sseshuf): New type attribute.
	* config/i386/athlon.md (sseshuf):Likewise.
	* config/i386/atom.md (sseshuf):Likewise.
	* config/i386/ppro.md (sseshuf):Likewise.
	* config/i386/bdver1.md (sseshuf):Likewise.
	* config/i386/i386.opt (flag_dispatch_scheduler): Add bdver3.
	* config/i386/i386-c.c (ix86_target_macros_internal): Add
	bdver3 def_and_undef
	* config/i386/driver-i386.c (host_detect_local_cpu): Let
	-march=native recognize bdver3 processors.
	* config/i386/i386.c (struct processor_costs bdver3_cost): New.
	(m_BDVER3): New definition.
	(m_AMD_MULTIPLE): Includes m_BDVER3.
	(initial_ix86_tune_features): Add bdver3 tune.
	(processor_target_table): Add bdver3 entry.
	(static const char *const cpu_names): Add bdver3 entry.
	(software_prefetching_beneficial_p): Add bdver3.
	(ix86_option_override_internal): Add bdver3 instruction sets.
	(ix86_option_override_internal): Remove XSAVEOPT for bdver1 
	and bdver2.
	(ix86_issue_rate): Add bdver3.
	(ix86_adjust_cost): Add bdver3.
	(enum target_cpu_default): Add TARGET_CPU_DEFAULT_bdver3.
	(enum processor_type): Add PROCESSOR_BDVER3.
	* config/i386/bdver3.md: New file describing bdver3 pipelines.

-----Original Message-----
From: Uros Bizjak [mailto:ubizjak@gmail.com] 
Sent: Monday, November 12, 2012 1:39 PM
To: Gopalasubramanian, Ganesh
Cc: gcc-patches@gcc.gnu.org
Subject: Re: [PATCH, i386]: AMD bdver3 enablement

On Mon, Nov 12, 2012 at 6:34 AM, Gopalasubramanian, Ganesh <Ganesh.Gopalasubramanian@amd.com> wrote:
>> You can see from the changes of sse.md that this is functionally a no-op change.
> Sseshuf replaces sselog.
> So, do you mean it should be added with sselog instead of sseadd?
> Adding it with sseadd (instead of sselog) influences the latency information.

sseshuf replaces sselog in some insn patterns, but should be handled in the same way in *existing* .md files.

Uros,
Uros Bizjak - Nov. 14, 2012, 10:44 a.m.
On Wed, Nov 14, 2012 at 10:22 AM, Gopalasubramanian, Ganesh
<Ganesh.Gopalasubramanian@amd.com> wrote:

>> sseshuf replaces sselog in some insn patterns, but should be handled in the same way in *existing* .md files.
>
> Modifications done as per the comments.
> 1. Sseshuf is added along with sselog in existing md files.
> 2. sseshuf is handled in a separate pattern in bdver3.md
>
> Bootstrapping and "make -k check" passes.
> Ok for trunk?
>
> 2012-11-14  Ganesh Gopalasubramanian  <Ganesh.Gopalasubramanian@amd.com>
>
>         bdver3 Enablement
>         * gcc/doc/extend.texi: Add details about bdver3.
>         * gcc/doc/invoke.texi: Add details about bdver3.
>         * config.gcc (i[34567]86-*-linux* | ...): Add bdver3.
>         (case ${target}): Add bdver3.
>         * config/i386/i386.h (TARGET_BDVER3): New definition.
>         * config/i386/i386.md (define_attr "cpu"): Add bdver3.
>         * config/i386/sse.md (sseshuf): New type attribute.
>         * config/i386/athlon.md (sseshuf):Likewise.
>         * config/i386/atom.md (sseshuf):Likewise.
>         * config/i386/ppro.md (sseshuf):Likewise.
>         * config/i386/bdver1.md (sseshuf):Likewise.
>         * config/i386/i386.opt (flag_dispatch_scheduler): Add bdver3.
>         * config/i386/i386-c.c (ix86_target_macros_internal): Add
>         bdver3 def_and_undef
>         * config/i386/driver-i386.c (host_detect_local_cpu): Let
>         -march=native recognize bdver3 processors.
>         * config/i386/i386.c (struct processor_costs bdver3_cost): New.
>         (m_BDVER3): New definition.
>         (m_AMD_MULTIPLE): Includes m_BDVER3.
>         (initial_ix86_tune_features): Add bdver3 tune.
>         (processor_target_table): Add bdver3 entry.
>         (static const char *const cpu_names): Add bdver3 entry.
>         (software_prefetching_beneficial_p): Add bdver3.
>         (ix86_option_override_internal): Add bdver3 instruction sets.
>         (ix86_option_override_internal): Remove XSAVEOPT for bdver1
>         and bdver2.
>         (ix86_issue_rate): Add bdver3.
>         (ix86_adjust_cost): Add bdver3.
>         (enum target_cpu_default): Add TARGET_CPU_DEFAULT_bdver3.
>         (enum processor_type): Add PROCESSOR_BDVER3.
>         * config/i386/bdver3.md: New file describing bdver3 pipelines.

OK for mainline.

Thanks,
Uros.
Gopalasubramanian, Ganesh - Nov. 16, 2012, 7:24 a.m.
Thank Uros for the comments.

The changes are committed to trunk
http://gcc.gnu.org/viewcvs?view=revision&revision=193548
http://gcc.gnu.org/viewcvs?view=revision&revision=193549

Regards
Ganesh

-----Original Message-----
From: Uros Bizjak [mailto:ubizjak@gmail.com] 
Sent: Wednesday, November 14, 2012 4:15 PM
To: Gopalasubramanian, Ganesh
Cc: gcc-patches@gcc.gnu.org
Subject: Re: [PATCH, i386]: AMD bdver3 enablement

On Wed, Nov 14, 2012 at 10:22 AM, Gopalasubramanian, Ganesh <Ganesh.Gopalasubramanian@amd.com> wrote:

>> sseshuf replaces sselog in some insn patterns, but should be handled in the same way in *existing* .md files.
>
> Modifications done as per the comments.
> 1. Sseshuf is added along with sselog in existing md files.
> 2. sseshuf is handled in a separate pattern in bdver3.md
>
> Bootstrapping and "make -k check" passes.
> Ok for trunk?
>
> 2012-11-14  Ganesh Gopalasubramanian  
> <Ganesh.Gopalasubramanian@amd.com>
>
>         bdver3 Enablement
>         * gcc/doc/extend.texi: Add details about bdver3.
>         * gcc/doc/invoke.texi: Add details about bdver3.
>         * config.gcc (i[34567]86-*-linux* | ...): Add bdver3.
>         (case ${target}): Add bdver3.
>         * config/i386/i386.h (TARGET_BDVER3): New definition.
>         * config/i386/i386.md (define_attr "cpu"): Add bdver3.
>         * config/i386/sse.md (sseshuf): New type attribute.
>         * config/i386/athlon.md (sseshuf):Likewise.
>         * config/i386/atom.md (sseshuf):Likewise.
>         * config/i386/ppro.md (sseshuf):Likewise.
>         * config/i386/bdver1.md (sseshuf):Likewise.
>         * config/i386/i386.opt (flag_dispatch_scheduler): Add bdver3.
>         * config/i386/i386-c.c (ix86_target_macros_internal): Add
>         bdver3 def_and_undef
>         * config/i386/driver-i386.c (host_detect_local_cpu): Let
>         -march=native recognize bdver3 processors.
>         * config/i386/i386.c (struct processor_costs bdver3_cost): New.
>         (m_BDVER3): New definition.
>         (m_AMD_MULTIPLE): Includes m_BDVER3.
>         (initial_ix86_tune_features): Add bdver3 tune.
>         (processor_target_table): Add bdver3 entry.
>         (static const char *const cpu_names): Add bdver3 entry.
>         (software_prefetching_beneficial_p): Add bdver3.
>         (ix86_option_override_internal): Add bdver3 instruction sets.
>         (ix86_option_override_internal): Remove XSAVEOPT for bdver1
>         and bdver2.
>         (ix86_issue_rate): Add bdver3.
>         (ix86_adjust_cost): Add bdver3.
>         (enum target_cpu_default): Add TARGET_CPU_DEFAULT_bdver3.
>         (enum processor_type): Add PROCESSOR_BDVER3.
>         * config/i386/bdver3.md: New file describing bdver3 pipelines.

OK for mainline.

Thanks,
Uros.

Patch

Index: gcc/doc/extend.texi
===================================================================
--- gcc/doc/extend.texi	(revision 193132)
+++ gcc/doc/extend.texi	(working copy)
@@ -9608,6 +9608,9 @@ 
 @item bdver2
 AMD family 15h Bulldozer version 2.
 
+@item bdver3
+AMD family 15h Bulldozer version 3.
+
 @item btver2
 AMD family 16h CPU.
 @end table
Index: gcc/doc/invoke.texi
===================================================================
--- gcc/doc/invoke.texi	(revision 193132)
+++ gcc/doc/invoke.texi	(working copy)
@@ -13678,6 +13678,11 @@ 
 supersets BMI, TBM, F16C, FMA, AVX, XOP, LWP, AES, PCL_MUL, CX16, MMX, SSE,
 SSE2, SSE3, SSE4A, SSSE3, SSE4.1, SSE4.2, ABM and 64-bit instruction set 
 extensions.)
+@item bdver3
+AMD Family 15h core based CPUs with x86-64 instruction set support.  (This
+supersets BMI, TBM, F16C, FMA, AVX, XOP, LWP, AES, PCL_MUL, CX16, MMX, SSE,
+SSE2, SSE3, SSE4A, SSSE3, SSE4.1, SSE4.2, ABM and 64-bit instruction set 
+extensions.)
 
 @item btver1
 CPUs based on AMD Family 14h cores with x86-64 instruction set support.  (This
Index: gcc/config.gcc
===================================================================
--- gcc/config.gcc	(revision 193132)
+++ gcc/config.gcc	(working copy)
@@ -1269,7 +1269,7 @@ 
 			TM_MULTILIB_CONFIG=`echo $TM_MULTILIB_CONFIG | sed 's/^,//'`
 			need_64bit_isa=yes
 			case X"${with_cpu}" in
-			Xgeneric|Xatom|Xcore2|Xcorei7|Xcorei7-avx|Xnocona|Xx86-64|Xbdver2|Xbdver1|Xbtver2|Xbtver1|Xamdfam10|Xbarcelona|Xk8|Xopteron|Xathlon64|Xathlon-fx|Xathlon64-sse3|Xk8-sse3|Xopteron-sse3)
+			Xgeneric|Xatom|Xcore2|Xcorei7|Xcorei7-avx|Xnocona|Xx86-64|Xbdver3|Xbdver2|Xbdver1|Xbtver2|Xbtver1|Xamdfam10|Xbarcelona|Xk8|Xopteron|Xathlon64|Xathlon-fx|Xathlon64-sse3|Xk8-sse3|Xopteron-sse3)
 				;;
 			X)
 				if test x$with_cpu_64 = x; then
@@ -1278,7 +1278,7 @@ 
 				;;
 			*)
 				echo "Unsupported CPU used in --with-cpu=$with_cpu, supported values:" 1>&2
-				echo "generic atom core2 corei7 corei7-avx nocona x86-64 bdver2 bdver1 btver2 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 bdver3 bdver2 bdver1 btver2 btver1 amdfam10 barcelona k8 opteron athlon64 athlon-fx athlon64-sse3 k8-sse3 opteron-sse3" 1>&2
 				exit 1
 				;;
 			esac
@@ -1390,7 +1390,7 @@ 
 		tmake_file="$tmake_file i386/t-sol2-64"
 		need_64bit_isa=yes
 		case X"${with_cpu}" in
-		Xgeneric|Xatom|Xcore2|Xcorei7|Xcorei7-avx|Xnocona|Xx86-64|Xbdver2|Xbdver1|Xbtver2|Xbtver1|Xamdfam10|Xbarcelona|Xk8|Xopteron|Xathlon64|Xathlon-fx|Xathlon64-sse3|Xk8-sse3|Xopteron-sse3)
+		Xgeneric|Xatom|Xcore2|Xcorei7|Xcorei7-avx|Xnocona|Xx86-64|Xbdver3|Xbdver2|Xbdver1|Xbtver2|Xbtver1|Xamdfam10|Xbarcelona|Xk8|Xopteron|Xathlon64|Xathlon-fx|Xathlon64-sse3|Xk8-sse3|Xopteron-sse3)
 			;;
 		X)
 			if test x$with_cpu_64 = x; then
@@ -1399,7 +1399,7 @@ 
 			;;
 		*)
 			echo "Unsupported CPU used in --with-cpu=$with_cpu, supported values:" 1>&2
-			echo "generic atom core2 corei7 corei7-avx nocona x86-64 bdver2 bdver1 btver2 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 bdver3 bdver2 bdver1 btver2 btver1 amdfam10 barcelona k8 opteron athlon64 athlon-fx athlon64-sse3 k8-sse3 opteron-sse3" 1>&2
 			exit 1
 			;;
 		esac
@@ -1456,7 +1456,7 @@ 
 			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|Xbdver2|Xbdver1|Xbtver2|Xbtver1|Xamdfam10|Xbarcelona|Xk8|Xopteron|Xathlon64|Xathlon-fx|Xathlon64-sse3|Xk8-sse3|Xopteron-sse3)
+				Xgeneric|Xatom|Xcore2|Xcorei7|Xcorei7-avx|Xnocona|Xx86-64|Xbdver3|Xbdver2|Xbdver1|Xbtver2|Xbtver1|Xamdfam10|Xbarcelona|Xk8|Xopteron|Xathlon64|Xathlon-fx|Xathlon64-sse3|Xk8-sse3|Xopteron-sse3)
 					;;
 				X)
 					if test x$with_cpu_64 = x; then
@@ -1465,7 +1465,7 @@ 
 					;;
 				*)
 					echo "Unsupported CPU used in --with-cpu=$with_cpu, supported values:" 1>&2
-					echo "generic atom core2 corei7 Xcorei7-avx nocona x86-64 bdver2 bdver1 btver2 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 bdver3 bdver2 bdver1 btver2 btver1 amdfam10 barcelona k8 opteron athlon64 athlon-fx athlon64-sse3 k8-sse3 opteron-sse3" 1>&2
 					exit 1
 					;;
 				esac
@@ -2706,6 +2706,10 @@ 
     ;;
   i686-*-* | i786-*-*)
     case ${target_noncanonical} in
+      bdver3-*)
+        arch=bdver3
+        cpu=bdver3
+        ;;
       bdver2-*)
         arch=bdver2
         cpu=bdver2
@@ -2807,6 +2811,10 @@ 
     ;;
   x86_64-*-*)
     case ${target_noncanonical} in
+      bdver3-*)
+        arch=bdver3
+        cpu=bdver3
+        ;;
       bdver2-*)
         arch=bdver2
         cpu=bdver2
@@ -3344,8 +3352,8 @@ 
 				;;
 			"" | x86-64 | generic | native \
 			| k8 | k8-sse3 | athlon64 | athlon64-sse3 | opteron \
-			| opteron-sse3 | athlon-fx | bdver2 | bdver1 | btver2 | btver1 \
-			| amdfam10 | barcelona | nocona | core2 | corei7 \
+			| opteron-sse3 | athlon-fx | bdver3 | bdver2 | bdver1 | btver2 \
+			| btver1 | amdfam10 | barcelona | nocona | core2 | corei7 \
 			| corei7-avx | core-avx-i | core-avx2 | atom)
 				# OK
 				;;
Index: gcc/config/i386/i386.h
===================================================================
--- gcc/config/i386/i386.h	(revision 193132)
+++ gcc/config/i386/i386.h	(working copy)
@@ -254,6 +254,7 @@ 
 #define TARGET_AMDFAM10 (ix86_tune == PROCESSOR_AMDFAM10)
 #define TARGET_BDVER1 (ix86_tune == PROCESSOR_BDVER1)
 #define TARGET_BDVER2 (ix86_tune == PROCESSOR_BDVER2)
+#define TARGET_BDVER3 (ix86_tune == PROCESSOR_BDVER3)
 #define TARGET_BTVER1 (ix86_tune == PROCESSOR_BTVER1)
 #define TARGET_BTVER2 (ix86_tune == PROCESSOR_BTVER2)
 #define TARGET_ATOM (ix86_tune == PROCESSOR_ATOM)
@@ -616,6 +617,7 @@ 
   TARGET_CPU_DEFAULT_amdfam10,
   TARGET_CPU_DEFAULT_bdver1,
   TARGET_CPU_DEFAULT_bdver2,
+  TARGET_CPU_DEFAULT_bdver3,
   TARGET_CPU_DEFAULT_btver1,
   TARGET_CPU_DEFAULT_btver2,
 
@@ -2098,6 +2100,7 @@ 
   PROCESSOR_AMDFAM10,
   PROCESSOR_BDVER1,
   PROCESSOR_BDVER2,
+  PROCESSOR_BDVER3,
   PROCESSOR_BTVER1,
   PROCESSOR_BTVER2,
   PROCESSOR_ATOM,
Index: gcc/config/i386/i386.md
===================================================================
--- gcc/config/i386/i386.md	(revision 193132)
+++ gcc/config/i386/i386.md	(working copy)
@@ -323,7 +323,7 @@ 
 
 ;; Processor type.
 (define_attr "cpu" "none,pentium,pentiumpro,geode,k6,athlon,k8,core2,corei7,
-		    atom,generic64,amdfam10,bdver1,bdver2,btver1,btver2"
+		    atom,generic64,amdfam10,bdver1,bdver2,bdver3,btver1,btver2"
   (const (symbol_ref "ix86_schedule")))
 
 ;; A basic instruction type.  Refinements due to arguments to be
@@ -336,9 +336,9 @@ 
    push,pop,call,callv,leave,
    str,bitmanip,
    fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint,
-   sselog,sselog1,sseiadd,sseiadd1,sseishft,sseishft1,sseimul,
-   sse,ssemov,sseadd,sseadd1,ssemul,ssecmp,ssecomi,ssecvt,ssecvt1,sseicvt,
-   ssediv,sseins,ssemuladd,sse4arg,lwp,
+   sselog,sselog1,sseiadd,sseiadd1,sseishft,sseishft1,sseimul,sse,
+   ssemov,sseadd,sseadd1,ssemul,ssecmp,ssecomi,ssecvt,ssecvt1,sseicvt,
+   sseshuf,sseshuf1,ssediv,sseins,ssemuladd,sse4arg,lwp,
    mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft"
   (const_string "other"))
 
@@ -353,7 +353,7 @@ 
 	   (const_string "i387")
 	 (eq_attr "type" "sselog,sselog1,sseiadd,sseiadd1,sseishft,sseishft1,sseimul,
 			  sse,ssemov,sseadd,sseadd1,ssemul,ssecmp,ssecomi,ssecvt,
-			  ssecvt1,sseicvt,ssediv,sseins,ssemuladd,sse4arg")
+			  sseshuf,sseshuf1,ssecvt1,sseicvt,ssediv,sseins,ssemuladd,sse4arg")
 	   (const_string "sse")
 	 (eq_attr "type" "mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft")
 	   (const_string "mmx")
@@ -594,7 +594,7 @@ 
 	   (if_then_else (match_operand 1 "constant_call_address_operand")
 	     (const_string "none")
 	     (const_string "load"))
-	 (and (eq_attr "type" "alu1,negnot,ishift1,sselog1")
+	 (and (eq_attr "type" "alu1,negnot,ishift1,sselog1,sseshuf1")
 	      (match_operand 1 "memory_operand"))
 	   (const_string "both")
 	 (and (match_operand 0 "memory_operand")
@@ -609,7 +609,7 @@ 
 		   imov,imovx,icmp,test,bitmanip,
 		   fmov,fcmp,fsgn,
 		   sse,ssemov,ssecmp,ssecomi,ssecvt,ssecvt1,sseicvt,sselog1,
-		   sseadd1,sseiadd1,mmx,mmxmov,mmxcmp,mmxcvt")
+		   sseshuf1,sseadd1,sseiadd1,mmx,mmxmov,mmxcmp,mmxcvt")
 	      (match_operand 2 "memory_operand"))
 	   (const_string "load")
 	 (and (eq_attr "type" "icmov,ssemuladd,sse4arg")
@@ -947,6 +947,7 @@ 
 (include "k6.md")
 (include "athlon.md")
 (include "bdver1.md")
+(include "bdver3.md")
 (include "geode.md")
 (include "atom.md")
 (include "core2.md")
Index: gcc/config/i386/athlon.md
===================================================================
--- gcc/config/i386/athlon.md	(revision 193132)
+++ gcc/config/i386/athlon.md	(working copy)
@@ -710,30 +710,30 @@ 
 
 (define_insn_reservation "athlon_sselog_load" 3
 			 (and (eq_attr "cpu" "athlon")
-			      (and (eq_attr "type" "sselog,sselog1")
+			      (and (eq_attr "type" "sselog,sselog1,sseshuf,sseshuf1")
 				   (eq_attr "memory" "load")))
 			 "athlon-vector,athlon-fpload2,(athlon-fmul*2)")
 (define_insn_reservation "athlon_sselog_load_k8" 5
 			 (and (eq_attr "cpu" "k8,generic64")
-			      (and (eq_attr "type" "sselog,sselog1")
+			      (and (eq_attr "type" "sselog,sselog1,sseshuf,sseshuf1")
 				   (eq_attr "memory" "load")))
 			 "athlon-double,athlon-fpload2k8,(athlon-fmul*2)")
 (define_insn_reservation "athlon_sselog_load_amdfam10" 4
 			 (and (eq_attr "cpu" "amdfam10")
-			      (and (eq_attr "type" "sselog,sselog1")
+			      (and (eq_attr "type" "sselog,sselog1,sseshuf,sseshuf1")
 				   (eq_attr "memory" "load")))
 			 "athlon-direct,athlon-fploadk8,(athlon-fadd|athlon-fmul)")
 (define_insn_reservation "athlon_sselog" 3
 			 (and (eq_attr "cpu" "athlon")
-			      (eq_attr "type" "sselog,sselog1"))
+			      (eq_attr "type" "sselog,sselog1,sseshuf,sseshuf1"))
 			 "athlon-vector,athlon-fpsched,athlon-fmul*2")
 (define_insn_reservation "athlon_sselog_k8" 3
 			 (and (eq_attr "cpu" "k8,generic64")
-			      (eq_attr "type" "sselog,sselog1"))
+			      (eq_attr "type" "sselog,sselog1,sseshuf,sseshuf1"))
 			 "athlon-double,athlon-fpsched,athlon-fmul")
 (define_insn_reservation "athlon_sselog_amdfam10" 2
 			 (and (eq_attr "cpu" "amdfam10")
-			      (eq_attr "type" "sselog,sselog1"))
+			      (eq_attr "type" "sselog,sselog1,sseshuf,sseshuf1"))
 			 "athlon-direct,athlon-fpsched,(athlon-fadd|athlon-fmul)")
 
 ;; ??? pcmp executes in addmul, probably not worthwhile to bother about that.
Index: gcc/config/i386/atom.md
===================================================================
--- gcc/config/i386/atom.md	(revision 193132)
+++ gcc/config/i386/atom.md	(working copy)
@@ -433,25 +433,25 @@ 
 
 (define_insn_reservation  "atom_sselog" 1
   (and (eq_attr "cpu" "atom")
-       (and (eq_attr "type" "sselog")
+       (and (eq_attr "type" "sselog,sseshuf")
             (eq_attr "memory" "none")))
   "atom-simple-either")
 
 (define_insn_reservation  "atom_sselog_mem" 1
   (and (eq_attr "cpu" "atom")
-       (and (eq_attr "type" "sselog")
+       (and (eq_attr "type" "sselog,sseshuf")
             (eq_attr "memory" "!none")))
   "atom-simple-either")
 
 (define_insn_reservation  "atom_sselog1" 1
   (and (eq_attr "cpu" "atom")
-       (and (eq_attr "type" "sselog1")
+       (and (eq_attr "type" "sselog1,sseshuf1")
             (eq_attr "memory" "none")))
   "atom-simple-0")
 
 (define_insn_reservation  "atom_sselog1_mem" 1
   (and (eq_attr "cpu" "atom")
-       (and (eq_attr "type" "sselog1")
+       (and (eq_attr "type" "sselog1,sseshuf1")
             (eq_attr "memory" "!none")))
   "atom-simple-0")
 
@@ -743,8 +743,8 @@ 
                   atom_imul_mem, atom_icmp_mem,
                   atom_test_mem, atom_icmov_mem, atom_sselog_mem,
                   atom_sselog1_mem, atom_fmov_mem, atom_sseadd_mem,
-                  atom_ishift_mem, atom_ishift1_mem, 
-                  atom_rotate_mem, atom_rotate1_mem"
+                  atom_ishift_mem, atom_ishift1_mem, atom_rotate_mem, 
+                  atom_rotate1_mem"
                   "ix86_agi_dependent")
 
 ;; Stall from imul to lea is 8 cycles.
Index: gcc/config/i386/ppro.md
===================================================================
--- gcc/config/i386/ppro.md	(revision 193132)
+++ gcc/config/i386/ppro.md	(working copy)
@@ -690,14 +690,14 @@ 
 			 (and (eq_attr "cpu" "pentiumpro")
 			      (and (eq_attr "memory" "none")
 				   (and (eq_attr "mode" "V4SF")
-					(eq_attr "type" "sselog,sselog1"))))
+					(eq_attr "type" "sselog,sselog1,sseshuf,sseshuf1"))))
 			 "decodern,p1")
 
 (define_insn_reservation "ppro_sse_log_V4SF_load" 2
 			 (and (eq_attr "cpu" "pentiumpro")
 			      (and (eq_attr "memory" "load")
 				   (and (eq_attr "mode" "V4SF")
-					(eq_attr "type" "sselog,sselog1"))))
+					(eq_attr "type" "sselog,sselog1,sseshuf,sseshuf1"))))
 			 "decoder0,(p2+p1)")
 
 (define_insn_reservation "ppro_sse_mov_V4SF" 1
Index: gcc/config/i386/sse.md
===================================================================
--- gcc/config/i386/sse.md	(revision 193132)
+++ gcc/config/i386/sse.md	(working copy)
@@ -3860,7 +3860,7 @@ 
 
   return "vshufps\t{%3, %2, %1, %0|%0, %1, %2, %3}";
 }
-  [(set_attr "type" "sselog")
+  [(set_attr "type" "sseshuf")
    (set_attr "length_immediate" "1")
    (set_attr "prefix" "vex")
    (set_attr "mode" "V8SF")])
@@ -3911,7 +3911,7 @@ 
     }
 }
   [(set_attr "isa" "noavx,avx")
-   (set_attr "type" "sselog")
+   (set_attr "type" "sseshuf")
    (set_attr "length_immediate" "1")
    (set_attr "prefix" "orig,vex")
    (set_attr "mode" "V4SF")])
@@ -4018,7 +4018,7 @@ 
    vmovlps\t{%2, %1, %0|%0, %1, %2}
    %vmovlps\t{%2, %0|%0, %2}"
   [(set_attr "isa" "noavx,avx,noavx,avx,*")
-   (set_attr "type" "sselog,sselog,ssemov,ssemov,ssemov")
+   (set_attr "type" "sseshuf,sseshuf,ssemov,ssemov,ssemov")
    (set_attr "length_immediate" "1,1,*,*,*")
    (set_attr "prefix" "orig,vex,orig,vex,maybe_vex")
    (set_attr "mode" "V4SF,V4SF,V2SF,V2SF,V2SF")])
@@ -4072,7 +4072,7 @@ 
    vbroadcastss\t{%1, %0|%0, %1}
    shufps\t{$0, %0, %0|%0, %0, 0}"
   [(set_attr "isa" "avx,avx,noavx")
-   (set_attr "type" "sselog1,ssemov,sselog1")
+   (set_attr "type" "sseshuf1,ssemov,sseshuf1")
    (set_attr "length_immediate" "1,0,1")
    (set_attr "prefix_extra" "0,1,*")
    (set_attr "prefix" "vex,vex,orig")
@@ -4802,7 +4802,7 @@ 
 
   return "vshufpd\t{%3, %2, %1, %0|%0, %1, %2, %3}";
 }
-  [(set_attr "type" "sselog")
+  [(set_attr "type" "sseshuf")
    (set_attr "length_immediate" "1")
    (set_attr "prefix" "vex")
    (set_attr "mode" "V4DF")])
@@ -4916,7 +4916,7 @@ 
     }
 }
   [(set_attr "isa" "noavx,avx")
-   (set_attr "type" "sselog")
+   (set_attr "type" "sseshuf")
    (set_attr "length_immediate" "1")
    (set_attr "prefix" "orig,vex")
    (set_attr "mode" "V2DF")])
Index: gcc/config/i386/i386-c.c
===================================================================
--- gcc/config/i386/i386-c.c	(revision 193132)
+++ gcc/config/i386/i386-c.c	(working copy)
@@ -114,6 +114,10 @@ 
       def_or_undef (parse_in, "__bdver2");
       def_or_undef (parse_in, "__bdver2__");
       break;
+    case PROCESSOR_BDVER3:
+      def_or_undef (parse_in, "__bdver3");
+      def_or_undef (parse_in, "__bdver3__");
+      break;
     case PROCESSOR_BTVER1:
       def_or_undef (parse_in, "__btver1");
       def_or_undef (parse_in, "__btver1__");
@@ -209,7 +213,10 @@ 
     case PROCESSOR_BDVER2:
       def_or_undef (parse_in, "__tune_bdver2__");
       break;
-   case PROCESSOR_BTVER1:
+    case PROCESSOR_BDVER3:
+      def_or_undef (parse_in, "__tune_bdver3__");
+      break;
+    case PROCESSOR_BTVER1:
       def_or_undef (parse_in, "__tune_btver1__");
       break;
     case PROCESSOR_BTVER2:
Index: gcc/config/i386/i386.opt
===================================================================
--- gcc/config/i386/i386.opt	(revision 193132)
+++ gcc/config/i386/i386.opt	(working copy)
@@ -419,7 +419,7 @@ 
 
 mdispatch-scheduler
 Target RejectNegative Var(flag_dispatch_scheduler)
-Do dispatch scheduling if processor is bdver1 or bdver2 and Haifa scheduling
+Do dispatch scheduling if processor is bdver1 or bdver2 or bdver3 and Haifa scheduling
 is selected.
 
 mprefer-avx128
Index: gcc/config/i386/bdver1.md
===================================================================
--- gcc/config/i386/bdver1.md	(revision 193132)
+++ gcc/config/i386/bdver1.md	(working copy)
@@ -482,23 +482,23 @@ 
 ;; SSE logs.
 (define_insn_reservation "bdver1_sselog_load_256" 7
 			 (and (eq_attr "cpu" "bdver1,bdver2")
-			      (and (eq_attr "type" "sselog,sselog1")
+			      (and (eq_attr "type" "sselog,sselog1,sseshuf,sseshuf1")
 				   (and (eq_attr "mode" "V8SF")
 				   (eq_attr "memory" "load"))))
 			 "bdver1-double,bdver1-fpload,bdver1-fmal")
 (define_insn_reservation "bdver1_sselog_256" 3
 			 (and (eq_attr "cpu" "bdver1,bdver2")
-			      (and (eq_attr "type" "sselog,sselog1")
+			      (and (eq_attr "type" "sselog,sselog1,sseshuf,sseshuf1")
                                    (eq_attr "mode" "V8SF")))
 			 "bdver1-double,bdver1-fpsched,bdver1-fmal")
 (define_insn_reservation "bdver1_sselog_load" 6
 			 (and (eq_attr "cpu" "bdver1,bdver2")
-			      (and (eq_attr "type" "sselog,sselog1")
+			      (and (eq_attr "type" "sselog,sselog1,sseshuf,sseshuf1")
 				   (eq_attr "memory" "load")))
 			 "bdver1-direct,bdver1-fpload,bdver1-fxbar")
 (define_insn_reservation "bdver1_sselog" 2
 			 (and (eq_attr "cpu" "bdver1,bdver2")
-			      (eq_attr "type" "sselog,sselog1"))
+			      (eq_attr "type" "sselog,sselog1,sseshuf,sseshuf1"))
 			 "bdver1-direct,bdver1-fpsched,bdver1-fxbar")
 
 ;; PCMP actually executes in FMAL.
Index: gcc/config/i386/driver-i386.c
===================================================================
--- gcc/config/i386/driver-i386.c	(revision 193132)
+++ gcc/config/i386/driver-i386.c	(working copy)
@@ -542,6 +542,8 @@ 
 	processor = PROCESSOR_GEODE;
       else if (has_movbe)
 	processor = PROCESSOR_BTVER2;
+      else if (has_xsaveopt)
+        processor = PROCESSOR_BDVER3;
       else if (has_bmi)
         processor = PROCESSOR_BDVER2;
       else if (has_xop)
@@ -712,6 +714,9 @@ 
     case PROCESSOR_BDVER2:
       cpu = "bdver2";
       break;
+    case PROCESSOR_BDVER3:
+      cpu = "bdver3";
+      break;
     case PROCESSOR_BTVER1:
       cpu = "btver1";
       break;
Index: gcc/config/i386/i386.c
===================================================================
--- gcc/config/i386/i386.c	(revision 193132)
+++ gcc/config/i386/i386.c	(working copy)
@@ -1427,6 +1427,85 @@ 
   1,					/* cond_not_taken_branch_cost.  */
 };
 
+struct processor_costs bdver3_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 */
+  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.  */
+
+  /*  BDVER3 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 */
@@ -1987,7 +2066,8 @@ 
 #define m_AMDFAM10 (1<<PROCESSOR_AMDFAM10)
 #define m_BDVER1 (1<<PROCESSOR_BDVER1)
 #define m_BDVER2 (1<<PROCESSOR_BDVER2)
-#define m_BDVER	(m_BDVER1 | m_BDVER2)
+#define m_BDVER3 (1<<PROCESSOR_BDVER3)
+#define m_BDVER	(m_BDVER1 | m_BDVER2 | m_BDVER3)
 #define m_BTVER (m_BTVER1 | m_BTVER2)
 #define m_BTVER1 (1<<PROCESSOR_BTVER1)
 #define m_BTVER2 (1<<PROCESSOR_BTVER2)
@@ -2690,6 +2770,7 @@ 
   {&amdfam10_cost, 32, 24, 32, 7, 32},
   {&bdver1_cost, 32, 24, 32, 7, 32},
   {&bdver2_cost, 32, 24, 32, 7, 32},
+  {&bdver3_cost, 32, 24, 32, 7, 32},
   {&btver1_cost, 32, 24, 32, 7, 32},
   {&btver2_cost, 32, 24, 32, 7, 32},
   {&atom_cost, 16, 15, 16, 7, 16}
@@ -2722,6 +2803,7 @@ 
   "amdfam10",
   "bdver1",
   "bdver2",
+  "bdver3",
   "btver1",
   "btver2"
 };
@@ -3173,18 +3255,24 @@ 
 	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_FMA4
-	| PTA_XOP | PTA_LWP | PTA_PRFCHW | PTA_FXSR | PTA_XSAVE
-	| PTA_XSAVEOPT},
+	| PTA_XOP | PTA_LWP | PTA_PRFCHW | PTA_FXSR | PTA_XSAVE},
       {"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_FMA4
 	| PTA_XOP | PTA_LWP | PTA_BMI | PTA_TBM | PTA_F16C
-	| PTA_FMA | PTA_PRFCHW | PTA_FXSR | PTA_XSAVE | PTA_XSAVEOPT},
+	| PTA_FMA | PTA_PRFCHW | PTA_FXSR | PTA_XSAVE},
+      {"bdver3", PROCESSOR_BDVER3, CPU_BDVER3,
+	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 | PTA_PRFCHW | PTA_FXSR | PTA_XSAVE 
+	| PTA_XSAVEOPT},
       {"btver1", PROCESSOR_BTVER1, CPU_GENERIC64,
 	PTA_64BIT | PTA_MMX |  PTA_SSE  | PTA_SSE2 | PTA_SSE3
 	| PTA_SSSE3 | PTA_SSE4A |PTA_ABM | PTA_CX16 | PTA_PRFCHW
-	| PTA_FXSR | PTA_XSAVE | PTA_XSAVEOPT},
+	| PTA_FXSR | PTA_XSAVE},
       {"btver2", PROCESSOR_BTVER2, CPU_GENERIC64,
 	PTA_64BIT | PTA_MMX |  PTA_SSE  | PTA_SSE2 | PTA_SSE3
 	| PTA_SSSE3 | PTA_SSE4A |PTA_ABM | PTA_CX16 | PTA_SSE4_1
@@ -24073,6 +24161,7 @@ 
     case PROCESSOR_GENERIC64:
     case PROCESSOR_BDVER1:
     case PROCESSOR_BDVER2:
+    case PROCESSOR_BDVER3:
     case PROCESSOR_BTVER1:
       return 3;
 
@@ -24262,6 +24351,7 @@ 
     case PROCESSOR_AMDFAM10:
     case PROCESSOR_BDVER1:
     case PROCESSOR_BDVER2:
+    case PROCESSOR_BDVER3:
     case PROCESSOR_BTVER1:
     case PROCESSOR_BTVER2:
     case PROCESSOR_ATOM:
@@ -28591,7 +28681,8 @@ 
     M_AMDFAM10H_SHANGHAI,
     M_AMDFAM10H_ISTANBUL,
     M_AMDFAM15H_BDVER1,
-    M_AMDFAM15H_BDVER2
+    M_AMDFAM15H_BDVER2,
+    M_AMDFAM15H_BDVER3
   };
 
   static struct _arch_names_table
@@ -28616,6 +28707,7 @@ 
       {"amdfam15h", M_AMDFAM15H},
       {"bdver1", M_AMDFAM15H_BDVER1},
       {"bdver2", M_AMDFAM15H_BDVER2},
+      {"bdver3", M_AMDFAM15H_BDVER3},
     };
 
   static struct _isa_names_table
@@ -40962,7 +41054,7 @@ 
 static bool
 has_dispatch (rtx insn, int action)
 {
-  if ((TARGET_BDVER1 || TARGET_BDVER2)
+  if ((TARGET_BDVER1 || TARGET_BDVER2 || TARGET_BDVER3)
       && flag_dispatch_scheduler)
     switch (action)
       {