]> git.ipfire.org Git - thirdparty/gcc.git/blobdiff - gcc/config/i386/i386.md
i386: Fix TARGET_USE_VECTOR_FP_CONVERTS SF->DF float_extend splitter [PR113133]
[thirdparty/gcc.git] / gcc / config / i386 / i386.md
index 89a7fb0de2601eddc9ab828a77ddcffc7b0c23af..e693d937ba4a23523b1d7f600d6341fd7bc982ac 100644 (file)
   UNSPEC_SBB
   UNSPEC_CC_NE
   UNSPEC_STC
+  UNSPEC_PUSHFL
+  UNSPEC_POPFL
 
   ;; For SSE/MMX support:
   UNSPEC_FIX_NOTRUNC
   ;; For insn_callee_abi:
   UNSPEC_CALLEE_ABI
 
+  ;; For APX PUSH2/POP2 support
+  UNSPEC_APXPUSH2
+  UNSPEC_APXPOP2_LOW
+  UNSPEC_APXPOP2_HIGH
+
+  ;; For APX PPX support
+  UNSPEC_APX_PPX
 ])
 
 (define_c_enum "unspecv" [
 
   ;; For PREFETCHI support
   UNSPECV_PREFETCHI
+
+  ;; For USER_MSR support
+  UNSPECV_URDMSR
+  UNSPECV_UWRMSR
 ])
 
 ;; Constants to represent rounding modes in the ROUND instruction
    (MASK5_REG                  73)
    (MASK6_REG                  74)
    (MASK7_REG                  75)
-   (FIRST_PSEUDO_REG           76)
+   (R16_REG                    76)
+   (R17_REG                    77)
+   (R18_REG                    78)
+   (R19_REG                    79)
+   (R20_REG                    80)
+   (R21_REG                    81)
+   (R22_REG                    82)
+   (R23_REG                    83)
+   (R24_REG                    84)
+   (R25_REG                    85)
+   (R26_REG                    86)
+   (R27_REG                    87)
+   (R28_REG                    88)
+   (R29_REG                    89)
+   (R30_REG                    90)
+   (R31_REG                    91)
+   (FIRST_PSEUDO_REG           92)
   ])
 
 ;; Insn callee abi index.
 \f
 ;; Processor type.
 (define_attr "cpu" "none,pentium,pentiumpro,geode,k6,athlon,k8,core2,nehalem,
-                   atom,slm,glm,haswell,generic,lujiazui,amdfam10,bdver1,
+                   atom,slm,glm,haswell,generic,lujiazui,yongfeng,amdfam10,bdver1,
                    bdver2,bdver3,bdver4,btver2,znver1,znver2,znver3,znver4"
   (const (symbol_ref "ix86_schedule")))
 
           (const_string "unknown")]
         (const_string "integer")))
 
+;; Used to control the "enabled" attribute on a per-instruction basis.
+(define_attr "isa" "base,x64,nox64,x64_sse2,x64_sse4,x64_sse4_noavx,
+                   x64_avx,x64_avx512bw,x64_avx512dq,aes,apx_ndd,
+                   sse_noavx,sse2,sse2_noavx,sse3,sse3_noavx,sse4,sse4_noavx,
+                   avx,noavx,avx2,noavx2,bmi,bmi2,fma4,fma,avx512f,avx512f_512,
+                   noavx512f,avx512bw,avx512bw_512,noavx512bw,avx512dq,
+                   noavx512dq,fma_or_avx512vl,avx512vl,noavx512vl,avxvnni,
+                   avx512vnnivl,avx512fp16,avxifma,avx512ifmavl,avxneconvert,
+                   avx512bf16vl,vpclmulqdqvl,avx_noavx512f,avx_noavx512vl"
+  (const_string "base"))
+
 ;; The (bounding maximum) length of an instruction immediate.
 (define_attr "length_immediate" ""
   (cond [(eq_attr "type" "incdec,setcc,icmov,str,lea,other,multi,idiv,leave,
                          bitmanip,imulx,msklog,mskmov")
           (const_int 0)
+        (ior (eq_attr "type" "sse4arg")
+             (eq_attr "isa" "fma4"))
+          (const_int 1)
         (eq_attr "unit" "i387,sse,mmx")
           (const_int 0)
         (eq_attr "type" "alu,alu1,negnot,imovx,ishift,ishiftx,ishift1,
        (const_int 0)))
 
 ;; There are also additional prefixes in 3DNOW, SSSE3.
-;; ssemuladd,sse4arg default to 0f24/0f25 and DREX byte,
-;; sseiadd1,ssecvt1 to 0f7a with no DREX byte.
 ;; 3DNOW has 0f0f prefix, SSSE3 and SSE4_{1,2} 0f38/0f3a.
+;; While generally inapplicable to VEX/XOP/EVEX encodings, "length_vex" uses
+;; the attribute evaluating to zero to know that VEX2 encoding may be usable.
 (define_attr "prefix_extra" ""
-  (cond [(eq_attr "type" "ssemuladd,sse4arg")
-          (const_int 2)
-        (eq_attr "type" "sseiadd1,ssecvt1")
+  (cond [(eq_attr "type" "ssemuladd,sse4arg,sseiadd1,ssecvt1")
           (const_int 1)
        ]
        (const_int 0)))
            (const_string "vex")
          (eq_attr "mode" "XI,V16SF,V8DF")
            (const_string "evex")
+        (eq_attr "type" "ssemuladd")
+          (if_then_else (eq_attr "isa" "fma4")
+            (const_string "vex")
+            (const_string "maybe_evex"))
+        (eq_attr "type" "sse4arg")
+          (const_string "vex")
         ]
         (const_string "orig")))
 
 ;; Define attribute to indicate unaligned ssemov insns
 (define_attr "movu" "0,1" (const_string "0"))
 
-;; Used to control the "enabled" attribute on a per-instruction basis.
-(define_attr "isa" "base,x64,nox64,x64_sse2,x64_sse4,x64_sse4_noavx,
-                   x64_avx,x64_avx512bw,x64_avx512dq,aes,
-                   sse_noavx,sse2,sse2_noavx,sse3,sse3_noavx,sse4,sse4_noavx,
-                   avx,noavx,avx2,noavx2,bmi,bmi2,fma4,fma,avx512f,noavx512f,
-                   avx512bw,noavx512bw,avx512dq,noavx512dq,fma_or_avx512vl,
-                   avx512vl,noavx512vl,avxvnni,avx512vnnivl,avx512fp16,avxifma,
-                   avx512ifmavl,avxneconvert,avx512bf16vl,vpclmulqdqvl"
-  (const_string "base"))
+;; Define attribute to limit memory address register set.
+(define_attr "addr" "gpr8,gpr16,gpr32" (const_string "gpr32"))
 
 ;; Define instruction set of MMX instructions
 (define_attr "mmx_isa" "base,native,sse,sse_noavx,avx"
         (eq_attr "isa" "sse4_noavx")
           (symbol_ref "TARGET_SSE4_1 && !TARGET_AVX")
         (eq_attr "isa" "avx") (symbol_ref "TARGET_AVX")
+        (eq_attr "isa" "avx_noavx512f")
+          (symbol_ref "TARGET_AVX && !TARGET_AVX512F")
+        (eq_attr "isa" "avx_noavx512vl")
+          (symbol_ref "TARGET_AVX && !TARGET_AVX512VL")
         (eq_attr "isa" "noavx") (symbol_ref "!TARGET_AVX")
         (eq_attr "isa" "avx2") (symbol_ref "TARGET_AVX2")
         (eq_attr "isa" "noavx2") (symbol_ref "!TARGET_AVX2")
         (eq_attr "isa" "fma_or_avx512vl")
           (symbol_ref "TARGET_FMA || TARGET_AVX512VL")
         (eq_attr "isa" "avx512f") (symbol_ref "TARGET_AVX512F")
+        (eq_attr "isa" "avx512f_512")
+          (symbol_ref "TARGET_AVX512F && TARGET_EVEX512")
         (eq_attr "isa" "noavx512f") (symbol_ref "!TARGET_AVX512F")
         (eq_attr "isa" "avx512bw") (symbol_ref "TARGET_AVX512BW")
+        (eq_attr "isa" "avx512bw_512")
+          (symbol_ref "TARGET_AVX512BW && TARGET_EVEX512")
         (eq_attr "isa" "noavx512bw") (symbol_ref "!TARGET_AVX512BW")
         (eq_attr "isa" "avx512dq") (symbol_ref "TARGET_AVX512DQ")
         (eq_attr "isa" "noavx512dq") (symbol_ref "!TARGET_AVX512DQ")
           (symbol_ref "TARGET_AVX512BF16 && TARGET_AVX512VL")
         (eq_attr "isa" "vpclmulqdqvl")
           (symbol_ref "TARGET_VPCLMULQDQ && TARGET_AVX512VL")
+        (eq_attr "isa" "apx_ndd")
+          (symbol_ref "TARGET_APX_NDD")
 
         (eq_attr "mmx_isa" "native")
           (symbol_ref "!TARGET_MMX_WITH_SSE")
    (set_attr "type" "multi")])
 
 (define_code_iterator plusminus [plus minus])
+(define_code_iterator plusminusmult [plus minus mult])
 (define_code_iterator plusminusmultdiv [plus minus mult div])
 
 (define_code_iterator sat_plusminus [ss_plus us_plus ss_minus us_minus])
 (define_code_iterator any_shift [ashift lshiftrt ashiftrt])
 
 ;; Base name for insn mnemonic.
-(define_code_attr shift [(ashift "sll") (lshiftrt "shr") (ashiftrt "sar")])
+(define_code_attr shift [(ashift "sal") (lshiftrt "shr") (ashiftrt "sar")])
 (define_code_attr vshift [(ashift "sll") (lshiftrt "srl") (ashiftrt "sra")])
 
 ;; Mapping of rotate operators
 (include "core2.md")
 (include "haswell.md")
 (include "lujiazui.md")
+(include "yongfeng.md")
 
 \f
 ;; Operand and operator predicates and constraints
   DONE;
 })
 
+(define_expand "cbranchxi4"
+  [(set (reg:CC FLAGS_REG)
+       (compare:CC (match_operand:XI 1 "nonimmediate_operand")
+                   (match_operand:XI 2 "nonimmediate_operand")))
+   (set (pc) (if_then_else
+              (match_operator 0 "bt_comparison_operator"
+               [(reg:CC FLAGS_REG) (const_int 0)])
+              (label_ref (match_operand 3))
+              (pc)))]
+  "TARGET_AVX512F && TARGET_EVEX512 && !TARGET_PREFER_AVX256"
+{
+  ix86_expand_branch (GET_CODE (operands[0]),
+                     operands[1], operands[2], operands[3]);
+  DONE;
+})
+
 (define_expand "cstore<mode>4"
   [(set (reg:CC FLAGS_REG)
        (compare:CC (match_operand:SDWIM 2 "nonimmediate_operand")
   [(set_attr "type" "icmp")
    (set_attr "mode" "<MODE>")])
 
-(define_insn "*cmpqi_ext<mode>_1_mem_rex64"
-  [(set (reg FLAGS_REG)
-       (compare
-         (match_operand:QI 0 "norex_memory_operand" "Bn")
-         (subreg:QI
-           (match_operator:SWI248 2 "extract_operator"
-             [(match_operand 1 "int248_register_operand" "Q")
-              (const_int 8)
-              (const_int 8)]) 0)))]
-  "TARGET_64BIT && reload_completed
-   && ix86_match_ccmode (insn, CCmode)"
-  "cmp{b}\t{%h1, %0|%0, %h1}"
-  [(set_attr "type" "icmp")
-   (set_attr "mode" "QI")])
-
 (define_insn "*cmpqi_ext<mode>_1"
   [(set (reg FLAGS_REG)
        (compare
-         (match_operand:QI 0 "nonimmediate_operand" "QBc,m")
+         (match_operand:QI 0 "nonimmediate_operand" "QBn")
          (subreg:QI
            (match_operator:SWI248 2 "extract_operator"
-             [(match_operand 1 "int248_register_operand" "Q,Q")
+             [(match_operand 1 "int248_register_operand" "Q")
               (const_int 8)
               (const_int 8)]) 0)))]
   "ix86_match_ccmode (insn, CCmode)"
   "cmp{b}\t{%h1, %0|%0, %h1}"
-  [(set_attr "isa" "*,nox64")
+  [(set_attr "addr" "gpr8")
    (set_attr "type" "icmp")
    (set_attr "mode" "QI")])
 
-(define_peephole2
-  [(set (match_operand:QI 0 "register_operand")
-       (match_operand:QI 1 "norex_memory_operand"))
-   (set (match_operand 3 "flags_reg_operand")
-       (match_operator 4 "compare_operator"
-         [(match_dup 0)
-          (subreg:QI
-            (match_operator:SWI248 5 "extract_operator"
-              [(match_operand 2 "int248_register_operand")
-               (const_int 8)
-               (const_int 8)]) 0)]))]
-  "TARGET_64BIT
-   && peep2_reg_dead_p (2, operands[0])"
-  [(set (match_dup 3)
-       (match_op_dup 4
-         [(match_dup 1)
-          (subreg:QI
-            (match_op_dup 5
-              [(match_dup 2)
-               (const_int 8)
-               (const_int 8)]) 0)]))])
-
 (define_insn "*cmpqi_ext<mode>_2"
   [(set (reg FLAGS_REG)
        (compare
              (const_int 8)) 0)
          (match_operand:QI 1 "const_int_operand")))])
 
-(define_insn "*cmpqi_ext<mode>_3_mem_rex64"
-  [(set (reg FLAGS_REG)
-       (compare
-         (subreg:QI
-           (match_operator:SWI248 2 "extract_operator"
-             [(match_operand 0 "int248_register_operand" "Q")
-              (const_int 8)
-              (const_int 8)]) 0)
-         (match_operand:QI 1 "norex_memory_operand" "Bn")))]
-  "TARGET_64BIT && reload_completed
-   && ix86_match_ccmode (insn, CCmode)"
-  "cmp{b}\t{%1, %h0|%h0, %1}"
-  [(set_attr "type" "icmp")
-   (set_attr "mode" "QI")])
-
 (define_insn "*cmpqi_ext<mode>_3"
   [(set (reg FLAGS_REG)
        (compare
          (subreg:QI
            (match_operator:SWI248 2 "extract_operator"
-             [(match_operand 0 "int248_register_operand" "Q,Q")
+             [(match_operand 0 "int248_register_operand" "Q")
               (const_int 8)
               (const_int 8)]) 0)
-         (match_operand:QI 1 "general_operand" "QnBc,m")))]
+         (match_operand:QI 1 "general_operand" "QnBn")))]
   "ix86_match_ccmode (insn, CCmode)"
   "cmp{b}\t{%1, %h0|%h0, %1}"
-  [(set_attr "isa" "*,nox64")
+  [(set_attr "addr" "gpr8")
    (set_attr "type" "icmp")
    (set_attr "mode" "QI")])
 
-(define_peephole2
-  [(set (match_operand:QI 0 "register_operand")
-       (match_operand:QI 1 "norex_memory_operand"))
-   (set (match_operand 3 "flags_reg_operand")
-       (match_operator 4 "compare_operator"
-         [(subreg:QI
-            (match_operator:SWI248 5 "extract_operator"
-              [(match_operand 2 "int248_register_operand")
-               (const_int 8)
-               (const_int 8)]) 0)
-          (match_dup 0)]))]
-  "TARGET_64BIT
-   && peep2_reg_dead_p (2, operands[0])"
-  [(set (match_dup 3)
-       (match_op_dup 4
-         [(subreg:QI
-            (match_op_dup 5
-              [(match_dup 2)
-               (const_int 8)
-               (const_int 8)]) 0)
-          (match_dup 1)]))])
-
 (define_insn "*cmpqi_ext<mode>_4"
   [(set (reg FLAGS_REG)
        (compare
   [(set_attr "type" "pop")
    (set_attr "mode" "<MODE>")])
 
-(define_insn "*pushfl<mode>2"
+(define_insn "@pushfl<mode>2"
   [(set (match_operand:W 0 "push_operand" "=<")
-       (match_operand:W 1 "flags_reg_operand"))]
+       (unspec:W [(match_operand:CC 1 "flags_reg_operand")]
+                 UNSPEC_PUSHFL))]
   ""
   "pushf{<imodesuffix>}"
   [(set_attr "type" "push")
    (set_attr "mode" "<MODE>")])
 
-(define_insn "*popfl<mode>1"
-  [(set (match_operand:W 0 "flags_reg_operand")
-       (match_operand:W 1 "pop_operand" ">"))]
+(define_insn "@popfl<mode>1"
+  [(set (match_operand:CC 0 "flags_reg_operand")
+       (unspec:CC [(match_operand:W 1 "pop_operand" ">")]
+                  UNSPEC_POPFL))]
   ""
   "popf{<imodesuffix>}"
   [(set_attr "type" "pop")
 (define_expand "movxi"
   [(set (match_operand:XI 0 "nonimmediate_operand")
        (match_operand:XI 1 "general_operand"))]
-  "TARGET_AVX512F"
+  "TARGET_AVX512F && TARGET_EVEX512"
   "ix86_expand_vector_move (XImode, operands); DONE;")
 
 (define_expand "movoi"
 (define_insn "*movxi_internal_avx512f"
   [(set (match_operand:XI 0 "nonimmediate_operand"             "=v,v ,v ,m")
        (match_operand:XI 1 "nonimmediate_or_sse_const_operand" " C,BC,vm,v"))]
-  "TARGET_AVX512F
+  "TARGET_AVX512F && TARGET_EVEX512
    && (register_operand (operands[0], XImode)
        || register_operand (operands[1], XImode))"
 {
    (set_attr "mode" "OI")])
 
 (define_insn "*movti_internal"
-  [(set (match_operand:TI 0 "nonimmediate_operand" "=!r ,o ,v,v ,v ,m,?r,?Yd")
-       (match_operand:TI 1 "general_operand"      "riFo,re,C,BC,vm,v,Yd,r"))]
+  [(set (match_operand:TI 0 "nonimmediate_operand" "=!r ,o ,v,v ,v ,m,?jc,?Yd")
+       (match_operand:TI 1 "general_operand"      "riFo,re,C,BC,vm,v,Yd,jc"))]
   "(TARGET_64BIT
     && !(MEM_P (operands[0]) && MEM_P (operands[1])))
    || (TARGET_SSE
 
 (define_insn "*movdi_internal"
   [(set (match_operand:DI 0 "nonimmediate_operand"
-    "=r  ,o  ,r,r  ,r,m ,*y,*y,?*y,?m,?r,?*y,?v,?v,?v,m ,m,?r ,?*Yd,?r,?v,?*y,?*x,*k,*k  ,*r,*m,*k")
+    "=r  ,o  ,r,r  ,r,m ,*y,*y,?*y,?m,?r,?*y,?Yv,?v,?v,m ,m,?jc,?*Yd,?r,?v,?*y,?*x,*k,*k  ,*r,*m,*k")
        (match_operand:DI 1 "general_operand"
-    "riFo,riF,Z,rem,i,re,C ,*y,Bk ,*y,*y,r  ,C ,?v,Bk,?v,v,*Yd,r   ,?v,r  ,*x ,*y ,*r,*kBk,*k,*k,CBC"))]
+    "riFo,riF,Z,rem,i,re,C ,*y,Bk ,*y,*y,r  ,C  ,?v,Bk,?v,v,*Yd,jc  ,?v,r  ,*x ,*y ,*r,*kBk,*k,*k,CBC"))]
   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
    && ix86_hardreg_mov_ok (operands[0], operands[1])"
 {
    (set (attr "mode")
      (cond [(eq_attr "alternative" "2")
              (const_string "SI")
-           (eq_attr "alternative" "12,13")
+           (eq_attr "alternative" "12")
              (cond [(match_test "TARGET_AVX")
                       (const_string "TI")
                     (ior (not (match_test "TARGET_SSE2"))
                       (const_string "V4SF")
                    ]
                    (const_string "TI"))
+           (eq_attr "alternative" "13")
+             (cond [(match_test "TARGET_AVX512VL")
+                      (const_string "TI")
+                    (match_test "TARGET_AVX512F")
+                      (const_string "DF")
+                    (match_test "TARGET_AVX")
+                      (const_string "TI")
+                    (ior (not (match_test "TARGET_SSE2"))
+                         (match_test "optimize_function_for_size_p (cfun)"))
+                      (const_string "V4SF")
+                   ]
+                   (const_string "TI"))
 
            (and (eq_attr "alternative" "14,15,16")
                 (not (match_test "TARGET_SSE2")))
              (clobber (reg:CC FLAGS_REG))])]
 {
   int shift = ctz_hwi (UINTVAL (operands[1]));
-  operands[1] = gen_int_mode (UINTVAL (operands[1]) >> shift, DImode);
+  rtx op1 = gen_int_mode (UINTVAL (operands[1]) >> shift, DImode);
+  if (ix86_endbr_immediate_operand (op1, VOIDmode))
+    FAIL;
+  operands[1] = op1;
   operands[2] = gen_int_mode (shift, QImode);
 })
 
 (define_insn "*movsi_internal"
   [(set (match_operand:SI 0 "nonimmediate_operand"
-    "=r,m ,*y,*y,?*y,?m,?r,?*y,?v,?v,?v,m ,?r,?v,*k,*k  ,*rm,*k")
+    "=r,m ,*y,*y,?*y,?m,?r,?*y,?Yv,?v,?v,m ,?r,?v,*k,*k  ,*rm,*k")
        (match_operand:SI 1 "general_operand"
-    "g ,re,C ,*y,Bk ,*y,*y,r  ,C ,?v,Bk,?v,?v,r  ,*r,*kBk,*k ,CBC"))]
+    "g ,re,C ,*y,Bk ,*y,*y,r  ,C  ,?v,Bk,?v,?v,r  ,*r,*kBk,*k ,CBC"))]
   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
    && ix86_hardreg_mov_ok (operands[0], operands[1])"
 {
    (set (attr "mode")
      (cond [(eq_attr "alternative" "2,3")
              (const_string "DI")
-           (eq_attr "alternative" "8,9")
+           (eq_attr "alternative" "8")
              (cond [(match_test "TARGET_AVX")
                       (const_string "TI")
                     (ior (not (match_test "TARGET_SSE2"))
                       (const_string "V4SF")
                    ]
                    (const_string "TI"))
+           (eq_attr "alternative" "9")
+             (cond [(match_test "TARGET_AVX512VL")
+                      (const_string "TI")
+                    (match_test "TARGET_AVX512F")
+                      (const_string "SF")
+                    (match_test "TARGET_AVX")
+                      (const_string "TI")
+                    (ior (not (match_test "TARGET_SSE2"))
+                         (match_test "optimize_function_for_size_p (cfun)"))
+                      (const_string "V4SF")
+                   ]
+                   (const_string "TI"))
 
            (and (eq_attr "alternative" "10,11")
                 (not (match_test "TARGET_SSE2")))
 
 (define_insn "*movhi_internal"
   [(set (match_operand:HI 0 "nonimmediate_operand"
-    "=r,r,r,m ,*k,*k ,r ,m ,*k ,?r,?*v,*v,*v,*v,m")
+    "=r,r,r,m ,*k,*k ,r ,m ,*k ,?r,?*v,*Yv,*v,*v,jm,m")
        (match_operand:HI 1 "general_operand"
-    "r ,n,m,rn,r ,*km,*k,*k,CBC,*v,r  ,C ,*v,m ,*v"))]
+    "r ,n,m,rn,r ,*km,*k,*k,CBC,*v,r  ,C  ,*v,m ,*x,*v"))]
   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
    && ix86_hardreg_mov_ok (operands[0], operands[1])"
 {
        (cond [(eq_attr "alternative" "9,10,11,12,13")
                  (const_string "sse2")
               (eq_attr "alternative" "14")
-                 (const_string "sse4")
+                 (const_string "sse4_noavx")
+              (eq_attr "alternative" "15")
+                 (const_string "avx")
               ]
               (const_string "*")))
+   (set (attr "addr")
+       (if_then_else (eq_attr "alternative" "14")
+                     (const_string "gpr16")
+                     (const_string "*")))
    (set (attr "type")
      (cond [(eq_attr "alternative" "4,5,6,7")
              (const_string "mskmov")
            (eq_attr "alternative" "8")
              (const_string "msklog")
-           (eq_attr "alternative" "13,14")
+           (eq_attr "alternative" "13,14,15")
              (if_then_else (match_test "TARGET_AVX512FP16")
                (const_string "ssemov")
                (const_string "sselog1"))
    (set (attr "prefix")
        (cond [(eq_attr "alternative" "4,5,6,7,8")
                 (const_string "vex")
-              (eq_attr "alternative" "9,10,11,12,13,14")
+              (eq_attr "alternative" "9,10,11,12,13,14,15")
                 (const_string "maybe_evex")
              ]
              (const_string "orig")))
              (if_then_else (match_test "TARGET_AVX512FP16")
                (const_string "HI")
                (const_string "SI"))
-           (eq_attr "alternative" "13,14")
+           (eq_attr "alternative" "13,14,15")
              (if_then_else (match_test "TARGET_AVX512FP16")
                (const_string "HI")
                (const_string "TI"))
                    ]
                    (const_string "TI"))
            (eq_attr "alternative" "12")
-             (cond [(match_test "TARGET_AVX512FP16")
+             (cond [(match_test "TARGET_AVX512VL")
+                      (const_string "TI")
+                    (match_test "TARGET_AVX512FP16")
                       (const_string "HF")
+                    (match_test "TARGET_AVX512F")
+                      (const_string "SF")
                     (match_test "TARGET_AVX")
                       (const_string "TI")
                     (ior (not (match_test "TARGET_SSE2"))
    (set_attr "mode" "<MODE>")
    (set_attr "length_immediate" "0")])
 
+(define_insn "*movstrictqi_ext<mode>_1"
+  [(set (strict_low_part
+         (match_operand:QI 0 "register_operand" "+Q"))
+         (subreg:QI
+           (match_operator:SWI248 2 "extract_operator"
+             [(match_operand 1 "int248_register_operand" "Q")
+              (const_int 8)
+              (const_int 8)]) 0))]
+  "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
+  "mov{b}\t{%h1, %0|%0, %h1}"
+  [(set_attr "type" "imov")
+   (set_attr "mode" "QI")])
+
 (define_expand "extv<mode>"
   [(set (match_operand:SWI24 0 "register_operand")
        (sign_extract:SWI24 (match_operand:SWI24 1 "register_operand")
-                           (match_operand:SI 2 "const_int_operand")
-                           (match_operand:SI 3 "const_int_operand")))]
+                           (match_operand:QI 2 "const_int_operand")
+                           (match_operand:QI 3 "const_int_operand")))]
   ""
 {
   /* Handle extractions from %ah et al.  */
   [(set_attr "type" "imovx")
    (set_attr "mode" "SI")])
 
+;; Split sign-extension of single least significant bit as and x,$1;neg x
+(define_insn_and_split "*extv<mode>_1_0"
+  [(set (match_operand:SWI48 0 "register_operand" "=r")
+       (sign_extract:SWI48 (match_operand:SWI48 1 "register_operand" "0")
+                           (const_int 1)
+                           (const_int 0)))
+   (clobber (reg:CC FLAGS_REG))]
+  ""
+  "#"
+  ""
+  [(parallel [(set (match_dup 0) (and:SWI48 (match_dup 1) (const_int 1)))
+             (clobber (reg:CC FLAGS_REG))])
+   (parallel [(set (match_dup 0) (neg:SWI48 (match_dup 0)))
+             (clobber (reg:CC FLAGS_REG))])])
+
 (define_expand "extzv<mode>"
   [(set (match_operand:SWI248 0 "register_operand")
        (zero_extract:SWI248 (match_operand:SWI248 1 "register_operand")
-                            (match_operand:SI 2 "const_int_operand")
-                            (match_operand:SI 3 "const_int_operand")))]
+                            (match_operand:QI 2 "const_int_operand")
+                            (match_operand:QI 3 "const_int_operand")))]
   ""
 {
   if (ix86_expand_pextr (operands))
   [(set_attr "type" "imovx")
    (set_attr "mode" "SI")])
 
-(define_insn "*extzvqi_mem_rex64"
-  [(set (match_operand:QI 0 "norex_memory_operand" "=Bn")
-       (subreg:QI
-         (match_operator:SWI248 2 "extract_operator"
-           [(match_operand 1 "int248_register_operand" "Q")
-            (const_int 8)
-            (const_int 8)]) 0))]
-  "TARGET_64BIT && reload_completed"
-  "mov{b}\t{%h1, %0|%0, %h1}"
-  [(set_attr "type" "imov")
-   (set_attr "mode" "QI")])
-
 (define_insn "*extzvqi"
-  [(set (match_operand:QI 0 "nonimmediate_operand" "=QBc,?R,m")
+  [(set (match_operand:QI 0 "nonimmediate_operand" "=QBn,?R")
        (subreg:QI
          (match_operator:SWI248 2 "extract_operator"
-           [(match_operand 1 "int248_register_operand" "Q,Q,Q")
+           [(match_operand 1 "int248_register_operand" "Q,Q")
             (const_int 8)
             (const_int 8)]) 0))]
   ""
       return "mov{b}\t{%h1, %0|%0, %h1}";
     }
 }
-  [(set_attr "isa" "*,*,nox64")
+  [(set_attr "addr" "gpr8,*")
    (set (attr "type")
      (if_then_else (and (match_operand:QI 0 "register_operand")
                        (ior (not (match_operand:QI 0 "QIreg_operand"))
        (const_string "SI")
        (const_string "QI")))])
 
-(define_peephole2
-  [(set (match_operand:QI 0 "register_operand")
-       (subreg:QI
-         (match_operator:SWI248 3 "extract_operator"
-           [(match_operand 1 "int248_register_operand")
-            (const_int 8)
-            (const_int 8)]) 0))
-   (set (match_operand:QI 2 "norex_memory_operand") (match_dup 0))]
-  "TARGET_64BIT
-   && peep2_reg_dead_p (2, operands[0])"
-  [(set (match_dup 2)
-       (subreg:QI
-         (match_op_dup 3
-           [(match_dup 1)
-            (const_int 8)
-            (const_int 8)]) 0))])
-
 (define_expand "insv<mode>"
   [(set (zero_extract:SWI248 (match_operand:SWI248 0 "register_operand")
-                            (match_operand:SI 1 "const_int_operand")
-                            (match_operand:SI 2 "const_int_operand"))
+                            (match_operand:QI 1 "const_int_operand")
+                            (match_operand:QI 2 "const_int_operand"))
         (match_operand:SWI248 3 "register_operand"))]
   ""
 {
   DONE;
 })
 
-(define_insn "*insvqi_1_mem_rex64"
-  [(set (zero_extract:SWI248
-         (match_operand 0 "int248_register_operand" "+Q")
-         (const_int 8)
-         (const_int 8))
-       (subreg:SWI248
-         (match_operand:QI 1 "norex_memory_operand" "Bn") 0))]
-  "TARGET_64BIT && reload_completed"
-  "mov{b}\t{%1, %h0|%h0, %1}"
-  [(set_attr "type" "imov")
-   (set_attr "mode" "QI")])
-
 (define_insn "@insv<mode>_1"
   [(set (zero_extract:SWI248
-         (match_operand 0 "int248_register_operand" "+Q,Q")
+         (match_operand 0 "int248_register_operand" "+Q")
          (const_int 8)
          (const_int 8))
-       (match_operand:SWI248 1 "general_operand" "QnBc,m"))]
+       (match_operand:SWI248 1 "general_operand" "QnBn"))]
   ""
 {
   if (CONST_INT_P (operands[1]))
     operands[1] = gen_int_mode (INTVAL (operands[1]), QImode);
   return "mov{b}\t{%b1, %h0|%h0, %b1}";
 }
-  [(set_attr "isa" "*,nox64")
+  [(set_attr "addr" "gpr8")
    (set_attr "type" "imov")
    (set_attr "mode" "QI")])
 
 (define_insn "*insvqi_1"
   [(set (zero_extract:SWI248
-         (match_operand 0 "int248_register_operand" "+Q,Q")
+         (match_operand 0 "int248_register_operand" "+Q")
          (const_int 8)
          (const_int 8))
        (subreg:SWI248
-         (match_operand:QI 1 "general_operand" "QnBc,m") 0))]
+         (match_operand:QI 1 "general_operand" "QnBn") 0))]
   ""
   "mov{b}\t{%1, %h0|%h0, %1}"
-  [(set_attr "isa" "*,nox64")
+  [(set_attr "addr" "gpr8")
    (set_attr "type" "imov")
    (set_attr "mode" "QI")])
 
-(define_peephole2
-  [(set (match_operand:QI 0 "register_operand")
-       (match_operand:QI 1 "norex_memory_operand"))
-   (set (zero_extract:SWI248 (match_operand 2 "int248_register_operand")
-                            (const_int 8)
-                            (const_int 8))
-       (subreg:SWI248 (match_dup 0) 0))]
-  "TARGET_64BIT
-   && peep2_reg_dead_p (2, operands[0])"
-  [(set (zero_extract:SWI248 (match_dup 2)
-                            (const_int 8)
-                            (const_int 8))
-          (subreg:SWI248 (match_dup 1) 0))])
-
 ;; Eliminate redundant insv, e.g. xorl %eax,%eax; movb $0, %ah
 (define_peephole2
   [(parallel [(set (match_operand:SWI48 0 "general_reg_operand")
    (set_attr "type" "push,multi")
    (set_attr "mode" "SI,TI")])
 
+(define_insn "push2_di"
+  [(set (match_operand:TI 0 "push_operand" "=<")
+       (unspec:TI [(match_operand:DI 1 "register_operand" "r")
+                   (match_operand:DI 2 "register_operand" "r")]
+                   UNSPEC_APXPUSH2))]
+  "TARGET_APX_PUSH2POP2"
+  "push2\t{%2, %1|%1, %2}"
+  [(set_attr "mode" "TI")
+   (set_attr "type" "multi")
+   (set_attr "prefix" "evex")])
+
+(define_insn "pop2_di"
+  [(parallel [(set (match_operand:DI 0 "register_operand" "=r")
+                  (unspec:DI [(match_operand:TI 1 "pop_operand" ">")]
+                             UNSPEC_APXPOP2_LOW))
+             (set (match_operand:DI 2 "register_operand" "=r")
+                  (unspec:DI [(const_int 0)] UNSPEC_APXPOP2_HIGH))])]
+  "TARGET_APX_PUSH2POP2"
+  "pop2\t{%2, %0|%0, %2}"
+  [(set_attr "mode" "TI")
+   (set_attr "prefix" "evex")])
+
+(define_insn "pushp_di"
+  [(set (match_operand:DI 0 "push_operand" "=<")
+       (match_operand:DI 1 "register_operand" "r"))
+   (unspec:DI [(const_int 0)] UNSPEC_APX_PPX)]
+  "TARGET_64BIT"
+  "pushp\t%1"
+  [(set_attr "mode" "DI")])
+
+(define_insn "popp_di"
+  [(set (match_operand:DI 0 "register_operand" "=r")
+       (match_operand:DI 1 "pop_operand" ">"))
+   (unspec:DI [(const_int 0)] UNSPEC_APX_PPX)]
+  "TARGET_APX_PPX"
+  "popp\t%0"
+  [(set_attr "mode" "DI")])
+
+(define_insn "push2p_di"
+  [(set (match_operand:TI 0 "push_operand" "=<")
+       (unspec:TI [(match_operand:DI 1 "register_operand" "r")
+                   (match_operand:DI 2 "register_operand" "r")]
+                   UNSPEC_APXPUSH2))
+   (unspec:DI [(const_int 0)] UNSPEC_APX_PPX)]
+  "TARGET_APX_PUSH2POP2 && TARGET_APX_PPX"
+  "push2p\t{%2, %1|%1, %2}"
+  [(set_attr "mode" "TI")
+   (set_attr "type" "multi")
+   (set_attr "prefix" "evex")])
+
+(define_insn "pop2p_di"
+  [(parallel [(set (match_operand:DI 0 "register_operand" "=r")
+                  (unspec:DI [(match_operand:TI 1 "pop_operand" ">")]
+                             UNSPEC_APXPOP2_LOW))
+             (set (match_operand:DI 2 "register_operand" "=r")
+                  (unspec:DI [(const_int 0)] UNSPEC_APXPOP2_HIGH))
+             (unspec:DI [(const_int 0)] UNSPEC_APX_PPX)])]
+  "TARGET_APX_PUSH2POP2 && TARGET_APX_PPX"
+  "pop2p\t{%2, %0|%0, %2}"
+  [(set_attr "mode" "TI")
+   (set_attr "prefix" "evex")])
+
 (define_insn "*pushsf_rex64"
   [(set (match_operand:SF 0 "push_operand" "=X,X,X")
        (match_operand:SF 1 "nonmemory_no_elim_operand" "f,rF,v"))]
 ;; Possible store forwarding (partial memory) stall in alternatives 4, 6 and 7.
 (define_insn "*movdf_internal"
   [(set (match_operand:DF 0 "nonimmediate_operand"
-    "=Yf*f,m   ,Yf*f,?r ,!o,?*r ,!o,!o,?r,?m,?r,?r,v,v,v,m,*x,*x,*x,m ,?r,?v,r  ,o ,r  ,m")
+    "=Yf*f,m   ,Yf*f,?r ,!o,?*r ,!o,!o,?r,?m,?r,?r,Yv,v,v,m,*x,*x,*x,m ,?r,?v,r  ,o ,r  ,m")
        (match_operand:DF 1 "general_operand"
-    "Yf*fm,Yf*f,G   ,roF,r ,*roF,*r,F ,rm,rC,C ,F ,C,v,m,v,C ,*x,m ,*x, v, r,roF,rF,rmF,rC"))]
+    "Yf*fm,Yf*f,G   ,roF,r ,*roF,*r,F ,rm,rC,C ,F ,C ,v,m,v,C ,*x,m ,*x, v, r,roF,rF,rmF,rC"))]
   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
    && (lra_in_progress || reload_completed
        || !CONST_DOUBLE_P (operands[1])
 
               /* movaps is one byte shorter for non-AVX targets.  */
               (eq_attr "alternative" "13,17")
-                (cond [(match_test "TARGET_AVX")
+                (cond [(match_test "TARGET_AVX512VL")
+                         (const_string "V2DF")
+                       (match_test "TARGET_AVX512F")
                          (const_string "DF")
+                       (match_test "TARGET_AVX")
+                         (const_string "V2DF")
                        (ior (not (match_test "TARGET_SSE2"))
                             (match_test "optimize_function_for_size_p (cfun)"))
                          (const_string "V4SF")
 
 (define_insn "*movsf_internal"
   [(set (match_operand:SF 0 "nonimmediate_operand"
-         "=Yf*f,m   ,Yf*f,?r ,?m,v,v,v,m,?r,?v,!*y,!*y,!m,!r,!*y,r  ,m")
+         "=Yf*f,m   ,Yf*f,?r ,?m,Yv,v,v,m,?r,?v,!*y,!*y,!m,!r,!*y,r  ,m")
        (match_operand:SF 1 "general_operand"
-         "Yf*fm,Yf*f,G   ,rmF,rF,C,v,m,v,v ,r ,*y ,m  ,*y,*y,r  ,rmF,rF"))]
+         "Yf*fm,Yf*f,G   ,rmF,rF,C ,v,m,v,v ,r ,*y ,m  ,*y,*y,r  ,rmF,rF"))]
   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
    && (lra_in_progress || reload_completed
        || !CONST_DOUBLE_P (operands[1])
               (eq_attr "alternative" "11")
                 (const_string "DI")
               (eq_attr "alternative" "5")
-                (cond [(and (match_test "TARGET_AVX512F")
+                (cond [(and (match_test "TARGET_AVX512F && TARGET_EVEX512")
                             (not (match_test "TARGET_PREFER_AVX256")))
                          (const_string "V16SF")
                        (match_test "TARGET_AVX")
                  better to maintain the whole registers in single format
                  to avoid problems on using packed logical operations.  */
               (eq_attr "alternative" "6")
-                (cond [(ior (match_test "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
+                (cond [(match_test "TARGET_AVX512VL")
+                         (const_string "V4SF")
+                       (match_test "TARGET_AVX512F")
+                         (const_string "SF")
+                       (ior (match_test "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
                             (match_test "TARGET_SSE_SPLIT_REGS"))
                          (const_string "V4SF")
                       ]
 
 (define_insn "*mov<mode>_internal"
  [(set (match_operand:HFBF 0 "nonimmediate_operand"
-        "=?r,?r,?r,?m,v,v,?r,m,?v,v")
+        "=?r,?r,?r,?m           ,Yv,v,?r,jm,m,?v,v")
        (match_operand:HFBF 1 "general_operand"
-        "r  ,F ,m ,r<hfbfconstf>,C,v, v,v,r ,m"))]
+        "r  ,F ,m ,r<hfbfconstf>,C ,v, v,v ,v,r ,m"))]
  "!(MEM_P (operands[0]) && MEM_P (operands[1]))
   && (lra_in_progress
       || reload_completed
     }
 }
   [(set (attr "isa")
-       (cond [(eq_attr "alternative" "4,5,6,8,9")
+       (cond [(eq_attr "alternative" "4,5,6,9,10")
                 (const_string "sse2")
               (eq_attr "alternative" "7")
-                (const_string "sse4")
+                (const_string "sse4_noavx")
+              (eq_attr "alternative" "8")
+                (const_string "avx")
              ]
              (const_string "*")))
+   (set (attr "addr")
+       (if_then_else (eq_attr "alternative" "7")
+                     (const_string "gpr16")
+                     (const_string "*")))
    (set (attr "type")
        (cond [(eq_attr "alternative" "4")
                 (const_string "sselog1")
-              (eq_attr "alternative" "5,6,8")
+              (eq_attr "alternative" "5,6,9")
                 (const_string "ssemov")
-              (eq_attr "alternative" "7,9")
+              (eq_attr "alternative" "7,8,10")
                 (if_then_else
                   (match_test ("TARGET_AVX512FP16"))
                   (const_string "ssemov")
                 ]
              (const_string "imov")))
    (set (attr "prefix")
-       (cond [(eq_attr "alternative" "4,5,6,7,8,9")
+       (cond [(eq_attr "alternative" "4,5,6,7,8,9,10")
                 (const_string "maybe_vex")
              ]
              (const_string "orig")))
    (set (attr "mode")
        (cond [(eq_attr "alternative" "4")
                 (const_string "V4SF")
-              (eq_attr "alternative" "6,8")
+              (eq_attr "alternative" "6,9")
                 (if_then_else
                   (match_test "TARGET_AVX512FP16")
                   (const_string "HI")
                   (const_string "SI"))
-              (eq_attr "alternative" "7,9")
+              (eq_attr "alternative" "7,8,10")
                 (if_then_else
                   (match_test "TARGET_AVX512FP16")
                   (const_string "HI")
                   (const_string "TI"))
               (eq_attr "alternative" "5")
-                (cond [(match_test "TARGET_AVX512FP16")
+                (cond [(match_test "TARGET_AVX512VL")
+                       (const_string "V4SF")
+                       (match_test "TARGET_AVX512FP16")
                          (const_string "HF")
+                       (match_test "TARGET_AVX512F")
+                         (const_string "SF")
+                       (match_test "TARGET_AVX")
+                         (const_string "V4SF")
                        (ior (match_test "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
                             (match_test "TARGET_SSE_SPLIT_REGS"))
                          (const_string "V4SF")
       /* If it is unsafe to overwrite upper half of source, we need
         to move to destination and unpack there.  */
       if (REGNO (operands[0]) != REGNO (operands[1])
-         || (EXT_REX_SSE_REG_P (operands[1])
-             && !TARGET_AVX512VL))
+         || (EXT_REX_SSE_REG_P (operands[1]) && !TARGET_AVX512VL))
        {
          rtx tmp = lowpart_subreg (SFmode, operands[0], DFmode);
          emit_move_insn (tmp, operands[1]);
    (set_attr "memory" "none")
    (set (attr "enabled")
      (if_then_else (eq_attr "alternative" "2")
-       (symbol_ref "TARGET_AVX512F && !TARGET_AVX512VL
-                   && !TARGET_PREFER_AVX256")
+       (symbol_ref "TARGET_AVX512F && TARGET_EVEX512
+                   && !TARGET_AVX512VL && !TARGET_PREFER_AVX256")
        (const_string "*")))])
 
 (define_expand "extend<mode>xf2"
       gcc_assert (TARGET_64BIT);
       return "lea{l}\t{%E1, %k0|%k0, %E1}";
     }
-  else 
+  else
     return "lea{<imodesuffix>}\t{%E1, %0|%0, %E1}";
 }
   [(set_attr "type" "lea")
        (plus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand")
                    (match_operand:SDWIM 2 "<general_hilo_operand>")))]
   ""
-  "ix86_expand_binary_operator (PLUS, <MODE>mode, operands); DONE;")
+{
+  ix86_expand_binary_operator (PLUS, <MODE>mode, operands, TARGET_APX_NDD);
+  DONE;
+})
 
 (define_insn_and_split "*add<dwi>3_doubleword"
-  [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro,r")
+  [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro,r,&r,&r")
        (plus:<DWI>
-         (match_operand:<DWI> 1 "nonimmediate_operand" "%0,0")
-         (match_operand:<DWI> 2 "x86_64_hilo_general_operand" "r<di>,o")))
+         (match_operand:<DWI> 1 "nonimmediate_operand" "%0,0,ro,r")
+         (match_operand:<DWI> 2 "x86_64_hilo_general_operand" "r<di>,o,r<di>,r")))
    (clobber (reg:CC FLAGS_REG))]
-  "ix86_binary_operator_ok (PLUS, <DWI>mode, operands)"
+  "ix86_binary_operator_ok (PLUS, <DWI>mode, operands, TARGET_APX_NDD)"
   "#"
   "&& reload_completed"
   [(parallel [(set (reg:CCC FLAGS_REG)
   split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);
   if (operands[2] == const0_rtx)
     {
+      /* Under NDD op0 and op1 may not equal, do not delete insn then.  */
+      bool emit_insn_deleted_note_p = true;
+      if (!rtx_equal_p (operands[0], operands[1]))
+       {
+         emit_move_insn (operands[0], operands[1]);
+         emit_insn_deleted_note_p = false;
+       }
       if (operands[5] != const0_rtx)
-       ix86_expand_binary_operator (PLUS, <MODE>mode, &operands[3]);
+       ix86_expand_binary_operator (PLUS, <MODE>mode, &operands[3],
+                                    TARGET_APX_NDD);
       else if (!rtx_equal_p (operands[3], operands[4]))
        emit_move_insn (operands[3], operands[4]);
-      else
+      else if (emit_insn_deleted_note_p)
        emit_note (NOTE_INSN_DELETED);
       DONE;
     }
-})
+}
+[(set_attr "isa" "*,*,apx_ndd,apx_ndd")])
 
 (define_insn_and_split "*add<dwi>3_doubleword_zext"
-  [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
+  [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o,&r,&r")
        (plus:<DWI>
          (zero_extend:<DWI>
-           (match_operand:DWIH 2 "nonimmediate_operand" "rm,r")) 
-         (match_operand:<DWI> 1 "nonimmediate_operand" "0,0")))
+           (match_operand:DWIH 2 "nonimmediate_operand" "rm,r,rm,r"))
+         (match_operand:<DWI> 1 "nonimmediate_operand" "0,0,r,m")))
    (clobber (reg:CC FLAGS_REG))]
-  "ix86_binary_operator_ok (UNKNOWN, <DWI>mode, operands)"
+  "ix86_binary_operator_ok (UNKNOWN, <DWI>mode, operands, TARGET_APX_NDD)"
   "#"
   "&& reload_completed"
   [(parallel [(set (reg:CCC FLAGS_REG)
                       (match_dup 4))
                     (const_int 0)))
              (clobber (reg:CC FLAGS_REG))])]
- "split_double_mode (<DWI>mode, &operands[0], 2, &operands[0], &operands[3]);")
+ "split_double_mode (<DWI>mode, &operands[0], 2, &operands[0], &operands[3]);"
+ [(set_attr "isa" "*,*,apx_ndd,apx_ndd")])
 
 (define_insn_and_split "*add<dwi>3_doubleword_concat"
   [(set (match_operand:<DWI> 0 "register_operand" "=&r")
  "split_double_mode (<DWI>mode, &operands[0], 1, &operands[0], &operands[5]);")
 
 (define_insn "*add<mode>_1"
-  [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r,r,r")
+  [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r,r,r,r,r,r,r")
        (plus:SWI48
-         (match_operand:SWI48 1 "nonimmediate_operand" "%0,0,r,r")
-         (match_operand:SWI48 2 "x86_64_general_operand" "re,BM,0,le")))
+         (match_operand:SWI48 1 "nonimmediate_operand" "%0,0,r,r,rm,r,m,r")
+         (match_operand:SWI48 2 "x86_64_general_operand" "re,BM,0,le,r,e,je,BM")))
    (clobber (reg:CC FLAGS_REG))]
-  "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
+  "ix86_binary_operator_ok (PLUS, <MODE>mode, operands, TARGET_APX_NDD)"
 {
+  bool use_ndd = get_attr_isa (insn) == ISA_APX_NDD;
   switch (get_attr_type (insn))
     {
     case TYPE_LEA:
       return "#";
 
     case TYPE_INCDEC:
-      gcc_assert (rtx_equal_p (operands[0], operands[1]));
       if (operands[2] == const1_rtx)
-        return "inc{<imodesuffix>}\t%0";
+        return use_ndd ? "inc{<imodesuffix>}\t{%1, %0|%0, %1}"
+                     : "inc{<imodesuffix>}\t%0";
       else
         {
          gcc_assert (operands[2] == constm1_rtx);
-          return "dec{<imodesuffix>}\t%0";
+         return use_ndd ? "dec{<imodesuffix>}\t{%1, %0|%0, %1}"
+                       : "dec{<imodesuffix>}\t%0";
        }
 
     default:
       if (which_alternative == 2)
         std::swap (operands[1], operands[2]);
         
-      gcc_assert (rtx_equal_p (operands[0], operands[1]));
       if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
-        return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
+        return use_ndd ? "sub{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}"
+                     : "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
 
-      return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
+      return use_ndd ? "add{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}"
+                   : "add{<imodesuffix>}\t{%2, %0|%0, %2}";
     }
 }
-  [(set (attr "type")
+  [(set_attr "isa" "*,*,*,*,apx_ndd,apx_ndd,apx_ndd,apx_ndd")
+   (set (attr "type")
      (cond [(eq_attr "alternative" "3")
               (const_string "lea")
            (match_operand:SWI48 2 "incdec_operand")
 ;; patterns constructed from addsi_1 to match.
 
 (define_insn "addsi_1_zext"
-  [(set (match_operand:DI 0 "register_operand" "=r,r,r")
+  [(set (match_operand:DI 0 "register_operand" "=r,r,r,r,r")
        (zero_extend:DI
-         (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r,r")
-                  (match_operand:SI 2 "x86_64_general_operand" "rBMe,0,le"))))
+         (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r,r,r,rm")
+                  (match_operand:SI 2 "x86_64_general_operand" "rBMe,0,le,rBMe,re"))))
    (clobber (reg:CC FLAGS_REG))]
-  "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
+  "TARGET_64BIT
+   && ix86_binary_operator_ok (PLUS, SImode, operands, TARGET_APX_NDD)"
 {
+  bool use_ndd = get_attr_isa (insn) == ISA_APX_NDD;
   switch (get_attr_type (insn))
     {
     case TYPE_LEA:
 
     case TYPE_INCDEC:
       if (operands[2] == const1_rtx)
-        return "inc{l}\t%k0";
+        return use_ndd ? "inc{l}\t{%1, %k0|%k0, %1}"
+                      : "inc{l}\t%k0";
       else
         {
          gcc_assert (operands[2] == constm1_rtx);
-          return "dec{l}\t%k0";
+         return use_ndd ? "dec{l}\t{%1, %k0|%k0, %1}"
+                        : "dec{l}\t%k0";
        }
 
     default:
         std::swap (operands[1], operands[2]);
 
       if (x86_maybe_negate_const_int (&operands[2], SImode))
-        return "sub{l}\t{%2, %k0|%k0, %2}";
+        return use_ndd ? "sub{l}\t{%2 ,%1, %k0|%k0, %1, %2}"
+                      : "sub{l}\t{%2, %k0|%k0, %2}";
 
-      return "add{l}\t{%2, %k0|%k0, %2}";
+      return use_ndd ? "add{l}\t{%2 ,%1, %k0|%k0, %1, %2}"
+                    : "add{l}\t{%2, %k0|%k0, %2}";
     }
 }
-  [(set (attr "type")
+  [(set_attr "isa" "*,*,*,apx_ndd,apx_ndd")
+   (set (attr "type")
      (cond [(eq_attr "alternative" "2")
              (const_string "lea")
            (match_operand:SI 2 "incdec_operand")
    (set_attr "mode" "SI")])
 
 (define_insn "*addhi_1"
-  [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r,Yp")
-       (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r,Yp")
-                (match_operand:HI 2 "general_operand" "rn,m,0,ln")))
+  [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r,Yp,r,r")
+       (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r,Yp,rm,r")
+                (match_operand:HI 2 "general_operand" "rn,m,0,ln,rn,m")))
    (clobber (reg:CC FLAGS_REG))]
-  "ix86_binary_operator_ok (PLUS, HImode, operands)"
+  "ix86_binary_operator_ok (PLUS, HImode, operands, TARGET_APX_NDD)"
 {
+  bool use_ndd = get_attr_isa (insn) == ISA_APX_NDD;
   switch (get_attr_type (insn))
     {
     case TYPE_LEA:
       return "#";
 
     case TYPE_INCDEC:
-      gcc_assert (rtx_equal_p (operands[0], operands[1]));
       if (operands[2] == const1_rtx)
-       return "inc{w}\t%0";
+       return use_ndd ? "inc{w}\t{%1, %0|%0, %1}" : "inc{w}\t%0";
       else
        {
          gcc_assert (operands[2] == constm1_rtx);
-         return "dec{w}\t%0";
+         return use_ndd ? "dec{w}\t{%1, %0|%0, %1}" : "dec{w}\t%0";
        }
 
     default:
       if (which_alternative == 2)
         std::swap (operands[1], operands[2]);
 
-      gcc_assert (rtx_equal_p (operands[0], operands[1]));
       if (x86_maybe_negate_const_int (&operands[2], HImode))
-       return "sub{w}\t{%2, %0|%0, %2}";
+       return use_ndd ? "sub{w}\t{%2, %1, %0|%0, %1, %2}"
+                      : "sub{w}\t{%2, %0|%0, %2}";
 
-      return "add{w}\t{%2, %0|%0, %2}";
+      return use_ndd ? "add{w}\t{%2, %1, %0|%0, %1, %2}"
+                    : "add{w}\t{%2, %0|%0, %2}";
     }
 }
-  [(set (attr "type")
+  [(set_attr "isa" "*,*,*,*,apx_ndd,apx_ndd")
+   (set (attr "type")
      (cond [(eq_attr "alternative" "3")
               (const_string "lea")
            (match_operand:HI 2 "incdec_operand")
        (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
        (const_string "1")
        (const_string "*")))
-   (set_attr "mode" "HI,HI,HI,SI")])
+   (set_attr "mode" "HI,HI,HI,SI,HI,HI")])
 
 (define_insn "*addqi_1"
-  [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,q,r,r,Yp")
-       (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,q,0,r,Yp")
-                (match_operand:QI 2 "general_operand" "qn,m,0,rn,0,ln")))
+  [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,q,r,r,Yp,r,r")
+       (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,q,0,r,Yp,rm,r")
+                (match_operand:QI 2 "general_operand" "qn,m,0,rn,0,ln,rn,m")))
    (clobber (reg:CC FLAGS_REG))]
-  "ix86_binary_operator_ok (PLUS, QImode, operands)"
+  "ix86_binary_operator_ok (PLUS, QImode, operands, TARGET_APX_NDD)"
 {
   bool widen = (get_attr_mode (insn) != MODE_QI);
-
+  bool use_ndd = get_attr_isa (insn) == ISA_APX_NDD;
   switch (get_attr_type (insn))
     {
     case TYPE_LEA:
       return "#";
 
     case TYPE_INCDEC:
-      gcc_assert (rtx_equal_p (operands[0], operands[1]));
       if (operands[2] == const1_rtx)
-       return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
+       if (use_ndd)
+         return "inc{b}\t{%1, %0|%0, %1}";
+       else
+         return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
       else
        {
          gcc_assert (operands[2] == constm1_rtx);
-         return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
+         if (use_ndd)
+           return "dec{b}\t{%1, %0|%0, %1}";
+         else
+           return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
        }
 
     default:
       if (which_alternative == 2 || which_alternative == 4)
         std::swap (operands[1], operands[2]);
 
-      gcc_assert (rtx_equal_p (operands[0], operands[1]));
       if (x86_maybe_negate_const_int (&operands[2], QImode))
        {
-         if (widen)
-           return "sub{l}\t{%2, %k0|%k0, %2}";
+         if (use_ndd)
+           return "sub{b}\t{%2, %1, %0|%0, %1, %2}";
          else
-           return "sub{b}\t{%2, %0|%0, %2}";
+           return widen ? "sub{l}\t{%2, %k0|%k0, %2}"
+                        : "sub{b}\t{%2, %0|%0, %2}";
        }
-      if (widen)
-        return "add{l}\t{%k2, %k0|%k0, %k2}";
+      if (use_ndd)
+       return "add{b}\t{%2, %1, %0|%0, %1, %2}";
       else
-        return "add{b}\t{%2, %0|%0, %2}";
+       return widen ? "add{l}\t{%k2, %k0|%k0, %k2}"
+                    : "add{b}\t{%2, %0|%0, %2}";
     }
 }
-  [(set (attr "type")
+  [(set_attr "isa" "*,*,*,*,*,*,apx_ndd,apx_ndd")
+   (set (attr "type")
      (cond [(eq_attr "alternative" "5")
               (const_string "lea")
            (match_operand:QI 2 "incdec_operand")
        (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
        (const_string "1")
        (const_string "*")))
-   (set_attr "mode" "QI,QI,QI,SI,SI,SI")
+   (set_attr "mode" "QI,QI,QI,SI,SI,SI,QI,QI")
    ;; Potential partial reg stall on alternatives 3 and 4.
    (set (attr "preferred_for_speed")
      (cond [(eq_attr "alternative" "3,4")
       return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
     }
 }
-  "&& reload_completed"
+  "&& reload_completed
+   && !(rtx_equal_p (operands[0], operands[1])
+       || rtx_equal_p (operands[0], operands[2]))"
   [(set (strict_low_part (match_dup 0)) (match_dup 1))
    (parallel
      [(set (strict_low_part (match_dup 0))
        (const_string "alu")))
    (set_attr "mode" "<MODE>")])
 
+;; Alternative 1 is needed to work around LRA limitation, see PR82524.
+(define_insn_and_split "*addqi_ext<mode>_1_slp"
+  [(set (strict_low_part (match_operand:QI 0 "register_operand" "+Q,&Q"))
+       (plus:QI
+         (subreg:QI
+           (match_operator:SWI248 3 "extract_operator"
+             [(match_operand 2 "int248_register_operand" "Q,Q")
+              (const_int 8)
+              (const_int 8)]) 0)
+         (match_operand:QI 1 "nonimmediate_operand" "0,!qm")))
+   (clobber (reg:CC FLAGS_REG))]
+  "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
+  "@
+   add{b}\t{%h2, %0|%0, %h2}
+   #"
+  "&& reload_completed
+   && !rtx_equal_p (operands[0], operands[1])"
+  [(set (strict_low_part (match_dup 0)) (match_dup 1))
+   (parallel
+     [(set (strict_low_part (match_dup 0))
+          (plus:QI
+            (subreg:QI
+              (match_op_dup 3
+                [(match_dup 2) (const_int 8) (const_int 8)]) 0)
+            (match_dup 0)))
+      (clobber (reg:CC FLAGS_REG))])]
+  ""
+  [(set_attr "type" "alu")
+   (set_attr "mode" "QI")])
+
+(define_insn_and_split "*addqi_ext<mode>_2_slp"
+  [(set (strict_low_part (match_operand:QI 0 "register_operand" "+&Q"))
+       (plus:QI
+         (subreg:QI
+           (match_operator:SWI248 3 "extract_operator"
+             [(match_operand 1 "int248_register_operand" "Q")
+              (const_int 8)
+              (const_int 8)]) 0)
+         (subreg:QI
+           (match_operator:SWI248 4 "extract_operator"
+             [(match_operand 2 "int248_register_operand" "Q")
+              (const_int 8)
+              (const_int 8)]) 0)))
+   (clobber (reg:CC FLAGS_REG))]
+  "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
+  "#"
+  "&& reload_completed"
+  [(set (strict_low_part (match_dup 0))
+       (subreg:QI
+         (match_op_dup 4
+           [(match_dup 2) (const_int 8) (const_int 8)]) 0))
+   (parallel
+     [(set (strict_low_part (match_dup 0))
+          (plus:QI
+            (subreg:QI
+              (match_op_dup 3
+                [(match_dup 1) (const_int 8) (const_int 8)]) 0)
+            (match_dup 0)))
+      (clobber (reg:CC FLAGS_REG))])]
+  ""
+  [(set_attr "type" "alu")
+   (set_attr "mode" "QI")])
+
 ;; Split non destructive adds if we cannot use lea.
 (define_split
   [(set (match_operand:SWI48 0 "register_operand")
   [(set (reg FLAGS_REG)
        (compare
          (plus:SWI
-           (match_operand:SWI 1 "nonimmediate_operand" "%0,0,<r>")
-           (match_operand:SWI 2 "<general_operand>" "<r><i>,<m>,0"))
+           (match_operand:SWI 1 "nonimmediate_operand" "%0,0,<r>,rm,r")
+           (match_operand:SWI 2 "<general_operand>" "<r><i>,<m>,0,r<i>,<m>"))
          (const_int 0)))
-   (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>,<r>")
+   (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>,<r>,r,r")
        (plus:SWI (match_dup 1) (match_dup 2)))]
   "ix86_match_ccmode (insn, CCGOCmode)
-   && ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
+   && ix86_binary_operator_ok (PLUS, <MODE>mode, operands, TARGET_APX_NDD)"
 {
+  bool use_ndd = get_attr_isa (insn) == ISA_APX_NDD;
   switch (get_attr_type (insn))
     {
     case TYPE_INCDEC:
       if (operands[2] == const1_rtx)
-        return "inc{<imodesuffix>}\t%0";
+        return use_ndd ? "inc{<imodesuffix>}\t{%1, %0|%0, %1}"
+                      : "inc{<imodesuffix>}\t%0";
       else
         {
          gcc_assert (operands[2] == constm1_rtx);
-          return "dec{<imodesuffix>}\t%0";
+         return use_ndd ? "dec{<imodesuffix>}\t{%1, %0|%0, %1}"
+                        : "dec{<imodesuffix>}\t%0";
        }
 
     default:
       if (which_alternative == 2)
         std::swap (operands[1], operands[2]);
         
-      gcc_assert (rtx_equal_p (operands[0], operands[1]));
       if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
-        return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
+        return use_ndd ? "sub{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}"
+                      : "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
 
-      return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
+      return use_ndd ? "add{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}"
+                    : "add{<imodesuffix>}\t{%2, %0|%0, %2}";
     }
 }
-  [(set (attr "type")
+  [(set_attr "isa" "*,*,*,apx_ndd,apx_ndd")
+   (set (attr "type")
      (if_then_else (match_operand:SWI 2 "incdec_operand")
        (const_string "incdec")
        (const_string "alu")))
 (define_insn "*addsi_2_zext"
   [(set (reg FLAGS_REG)
        (compare
-         (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r")
-                  (match_operand:SI 2 "x86_64_general_operand" "rBMe,0"))
+         (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r,r,rm")
+                  (match_operand:SI 2 "x86_64_general_operand" "rBMe,0,rBMe,re"))
          (const_int 0)))
-   (set (match_operand:DI 0 "register_operand" "=r,r")
+   (set (match_operand:DI 0 "register_operand" "=r,r,r,r")
        (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
-   && ix86_binary_operator_ok (PLUS, SImode, operands)"
+   && ix86_binary_operator_ok (PLUS, SImode, operands, TARGET_APX_NDD)"
 {
+  bool use_ndd = get_attr_isa (insn) == ISA_APX_NDD;
   switch (get_attr_type (insn))
     {
     case TYPE_INCDEC:
       if (operands[2] == const1_rtx)
-        return "inc{l}\t%k0";
+        return use_ndd ? "inc{l}\t{%1, %k0|%k0, %1}"
+                      : "inc{l}\t%k0";
       else
        {
          gcc_assert (operands[2] == constm1_rtx);
-          return "dec{l}\t%k0";
+         return use_ndd ? "dec{l}\t{%1, %k0|%k0, %1}"
+                        : "dec{l}\t%k0";
        }
 
     default:
         std::swap (operands[1], operands[2]);
 
       if (x86_maybe_negate_const_int (&operands[2], SImode))
-        return "sub{l}\t{%2, %k0|%k0, %2}";
+       return use_ndd ? "sub{l}\t{%2, %1, %k0|%k0, %1, %2}"
+                      : "sub{l}\t{%2, %k0|%k0, %2}";
 
-      return "add{l}\t{%2, %k0|%k0, %2}";
+      return use_ndd ? "add{l}\t{%2, %1, %k0|%k0, %1, %2}"
+                    : "add{l}\t{%2, %k0|%k0, %2}";
     }
 }
-  [(set (attr "type")
+  [(set_attr "isa" "*,*,apx_ndd,apx_ndd")
+   (set (attr "type")
      (if_then_else (match_operand:SI 2 "incdec_operand")
        (const_string "incdec")
        (const_string "alu")))
 (define_insn "*add<mode>_3"
   [(set (reg FLAGS_REG)
        (compare
-         (neg:SWI (match_operand:SWI 2 "<general_operand>" "<g>,0"))
-         (match_operand:SWI 1 "nonimmediate_operand" "%0,<r>")))
-   (clobber (match_scratch:SWI 0 "=<r>,<r>"))]
+         (neg:SWI (match_operand:SWI 2 "<general_operand>" "<g>,0,<g>,re"))
+         (match_operand:SWI 1 "nonimmediate_operand" "%0,<r>,r,rm")))
+   (clobber (match_scratch:SWI 0 "=<r>,<r>,r,r"))]
   "ix86_match_ccmode (insn, CCZmode)
    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
 {
+  bool use_ndd = get_attr_isa (insn) == ISA_APX_NDD;
   switch (get_attr_type (insn))
     {
     case TYPE_INCDEC:
       if (operands[2] == const1_rtx)
-        return "inc{<imodesuffix>}\t%0";
+        return use_ndd ? "inc{<imodesuffix>}\t{%1, %0|%0, %1}"
+                      : "inc{<imodesuffix>}\t%0";
       else
         {
          gcc_assert (operands[2] == constm1_rtx);
-          return "dec{<imodesuffix>}\t%0";
+          return use_ndd ? "dec{<imodesuffix>}\t{%1, %0|%0, %1}"
+                        : "dec{<imodesuffix>}\t%0";
        }
 
     default:
       if (which_alternative == 1)
         std::swap (operands[1], operands[2]);
 
-      gcc_assert (rtx_equal_p (operands[0], operands[1]));
       if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
-        return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
+        return use_ndd ? "sub{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}"
+                       : "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
 
-      return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
+      return use_ndd ? "add{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}"
+                     : "add{<imodesuffix>}\t{%2, %0|%0, %2}";
     }
 }
-  [(set (attr "type")
+  [(set_attr "isa" "*,*,apx_ndd,apx_ndd")
+   (set (attr "type")
      (if_then_else (match_operand:SWI 2 "incdec_operand")
        (const_string "incdec")
        (const_string "alu")))
 (define_insn "*addsi_3_zext"
   [(set (reg FLAGS_REG)
        (compare
-         (neg:SI (match_operand:SI 2 "x86_64_general_operand" "rBMe,0"))
-         (match_operand:SI 1 "nonimmediate_operand" "%0,r")))
-   (set (match_operand:DI 0 "register_operand" "=r,r")
+         (neg:SI (match_operand:SI 2 "x86_64_general_operand" "rBMe,0,rBMe,re"))
+         (match_operand:SI 1 "nonimmediate_operand" "%0,r,r,rm")))
+   (set (match_operand:DI 0 "register_operand" "=r,r,r,r")
        (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
   "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
-   && ix86_binary_operator_ok (PLUS, SImode, operands)"
+   && ix86_binary_operator_ok (PLUS, SImode, operands, TARGET_APX_NDD)"
 {
+  bool use_ndd = get_attr_isa (insn) == ISA_APX_NDD;
   switch (get_attr_type (insn))
     {
     case TYPE_INCDEC:
       if (operands[2] == const1_rtx)
-        return "inc{l}\t%k0";
+        return use_ndd ? "inc{l}\t{%1, %k0|%k0, %1}" : "inc{l}\t%k0";
       else
         {
          gcc_assert (operands[2] == constm1_rtx);
-          return "dec{l}\t%k0";
+         return use_ndd ? "dec{l}\t{%1, %k0|%k0, %1}" : "dec{l}\t%k0";
        }
 
     default:
         std::swap (operands[1], operands[2]);
 
       if (x86_maybe_negate_const_int (&operands[2], SImode))
-        return "sub{l}\t{%2, %k0|%k0, %2}";
+        return use_ndd ? "sub{l}\t{%2, %1, %k0|%k0, %1, %2}"
+                      : "sub{l}\t{%2, %k0|%k0, %2}";
 
-      return "add{l}\t{%2, %k0|%k0, %2}";
+      return use_ndd ? "add{l}\t{%2, %1, %k0|%k0, %1, %2}"
+                    : "add{l}\t{%2, %k0|%k0, %2}";
     }
 }
-  [(set (attr "type")
+  [(set_attr "isa" "*,*,apx_ndd,apx_ndd")
+   (set (attr "type")
      (if_then_else (match_operand:SI 2 "incdec_operand")
        (const_string "incdec")
        (const_string "alu")))
 (define_insn "*adddi_4"
   [(set (reg FLAGS_REG)
        (compare
-         (match_operand:DI 1 "nonimmediate_operand" "0")
-         (match_operand:DI 2 "x86_64_immediate_operand" "e")))
-   (clobber (match_scratch:DI 0 "=r"))]
+         (match_operand:DI 1 "nonimmediate_operand" "0,rm")
+         (match_operand:DI 2 "x86_64_immediate_operand" "e,e")))
+   (clobber (match_scratch:DI 0 "=r,r"))]
   "TARGET_64BIT
    && ix86_match_ccmode (insn, CCGCmode)"
 {
+  bool use_ndd = get_attr_isa (insn) == ISA_APX_NDD;
   switch (get_attr_type (insn))
     {
     case TYPE_INCDEC:
       if (operands[2] == constm1_rtx)
-        return "inc{q}\t%0";
+        return use_ndd ? "inc{q}\t{%1, %0|%0, %1}" : "inc{q}\t%0";
       else
         {
          gcc_assert (operands[2] == const1_rtx);
-          return "dec{q}\t%0";
+         return use_ndd ? "dec{q}\t{%1, %0|%0, %1}" : "dec{q}\t%0";
        }
 
     default:
       if (x86_maybe_negate_const_int (&operands[2], DImode))
-       return "add{q}\t{%2, %0|%0, %2}";
+       return use_ndd ? "add{q}\t{%2, %1, %0|%0, %1, %2}"
+                      : "add{q}\t{%2, %0|%0, %2}";
 
-      return "sub{q}\t{%2, %0|%0, %2}";
+      return use_ndd ? "sub{q}\t{%2, %1, %0|%0, %1, %2}"
+                    : "sub{q}\t{%2, %0|%0, %2}";
     }
 }
-  [(set (attr "type")
+  [(set_attr "isa" "*,apx_ndd")
+   (set (attr "type")
      (if_then_else (match_operand:DI 2 "incdec_operand")
        (const_string "incdec")
        (const_string "alu")))
 (define_insn "*add<mode>_4"
   [(set (reg FLAGS_REG)
        (compare
-         (match_operand:SWI124 1 "nonimmediate_operand" "0")
+         (match_operand:SWI124 1 "nonimmediate_operand" "0,rm")
          (match_operand:SWI124 2 "const_int_operand")))
-   (clobber (match_scratch:SWI124 0 "=<r>"))]
+   (clobber (match_scratch:SWI124 0 "=<r>,r"))]
   "ix86_match_ccmode (insn, CCGCmode)"
 {
+  bool use_ndd = get_attr_isa (insn) == ISA_APX_NDD;
   switch (get_attr_type (insn))
     {
     case TYPE_INCDEC:
       if (operands[2] == constm1_rtx)
-        return "inc{<imodesuffix>}\t%0";
+        return use_ndd ? "inc{<imodesuffix>}\t{%1, %0|%0, %1}"
+                      : "inc{<imodesuffix>}\t%0";
       else
         {
          gcc_assert (operands[2] == const1_rtx);
-          return "dec{<imodesuffix>}\t%0";
+         return use_ndd ? "dec{<imodesuffix>}\t{%1, %0|%0, %1}"
+                        : "dec{<imodesuffix>}\t%0";
        }
 
     default:
       if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
-       return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
+       return use_ndd ? "add{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}"
+                      : "add{<imodesuffix>}\t{%2, %0|%0, %2}";
 
-      return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
+      return use_ndd ? "sub{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}"
+                    : "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
     }
 }
-  [(set (attr "type")
+  [(set_attr "isa" "*,apx_ndd")
+   (set (attr "type")
      (if_then_else (match_operand:<MODE> 2 "incdec_operand")
        (const_string "incdec")
        (const_string "alu")))
   [(set (reg FLAGS_REG)
        (compare
          (plus:SWI
-           (match_operand:SWI 1 "nonimmediate_operand" "%0,<r>")
-           (match_operand:SWI 2 "<general_operand>" "<g>,0"))
+           (match_operand:SWI 1 "nonimmediate_operand" "%0,<r>,r,rm")
+           (match_operand:SWI 2 "<general_operand>" "<g>,0,<g>,re"))
          (const_int 0)))
-   (clobber (match_scratch:SWI 0 "=<r>,<r>"))]
+   (clobber (match_scratch:SWI 0 "=<r>,<r>,r,r"))]
   "ix86_match_ccmode (insn, CCGOCmode)
    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
 {
+  bool use_ndd = get_attr_isa (insn) == ISA_APX_NDD;
   switch (get_attr_type (insn))
     {
     case TYPE_INCDEC:
       if (operands[2] == const1_rtx)
-        return "inc{<imodesuffix>}\t%0";
+        return use_ndd ? "inc{<imodesuffix>}\t{%1, %0|%0, %1}"
+                      : "inc{<imodesuffix>}\t%0";
       else
         {
           gcc_assert (operands[2] == constm1_rtx);
-          return "dec{<imodesuffix>}\t%0";
+         return use_ndd ? "dec{<imodesuffix>}\t{%1, %0|%0, %1}"
+                        : "dec{<imodesuffix>}\t%0";
        }
 
     default:
       if (which_alternative == 1)
         std::swap (operands[1], operands[2]);
 
-      gcc_assert (rtx_equal_p (operands[0], operands[1]));
       if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
-        return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
+       return use_ndd ? "sub{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}"
+                      : "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
 
-      return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
+      return use_ndd ? "add{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}"
+                    : "add{<imodesuffix>}\t{%2, %0|%0, %2}";
     }
 }
-  [(set (attr "type")
+  [(set_attr "isa" "*,*,apx_ndd,apx_ndd")
+   (set (attr "type")
      (if_then_else (match_operand:SWI 2 "incdec_operand")
        (const_string "incdec")
        (const_string "alu")))
    (set_attr "mode" "<MODE>")])
 
 (define_insn "*addqi_ext<mode>_0"
-  [(set (match_operand:QI 0 "nonimm_x64constmem_operand" "=QBc,m")
+  [(set (match_operand:QI 0 "nonimmediate_operand" "=QBn")
        (plus:QI
          (subreg:QI
            (match_operator:SWI248 3 "extract_operator"
-             [(match_operand 2 "int248_register_operand" "Q,Q")
+             [(match_operand 2 "int248_register_operand" "Q")
               (const_int 8)
               (const_int 8)]) 0)
-         (match_operand:QI 1 "nonimm_x64constmem_operand" "0,0")))
+         (match_operand:QI 1 "nonimmediate_operand" "0")))
    (clobber (reg:CC FLAGS_REG))]
   ""
   "add{b}\t{%h2, %0|%0, %h2}"
-  [(set_attr "isa" "*,nox64")
+  [(set_attr "addr" "gpr8")
    (set_attr "type" "alu")
    (set_attr "mode" "QI")])
 
+(define_insn_and_split "*addqi_ext2<mode>_0"
+  [(set (match_operand:QI 0 "register_operand" "=&Q")
+       (plus:QI
+         (subreg:QI
+           (match_operator:SWI248 3 "extract_operator"
+             [(match_operand 1 "int248_register_operand" "Q")
+              (const_int 8)
+              (const_int 8)]) 0)
+         (subreg:QI
+           (match_operator:SWI248 4 "extract_operator"
+             [(match_operand 2 "int248_register_operand" "Q")
+              (const_int 8)
+              (const_int 8)]) 0)))
+   (clobber (reg:CC FLAGS_REG))]
+  ""
+  "#"
+  "&& reload_completed"
+  [(set (match_dup 0)
+       (subreg:QI
+         (match_op_dup 4
+           [(match_dup 2) (const_int 8) (const_int 8)]) 0))
+   (parallel
+     [(set (match_dup 0)
+          (plus:QI
+            (subreg:QI
+              (match_op_dup 3
+                [(match_dup 1) (const_int 8) (const_int 8)]) 0)
+          (match_dup 0)))
+      (clobber (reg:CC FLAGS_REG))])]
+  ""
+  [(set_attr "type" "alu")
+   (set_attr "mode" "QI")])
+
 (define_expand "addqi_ext_1"
   [(parallel
      [(set (zero_extract:HI (match_operand:HI 0 "register_operand")
               (match_operand:QI 2 "const_int_operand")) 0))
       (clobber (reg:CC FLAGS_REG))])])
 
-(define_insn "*addqi_ext<mode>_1"
+;; Alternative 1 is needed to work around LRA limitation, see PR82524.
+(define_insn_and_split "*addqi_ext<mode>_1"
   [(set (zero_extract:SWI248
-         (match_operand 0 "int248_register_operand" "+Q,Q")
+         (match_operand 0 "int248_register_operand" "+Q,&Q")
          (const_int 8)
          (const_int 8))
        (subreg:SWI248
          (plus:QI
            (subreg:QI
              (match_operator:SWI248 3 "extract_operator"
-               [(match_operand 1 "int248_register_operand" "0,0")
+               [(match_operand 1 "int248_register_operand" "0,!Q")
                 (const_int 8)
                 (const_int 8)]) 0)
-           (match_operand:QI 2 "general_x64constmem_operand" "QnBc,m")) 0))
+           (match_operand:QI 2 "general_operand" "QnBn,QnBn")) 0))
    (clobber (reg:CC FLAGS_REG))]
-  "/* FIXME: without this LRA can't reload this pattern, see PR82524.  */
-   rtx_equal_p (operands[0], operands[1])"
+  ""
 {
+  if (which_alternative)
+    return "#";
+
   switch (get_attr_type (insn))
     {
     case TYPE_INCDEC:
       if (operands[2] == const1_rtx)
        return "inc{b}\t%h0";
       else
-        {
+       {
          gcc_assert (operands[2] == constm1_rtx);
-          return "dec{b}\t%h0";
-        }
+         return "dec{b}\t%h0";
+       }
 
     default:
       return "add{b}\t{%2, %h0|%h0, %2}";
     }
 }
-  [(set_attr "isa" "*,nox64")
+  "reload_completed
+   && !rtx_equal_p (operands[0], operands[1])"
+  [(set (zero_extract:SWI248
+         (match_dup 0) (const_int 8) (const_int 8))
+       (zero_extract:SWI248
+         (match_dup 1) (const_int 8) (const_int 8)))
+   (parallel
+     [(set (zero_extract:SWI248
+            (match_dup 0) (const_int 8) (const_int 8))
+          (subreg:SWI248
+            (plus:QI
+              (subreg:QI
+                (match_op_dup 3
+                  [(match_dup 0) (const_int 8) (const_int 8)]) 0)
+              (match_dup 2)) 0))
+      (clobber (reg:CC FLAGS_REG))])]
+  ""
+  [(set_attr "addr" "gpr8")
    (set (attr "type")
      (if_then_else (match_operand:QI 2 "incdec_operand")
        (const_string "incdec")
        (const_string "alu")))
    (set_attr "mode" "QI")])
 
-(define_insn "*addqi_ext<mode>_2"
+;; Alternative 1 is needed to work around LRA limitation, see PR82524.
+(define_insn_and_split "*<insn>qi_ext<mode>_2"
   [(set (zero_extract:SWI248
-         (match_operand 0 "int248_register_operand" "+Q")
+         (match_operand 0 "int248_register_operand" "+Q,&Q")
          (const_int 8)
          (const_int 8))
        (subreg:SWI248
-         (plus:QI
+         (plusminus:QI
            (subreg:QI
              (match_operator:SWI248 3 "extract_operator"
-               [(match_operand 1 "int248_register_operand" "%0")
+               [(match_operand 1 "int248_register_operand" "<comm>0,!Q")
                 (const_int 8)
                 (const_int 8)]) 0)
            (subreg:QI
              (match_operator:SWI248 4 "extract_operator"
-               [(match_operand 2 "int248_register_operand" "Q")
+               [(match_operand 2 "int248_register_operand" "Q,Q")
                 (const_int 8)
                 (const_int 8)]) 0)) 0))
-  (clobber (reg:CC FLAGS_REG))]
-  "/* FIXME: without this LRA can't reload this pattern, see PR82524.  */
-   rtx_equal_p (operands[0], operands[1])
-   || rtx_equal_p (operands[0], operands[2])"
-  "add{b}\t{%h2, %h0|%h0, %h2}"
+   (clobber (reg:CC FLAGS_REG))]
+  ""
+  "@
+   <insn>{b}\t{%h2, %h0|%h0, %h2}
+   #"
+  "reload_completed
+   && !(rtx_equal_p (operands[0], operands[1])
+       || (<CODE> == PLUS && rtx_equal_p (operands[0], operands[2])))"
+  [(set (zero_extract:SWI248
+         (match_dup 0) (const_int 8) (const_int 8))
+       (zero_extract:SWI248
+         (match_dup 1) (const_int 8) (const_int 8)))
+   (parallel
+     [(set (zero_extract:SWI248
+            (match_dup 0) (const_int 8) (const_int 8))
+          (subreg:SWI248
+            (plusminus:QI
+              (subreg:QI
+                (match_op_dup 3
+                  [(match_dup 0) (const_int 8) (const_int 8)]) 0)
+              (subreg:QI
+                (match_op_dup 4
+                  [(match_dup 2) (const_int 8) (const_int 8)]) 0)) 0))
+      (clobber (reg:CC FLAGS_REG))])]
+  ""
   [(set_attr "type" "alu")
    (set_attr "mode" "QI")])
 
   [(set (reg:CCO FLAGS_REG)
        (eq:CCO (plus:<DWI>
                   (sign_extend:<DWI>
-                     (match_operand:SWI 1 "nonimmediate_operand" "%0,0"))
+                     (match_operand:SWI 1 "nonimmediate_operand" "%0,0,rm,r"))
                   (sign_extend:<DWI>
-                     (match_operand:SWI 2 "<general_sext_operand>" "<r>We,m")))
+                     (match_operand:SWI 2 "<general_sext_operand>" "<r>We,m,rWe,m")))
                (sign_extend:<DWI>
                   (plus:SWI (match_dup 1) (match_dup 2)))))
-   (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
+   (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>,r,r")
        (plus:SWI (match_dup 1) (match_dup 2)))]
-  "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
-  "add{<imodesuffix>}\t{%2, %0|%0, %2}"
-  [(set_attr "type" "alu")
+  "ix86_binary_operator_ok (PLUS, <MODE>mode, operands, TARGET_APX_NDD)"
+  "@
+   add{<imodesuffix>}\t{%2, %0|%0, %2}
+   add{<imodesuffix>}\t{%2, %0|%0, %2}
+   add{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
+   add{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}"
+  [(set_attr "isa" "*,*,apx_ndd,apx_ndd")
+   (set_attr "type" "alu")
    (set_attr "mode" "<MODE>")])
 
 (define_insn "addv<mode>4_1"
   [(set (reg:CCO FLAGS_REG)
        (eq:CCO (plus:<DWI>
                   (sign_extend:<DWI>
-                     (match_operand:SWI 1 "nonimmediate_operand" "0"))
+                     (match_operand:SWI 1 "nonimmediate_operand" "0,rm"))
                   (match_operand:<DWI> 3 "const_int_operand"))
                (sign_extend:<DWI>
                   (plus:SWI
                     (match_dup 1)
-                    (match_operand:SWI 2 "x86_64_immediate_operand" "<i>")))))
-   (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
+                    (match_operand:SWI 2 "x86_64_immediate_operand" "<i>,<i>")))))
+   (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,r")
        (plus:SWI (match_dup 1) (match_dup 2)))]
-  "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)
+  "ix86_binary_operator_ok (PLUS, <MODE>mode, operands, TARGET_APX_NDD)
    && CONST_INT_P (operands[2])
    && INTVAL (operands[2]) == INTVAL (operands[3])"
-  "add{<imodesuffix>}\t{%2, %0|%0, %2}"
-  [(set_attr "type" "alu")
+  "@
+  add{<imodesuffix>}\t{%2, %0|%0, %2}
+  add{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}"
+  [(set_attr "isa" "*,apx_ndd")
+   (set_attr "type" "alu")
    (set_attr "mode" "<MODE>")
    (set (attr "length_immediate")
        (cond [(match_test "IN_RANGE (INTVAL (operands[2]), -128, 127)")
        (eq:CCO
          (plus:<QPWI>
            (sign_extend:<QPWI>
-             (match_operand:<DWI> 1 "nonimmediate_operand" "%0,0"))
+             (match_operand:<DWI> 1 "nonimmediate_operand" "%0,0,ro,r"))
            (sign_extend:<QPWI>
-             (match_operand:<DWI> 2 "nonimmediate_operand" "r,o")))
+             (match_operand:<DWI> 2 "nonimmediate_operand" "r,o,r,o")))
          (sign_extend:<QPWI>
            (plus:<DWI> (match_dup 1) (match_dup 2)))))
-   (set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro,r")
+   (set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro,r,&r,&r")
        (plus:<DWI> (match_dup 1) (match_dup 2)))]
-  "ix86_binary_operator_ok (PLUS, <DWI>mode, operands)"
+  "ix86_binary_operator_ok (PLUS, <DWI>mode, operands, TARGET_APX_NDD)"
   "#"
   "&& reload_completed"
   [(parallel [(set (reg:CCC FLAGS_REG)
                     (match_dup 5)))])]
 {
   split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);
-})
+}
+[(set_attr "isa" "*,*,apx_ndd,apx_ndd")])
 
 (define_insn_and_split "*addv<dwi>4_doubleword_1"
   [(set (reg:CCO FLAGS_REG)
        (eq:CCO
          (plus:<QPWI>
            (sign_extend:<QPWI>
-             (match_operand:<DWI> 1 "nonimmediate_operand" "%0"))
-           (match_operand:<QPWI> 3 "const_scalar_int_operand" "n"))
+             (match_operand:<DWI> 1 "nonimmediate_operand" "%0,rm"))
+           (match_operand:<QPWI> 3 "const_scalar_int_operand" "n,n"))
          (sign_extend:<QPWI>
            (plus:<DWI>
              (match_dup 1)
-             (match_operand:<DWI> 2 "x86_64_hilo_general_operand" "<di>")))))
-   (set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro")
+             (match_operand:<DWI> 2 "x86_64_hilo_general_operand" "<di>,<di>")))))
+   (set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro,&r")
        (plus:<DWI> (match_dup 1) (match_dup 2)))]
-  "ix86_binary_operator_ok (PLUS, <DWI>mode, operands)
+  "ix86_binary_operator_ok (PLUS, <DWI>mode, operands, TARGET_APX_NDD)
    && CONST_SCALAR_INT_P (operands[2])
    && rtx_equal_p (operands[2], operands[3])"
   "#"
   split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);
   if (operands[2] == const0_rtx)
     {
+      if (!rtx_equal_p (operands[0], operands[1]))
+       emit_move_insn (operands[0], operands[1]);
       emit_insn (gen_addv<mode>4_1 (operands[3], operands[4], operands[5],
                                    operands[5]));
       DONE;
     }
-})
+}
+[(set_attr "isa" "*,apx_ndd")])
 
 (define_insn "*addv<mode>4_overflow_1"
   [(set (reg:CCO FLAGS_REG)
              (match_operator:<DWI> 4 "ix86_carry_flag_operator"
                [(match_operand 3 "flags_reg_operand") (const_int 0)])
              (sign_extend:<DWI>
-               (match_operand:SWI 1 "nonimmediate_operand" "%0,0")))
+               (match_operand:SWI 1 "nonimmediate_operand" "%0,0,rm,r")))
            (sign_extend:<DWI>
-             (match_operand:SWI 2 "<general_sext_operand>" "rWe,m")))
+             (match_operand:SWI 2 "<general_sext_operand>" "rWe,m,rWe,m")))
          (sign_extend:<DWI>
            (plus:SWI
              (plus:SWI
                  [(match_dup 3) (const_int 0)])
                (match_dup 1))
              (match_dup 2)))))
-   (set (match_operand:SWI 0 "nonimmediate_operand" "=rm,r")
+   (set (match_operand:SWI 0 "nonimmediate_operand" "=rm,r,r,r")
        (plus:SWI
          (plus:SWI
            (match_op_dup 5 [(match_dup 3) (const_int 0)])
            (match_dup 1))
          (match_dup 2)))]
-  "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
-  "adc{<imodesuffix>}\t{%2, %0|%0, %2}"
-  [(set_attr "type" "alu")
+  "ix86_binary_operator_ok (PLUS, <MODE>mode, operands, TARGET_APX_NDD)"
+  "@
+   adc{<imodesuffix>}\t{%2, %0|%0, %2}
+   adc{<imodesuffix>}\t{%2, %0|%0, %2}
+   adc{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
+   adc{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}"
+  [(set_attr "isa" "*,*,apx_ndd,apx_ndd")
+   (set_attr "type" "alu")
    (set_attr "mode" "<MODE>")])
 
 (define_insn "*addv<mode>4_overflow_2"
              (match_operator:<DWI> 4 "ix86_carry_flag_operator"
                [(match_operand 3 "flags_reg_operand") (const_int 0)])
              (sign_extend:<DWI>
-               (match_operand:SWI 1 "nonimmediate_operand" "%0")))
-           (match_operand:<DWI> 6 "const_int_operand" "n"))
+               (match_operand:SWI 1 "nonimmediate_operand" "%0,rm")))
+           (match_operand:<DWI> 6 "const_int_operand" "n,n"))
          (sign_extend:<DWI>
            (plus:SWI
              (plus:SWI
                (match_operator:SWI 5 "ix86_carry_flag_operator"
                  [(match_dup 3) (const_int 0)])
                (match_dup 1))
-             (match_operand:SWI 2 "x86_64_immediate_operand" "e")))))
-   (set (match_operand:SWI 0 "nonimmediate_operand" "=rm")
+             (match_operand:SWI 2 "x86_64_immediate_operand" "e,e")))))
+   (set (match_operand:SWI 0 "nonimmediate_operand" "=rm,r")
        (plus:SWI
          (plus:SWI
            (match_op_dup 5 [(match_dup 3) (const_int 0)])
            (match_dup 1))
          (match_dup 2)))]
-  "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)
+  "ix86_binary_operator_ok (PLUS, <MODE>mode, operands, TARGET_APX_NDD)
    && CONST_INT_P (operands[2])
    && INTVAL (operands[2]) == INTVAL (operands[6])"
-  "adc{<imodesuffix>}\t{%2, %0|%0, %2}"
-  [(set_attr "type" "alu")
+  "@
+  adc{<imodesuffix>}\t{%2, %0|%0, %2}
+  adc{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}"
+  [(set_attr "isa" "*,apx_ndd")
+   (set_attr "type" "alu")
    (set_attr "mode" "<MODE>")
    (set (attr "length_immediate")
      (if_then_else (match_test "IN_RANGE (INTVAL (operands[2]), -128, 127)")
        (minus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand")
                     (match_operand:SDWIM 2 "<general_hilo_operand>")))]
   ""
-  "ix86_expand_binary_operator (MINUS, <MODE>mode, operands); DONE;")
+{
+  ix86_expand_binary_operator (MINUS, <MODE>mode, operands, TARGET_APX_NDD);
+  DONE;
+})
 
 (define_insn_and_split "*sub<dwi>3_doubleword"
-  [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro,r")
+  [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro,r,&r,&r")
        (minus:<DWI>
-         (match_operand:<DWI> 1 "nonimmediate_operand" "0,0")
-         (match_operand:<DWI> 2 "x86_64_hilo_general_operand" "r<di>,o")))
+         (match_operand:<DWI> 1 "nonimmediate_operand" "0,0,ro,r")
+         (match_operand:<DWI> 2 "x86_64_hilo_general_operand" "r<di>,o,r<di>,o")))
    (clobber (reg:CC FLAGS_REG))]
-  "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
+  "ix86_binary_operator_ok (MINUS, <MODE>mode, operands, TARGET_APX_NDD)"
   "#"
   "&& reload_completed"
   [(parallel [(set (reg:CC FLAGS_REG)
   split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);
   if (operands[2] == const0_rtx)
     {
-      ix86_expand_binary_operator (MINUS, <MODE>mode, &operands[3]);
+      if (!rtx_equal_p (operands[0], operands[1]))
+       emit_move_insn (operands[0], operands[1]);
+      ix86_expand_binary_operator (MINUS, <MODE>mode, &operands[3],
+                                  TARGET_APX_NDD);
       DONE;
     }
-})
+}
+[(set_attr "isa" "*,*,apx_ndd,apx_ndd")])
 
 (define_insn_and_split "*sub<dwi>3_doubleword_zext"
-  [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
+  [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o,&r,&r")
        (minus:<DWI>
-         (match_operand:<DWI> 1 "nonimmediate_operand" "0,0")
+         (match_operand:<DWI> 1 "nonimmediate_operand" "0,0,r,o")
          (zero_extend:<DWI>
-           (match_operand:DWIH 2 "nonimmediate_operand" "rm,r"))))
+           (match_operand:DWIH 2 "nonimmediate_operand" "rm,r,rm,r"))))
    (clobber (reg:CC FLAGS_REG))]
-  "ix86_binary_operator_ok (UNKNOWN, <DWI>mode, operands)"
+  "ix86_binary_operator_ok (UNKNOWN, <DWI>mode, operands, TARGET_APX_NDD)"
   "#"
   "&& reload_completed"
   [(parallel [(set (reg:CC FLAGS_REG)
                       (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0)))
                     (const_int 0)))
              (clobber (reg:CC FLAGS_REG))])]
-  "split_double_mode (<DWI>mode, &operands[0], 2, &operands[0], &operands[3]);")
+  "split_double_mode (<DWI>mode, &operands[0], 2, &operands[0], &operands[3]);"
+[(set_attr "isa" "*,*,apx_ndd,apx_ndd")])
 
 (define_insn "*sub<mode>_1"
-  [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
+  [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>,r,r")
        (minus:SWI
-         (match_operand:SWI 1 "nonimmediate_operand" "0,0")
-         (match_operand:SWI 2 "<general_operand>" "<r><i>,<m>")))
+         (match_operand:SWI 1 "nonimmediate_operand" "0,0,rm,r")
+         (match_operand:SWI 2 "<general_operand>" "<r><i>,<m>,r<i>,<m>")))
    (clobber (reg:CC FLAGS_REG))]
-  "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
-  "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
-  [(set_attr "type" "alu")
+  "ix86_binary_operator_ok (MINUS, <MODE>mode, operands, TARGET_APX_NDD)"
+  "@
+  sub{<imodesuffix>}\t{%2, %0|%0, %2}
+  sub{<imodesuffix>}\t{%2, %0|%0, %2}
+  sub{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
+  sub{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}"
+  [(set_attr "isa" "*,*,apx_ndd,apx_ndd")
+   (set_attr "type" "alu")
    (set_attr "mode" "<MODE>")])
 
 (define_insn "*subsi_1_zext"
-  [(set (match_operand:DI 0 "register_operand" "=r")
+  [(set (match_operand:DI 0 "register_operand" "=r,r,r")
        (zero_extend:DI
-         (minus:SI (match_operand:SI 1 "register_operand" "0")
-                   (match_operand:SI 2 "x86_64_general_operand" "rBMe"))))
+         (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,r,rm")
+                   (match_operand:SI 2 "x86_64_general_operand" "rBMe,rBMe,re"))))
    (clobber (reg:CC FLAGS_REG))]
-  "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
-  "sub{l}\t{%2, %k0|%k0, %2}"
-  [(set_attr "type" "alu")
+  "TARGET_64BIT
+   && ix86_binary_operator_ok (MINUS, SImode, operands, TARGET_APX_NDD)"
+  "@
+  sub{l}\t{%2, %k0|%k0, %2}
+  sub{l}\t{%2, %1, %k0|%k0, %1, %2}
+  sub{l}\t{%2, %1, %k0|%k0, %1, %2}"
+  [(set_attr "isa" "*,apx_ndd,apx_ndd")
+   (set_attr "type" "alu")
    (set_attr "mode" "SI")])
 
 ;; Alternative 1 is needed to work around LRA limitation, see PR82524.
   "@
    sub{<imodesuffix>}\t{%2, %0|%0, %2}
    #"
-  "&& reload_completed"
+  "&& reload_completed
+   && !(rtx_equal_p (operands[0], operands[1]))"
   [(set (strict_low_part (match_dup 0)) (match_dup 1))
    (parallel
      [(set (strict_low_part (match_dup 0))
   [(set_attr "type" "alu")
    (set_attr "mode" "<MODE>")])
 
+;; Alternative 1 is needed to work around LRA limitation, see PR82524.
+(define_insn_and_split "*subqi_ext<mode>_1_slp"
+  [(set (strict_low_part (match_operand:QI 0 "register_operand" "+Q,&Q"))
+       (minus:QI
+         (match_operand:QI 1 "nonimmediate_operand" "0,!qm")
+         (subreg:QI
+           (match_operator:SWI248 3 "extract_operator"
+             [(match_operand 2 "int248_register_operand" "Q,Q")
+              (const_int 8)
+              (const_int 8)]) 0)))
+   (clobber (reg:CC FLAGS_REG))]
+  "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
+  "@
+   sub{b}\t{%h2, %0|%0, %h2}
+   #"
+  "&& reload_completed
+   && !rtx_equal_p (operands[0], operands[1])"
+  [(set (strict_low_part (match_dup 0)) (match_dup 1))
+   (parallel
+     [(set (strict_low_part (match_dup 0))
+          (minus:QI
+            (match_dup 0)
+            (subreg:QI
+              (match_op_dup 3
+                [(match_dup 2) (const_int 8) (const_int 8)]) 0)))
+      (clobber (reg:CC FLAGS_REG))])]
+  ""
+  [(set_attr "type" "alu")
+   (set_attr "mode" "QI")])
+
+(define_insn_and_split "*subqi_ext<mode>_2_slp"
+  [(set (strict_low_part (match_operand:QI 0 "register_operand" "+&Q"))
+       (minus:QI
+         (subreg:QI
+           (match_operator:SWI248 3 "extract_operator"
+             [(match_operand 1 "int248_register_operand" "Q")
+              (const_int 8)
+              (const_int 8)]) 0)
+         (subreg:QI
+           (match_operator:SWI248 4 "extract_operator"
+             [(match_operand 2 "int248_register_operand" "Q")
+              (const_int 8)
+              (const_int 8)]) 0)))
+   (clobber (reg:CC FLAGS_REG))]
+  "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
+  "#"
+  "&& reload_completed"
+  [(set (strict_low_part (match_dup 0))
+       (subreg:QI
+         (match_op_dup 3
+           [(match_dup 1) (const_int 8) (const_int 8)]) 0))
+   (parallel
+     [(set (strict_low_part (match_dup 0))
+          (minus:QI
+          (match_dup 0)
+            (subreg:QI
+              (match_op_dup 4
+                [(match_dup 2) (const_int 8) (const_int 8)]) 0)))
+      (clobber (reg:CC FLAGS_REG))])]
+  ""
+  [(set_attr "type" "alu")
+   (set_attr "mode" "QI")])
+
 (define_insn "*sub<mode>_2"
   [(set (reg FLAGS_REG)
        (compare
          (minus:SWI
-           (match_operand:SWI 1 "nonimmediate_operand" "0,0")
-           (match_operand:SWI 2 "<general_operand>" "<r><i>,<m>"))
+           (match_operand:SWI 1 "nonimmediate_operand" "0,0,rm,r")
+           (match_operand:SWI 2 "<general_operand>" "<r><i>,<m>,r<i>,<m>"))
          (const_int 0)))
-   (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
+   (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>,r,r")
        (minus:SWI (match_dup 1) (match_dup 2)))]
   "ix86_match_ccmode (insn, CCGOCmode)
-   && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
-  "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
-  [(set_attr "type" "alu")
+   && ix86_binary_operator_ok (MINUS, <MODE>mode, operands, TARGET_APX_NDD)"
+  "@
+  sub{<imodesuffix>}\t{%2, %0|%0, %2}
+  sub{<imodesuffix>}\t{%2, %0|%0, %2}
+  sub{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
+  sub{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}"
+  [(set_attr "isa" "*,*,apx_ndd,apx_ndd")
+   (set_attr "type" "alu")
    (set_attr "mode" "<MODE>")])
 
 (define_insn "*subsi_2_zext"
   [(set (reg FLAGS_REG)
        (compare
-         (minus:SI (match_operand:SI 1 "register_operand" "0")
-                   (match_operand:SI 2 "x86_64_general_operand" "rBMe"))
+         (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,r,rm")
+                   (match_operand:SI 2 "x86_64_general_operand" "rBMe,rBMe,re"))
          (const_int 0)))
-   (set (match_operand:DI 0 "register_operand" "=r")
+   (set (match_operand:DI 0 "register_operand" "=r,r,r")
        (zero_extend:DI
          (minus:SI (match_dup 1)
                    (match_dup 2))))]
   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
-   && ix86_binary_operator_ok (MINUS, SImode, operands)"
-  "sub{l}\t{%2, %k0|%k0, %2}"
-  [(set_attr "type" "alu")
+   && ix86_binary_operator_ok (MINUS, SImode, operands, TARGET_APX_NDD)"
+  "@
+  sub{l}\t{%2, %k0|%k0, %2}
+  sub{l}\t{%2, %1, %k0|%k0, %1, %2}
+  sub{l}\t{%2, %1, %k0|%k0, %1, %2}"
+  [(set_attr "isa" "*,apx_ndd,apx_ndd")
+   (set_attr "type" "alu")
    (set_attr "mode" "SI")])
 
 (define_insn "*subqi_ext<mode>_0"
-  [(set (match_operand:QI 0 "nonimm_x64constmem_operand" "=QBc,m")
+  [(set (match_operand:QI 0 "nonimmediate_operand" "=QBn")
        (minus:QI
-         (match_operand:QI 1 "nonimm_x64constmem_operand" "0,0")
+         (match_operand:QI 1 "nonimmediate_operand" "0")
          (subreg:QI
            (match_operator:SWI248 3 "extract_operator"
-             [(match_operand 2 "int248_register_operand" "Q,Q")
+             [(match_operand 2 "int248_register_operand" "Q")
               (const_int 8)
               (const_int 8)]) 0)))
    (clobber (reg:CC FLAGS_REG))]
   ""
   "sub{b}\t{%h2, %0|%0, %h2}"
-  [(set_attr "isa" "*,nox64")
+  [(set_attr "addr" "gpr8")
    (set_attr "type" "alu")
    (set_attr "mode" "QI")])
 
-(define_insn "*subqi_ext<mode>_2"
+(define_insn_and_split "*subqi_ext2<mode>_0"
+  [(set (match_operand:QI 0 "register_operand" "=&Q")
+       (minus:QI
+         (subreg:QI
+           (match_operator:SWI248 3 "extract_operator"
+             [(match_operand 1 "int248_register_operand" "Q")
+              (const_int 8)
+              (const_int 8)]) 0)
+         (subreg:QI
+           (match_operator:SWI248 4 "extract_operator"
+             [(match_operand 2 "int248_register_operand" "Q")
+              (const_int 8)
+              (const_int 8)]) 0)))
+   (clobber (reg:CC FLAGS_REG))]
+  ""
+  "#"
+  "&& reload_completed"
+  [(set (match_dup 0)
+       (subreg:QI
+         (match_op_dup 3
+           [(match_dup 1) (const_int 8) (const_int 8)]) 0))
+   (parallel
+     [(set (match_dup 0)
+          (minus:QI
+            (match_dup 0)
+            (subreg:QI
+              (match_op_dup 4
+                [(match_dup 2) (const_int 8) (const_int 8)]) 0)))
+      (clobber (reg:CC FLAGS_REG))])]
+  ""
+  [(set_attr "type" "alu")
+   (set_attr "mode" "QI")])
+
+;; Alternative 1 is needed to work around LRA limitation, see PR82524.
+(define_insn_and_split "*subqi_ext<mode>_1"
   [(set (zero_extract:SWI248
-         (match_operand 0 "int248_register_operand" "+Q")
+         (match_operand 0 "int248_register_operand" "+Q,&Q")
          (const_int 8)
          (const_int 8))
        (subreg:SWI248
          (minus:QI
            (subreg:QI
              (match_operator:SWI248 3 "extract_operator"
-               [(match_operand 1 "int248_register_operand" "0")
+               [(match_operand 1 "int248_register_operand" "0,!Q")
                 (const_int 8)
                 (const_int 8)]) 0)
-           (subreg:QI
-             (match_operator:SWI248 4 "extract_operator"
-               [(match_operand 2 "int248_register_operand" "Q")
-                (const_int 8)
-                (const_int 8)]) 0)) 0))
-  (clobber (reg:CC FLAGS_REG))]
-  "/* FIXME: without this LRA can't reload this pattern, see PR82524.  */
-   rtx_equal_p (operands[0], operands[1])"
-  "sub{b}\t{%h2, %h0|%h0, %h2}"
-  [(set_attr "type" "alu")
+           (match_operand:QI 2 "general_operand" "QnBn,QnBn")) 0))
+   (clobber (reg:CC FLAGS_REG))]
+  ""
+  "@
+   sub{b}\t{%2, %h0|%h0, %2}
+   #"
+  "reload_completed
+   && !(rtx_equal_p (operands[0], operands[1]))"
+  [(set (zero_extract:SWI248
+         (match_dup 0) (const_int 8) (const_int 8))
+       (zero_extract:SWI248
+         (match_dup 1) (const_int 8) (const_int 8)))
+   (parallel
+     [(set (zero_extract:SWI248
+            (match_dup 0) (const_int 8) (const_int 8))
+          (subreg:SWI248
+            (minus:QI
+              (subreg:QI
+                (match_op_dup 3
+                  [(match_dup 0) (const_int 8) (const_int 8)]) 0)
+              (match_dup 2)) 0))
+      (clobber (reg:CC FLAGS_REG))])]
+  ""
+  [(set_attr "addr" "gpr8")
+   (set_attr "type" "alu")
    (set_attr "mode" "QI")])
 
 ;; Subtract with jump on overflow.
               (pc)))]
   ""
 {
-  ix86_fixup_binary_operands_no_copy (MINUS, <MODE>mode, operands);
+  ix86_fixup_binary_operands_no_copy (MINUS, <MODE>mode, operands,
+                                     TARGET_APX_NDD);
   if (CONST_SCALAR_INT_P (operands[2]))
     operands[4] = operands[2];
   else
   [(set (reg:CCO FLAGS_REG)
        (eq:CCO (minus:<DWI>
                   (sign_extend:<DWI>
-                     (match_operand:SWI 1 "nonimmediate_operand" "0,0"))
+                     (match_operand:SWI 1 "nonimmediate_operand" "0,0,rm,r"))
                   (sign_extend:<DWI>
-                     (match_operand:SWI 2 "<general_sext_operand>" "<r>We,m")))
+                     (match_operand:SWI 2 "<general_sext_operand>" "<r>We,m,rWe,m")))
                (sign_extend:<DWI>
                   (minus:SWI (match_dup 1) (match_dup 2)))))
-   (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
+   (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>,r,r")
        (minus:SWI (match_dup 1) (match_dup 2)))]
-  "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
-  "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
-  [(set_attr "type" "alu")
+  "ix86_binary_operator_ok (MINUS, <MODE>mode, operands, TARGET_APX_NDD)"
+  "@
+  sub{<imodesuffix>}\t{%2, %0|%0, %2}
+  sub{<imodesuffix>}\t{%2, %0|%0, %2}
+  sub{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
+  sub{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}"
+  [(set_attr "isa" "*,*,apx_ndd,apx_ndd")
+   (set_attr "type" "alu")
    (set_attr "mode" "<MODE>")])
 
 (define_insn "subv<mode>4_1"
   [(set (reg:CCO FLAGS_REG)
        (eq:CCO (minus:<DWI>
                   (sign_extend:<DWI>
-                     (match_operand:SWI 1 "nonimmediate_operand" "0"))
+                     (match_operand:SWI 1 "nonimmediate_operand" "0,rm"))
                   (match_operand:<DWI> 3 "const_int_operand"))
                (sign_extend:<DWI>
                   (minus:SWI
                     (match_dup 1)
-                    (match_operand:SWI 2 "x86_64_immediate_operand" "<i>")))))
-   (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
+                    (match_operand:SWI 2 "x86_64_immediate_operand" "<i>,<i>")))))
+   (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,r")
        (minus:SWI (match_dup 1) (match_dup 2)))]
-  "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)
+  "ix86_binary_operator_ok (MINUS, <MODE>mode, operands, TARGET_APX_NDD)
    && CONST_INT_P (operands[2])
    && INTVAL (operands[2]) == INTVAL (operands[3])"
-  "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
-  [(set_attr "type" "alu")
+  "@
+  sub{<imodesuffix>}\t{%2, %0|%0, %2}
+  sub{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}"
+  [(set_attr "isa" "*,apx_ndd")
+   (set_attr "type" "alu")
    (set_attr "mode" "<MODE>")
    (set (attr "length_immediate")
        (cond [(match_test "IN_RANGE (INTVAL (operands[2]), -128, 127)")
        (eq:CCO
          (minus:<QPWI>
            (sign_extend:<QPWI>
-             (match_operand:<DWI> 1 "nonimmediate_operand" "0,0"))
+             (match_operand:<DWI> 1 "nonimmediate_operand" "0,0,ro,r"))
            (sign_extend:<QPWI>
-             (match_operand:<DWI> 2 "nonimmediate_operand" "r,o")))
+             (match_operand:<DWI> 2 "nonimmediate_operand" "r,o,r,o")))
          (sign_extend:<QPWI>
            (minus:<DWI> (match_dup 1) (match_dup 2)))))
-   (set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro,r")
+   (set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro,r,&r,&r")
        (minus:<DWI> (match_dup 1) (match_dup 2)))]
-  "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
+  "ix86_binary_operator_ok (MINUS, <MODE>mode, operands, TARGET_APX_NDD)"
   "#"
   "&& reload_completed"
   [(parallel [(set (reg:CC FLAGS_REG)
                     (match_dup 5)))])]
 {
   split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);
-})
+}
+[(set_attr "isa" "*,*,apx_ndd,apx_ndd")])
 
 (define_insn_and_split "*subv<dwi>4_doubleword_1"
   [(set (reg:CCO FLAGS_REG)
        (eq:CCO
          (minus:<QPWI>
            (sign_extend:<QPWI>
-             (match_operand:<DWI> 1 "nonimmediate_operand" "0"))
+             (match_operand:<DWI> 1 "nonimmediate_operand" "0,ro"))
            (match_operand:<QPWI> 3 "const_scalar_int_operand"))
          (sign_extend:<QPWI>
            (minus:<DWI>
              (match_dup 1)
-             (match_operand:<DWI> 2 "x86_64_hilo_general_operand" "<di>")))))
-   (set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro")
+             (match_operand:<DWI> 2 "x86_64_hilo_general_operand" "<di>,<di>")))))
+   (set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro,&r")
        (minus:<DWI> (match_dup 1) (match_dup 2)))]
-  "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)
+  "ix86_binary_operator_ok (MINUS, <MODE>mode, operands, TARGET_APX_NDD)
    && CONST_SCALAR_INT_P (operands[2])
    && rtx_equal_p (operands[2], operands[3])"
   "#"
   split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);
   if (operands[2] == const0_rtx)
     {
+      if (!rtx_equal_p (operands[0], operands[1]))
+       emit_move_insn (operands[0], operands[1]);
       emit_insn (gen_subv<mode>4_1 (operands[3], operands[4], operands[5],
                                    operands[5]));
       DONE;
     }
-})
+}
+[(set_attr "isa" "*,apx_ndd")])
 
 (define_insn "*subv<mode>4_overflow_1"
   [(set (reg:CCO FLAGS_REG)
          (minus:<DWI>
            (minus:<DWI>
              (sign_extend:<DWI>
-               (match_operand:SWI 1 "nonimmediate_operand" "%0,0"))
+               (match_operand:SWI 1 "nonimmediate_operand" "%0,0,rm,r"))
              (match_operator:<DWI> 4 "ix86_carry_flag_operator"
                [(match_operand 3 "flags_reg_operand") (const_int 0)]))
            (sign_extend:<DWI>
-             (match_operand:SWI 2 "<general_sext_operand>" "rWe,m")))
+             (match_operand:SWI 2 "<general_sext_operand>" "rWe,m,rWe,m")))
          (sign_extend:<DWI>
            (minus:SWI
              (minus:SWI
                (match_operator:SWI 5 "ix86_carry_flag_operator"
                  [(match_dup 3) (const_int 0)]))
              (match_dup 2)))))
-   (set (match_operand:SWI 0 "nonimmediate_operand" "=rm,r")
+   (set (match_operand:SWI 0 "nonimmediate_operand" "=rm,r,r,r")
        (minus:SWI
          (minus:SWI
            (match_dup 1)
            (match_op_dup 5 [(match_dup 3) (const_int 0)]))
          (match_dup 2)))]
-  "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
-  "sbb{<imodesuffix>}\t{%2, %0|%0, %2}"
-  [(set_attr "type" "alu")
+  "ix86_binary_operator_ok (MINUS, <MODE>mode, operands, TARGET_APX_NDD)"
+  "@
+  sbb{<imodesuffix>}\t{%2, %0|%0, %2}
+  sbb{<imodesuffix>}\t{%2, %0|%0, %2}
+  sbb{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
+  sbb{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}"
+  [(set_attr "isa" "*,*,apx_ndd,apx_ndd")
+   (set_attr "type" "alu")
    (set_attr "mode" "<MODE>")])
 
 (define_insn "*subv<mode>4_overflow_2"
          (minus:<DWI>
            (minus:<DWI>
              (sign_extend:<DWI>
-               (match_operand:SWI 1 "nonimmediate_operand" "%0"))
+               (match_operand:SWI 1 "nonimmediate_operand" "%0,rm"))
              (match_operator:<DWI> 4 "ix86_carry_flag_operator"
                [(match_operand 3 "flags_reg_operand") (const_int 0)]))
-           (match_operand:<DWI> 6 "const_int_operand" "n"))
+           (match_operand:<DWI> 6 "const_int_operand" "n,n"))
          (sign_extend:<DWI>
            (minus:SWI
              (minus:SWI
                (match_dup 1)
                (match_operator:SWI 5 "ix86_carry_flag_operator"
                  [(match_dup 3) (const_int 0)]))
-             (match_operand:SWI 2 "x86_64_immediate_operand" "e")))))
-   (set (match_operand:SWI 0 "nonimmediate_operand" "=rm")
+             (match_operand:SWI 2 "x86_64_immediate_operand" "e,e")))))
+   (set (match_operand:SWI 0 "nonimmediate_operand" "=rm,r")
        (minus:SWI
          (minus:SWI
            (match_dup 1)
            (match_op_dup 5 [(match_dup 3) (const_int 0)]))
          (match_dup 2)))]
-  "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)
+  "ix86_binary_operator_ok (MINUS, <MODE>mode, operands, TARGET_APX_NDD)
    && CONST_INT_P (operands[2])
    && INTVAL (operands[2]) == INTVAL (operands[6])"
-  "sbb{<imodesuffix>}\t{%2, %0|%0, %2}"
-  [(set_attr "type" "alu")
+  "@
+  sbb{<imodesuffix>}\t{%2, %0|%0, %2}
+  sbb{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}"
+  [(set_attr "isa" "*,apx_ndd")
+   (set_attr "type" "alu")
    (set_attr "mode" "<MODE>")
    (set (attr "length_immediate")
      (if_then_else (match_test "IN_RANGE (INTVAL (operands[2]), -128, 127)")
               (label_ref (match_operand 3))
               (pc)))]
   ""
-  "ix86_fixup_binary_operands_no_copy (MINUS, <MODE>mode, operands);")
+  "ix86_fixup_binary_operands_no_copy (MINUS, <MODE>mode, operands,
+                                      TARGET_APX_NDD);")
 
 (define_insn "*sub<mode>_3"
   [(set (reg FLAGS_REG)
-       (compare (match_operand:SWI 1 "nonimmediate_operand" "0,0")
-                (match_operand:SWI 2 "<general_operand>" "<r><i>,<m>")))
-   (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
+       (compare (match_operand:SWI 1 "nonimmediate_operand" "0,0,rm,r")
+                (match_operand:SWI 2 "<general_operand>" "<r><i>,<m>,r<i>,<m>")))
+   (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>i,r,r")
        (minus:SWI (match_dup 1) (match_dup 2)))]
   "ix86_match_ccmode (insn, CCmode)
-   && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
-  "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
-  [(set_attr "type" "alu")
+   && ix86_binary_operator_ok (MINUS, <MODE>mode, operands, TARGET_APX_NDD)"
+  "@
+  sub{<imodesuffix>}\t{%2, %0|%0, %2}
+  sub{<imodesuffix>}\t{%2, %0|%0, %2}
+  sub{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
+  sub{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}"
+  [(set_attr "isa" "*,*,apx_ndd,apx_ndd")
+   (set_attr "type" "alu")
    (set_attr "mode" "<MODE>")])
 
 (define_peephole2
 
 (define_insn "*subsi_3_zext"
   [(set (reg FLAGS_REG)
-       (compare (match_operand:SI 1 "register_operand" "0")
-                (match_operand:SI 2 "x86_64_general_operand" "rBMe")))
-   (set (match_operand:DI 0 "register_operand" "=r")
+       (compare (match_operand:SI 1 "nonimmediate_operand" "0,r,rm")
+                (match_operand:SI 2 "x86_64_general_operand" "rBMe,rBMe,re")))
+   (set (match_operand:DI 0 "register_operand" "=r,r,r")
        (zero_extend:DI
          (minus:SI (match_dup 1)
                    (match_dup 2))))]
   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
-   && ix86_binary_operator_ok (MINUS, SImode, operands)"
-  "sub{l}\t{%2, %1|%1, %2}"
-  [(set_attr "type" "alu")
+   && ix86_binary_operator_ok (MINUS, SImode, operands, TARGET_APX_NDD)"
+  "@
+  sub{l}\t{%2, %1|%1, %2}
+  sub{l}\t{%2, %1, %k0|%k0, %1, %2}
+  sub{l}\t{%2, %1, %k0|%k0, %1, %2}"
+  [(set_attr "isa" "*,apx_ndd,apx_ndd")
+   (set_attr "type" "alu")
    (set_attr "mode" "SI")])
 \f
 ;; Add with carry and subtract with borrow
 
 (define_insn "@add<mode>3_carry"
-  [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
+  [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>,r,r")
        (plus:SWI
          (plus:SWI
            (match_operator:SWI 4 "ix86_carry_flag_operator"
             [(match_operand 3 "flags_reg_operand") (const_int 0)])
-           (match_operand:SWI 1 "nonimmediate_operand" "%0,0"))
-         (match_operand:SWI 2 "<general_operand>" "<r><i>,<m>")))
+           (match_operand:SWI 1 "nonimmediate_operand" "%0,0,rm,r"))
+         (match_operand:SWI 2 "<general_operand>" "<r><i>,<m>,r<i>,<m>")))
    (clobber (reg:CC FLAGS_REG))]
-  "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
-  "adc{<imodesuffix>}\t{%2, %0|%0, %2}"
-  [(set_attr "type" "alu")
+  "ix86_binary_operator_ok (PLUS, <MODE>mode, operands, TARGET_APX_NDD)"
+  "@
+   adc{<imodesuffix>}\t{%2, %0|%0, %2}
+   adc{<imodesuffix>}\t{%2, %0|%0, %2}
+   adc{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
+   adc{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}"
+  [(set_attr "isa" "*,*,apx_ndd,apx_ndd")
+   (set_attr "type" "alu")
    (set_attr "use_carry" "1")
    (set_attr "pent_pair" "pu")
    (set_attr "mode" "<MODE>")])
    (set_attr "mode" "<MODE>")])
 
 (define_insn "*addsi3_carry_zext"
-  [(set (match_operand:DI 0 "register_operand" "=r")
+  [(set (match_operand:DI 0 "register_operand" "=r,r,r")
        (zero_extend:DI
          (plus:SI
            (plus:SI (match_operator:SI 3 "ix86_carry_flag_operator"
                      [(reg FLAGS_REG) (const_int 0)])
-                    (match_operand:SI 1 "register_operand" "%0"))
-           (match_operand:SI 2 "x86_64_general_operand" "rBMe"))))
+                    (match_operand:SI 1 "nonimmediate_operand" "%0,r,rm"))
+           (match_operand:SI 2 "x86_64_general_operand" "rBMe,rBMe,re"))))
    (clobber (reg:CC FLAGS_REG))]
-  "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
-  "adc{l}\t{%2, %k0|%k0, %2}"
-  [(set_attr "type" "alu")
+  "TARGET_64BIT
+   && ix86_binary_operator_ok (PLUS, SImode, operands, TARGET_APX_NDD)"
+  "@
+  adc{l}\t{%2, %k0|%k0, %2}
+  adc{l}\t{%2, %1, %k0|%k0, %1, %2}
+  adc{l}\t{%2, %1, %k0|%k0, %1, %2}"
+  [(set_attr "isa" "*,apx_ndd,apx_ndd")
+   (set_attr "type" "alu")
    (set_attr "use_carry" "1")
    (set_attr "pent_pair" "pu")
    (set_attr "mode" "SI")])
 
 (define_insn "*addsi3_carry_zext_0"
-  [(set (match_operand:DI 0 "register_operand" "=r")
+  [(set (match_operand:DI 0 "register_operand" "=r,r")
        (zero_extend:DI
          (plus:SI (match_operator:SI 2 "ix86_carry_flag_operator"
                    [(reg FLAGS_REG) (const_int 0)])
-                  (match_operand:SI 1 "register_operand" "0"))))
+                  (match_operand:SI 1 "nonimmediate_operand" "0,rm"))))
    (clobber (reg:CC FLAGS_REG))]
   "TARGET_64BIT"
-  "adc{l}\t{$0, %k0|%k0, 0}"
-  [(set_attr "type" "alu")
+  "@
+  adc{l}\t{$0, %k0|%k0, 0}
+  adc{l}\t{$0, %1, %k0|%k0, %1, 0}"
+  [(set_attr "isa" "*,apx_ndd")
+   (set_attr "type" "alu")
    (set_attr "use_carry" "1")
    (set_attr "pent_pair" "pu")
    (set_attr "mode" "SI")])
 
 (define_insn "*addsi3_carry_zext_0r"
-  [(set (match_operand:DI 0 "register_operand" "=r")
+  [(set (match_operand:DI 0 "register_operand" "=r,r")
        (zero_extend:DI
          (plus:SI (match_operator:SI 2 "ix86_carry_flag_unset_operator"
                    [(reg FLAGS_REG) (const_int 0)])
-                  (match_operand:SI 1 "register_operand" "0"))))
+                  (match_operand:SI 1 "nonimmediate_operand" "0,rm"))))
    (clobber (reg:CC FLAGS_REG))]
   "TARGET_64BIT"
-  "sbb{l}\t{$-1, %k0|%k0, -1}"
-  [(set_attr "type" "alu")
+  "@
+  sbb{l}\t{$-1, %k0|%k0, -1}
+  sbb{l}\t{$-1, %1, %k0|%k0, %1, -1}"
+  [(set_attr "isa" "*,apx_ndd")
+   (set_attr "type" "alu")
    (set_attr "use_carry" "1")
    (set_attr "pent_pair" "pu")
    (set_attr "mode" "SI")])
              (plus:SWI48
                (match_operator:SWI48 5 "ix86_carry_flag_operator"
                  [(match_operand 3 "flags_reg_operand") (const_int 0)])
-               (match_operand:SWI48 1 "nonimmediate_operand" "%0,0"))
-             (match_operand:SWI48 2 "nonimmediate_operand" "r,rm")))
+               (match_operand:SWI48 1 "nonimmediate_operand" "%0,0,rm,r"))
+             (match_operand:SWI48 2 "nonimmediate_operand" "r,rm,r,m")))
          (plus:<DWI>
            (zero_extend:<DWI> (match_dup 2))
            (match_operator:<DWI> 4 "ix86_carry_flag_operator"
              [(match_dup 3) (const_int 0)]))))
-   (set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
+   (set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r,r,r")
        (plus:SWI48 (plus:SWI48 (match_op_dup 5
                                 [(match_dup 3) (const_int 0)])
                                (match_dup 1))
                    (match_dup 2)))]
-  "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
-  "adc{<imodesuffix>}\t{%2, %0|%0, %2}"
-  [(set_attr "type" "alu")
+  "ix86_binary_operator_ok (PLUS, <MODE>mode, operands, TARGET_APX_NDD)"
+  "@
+  adc{<imodesuffix>}\t{%2, %0|%0, %2}
+  adc{<imodesuffix>}\t{%2, %0|%0, %2}
+  adc{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
+  adc{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}"
+  [(set_attr "isa" "*,*,apx_ndd,apx_ndd")
+   (set_attr "type" "alu")
    (set_attr "use_carry" "1")
    (set_attr "pent_pair" "pu")
    (set_attr "mode" "<MODE>")])
             (match_dup 1)))
       (set (match_operand:SWI48 0 "nonimmediate_operand")
           (plus:SWI48 (match_dup 1) (match_dup 2)))])]
-  "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)")
+  "ix86_binary_operator_ok (PLUS, <MODE>mode, operands, TARGET_APX_NDD)")
 
 (define_insn "*addcarry<mode>_1"
   [(set (reg:CCC FLAGS_REG)
              (plus:SWI48
                (match_operator:SWI48 5 "ix86_carry_flag_operator"
                  [(match_operand 3 "flags_reg_operand") (const_int 0)])
-               (match_operand:SWI48 1 "nonimmediate_operand" "%0"))
-             (match_operand:SWI48 2 "x86_64_immediate_operand" "e")))
+               (match_operand:SWI48 1 "nonimmediate_operand" "%0,rm"))
+             (match_operand:SWI48 2 "x86_64_immediate_operand" "e,e")))
          (plus:<DWI>
            (match_operand:<DWI> 6 "const_scalar_int_operand")
            (match_operator:<DWI> 4 "ix86_carry_flag_operator"
              [(match_dup 3) (const_int 0)]))))
-   (set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
+   (set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
        (plus:SWI48 (plus:SWI48 (match_op_dup 5
                                 [(match_dup 3) (const_int 0)])
                                (match_dup 1))
                    (match_dup 2)))]
-  "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)
+  "ix86_binary_operator_ok (PLUS, <MODE>mode, operands, TARGET_APX_NDD)
    && CONST_INT_P (operands[2])
    /* Check that operands[6] is operands[2] zero extended from
       <MODE>mode to <DWI>mode.  */
          && ((unsigned HOST_WIDE_INT) CONST_WIDE_INT_ELT (operands[6], 0)
              == UINTVAL (operands[2]))
          && CONST_WIDE_INT_ELT (operands[6], 1) == 0))"
-  "adc{<imodesuffix>}\t{%2, %0|%0, %2}"
-  [(set_attr "type" "alu")
+  "@
+  adc{<imodesuffix>}\t{%2, %0|%0, %2}
+  adc{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}"
+  [(set_attr "isa" "*,apx_ndd")
+   (set_attr "type" "alu")
    (set_attr "use_carry" "1")
    (set_attr "pent_pair" "pu")
    (set_attr "mode" "<MODE>")
        (const_string "4")))])
 
 (define_insn "@sub<mode>3_carry"
-  [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
+  [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>,r,r")
        (minus:SWI
          (minus:SWI
-           (match_operand:SWI 1 "nonimmediate_operand" "0,0")
+           (match_operand:SWI 1 "nonimmediate_operand" "0,0,rm,r")
            (match_operator:SWI 4 "ix86_carry_flag_operator"
             [(match_operand 3 "flags_reg_operand") (const_int 0)]))
-         (match_operand:SWI 2 "<general_operand>" "<r><i>,<m>")))
+         (match_operand:SWI 2 "<general_operand>" "<r><i>,<m>,r<i>,<m>")))
    (clobber (reg:CC FLAGS_REG))]
-  "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
-  "sbb{<imodesuffix>}\t{%2, %0|%0, %2}"
-  [(set_attr "type" "alu")
+  "ix86_binary_operator_ok (MINUS, <MODE>mode, operands, TARGET_APX_NDD)"
+  "@
+  sbb{<imodesuffix>}\t{%2, %0|%0, %2}
+  sbb{<imodesuffix>}\t{%2, %0|%0, %2}
+  sbb{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
+  sbb{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}"
+  [(set_attr "isa" "*,*,apx_ndd,apx_ndd")
+   (set_attr "type" "alu")
    (set_attr "use_carry" "1")
    (set_attr "pent_pair" "pu")
    (set_attr "mode" "<MODE>")])
    (set_attr "mode" "<MODE>")])
 
 (define_insn "*subsi3_carry_zext"
-  [(set (match_operand:DI 0 "register_operand" "=r")
+  [(set (match_operand:DI 0 "register_operand" "=r,r,r")
        (zero_extend:DI
          (minus:SI
            (minus:SI
-             (match_operand:SI 1 "register_operand" "0")
+             (match_operand:SI 1 "nonimmediate_operand" "0,r,rm")
              (match_operator:SI 3 "ix86_carry_flag_operator"
               [(reg FLAGS_REG) (const_int 0)]))
-           (match_operand:SI 2 "x86_64_general_operand" "rBMe"))))
+           (match_operand:SI 2 "x86_64_general_operand" "rBMe,rBMe,re"))))
    (clobber (reg:CC FLAGS_REG))]
-  "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
-  "sbb{l}\t{%2, %k0|%k0, %2}"
-  [(set_attr "type" "alu")
+  "TARGET_64BIT
+   && ix86_binary_operator_ok (MINUS, SImode, operands, TARGET_APX_NDD)"
+  "@
+  sbb{l}\t{%2, %k0|%k0, %2}
+  sbb{l}\t{%2, %1, %k0|%k0, %1, %2}
+  sbb{l}\t{%2, %1, %k0|%k0, %1, %2}"
+  [(set_attr "isa" "*,apx_ndd,apx_ndd")
+   (set_attr "type" "alu")
    (set_attr "use_carry" "1")
    (set_attr "pent_pair" "pu")
    (set_attr "mode" "SI")])
   [(set (reg:CCC FLAGS_REG)
        (compare:CCC
          (zero_extend:<DWI>
-           (match_operand:SWI48 1 "nonimmediate_operand" "0,0"))
+           (match_operand:SWI48 1 "nonimmediate_operand" "0,0,r,rm"))
          (plus:<DWI>
            (match_operator:<DWI> 4 "ix86_carry_flag_operator"
              [(match_operand 3 "flags_reg_operand") (const_int 0)])
            (zero_extend:<DWI>
-             (match_operand:SWI48 2 "nonimmediate_operand" "r,rm")))))
-   (set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
+             (match_operand:SWI48 2 "nonimmediate_operand" "r,rm,rm,r")))))
+   (set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r,r,r")
        (minus:SWI48 (minus:SWI48
                       (match_dup 1)
                       (match_operator:SWI48 5 "ix86_carry_flag_operator"
                         [(match_dup 3) (const_int 0)]))
                     (match_dup 2)))]
-  "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
-  "sbb{<imodesuffix>}\t{%2, %0|%0, %2}"
-  [(set_attr "type" "alu")
+  "ix86_binary_operator_ok (MINUS, <MODE>mode, operands, TARGET_APX_NDD)"
+  "@
+  sbb{<imodesuffix>}\t{%2, %0|%0, %2}
+  sbb{<imodesuffix>}\t{%2, %0|%0, %2}
+  sbb{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
+  sbb{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}"
+  [(set_attr "isa" "*,*,apx_ndd,apx_ndd")
+   (set_attr "type" "alu")
    (set_attr "use_carry" "1")
    (set_attr "pent_pair" "pu")
    (set_attr "mode" "<MODE>")])
             (match_operand:SWI48 2 "<general_operand>")))
       (set (match_operand:SWI48 0 "register_operand")
           (minus:SWI48 (match_dup 1) (match_dup 2)))])]
-  "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)")
+  "ix86_binary_operator_ok (MINUS, <MODE>mode, operands, TARGET_APX_NDD)")
 
 (define_expand "uaddc<mode>5"
   [(match_operand:SWI48 0 "register_operand")
   [(set (reg:CCC FLAGS_REG)
        (compare:CCC
          (plus:SWI
-           (match_operand:SWI 1 "nonimmediate_operand" "%0")
-           (match_operand:SWI 2 "<general_operand>" "<g>"))
+           (match_operand:SWI 1 "nonimmediate_operand" "%0,r,rm")
+           (match_operand:SWI 2 "<general_operand>" "<g>,<g>,re"))
          (match_dup 1)))
-   (clobber (match_scratch:SWI 0 "=<r>"))]
+   (clobber (match_scratch:SWI 0 "=<r>,r,r"))]
   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
-  "add{<imodesuffix>}\t{%2, %0|%0, %2}"
-  [(set_attr "type" "alu")
+  "@
+  add{<imodesuffix>}\t{%2, %0|%0, %2}
+  add{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
+  add{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}"
+  [(set_attr "isa" "*,apx_ndd,apx_ndd")
+   (set_attr "type" "alu")
    (set_attr "mode" "<MODE>")])
 
-(define_insn "*add<mode>3_cc_overflow_1"
+(define_insn "@add<mode>3_cc_overflow_1"
   [(set (reg:CCC FLAGS_REG)
        (compare:CCC
            (plus:SWI
-               (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
-               (match_operand:SWI 2 "<general_operand>" "<r><i>,<m>"))
+               (match_operand:SWI 1 "nonimmediate_operand" "%0,0,rm,r")
+               (match_operand:SWI 2 "<general_operand>" "<r><i>,<m>,r<i>,<m>"))
            (match_dup 1)))
-   (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
+   (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>,r,r")
        (plus:SWI (match_dup 1) (match_dup 2)))]
-  "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
-  "add{<imodesuffix>}\t{%2, %0|%0, %2}"
-  [(set_attr "type" "alu")
+  "ix86_binary_operator_ok (PLUS, <MODE>mode, operands, TARGET_APX_NDD)"
+  "@
+   add{<imodesuffix>}\t{%2, %0|%0, %2}
+   add{<imodesuffix>}\t{%2, %0|%0, %2}
+   add{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
+   add{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}"
+  [(set_attr "isa" "*,*,apx_ndd,apx_ndd")
+   (set_attr "type" "alu")
    (set_attr "mode" "<MODE>")])
 
 (define_peephole2
   [(set (reg:CCC FLAGS_REG)
        (compare:CCC
          (plus:SI
-           (match_operand:SI 1 "nonimmediate_operand" "%0")
-           (match_operand:SI 2 "x86_64_general_operand" "rBMe"))
+           (match_operand:SI 1 "nonimmediate_operand" "%0,r,rm")
+           (match_operand:SI 2 "x86_64_general_operand" "rBMe,rBMe,re"))
          (match_dup 1)))
-   (set (match_operand:DI 0 "register_operand" "=r")
+   (set (match_operand:DI 0 "register_operand" "=r,r,r")
        (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
-  "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
-  "add{l}\t{%2, %k0|%k0, %2}"
-  [(set_attr "type" "alu")
+  "TARGET_64BIT
+   && ix86_binary_operator_ok (PLUS, SImode, operands, TARGET_APX_NDD)"
+  "@
+  add{l}\t{%2, %k0|%k0, %2}
+  add{l}\t{%2, %1, %k0|%k0, %1, %2}
+  add{l}\t{%2, %1, %k0|%k0, %1, %2}"
+  [(set_attr "isa" "*,apx_ndd,apx_ndd")
+   (set_attr "type" "alu")
    (set_attr "mode" "SI")])
 
 (define_insn "*add<mode>3_cconly_overflow_2"
   [(set (reg:CCC FLAGS_REG)
        (compare:CCC
          (plus:SWI
-           (match_operand:SWI 1 "nonimmediate_operand" "%0")
-           (match_operand:SWI 2 "<general_operand>" "<g>"))
+           (match_operand:SWI 1 "nonimmediate_operand" "%0,r,rm")
+           (match_operand:SWI 2 "<general_operand>" "<g>,<g>,re"))
          (match_dup 2)))
-   (clobber (match_scratch:SWI 0 "=<r>"))]
+   (clobber (match_scratch:SWI 0 "=<r>,r,r"))]
   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
-  "add{<imodesuffix>}\t{%2, %0|%0, %2}"
-  [(set_attr "type" "alu")
+  "@
+  add{<imodesuffix>}\t{%2, %0|%0, %2}
+  add{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
+  add{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}"
+  [(set_attr "isa" "*,apx_ndd,apx_ndd")
+   (set_attr "type" "alu")
    (set_attr "mode" "<MODE>")])
 
 (define_insn "*add<mode>3_cc_overflow_2"
   [(set (reg:CCC FLAGS_REG)
        (compare:CCC
            (plus:SWI
-               (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
-               (match_operand:SWI 2 "<general_operand>" "<r><i>,<m>"))
+               (match_operand:SWI 1 "nonimmediate_operand" "%0,0,rm,r")
+               (match_operand:SWI 2 "<general_operand>" "<r><i>,<m>,r<i>,<m>"))
            (match_dup 2)))
-   (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
+   (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>,r,r")
        (plus:SWI (match_dup 1) (match_dup 2)))]
-  "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
-  "add{<imodesuffix>}\t{%2, %0|%0, %2}"
-  [(set_attr "type" "alu")
+  "ix86_binary_operator_ok (PLUS, <MODE>mode, operands, TARGET_APX_NDD)"
+  "@
+  add{<imodesuffix>}\t{%2, %0|%0, %2}
+  add{<imodesuffix>}\t{%2, %0|%0, %2}
+  add{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
+  add{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}"
+  [(set_attr "isa" "*,*,apx_ndd,apx_ndd")
+   (set_attr "type" "alu")
    (set_attr "mode" "<MODE>")])
 
 (define_insn "*addsi3_zext_cc_overflow_2"
   [(set (reg:CCC FLAGS_REG)
        (compare:CCC
          (plus:SI
-           (match_operand:SI 1 "nonimmediate_operand" "%0")
-           (match_operand:SI 2 "x86_64_general_operand" "rBMe"))
+           (match_operand:SI 1 "nonimmediate_operand" "%0,r,rm")
+           (match_operand:SI 2 "x86_64_general_operand" "rBMe,rBMe,re"))
          (match_dup 2)))
-   (set (match_operand:DI 0 "register_operand" "=r")
+   (set (match_operand:DI 0 "register_operand" "=r,r,r")
        (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
-  "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
-  "add{l}\t{%2, %k0|%k0, %2}"
-  [(set_attr "type" "alu")
+  "TARGET_64BIT
+   && ix86_binary_operator_ok (PLUS, SImode, operands, TARGET_APX_NDD)"
+  "@
+  add{l}\t{%2, %k0|%k0, %2}
+  add{l}\t{%2, %1, %k0|%k0, %1, %2}
+  add{l}\t{%2, %1, %k0|%k0, %1, %2}"
+  [(set_attr "isa" "*,apx_ndd,apx_ndd")
+   (set_attr "type" "alu")
    (set_attr "mode" "SI")])
 
 (define_insn_and_split "*add<dwi>3_doubleword_cc_overflow_1"
   [(set (reg:CCC FLAGS_REG)
        (compare:CCC
          (plus:<DWI>
-           (match_operand:<DWI> 1 "nonimmediate_operand" "%0,0")
-           (match_operand:<DWI> 2 "x86_64_hilo_general_operand" "r<di>,o"))
+           (match_operand:<DWI> 1 "nonimmediate_operand" "%0,0,ro,r")
+           (match_operand:<DWI> 2 "x86_64_hilo_general_operand" "r<di>,o,r<di>,o"))
          (match_dup 1)))
-   (set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro,r")
+   (set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro,r,&r,&r")
        (plus:<DWI> (match_dup 1) (match_dup 2)))]
-  "ix86_binary_operator_ok (PLUS, <DWI>mode, operands)"
+  "ix86_binary_operator_ok (PLUS, <DWI>mode, operands, TARGET_APX_NDD)"
   "#"
   "&& reload_completed"
   [(parallel [(set (reg:CCC FLAGS_REG)
   split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);
   if (operands[2] == const0_rtx)
     {
+      if (!rtx_equal_p (operands[0], operands[1]))
+       emit_move_insn (operands[0], operands[1]);
       emit_insn (gen_addcarry<mode>_0 (operands[3], operands[4], operands[5]));
       DONE;
     }
                                            operands[5], <MODE>mode);
   else
     operands[6] = gen_rtx_ZERO_EXTEND (<DWI>mode, operands[5]);
-})
+}
+[(set_attr "isa" "*,*,apx_ndd,apx_ndd")])
 
 ;; x == 0 with zero flag test can be done also as x < 1U with carry flag
 ;; test, where the latter is preferrable if we have some carry consuming
            (match_operand:SWI 1 "nonimmediate_operand"))
          (match_operand:SWI 2 "<general_operand>")))
    (clobber (reg:CC FLAGS_REG))]
-  "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)
+  "ix86_binary_operator_ok (PLUS, <MODE>mode, operands, TARGET_APX_NDD)
    && ix86_pre_reload_split ()"
   "#"
   "&& 1"
   "CONST_INT_P (operands[2])
    && (<MODE>mode != DImode
        || INTVAL (operands[2]) != HOST_WIDE_INT_C (-0x80000000))
-   && ix86_binary_operator_ok (PLUS, <MODE>mode, operands)
+   && ix86_binary_operator_ok (PLUS, <MODE>mode, operands, TARGET_APX_NDD)
    && ix86_pre_reload_split ()"
   "#"
   "&& 1"
                    (const_int 0)))
          (match_operand:SWI 2 "<general_operand>")))
    (clobber (reg:CC FLAGS_REG))]
-  "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)
+  "ix86_binary_operator_ok (MINUS, <MODE>mode, operands, TARGET_APX_NDD)
    && ix86_pre_reload_split ()"
   "#"
   "&& 1"
   "CONST_INT_P (operands[2])
    && (<MODE>mode != DImode
        || INTVAL (operands[2]) != HOST_WIDE_INT_C (-0x80000000))
-   && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)
+   && ix86_binary_operator_ok (MINUS, <MODE>mode, operands, TARGET_APX_NDD)
    && ix86_pre_reload_split ()"
   "#"
   "&& 1"
   "CONST_INT_P (operands[2])
    && (<MODE>mode != DImode
        || INTVAL (operands[2]) != HOST_WIDE_INT_C (-0x80000000))
-   && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)
+   && ix86_binary_operator_ok (MINUS, <MODE>mode, operands, TARGET_APX_NDD)
    && ix86_pre_reload_split ()"
   "#"
   "&& 1"
   [(parallel [(set (match_operand:<DWI> 0 "register_operand")
                   (mult:<DWI>
                     (any_extend:<DWI>
-                      (match_operand:DWIH 1 "nonimmediate_operand"))
+                      (match_operand:DWIH 1 "register_operand"))
                     (any_extend:<DWI>
-                      (match_operand:DWIH 2 "register_operand"))))
+                      (match_operand:DWIH 2 "nonimmediate_operand"))))
              (clobber (reg:CC FLAGS_REG))])])
 
 (define_expand "<u>mulqihi3"
   [(parallel [(set (match_operand:HI 0 "register_operand")
                   (mult:HI
                     (any_extend:HI
-                      (match_operand:QI 1 "nonimmediate_operand"))
+                      (match_operand:QI 1 "register_operand"))
                     (any_extend:HI
-                      (match_operand:QI 2 "register_operand"))))
+                      (match_operand:QI 2 "nonimmediate_operand"))))
              (clobber (reg:CC FLAGS_REG))])]
   "TARGET_QIMODE_MATH")
 
 (define_insn "*bmi2_umul<mode><dwi>3_1"
   [(set (match_operand:DWIH 0 "register_operand" "=r")
        (mult:DWIH
-         (match_operand:DWIH 2 "nonimmediate_operand" "%d")
+         (match_operand:DWIH 2 "register_operand" "%d")
          (match_operand:DWIH 3 "nonimmediate_operand" "rm")))
    (set (match_operand:DWIH 1 "register_operand" "=r")
-       (truncate:DWIH
-         (lshiftrt:<DWI>
-           (mult:<DWI> (zero_extend:<DWI> (match_dup 2))
-                       (zero_extend:<DWI> (match_dup 3)))
-           (match_operand:QI 4 "const_int_operand"))))]
-  "TARGET_BMI2 && INTVAL (operands[4]) == <MODE_SIZE> * BITS_PER_UNIT
-   && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
+       (umul_highpart:DWIH (match_dup 2) (match_dup 3)))]
+  "TARGET_BMI2"
   "mulx\t{%3, %0, %1|%1, %0, %3}"
   [(set_attr "type" "imulx")
    (set_attr "prefix" "vex")
    (set_attr "mode" "<MODE>")])
 
+;; Tweak *bmi2_umul<mode><dwi>3_1 to eliminate following mov.
+(define_peephole2
+  [(parallel [(set (match_operand:DWIH 0 "general_reg_operand")
+                  (mult:DWIH (match_operand:DWIH 2 "register_operand")
+                             (match_operand:DWIH 3 "nonimmediate_operand")))
+             (set (match_operand:DWIH 1 "general_reg_operand")
+                  (umul_highpart:DWIH (match_dup 2) (match_dup 3)))])
+   (set (match_operand:DWIH 4 "general_reg_operand")
+       (match_operand:DWIH 5 "general_reg_operand"))]
+  "TARGET_BMI2
+   && ((REGNO (operands[5]) == REGNO (operands[0])
+        && REGNO (operands[1]) != REGNO (operands[4]))
+       || (REGNO (operands[5]) == REGNO (operands[1])
+          && REGNO (operands[0]) != REGNO (operands[4])))
+   && peep2_reg_dead_p (2, operands[5])"
+  [(parallel [(set (match_dup 0) (mult:DWIH (match_dup 2) (match_dup 3)))
+             (set (match_dup 1)
+                  (umul_highpart:DWIH (match_dup 2) (match_dup 3)))])]
+{
+  if (REGNO (operands[5]) == REGNO (operands[0]))
+    operands[0] = operands[4];
+  else
+    operands[1] = operands[4];
+})
+
 (define_insn "*umul<mode><dwi>3_1"
   [(set (match_operand:<DWI> 0 "register_operand" "=r,A")
        (mult:<DWI>
          (zero_extend:<DWI>
-           (match_operand:DWIH 1 "nonimmediate_operand" "%d,0"))
+           (match_operand:DWIH 1 "register_operand" "%d,a"))
          (zero_extend:<DWI>
            (match_operand:DWIH 2 "nonimmediate_operand" "rm,rm"))))
    (clobber (reg:CC FLAGS_REG))]
   [(parallel [(set (match_dup 3)
                   (mult:DWIH (match_dup 1) (match_dup 2)))
              (set (match_dup 4)
-                  (truncate:DWIH
-                    (lshiftrt:<DWI>
-                      (mult:<DWI> (zero_extend:<DWI> (match_dup 1))
-                                  (zero_extend:<DWI> (match_dup 2)))
-                      (match_dup 5))))])]
+                  (umul_highpart:DWIH (match_dup 1) (match_dup 2)))])]
 {
   split_double_mode (<DWI>mode, &operands[0], 1, &operands[3], &operands[4]);
 
   [(set (match_operand:<DWI> 0 "register_operand" "=A")
        (mult:<DWI>
          (sign_extend:<DWI>
-           (match_operand:DWIH 1 "nonimmediate_operand" "%0"))
+           (match_operand:DWIH 1 "register_operand" "%a"))
          (sign_extend:<DWI>
            (match_operand:DWIH 2 "nonimmediate_operand" "rm"))))
    (clobber (reg:CC FLAGS_REG))]
   [(set (match_operand:HI 0 "register_operand" "=a")
        (mult:HI
          (any_extend:HI
-           (match_operand:QI 1 "nonimmediate_operand" "%0"))
+           (match_operand:QI 1 "register_operand" "%0"))
          (any_extend:HI
            (match_operand:QI 2 "nonimmediate_operand" "qm"))))
    (clobber (reg:CC FLAGS_REG))]
    (set_attr "bdver1_decode" "direct")
    (set_attr "mode" "QI")])
 
+;; Widening multiplication peephole2s to tweak register allocation.
+;; mov imm,%rdx; mov %rdi,%rax; mulq %rdx  ->  mov imm,%rax; mulq %rdi
+(define_peephole2
+  [(set (match_operand:DWIH 0 "general_reg_operand")
+       (match_operand:DWIH 1 "immediate_operand"))
+   (set (match_operand:DWIH 2 "general_reg_operand")
+       (match_operand:DWIH 3 "general_reg_operand"))
+   (parallel [(set (match_operand:<DWI> 4 "general_reg_operand")
+                  (mult:<DWI> (zero_extend:<DWI> (match_dup 2))
+                              (zero_extend:<DWI> (match_dup 0))))
+             (clobber (reg:CC FLAGS_REG))])]
+  "REGNO (operands[3]) != AX_REG
+   && REGNO (operands[0]) != REGNO (operands[2])
+   && REGNO (operands[0]) != REGNO (operands[3])
+   && (REGNO (operands[0]) == REGNO (operands[4])
+       || REGNO (operands[0]) == DX_REG
+       || peep2_reg_dead_p (3, operands[0]))"
+  [(set (match_dup 2) (match_dup 1))
+   (parallel [(set (match_dup 4)
+                  (mult:<DWI> (zero_extend:<DWI> (match_dup 2))
+                              (zero_extend:<DWI> (match_dup 3))))
+             (clobber (reg:CC FLAGS_REG))])])
+
+;; mov imm,%rax; mov %rdi,%rdx; mulx %rax  ->  mov imm,%rdx; mulx %rdi
+(define_peephole2
+  [(set (match_operand:DWIH 0 "general_reg_operand")
+       (match_operand:DWIH 1 "immediate_operand"))
+   (set (match_operand:DWIH 2 "general_reg_operand")
+       (match_operand:DWIH 3 "general_reg_operand"))
+   (parallel [(set (match_operand:DWIH 4 "general_reg_operand")
+                  (mult:DWIH (match_dup 2) (match_dup 0)))
+             (set (match_operand:DWIH 5 "general_reg_operand")
+                  (umul_highpart:DWIH (match_dup 2) (match_dup 0)))])]
+  "REGNO (operands[3]) != DX_REG
+   && REGNO (operands[0]) != REGNO (operands[2])
+   && REGNO (operands[0]) != REGNO (operands[3])
+   && (REGNO (operands[0]) == REGNO (operands[4])
+       || REGNO (operands[0]) == REGNO (operands[5])
+       || peep2_reg_dead_p (3, operands[0]))
+   && (REGNO (operands[2]) == REGNO (operands[4])
+       || REGNO (operands[2]) == REGNO (operands[5])
+       || peep2_reg_dead_p (3, operands[2]))"
+  [(set (match_dup 2) (match_dup 1))
+   (parallel [(set (match_dup 4)
+                  (mult:DWIH (match_dup 2) (match_dup 3)))
+             (set (match_dup 5)
+                  (umul_highpart:DWIH (match_dup 2) (match_dup 3)))])])
+
 ;; Highpart multiplication patterns
 (define_insn "<s>mul<mode>3_highpart"
   [(set (match_operand:DWIH 0 "register_operand" "=d")
          (and:QI
            (subreg:QI
              (match_operator:SWI248 2 "extract_operator"
-               [(match_operand 0 "int248_register_operand" "Q,Q")
+               [(match_operand 0 "int248_register_operand" "Q")
                 (const_int 8)
                 (const_int 8)]) 0)
-           (match_operand:QI 1 "general_x64constmem_operand" "QnBc,m"))
+           (match_operand:QI 1 "general_operand" "QnBn"))
          (const_int 0)))]
   "ix86_match_ccmode (insn, CCNOmode)"
   "test{b}\t{%1, %h0|%h0, %1}"
-  [(set_attr "isa" "*,nox64")
+  [(set_attr "addr" "gpr8")
    (set_attr "type" "test")
    (set_attr "mode" "QI")])
 
         (match_operator 1 "compare_operator"
          [(zero_extract:SWI248
             (match_operand 2 "int_nonimmediate_operand" "rm")
-            (match_operand 3 "const_int_operand")
-            (match_operand 4 "const_int_operand"))
+            (match_operand:QI 3 "const_int_operand")
+            (match_operand:QI 4 "const_int_operand"))
           (const_int 0)]))]
   "/* Ensure that resulting mask is zero or sign extended operand.  */
    INTVAL (operands[4]) >= 0
   operands[3] = gen_int_mode (INTVAL (operands[3]), QImode);
 })
 
+;; Narrow test instructions with immediate operands that test
+;; memory locations for zero.  E.g. testl $0x00aa0000, mem can be
+;; converted to testb $0xaa, mem+2.  Reject volatile locations and
+;; targets where reading (possibly unaligned) part of memory
+;; location after a large write to the same address causes
+;; store-to-load forwarding stall.
+(define_peephole2
+  [(set (reg:CCZ FLAGS_REG)
+       (compare:CCZ
+         (and:SWI248 (match_operand:SWI248 0 "memory_operand")
+                     (match_operand 1 "const_int_operand"))
+         (const_int 0)))]
+  "!TARGET_PARTIAL_MEMORY_READ_STALL && !MEM_VOLATILE_P (operands[0])"
+  [(set (reg:CCZ FLAGS_REG)
+       (compare:CCZ (match_dup 2) (const_int 0)))]
+{
+  unsigned HOST_WIDE_INT ival = UINTVAL (operands[1]);
+  int first_nonzero_byte, bitsize;
+  rtx new_addr, new_const;
+  machine_mode new_mode;
+
+  if (ival == 0)
+    FAIL;
+
+  /* Clear bits outside mode width.  */
+  ival &= GET_MODE_MASK (<MODE>mode);
+
+  first_nonzero_byte = ctz_hwi (ival) / BITS_PER_UNIT;
+
+  ival >>= first_nonzero_byte * BITS_PER_UNIT;
+
+  bitsize = sizeof (ival) * BITS_PER_UNIT - clz_hwi (ival);
+
+  if (bitsize <= GET_MODE_BITSIZE (QImode))
+    new_mode = QImode;
+  else if (bitsize <= GET_MODE_BITSIZE (HImode))
+    new_mode = HImode;
+  else if (bitsize <= GET_MODE_BITSIZE (SImode))
+    new_mode = SImode;
+  else
+    new_mode = DImode;
+
+  if (GET_MODE_SIZE (new_mode) >= GET_MODE_SIZE (<MODE>mode))
+    FAIL;
+
+  new_addr = adjust_address (operands[0], new_mode, first_nonzero_byte);
+  new_const = gen_int_mode (ival, new_mode);
+
+  operands[2] = gen_rtx_AND (new_mode, new_addr, new_const);
+})
+
 ;; %%% This used to optimize known byte-wide and operations to memory,
 ;; and sometimes to QImode registers.  If this is considered useful,
 ;; it should be done with splitters.
               (operands[0], gen_lowpart (mode, operands[1]),
                <MODE>mode, mode, 1));
   else
-    ix86_expand_binary_operator (AND, <MODE>mode, operands);
+    ix86_expand_binary_operator (AND, <MODE>mode, operands, TARGET_APX_NDD);
 
   DONE;
 })
 
 (define_insn_and_split "*and<dwi>3_doubleword"
-  [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro,r")
+  [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro,r,&r,&r")
        (and:<DWI>
-        (match_operand:<DWI> 1 "nonimmediate_operand" "%0,0")
-        (match_operand:<DWI> 2 "x86_64_hilo_general_operand" "r<di>,o")))
+        (match_operand:<DWI> 1 "nonimmediate_operand" "%0,0,ro,r")
+        (match_operand:<DWI> 2 "x86_64_hilo_general_operand" "r<di>,o,r<di>,o")))
    (clobber (reg:CC FLAGS_REG))]
-  "ix86_binary_operator_ok (AND, <DWI>mode, operands)"
+  "ix86_binary_operator_ok (AND, <DWI>mode, operands, TARGET_APX_NDD)"
   "#"
   "&& reload_completed"
   [(const_int:DWIH 0)]
   if (operands[2] == const0_rtx)
     emit_move_insn (operands[0], const0_rtx);
   else if (operands[2] == constm1_rtx)
-    emit_insn_deleted_note_p = true;
+    {
+      if (!rtx_equal_p (operands[0], operands[1]))
+       emit_move_insn (operands[0], operands[1]);
+      else
+       emit_insn_deleted_note_p = true;
+    }
   else
-    ix86_expand_binary_operator (AND, <MODE>mode, &operands[0]);
+    ix86_expand_binary_operator (AND, <MODE>mode, &operands[0], TARGET_APX_NDD);
 
   if (operands[5] == const0_rtx)
     emit_move_insn (operands[3], const0_rtx);
   else if (operands[5] == constm1_rtx)
     {
-      if (emit_insn_deleted_note_p)
+      if (!rtx_equal_p (operands[3], operands[4]))
+       emit_move_insn (operands[3], operands[4]);
+      else if (emit_insn_deleted_note_p)
        emit_note (NOTE_INSN_DELETED);
     }
   else
-    ix86_expand_binary_operator (AND, <MODE>mode, &operands[3]);
+    ix86_expand_binary_operator (AND, <MODE>mode, &operands[3], TARGET_APX_NDD);
 
   DONE;
-})
+}
+[(set_attr "isa" "*,*,apx_ndd,apx_ndd")])
 
 (define_insn "*anddi_1"
-  [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r,?k")
+  [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm,r,r,r,r,?k")
        (and:DI
-        (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm,k")
-        (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,m,L,k")))
+        (match_operand:DI 1 "nonimmediate_operand" "%0,r,0,0,rm,r,qm,k")
+        (match_operand:DI 2 "x86_64_szext_general_operand" "Z,Z,re,m,re,m,L,k")))
    (clobber (reg:CC FLAGS_REG))]
-  "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
+  "TARGET_64BIT
+   && ix86_binary_operator_ok (AND, DImode, operands, TARGET_APX_NDD)"
   "@
    and{l}\t{%k2, %k0|%k0, %k2}
+   and{l}\t{%k2, %k1, %k0|%k0, %k1, %k2}
    and{q}\t{%2, %0|%0, %2}
    and{q}\t{%2, %0|%0, %2}
+   and{q}\t{%2, %1, %0|%0, %1, %2}
+   and{q}\t{%2, %1, %0|%0, %1, %2}
    #
    #"
-  [(set_attr "isa" "x64,x64,x64,x64,avx512bw")
-   (set_attr "type" "alu,alu,alu,imovx,msklog")
-   (set_attr "length_immediate" "*,*,*,0,*")
+  [(set_attr "isa" "x64,apx_ndd,x64,x64,apx_ndd,apx_ndd,x64,avx512bw")
+   (set_attr "type" "alu,alu,alu,alu,alu,alu,imovx,msklog")
+   (set_attr "length_immediate" "*,*,*,*,*,*,0,*")
    (set (attr "prefix_rex")
      (if_then_else
        (and (eq_attr "type" "imovx")
                 (match_operand 1 "ext_QIreg_operand")))
        (const_string "1")
        (const_string "*")))
-   (set_attr "mode" "SI,DI,DI,SI,DI")])
+   (set_attr "mode" "SI,SI,DI,DI,DI,DI,SI,DI")])
 
 (define_insn_and_split "*anddi_1_btr"
   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
 
 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
 (define_insn "*andsi_1_zext"
-  [(set (match_operand:DI 0 "register_operand" "=r")
+  [(set (match_operand:DI 0 "register_operand" "=r,r,r")
        (zero_extend:DI
-         (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
-                 (match_operand:SI 2 "x86_64_general_operand" "rBMe"))))
+         (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,rm,r")
+                 (match_operand:SI 2 "x86_64_general_operand" "rBMe,re,BM"))))
    (clobber (reg:CC FLAGS_REG))]
-  "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
-  "and{l}\t{%2, %k0|%k0, %2}"
+  "TARGET_64BIT
+   && ix86_binary_operator_ok (AND, SImode, operands, TARGET_APX_NDD)"
+  "@
+  and{l}\t{%2, %k0|%k0, %2}
+  and{l}\t{%2, %1, %k0|%k0, %1, %2}
+  and{l}\t{%2, %1, %k0|%k0, %1, %2}"
   [(set_attr "type" "alu")
+   (set_attr "isa" "*,apx_ndd,apx_ndd")
    (set_attr "mode" "SI")])
 
 (define_insn "*and<mode>_1"
-  [(set (match_operand:SWI24 0 "nonimmediate_operand" "=rm,r,Ya,?k")
-       (and:SWI24 (match_operand:SWI24 1 "nonimmediate_operand" "%0,0,qm,k")
-                  (match_operand:SWI24 2 "<general_operand>" "r<i>,<m>,L,k")))
+  [(set (match_operand:SWI24 0 "nonimmediate_operand" "=rm,r,r,r,Ya,?k")
+       (and:SWI24 (match_operand:SWI24 1 "nonimmediate_operand" "%0,0,rm,r,qm,k")
+                  (match_operand:SWI24 2 "<general_operand>" "r<i>,<m>,r<i>,<m>,L,k")))
    (clobber (reg:CC FLAGS_REG))]
-  "ix86_binary_operator_ok (AND, <MODE>mode, operands)"
+  "ix86_binary_operator_ok (AND, <MODE>mode, operands, TARGET_APX_NDD)"
   "@
    and{<imodesuffix>}\t{%2, %0|%0, %2}
    and{<imodesuffix>}\t{%2, %0|%0, %2}
+   and{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
+   and{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
    #
    #"
   [(set (attr "isa")
-       (cond [(eq_attr "alternative" "3")
+       (cond [(eq_attr "alternative" "2,3")
+                (const_string "apx_ndd")
+              (eq_attr "alternative" "5")
                 (if_then_else (eq_attr "mode" "SI")
                   (const_string "avx512bw")
                   (const_string "avx512f"))
              ]
              (const_string "*")))
-   (set_attr "type" "alu,alu,imovx,msklog")
-   (set_attr "length_immediate" "*,*,0,*")
+   (set_attr "type" "alu,alu,alu,alu,imovx,msklog")
+   (set_attr "length_immediate" "*,*,*,*,0,*")
    (set (attr "prefix_rex")
      (if_then_else
        (and (eq_attr "type" "imovx")
                 (match_operand 1 "ext_QIreg_operand")))
        (const_string "1")
        (const_string "*")))
-   (set_attr "mode" "<MODE>,<MODE>,SI,<MODE>")])
+   (set_attr "mode" "<MODE>,<MODE>,<MODE>,<MODE>,SI,<MODE>")])
 
 (define_insn "*andqi_1"
-  [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r,?k")
-       (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,k")
-               (match_operand:QI 2 "general_operand" "qn,m,rn,k")))
+  [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r,r,r,?k")
+       (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,rm,r,k")
+               (match_operand:QI 2 "general_operand" "qn,m,rn,rn,m,k")))
    (clobber (reg:CC FLAGS_REG))]
-  "ix86_binary_operator_ok (AND, QImode, operands)"
+  "ix86_binary_operator_ok (AND, QImode, operands, TARGET_APX_NDD)"
   "@
    and{b}\t{%2, %0|%0, %2}
    and{b}\t{%2, %0|%0, %2}
    and{l}\t{%k2, %k0|%k0, %k2}
+   and{b}\t{%2, %1, %0|%0, %1, %2}
+   and{b}\t{%2, %1, %0|%0, %1, %2}
    #"
-  [(set_attr "type" "alu,alu,alu,msklog")
+  [(set_attr "type" "alu,alu,alu,alu,alu,msklog")
+   (set_attr "isa" "*,*,*,apx_ndd,apx_ndd,*")
    (set (attr "mode")
        (cond [(eq_attr "alternative" "2")
                 (const_string "SI")
-               (and (eq_attr "alternative" "3")
+               (and (eq_attr "alternative" "5")
                     (match_test "!TARGET_AVX512DQ"))
                 (const_string "HI")
               ]
           (symbol_ref "true")))])
 
 ;; Alternative 1 is needed to work around LRA limitation, see PR82524.
-(define_insn_and_split "*and<mode>_1_slp"
+(define_insn_and_split "*<code><mode>_1_slp"
   [(set (strict_low_part (match_operand:SWI12 0 "register_operand" "+<r>,&<r>"))
-       (and:SWI12 (match_operand:SWI12 1 "nonimmediate_operand" "%0,!<r>")
-                  (match_operand:SWI12 2 "general_operand" "<r>mn,<r>mn")))
+       (any_logic:SWI12 (match_operand:SWI12 1 "nonimmediate_operand" "%0,!<r>")
+                     (match_operand:SWI12 2 "general_operand" "<r>mn,<r>mn")))
    (clobber (reg:CC FLAGS_REG))]
   "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
   "@
-   and{<imodesuffix>}\t{%2, %0|%0, %2}
+   <logic>{<imodesuffix>}\t{%2, %0|%0, %2}
    #"
-  "&& reload_completed"
+  "&& reload_completed
+   && !(rtx_equal_p (operands[0], operands[1])
+       || rtx_equal_p (operands[0], operands[2]))"
   [(set (strict_low_part (match_dup 0)) (match_dup 1))
    (parallel
      [(set (strict_low_part (match_dup 0))
-          (and:SWI12 (match_dup 0) (match_dup 2)))
+          (any_logic:SWI12 (match_dup 0) (match_dup 2)))
       (clobber (reg:CC FLAGS_REG))])]
   ""
   [(set_attr "type" "alu")
    (set_attr "mode" "<MODE>")])
 
+;; Alternative 1 is needed to work around LRA limitation, see PR82524.
+(define_insn_and_split "*<code>qi_ext<mode>_1_slp"
+  [(set (strict_low_part (match_operand:QI 0 "register_operand" "+Q,&Q"))
+       (any_logic:QI
+         (subreg:QI
+           (match_operator:SWI248 3 "extract_operator"
+             [(match_operand 2 "int248_register_operand" "Q,Q")
+              (const_int 8)
+              (const_int 8)]) 0)
+         (match_operand:QI 1 "nonimmediate_operand" "0,!qm")))
+   (clobber (reg:CC FLAGS_REG))]
+  "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
+  "@
+   <logic>{b}\t{%h2, %0|%0, %h2}
+   #"
+  "&& reload_completed
+   && !rtx_equal_p (operands[0], operands[1])"
+  [(set (strict_low_part (match_dup 0)) (match_dup 1))
+   (parallel
+     [(set (strict_low_part (match_dup 0))
+          (any_logic:QI
+            (subreg:QI
+              (match_op_dup 3
+                [(match_dup 2) (const_int 8) (const_int 8)]) 0)
+            (match_dup 0)))
+      (clobber (reg:CC FLAGS_REG))])]
+  ""
+  [(set_attr "type" "alu")
+   (set_attr "mode" "QI")])
+
+(define_insn_and_split "*<code>qi_ext<mode>_2_slp"
+  [(set (strict_low_part (match_operand:QI 0 "register_operand" "+&Q"))
+       (any_logic:QI
+         (subreg:QI
+           (match_operator:SWI248 3 "extract_operator"
+             [(match_operand 1 "int248_register_operand" "Q")
+              (const_int 8)
+              (const_int 8)]) 0)
+         (subreg:QI
+           (match_operator:SWI248 4 "extract_operator"
+             [(match_operand 2 "int248_register_operand" "Q")
+              (const_int 8)
+              (const_int 8)]) 0)))
+   (clobber (reg:CC FLAGS_REG))]
+  "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
+  "#"
+  "&& reload_completed"
+  [(set (strict_low_part (match_dup 0))
+       (subreg:QI
+         (match_op_dup 4
+           [(match_dup 2) (const_int 8) (const_int 8)]) 0))
+   (parallel
+     [(set (strict_low_part (match_dup 0))
+          (any_logic:QI
+            (subreg:QI
+              (match_op_dup 3
+                [(match_dup 1) (const_int 8) (const_int 8)]) 0)
+            (match_dup 0)))
+      (clobber (reg:CC FLAGS_REG))])]
+  ""
+  [(set_attr "type" "alu")
+   (set_attr "mode" "QI")])
+
 (define_split
   [(set (match_operand:SWI248 0 "register_operand")
        (and:SWI248 (match_operand:SWI248 1 "nonimmediate_operand")
    (clobber (reg:CC FLAGS_REG))]
   "reload_completed
    && (!REG_P (operands[1])
-       || REGNO (operands[0]) != REGNO (operands[1]))"
+       || REGNO (operands[0]) != REGNO (operands[1]))
+   && (UINTVAL (operands[2]) == GET_MODE_MASK (SImode)
+       || UINTVAL (operands[2]) == GET_MODE_MASK (HImode)
+       || UINTVAL (operands[2]) == GET_MODE_MASK (QImode))"
   [(const_int 0)]
 {
   unsigned HOST_WIDE_INT ival = UINTVAL (operands[2]);
   [(set (reg FLAGS_REG)
        (compare
         (and:DI
-         (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
-         (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,m"))
+         (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,r,rm,r")
+         (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,m,Z,re,m"))
         (const_int 0)))
-   (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r")
+   (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r,r,r")
        (and:DI (match_dup 1) (match_dup 2)))]
   "TARGET_64BIT
    && ix86_match_ccmode
          && (!CONST_INT_P (operands[2])
              || val_signbit_known_set_p (SImode, INTVAL (operands[2]))))
         ? CCZmode : CCNOmode)
-   && ix86_binary_operator_ok (AND, DImode, operands)"
+   && ix86_binary_operator_ok (AND, DImode, operands, TARGET_APX_NDD)"
   "@
    and{l}\t{%k2, %k0|%k0, %k2}
    and{q}\t{%2, %0|%0, %2}
-   and{q}\t{%2, %0|%0, %2}"
+   and{q}\t{%2, %0|%0, %2}
+   and{l}\t{%k2, %k1, %k0|%k0, %k1, %k2}
+   and{q}\t{%2, %1, %0|%0, %1, %2}
+   and{q}\t{%2, %1, %0|%0, %1, %2}"
   [(set_attr "type" "alu")
-   (set_attr "mode" "SI,DI,DI")])
+   (set_attr "isa" "*,*,*,apx_ndd,apx_ndd,apx_ndd")
+   (set_attr "mode" "SI,DI,DI,SI,DI,DI")])
 
 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
 (define_insn "*andsi_2_zext"
   [(set (reg FLAGS_REG)
        (compare (and:SI
-                 (match_operand:SI 1 "nonimmediate_operand" "%0")
-                 (match_operand:SI 2 "x86_64_general_operand" "rBMe"))
+                 (match_operand:SI 1 "nonimmediate_operand" "%0,rm,r")
+                 (match_operand:SI 2 "x86_64_general_operand" "rBMe,re,BM"))
                 (const_int 0)))
-   (set (match_operand:DI 0 "register_operand" "=r")
+   (set (match_operand:DI 0 "register_operand" "=r,r,r")
        (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
-   && ix86_binary_operator_ok (AND, SImode, operands)"
-  "and{l}\t{%2, %k0|%k0, %2}"
+   && ix86_binary_operator_ok (AND, SImode, operands, TARGET_APX_NDD)"
+  "@
+  and{l}\t{%2, %k0|%k0, %2}
+  and{l}\t{%2, %1, %k0|%k0, %1, %2}
+  and{l}\t{%2, %1, %k0|%k0, %1, %2}"
   [(set_attr "type" "alu")
+   (set_attr "isa" "*,apx_ndd,apx_ndd")
    (set_attr "mode" "SI")])
 
 (define_insn "*andqi_2_maybe_si"
   [(set (reg FLAGS_REG)
        (compare (and:QI
-                 (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
-                 (match_operand:QI 2 "general_operand" "qn,m,n"))
+                 (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,rm,r")
+                 (match_operand:QI 2 "general_operand" "qn,m,n,rn,m"))
                 (const_int 0)))
-   (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
+   (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r,r,r")
        (and:QI (match_dup 1) (match_dup 2)))]
-  "ix86_binary_operator_ok (AND, QImode, operands)
+  "ix86_binary_operator_ok (AND, QImode, operands, TARGET_APX_NDD)
    && ix86_match_ccmode (insn,
                         CONST_INT_P (operands[2])
                         && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)"
         operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
       return "and{l}\t{%2, %k0|%k0, %2}";
     }
+  if (which_alternative > 2)
+    return "and{b}\t{%2, %1, %0|%0, %1, %2}";
   return "and{b}\t{%2, %0|%0, %2}";
 }
   [(set_attr "type" "alu")
+   (set_attr "isa" "*,*,*,apx_ndd,apx_ndd")
    (set (attr "mode")
-     (cond [(eq_attr "alternative" "2")
+     (cond [(eq_attr "alternative" "3,4")
+             (const_string "QI")
+           (eq_attr "alternative" "2")
              (const_string "SI")
            (and (match_test "optimize_insn_for_size_p ()")
                 (and (match_operand 0 "ext_QIreg_operand")
 (define_insn "*and<mode>_2"
   [(set (reg FLAGS_REG)
        (compare (and:SWI124
-                 (match_operand:SWI124 1 "nonimmediate_operand" "%0,0")
-                 (match_operand:SWI124 2 "<general_operand>" "<r><i>,<m>"))
+                 (match_operand:SWI124 1 "nonimmediate_operand" "%0,0,rm,r")
+                 (match_operand:SWI124 2 "<general_operand>" "<r><i>,<m>,r<i>,<m>"))
                 (const_int 0)))
-   (set (match_operand:SWI124 0 "nonimmediate_operand" "=<r>m,<r>")
+   (set (match_operand:SWI124 0 "nonimmediate_operand" "=<r>m,<r>,r,r")
        (and:SWI124 (match_dup 1) (match_dup 2)))]
   "ix86_match_ccmode (insn, CCNOmode)
-   && ix86_binary_operator_ok (AND, <MODE>mode, operands)"
-  "and{<imodesuffix>}\t{%2, %0|%0, %2}"
+   && ix86_binary_operator_ok (AND, <MODE>mode, operands, TARGET_APX_NDD)"
+  "@
+  and{<imodesuffix>}\t{%2, %0|%0, %2}
+  and{<imodesuffix>}\t{%2, %0|%0, %2}
+  and{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
+  and{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}"
   [(set_attr "type" "alu")
+   (set_attr "isa" "*,*,apx_ndd,apx_ndd")
    (set_attr "mode" "<MODE>")])
 
-(define_insn "*andqi_ext<mode>_0"
-  [(set (match_operand:QI 0 "nonimm_x64constmem_operand" "=QBc,m")
-       (and:QI
+(define_insn "*<code>qi_ext<mode>_0"
+  [(set (match_operand:QI 0 "nonimmediate_operand" "=QBn")
+       (any_logic:QI
          (subreg:QI
            (match_operator:SWI248 3 "extract_operator"
-             [(match_operand 2 "int248_register_operand" "Q,Q")
+             [(match_operand 2 "int248_register_operand" "Q")
               (const_int 8)
               (const_int 8)]) 0)
-         (match_operand:QI 1 "nonimm_x64constmem_operand" "0,0")))
+         (match_operand:QI 1 "nonimmediate_operand" "0")))
    (clobber (reg:CC FLAGS_REG))]
   ""
-  "and{b}\t{%h2, %0|%0, %h2}"
-  [(set_attr "isa" "*,nox64")
+  "<logic>{b}\t{%h2, %0|%0, %h2}"
+  [(set_attr "addr" "gpr8")
    (set_attr "type" "alu")
    (set_attr "mode" "QI")])
 
+(define_insn_and_split "*<code>qi_ext2<mode>_0"
+  [(set (match_operand:QI 0 "register_operand" "=&Q")
+       (any_logic:QI
+         (subreg:QI
+           (match_operator:SWI248 3 "extract_operator"
+             [(match_operand 1 "int248_register_operand" "Q")
+              (const_int 8)
+              (const_int 8)]) 0)
+         (subreg:QI
+           (match_operator:SWI248 4 "extract_operator"
+             [(match_operand 2 "int248_register_operand" "Q")
+              (const_int 8)
+              (const_int 8)]) 0)))
+   (clobber (reg:CC FLAGS_REG))]
+  ""
+  "#"
+  "&& reload_completed"
+  [(set (match_dup 0)
+       (subreg:QI
+         (match_op_dup 4
+           [(match_dup 2) (const_int 8) (const_int 8)]) 0))
+   (parallel
+     [(set (match_dup 0)
+          (any_logic:QI
+            (subreg:QI
+              (match_op_dup 3
+                [(match_dup 1) (const_int 8) (const_int 8)]) 0)
+          (match_dup 0)))
+      (clobber (reg:CC FLAGS_REG))])]
+  ""
+  [(set_attr "type" "alu")
+   (set_attr "mode" "QI")])
+
 (define_expand "andqi_ext_1"
   [(parallel
      [(set (zero_extract:HI (match_operand:HI 0 "register_operand")
               (match_operand:QI 2 "const_int_operand")) 0))
       (clobber (reg:CC FLAGS_REG))])])
 
-(define_insn "*andqi_ext<mode>_1"
+;; Alternative 1 is needed to work around LRA limitation, see PR82524.
+(define_insn_and_split "*<code>qi_ext<mode>_1"
   [(set (zero_extract:SWI248
-         (match_operand 0 "int248_register_operand" "+Q,Q")
+         (match_operand 0 "int248_register_operand" "+Q,&Q")
          (const_int 8)
          (const_int 8))
        (subreg:SWI248
-         (and:QI
+         (any_logic:QI
            (subreg:QI
              (match_operator:SWI248 3 "extract_operator"
-               [(match_operand 1 "int248_register_operand" "0,0")
+               [(match_operand 1 "int248_register_operand" "0,!Q")
                 (const_int 8)
                 (const_int 8)]) 0)
-           (match_operand:QI 2 "general_x64constmem_operand" "QnBc,m")) 0))
+           (match_operand:QI 2 "general_operand" "QnBn,QnBn")) 0))
    (clobber (reg:CC FLAGS_REG))]
-  "/* FIXME: without this LRA can't reload this pattern, see PR82524.  */
-   rtx_equal_p (operands[0], operands[1])"
-  "and{b}\t{%2, %h0|%h0, %2}"
-  [(set_attr "isa" "*,nox64")
+  ""
+  "@
+   <logic>{b}\t{%2, %h0|%h0, %2}
+   #"
+  "reload_completed
+   && !(rtx_equal_p (operands[0], operands[1]))"
+  [(set (zero_extract:SWI248
+         (match_dup 0) (const_int 8) (const_int 8))
+       (zero_extract:SWI248
+         (match_dup 1) (const_int 8) (const_int 8)))
+   (parallel
+     [(set (zero_extract:SWI248
+            (match_dup 0) (const_int 8) (const_int 8))
+          (subreg:SWI248
+            (any_logic:QI
+              (subreg:QI
+                (match_op_dup 3
+                  [(match_dup 0) (const_int 8) (const_int 8)]) 0)
+              (match_dup 2)) 0))
+      (clobber (reg:CC FLAGS_REG))])]
+  ""
+  [(set_attr "addr" "gpr8")
    (set_attr "type" "alu")
    (set_attr "mode" "QI")])
 
-;; Generated by peephole translating test to and.  This shows up
-;; often in fp comparisons.
-(define_insn "*andqi_ext<mode>_1_cc"
-  [(set (reg FLAGS_REG)
-       (compare
-         (and:QI
-           (subreg:QI
-             (match_operator:SWI248 3 "extract_operator"
-               [(match_operand 1 "int248_register_operand" "0,0")
-                (const_int 8)
-                (const_int 8)]) 0)
-           (match_operand:QI 2 "general_x64constmem_operand" "QnBc,m"))
-         (const_int 0)))
+;; Alternative 1 is needed to work around LRA limitation, see PR82524.
+(define_insn_and_split "*<code>qi_ext<mode>_1_cc"
+  [(set (match_operand 4 "flags_reg_operand")
+       (match_operator 5 "compare_operator"
+         [(any_logic:QI
+            (subreg:QI
+              (match_operator:SWI248 3 "extract_operator"
+                [(match_operand 1 "int248_register_operand" "0,!Q")
+                 (const_int 8)
+                 (const_int 8)]) 0)
+            (match_operand:QI 2 "general_operand" "QnBn,QnBn"))
+         (const_int 0)]))
    (set (zero_extract:SWI248
-         (match_operand 0 "int248_register_operand" "+Q,Q")
+         (match_operand 0 "int248_register_operand" "+Q,&Q")
          (const_int 8)
          (const_int 8))
        (subreg:SWI248
-         (and:QI
+         (any_logic:QI
            (subreg:QI
              (match_op_dup 3
-               [(match_dup 1)
-                (const_int 8)
-                (const_int 8)]) 0)
+               [(match_dup 0) (const_int 8) (const_int 8)]) 0)
            (match_dup 2)) 0))]
-  "ix86_match_ccmode (insn, CCNOmode)
-   /* FIXME: without this LRA can't reload this pattern, see PR82524.  */
-   && rtx_equal_p (operands[0], operands[1])"
-  "and{b}\t{%2, %h0|%h0, %2}"
-  [(set_attr "isa" "*,nox64")
+  "ix86_match_ccmode (insn, CCNOmode)"
+  "@
+   <logic>{b}\t{%2, %h0|%h0, %2}
+   #"
+  "&& reload_completed
+   && !(rtx_equal_p (operands[0], operands[1]))"
+  [(set (zero_extract:SWI248
+         (match_dup 0) (const_int 8) (const_int 8))
+       (zero_extract:SWI248
+         (match_dup 1) (const_int 8) (const_int 8)))
+   (parallel
+     [(set (match_dup 4)
+          (match_op_dup 5
+            [(any_logic:QI
+               (subreg:QI
+                 (match_op_dup 3
+                   [(match_dup 0) (const_int 8) (const_int 8)]) 0)
+               (match_dup 2))
+             (const_int 0)]))
+      (set (zero_extract:SWI248
+            (match_dup 0) (const_int 8) (const_int 8))
+          (subreg:SWI248
+            (any_logic:QI
+              (subreg:QI
+                (match_op_dup 3
+                  [(match_dup 1) (const_int 8) (const_int 8)]) 0)
+              (match_dup 2)) 0))])]
+  ""
+  [(set_attr "addr" "gpr8")
    (set_attr "type" "alu")
    (set_attr "mode" "QI")])
 
-(define_insn "*andqi_ext<mode>_2"
+;; Alternative 1 is needed to work around LRA limitation, see PR82524.
+(define_insn_and_split "*<code>qi_ext<mode>_2"
   [(set (zero_extract:SWI248
-         (match_operand 0 "int248_register_operand" "+Q")
+         (match_operand 0 "int248_register_operand" "+Q,&Q")
          (const_int 8)
          (const_int 8))
        (subreg:SWI248
-         (and:QI
+         (any_logic:QI
            (subreg:QI
              (match_operator:SWI248 3 "extract_operator"
-               [(match_operand 1 "int248_register_operand" "%0")
+               [(match_operand 1 "int248_register_operand" "%0,!Q")
                 (const_int 8)
                 (const_int 8)]) 0)
            (subreg:QI
              (match_operator:SWI248 4 "extract_operator"
-               [(match_operand 2 "int248_register_operand" "Q")
+               [(match_operand 2 "int248_register_operand" "Q,Q")
                 (const_int 8)
                 (const_int 8)]) 0)) 0))
    (clobber (reg:CC FLAGS_REG))]
-  "/* FIXME: without this LRA can't reload this pattern, see PR82524.  */
-   rtx_equal_p (operands[0], operands[1])
-   || rtx_equal_p (operands[0], operands[2])"
-  "and{b}\t{%h2, %h0|%h0, %h2}"
+  ""
+  "@
+   <logic>{b}\t{%h2, %h0|%h0, %h2}
+   #"
+  "reload_completed
+   && !(rtx_equal_p (operands[0], operands[1])
+       || rtx_equal_p (operands[0], operands[2]))"
+  [(set (zero_extract:SWI248
+         (match_dup 0) (const_int 8) (const_int 8))
+       (zero_extract:SWI248
+         (match_dup 1) (const_int 8) (const_int 8)))
+   (parallel
+     [(set (zero_extract:SWI248
+            (match_dup 0) (const_int 8) (const_int 8))
+          (subreg:SWI248
+            (any_logic:QI
+              (subreg:QI
+                (match_op_dup 3
+                  [(match_dup 0) (const_int 8) (const_int 8)]) 0)
+              (subreg:QI
+                (match_op_dup 4
+                  [(match_dup 2) (const_int 8) (const_int 8)]) 0)) 0))
+      (clobber (reg:CC FLAGS_REG))])]
+  ""
   [(set_attr "type" "alu")
    (set_attr "mode" "QI")])
 
-;; *andqi_ext<mode>_3 is defined via *<code>qi_ext<mode>_3 below.
+;; Alternative 1 is needed to work around LRA limitation, see PR82524.
+(define_insn_and_split "*<code>qi_ext<mode>_3"
+  [(set (zero_extract:SWI248
+         (match_operand 0 "int248_register_operand" "+Q,&Q")
+         (const_int 8)
+         (const_int 8))
+       (match_operator:SWI248 3 "extract_operator"
+         [(any_logic
+            (match_operand 1 "int248_register_operand" "%0,!Q")
+            (match_operand 2 "int248_register_operand" "Q,Q"))
+          (const_int 8)
+          (const_int 8)]))
+   (clobber (reg:CC FLAGS_REG))]
+  "GET_MODE (operands[1]) == GET_MODE (operands[2])"
+  "@
+   <logic>{b}\t{%h2, %h0|%h0, %h2}
+   #"
+  "&& reload_completed
+   && !(rtx_equal_p (operands[0], operands[1])
+       || rtx_equal_p (operands[0], operands[2]))"
+  [(set (zero_extract:SWI248
+         (match_dup 0) (const_int 8) (const_int 8))
+       (zero_extract:SWI248
+         (match_dup 1) (const_int 8) (const_int 8)))
+   (parallel
+     [(set (zero_extract:SWI248
+            (match_dup 0) (const_int 8) (const_int 8))
+          (match_op_dup 3
+            [(any_logic (match_dup 4) (match_dup 2))
+             (const_int 8) (const_int 8)]))
+      (clobber (reg:CC FLAGS_REG))])]
+  "operands[4] = gen_lowpart (GET_MODE (operands[1]), operands[0]);"
+  [(set_attr "type" "alu")
+   (set_attr "mode" "QI")])
 
 ;; Convert wide AND instructions with immediate operand to shorter QImode
 ;; equivalents when possible.
 ;; Don't do the splitting with memory operands, since it introduces risk
 ;; of memory mismatch stalls.  We may want to do the splitting for optimizing
 ;; for size, but that can (should?) be handled by generic code instead.
+;; Don't do the splitting for APX NDD as NDD does not support *h registers.
 (define_split
   [(set (match_operand:SWI248 0 "QIreg_operand")
        (and:SWI248 (match_operand:SWI248 1 "register_operand")
    (clobber (reg:CC FLAGS_REG))]
    "reload_completed
     && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
-    && !(~INTVAL (operands[2]) & ~(255 << 8))"
+    && !(~INTVAL (operands[2]) & ~(255 << 8))
+    && !(TARGET_APX_NDD && REGNO (operands[0]) != REGNO (operands[1]))"
   [(parallel
      [(set (zero_extract:HI (match_dup 0)
                            (const_int 8)
    "reload_completed
     && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
     && !(~INTVAL (operands[2]) & ~255)
-    && !(INTVAL (operands[2]) & 128)"
+    && !(INTVAL (operands[2]) & 128)
+    && !(TARGET_APX_NDD
+        && !rtx_equal_p (operands[0], operands[1]))"
   [(parallel [(set (strict_low_part (match_dup 0))
                   (and:QI (match_dup 1)
                           (match_dup 2)))
       && !x86_64_hilo_general_operand (operands[2], <MODE>mode))
     operands[2] = force_reg (<MODE>mode, operands[2]);
 
-  ix86_expand_binary_operator (<CODE>, <MODE>mode, operands);
+  ix86_expand_binary_operator (<CODE>, <MODE>mode, operands, TARGET_APX_NDD);
   DONE;
 })
 
 (define_insn_and_split "*<code><dwi>3_doubleword"
-  [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro,r")
+  [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro,r,&r,&r")
        (any_or:<DWI>
-        (match_operand:<DWI> 1 "nonimmediate_operand" "%0,0")
-        (match_operand:<DWI> 2 "x86_64_hilo_general_operand" "r<di>,o")))
+        (match_operand:<DWI> 1 "nonimmediate_operand" "%0,0,ro,r")
+        (match_operand:<DWI> 2 "x86_64_hilo_general_operand" "r<di>,o,r<di>,o")))
    (clobber (reg:CC FLAGS_REG))]
-  "ix86_binary_operator_ok (<CODE>, <DWI>mode, operands)"
+  "ix86_binary_operator_ok (<CODE>, <DWI>mode, operands, TARGET_APX_NDD)"
   "#"
   "&& reload_completed"
   [(const_int:DWIH 0)]
   split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);
 
   if (operands[2] == const0_rtx)
-    emit_insn_deleted_note_p = true;
+    {
+      if (!rtx_equal_p (operands[0], operands[1]))
+       emit_move_insn (operands[0], operands[1]);
+      else
+       emit_insn_deleted_note_p = true;
+    }
   else if (operands[2] == constm1_rtx)
     {
       if (<CODE> == IOR)
        emit_move_insn (operands[0], constm1_rtx);
       else
-       ix86_expand_unary_operator (NOT, <MODE>mode, &operands[0]);
+       ix86_expand_unary_operator (NOT, <MODE>mode, &operands[0],
+                                   TARGET_APX_NDD);
     }
   else
-    ix86_expand_binary_operator (<CODE>, <MODE>mode, &operands[0]);
+    ix86_expand_binary_operator (<CODE>, <MODE>mode, &operands[0],
+                                TARGET_APX_NDD);
 
   if (operands[5] == const0_rtx)
     {
-      if (emit_insn_deleted_note_p)
+      if (!rtx_equal_p (operands[3], operands[4]))
+       emit_move_insn (operands[3], operands[4]);
+      else if (emit_insn_deleted_note_p)
        emit_note (NOTE_INSN_DELETED);
     }
   else if (operands[5] == constm1_rtx)
       if (<CODE> == IOR)
        emit_move_insn (operands[3], constm1_rtx);
       else
-       ix86_expand_unary_operator (NOT, <MODE>mode, &operands[3]);
+       ix86_expand_unary_operator (NOT, <MODE>mode, &operands[3],
+                                   TARGET_APX_NDD);
     }
   else
-    ix86_expand_binary_operator (<CODE>, <MODE>mode, &operands[3]);
+    ix86_expand_binary_operator (<CODE>, <MODE>mode, &operands[3],
+                                TARGET_APX_NDD);
 
   DONE;
-})
+}
+[(set_attr "isa" "*,*,apx_ndd,apx_ndd")])
 
 (define_insn "*<code><mode>_1"
-  [(set (match_operand:SWI248 0 "nonimmediate_operand" "=rm,r,?k")
+  [(set (match_operand:SWI248 0 "nonimmediate_operand" "=rm,r,r,r,?k")
        (any_or:SWI248
-        (match_operand:SWI248 1 "nonimmediate_operand" "%0,0,k")
-        (match_operand:SWI248 2 "<general_operand>" "r<i>,<m>,k")))
+        (match_operand:SWI248 1 "nonimmediate_operand" "%0,0,rm,r,k")
+        (match_operand:SWI248 2 "<general_operand>" "r<i>,<m>,r<i>,<m>,k")))
    (clobber (reg:CC FLAGS_REG))]
-  "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
+  "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands, TARGET_APX_NDD)"
   "@
    <logic>{<imodesuffix>}\t{%2, %0|%0, %2}
    <logic>{<imodesuffix>}\t{%2, %0|%0, %2}
+   <logic>{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
+   <logic>{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
    #"
-  [(set (attr "isa")
-       (cond [(eq_attr "alternative" "2")
-                (if_then_else (eq_attr "mode" "SI,DI")
-                  (const_string "avx512bw")
-                  (const_string "avx512f"))
-             ]
-             (const_string "*")))
-   (set_attr "type" "alu, alu, msklog")
+  [(set_attr "isa" "*,*,apx_ndd,apx_ndd,<kmov_isa>")
+   (set_attr "type" "alu, alu, alu, alu, msklog")
    (set_attr "mode" "<MODE>")])
 
 (define_insn_and_split "*notxor<mode>_1"
-  [(set (match_operand:SWI248 0 "nonimmediate_operand" "=rm,r,?k")
+  [(set (match_operand:SWI248 0 "nonimmediate_operand" "=rm,r,r,r,?k")
        (not:SWI248
          (xor:SWI248
-           (match_operand:SWI248 1 "nonimmediate_operand" "%0,0,k")
-           (match_operand:SWI248 2 "<general_operand>" "r<i>,<m>,k"))))
+           (match_operand:SWI248 1 "nonimmediate_operand" "%0,0,rm,r,k")
+           (match_operand:SWI248 2 "<general_operand>" "r<i>,<m>,r<i>,<m>,k"))))
    (clobber (reg:CC FLAGS_REG))]
-  "ix86_binary_operator_ok (XOR, <MODE>mode, operands)"
+  "ix86_binary_operator_ok (XOR, <MODE>mode, operands, TARGET_APX_NDD)"
   "#"
   "&& reload_completed"
   [(parallel
       DONE;
     }
 }
-  [(set (attr "isa")
-       (cond [(eq_attr "alternative" "2")
-                (if_then_else (eq_attr "mode" "SI,DI")
-                  (const_string "avx512bw")
-                  (const_string "avx512f"))
-             ]
-             (const_string "*")))
-   (set_attr "type" "alu, alu, msklog")
+  [(set_attr "isa" "*,*,apx_ndd,apx_ndd,<kmov_isa>")
+   (set_attr "type" "alu, alu, alu, alu, msklog")
    (set_attr "mode" "<MODE>")])
 
 (define_insn_and_split "*iordi_1_bts"
 
 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
 (define_insn "*<code>si_1_zext"
-  [(set (match_operand:DI 0 "register_operand" "=r")
+  [(set (match_operand:DI 0 "register_operand" "=r,r,r")
        (zero_extend:DI
-        (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
-                   (match_operand:SI 2 "x86_64_general_operand" "rBMe"))))
+        (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0,rm,r")
+                   (match_operand:SI 2 "x86_64_general_operand" "rBMe,re,BM"))))
    (clobber (reg:CC FLAGS_REG))]
-  "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
-  "<logic>{l}\t{%2, %k0|%k0, %2}"
+  "TARGET_64BIT
+   && ix86_binary_operator_ok (<CODE>, SImode, operands, TARGET_APX_NDD)"
+  "@
+  <logic>{l}\t{%2, %k0|%k0, %2}
+  <logic>{l}\t{%2, %1, %k0|%k0, %1, %2}
+  <logic>{l}\t{%2, %1, %k0|%k0, %1, %2}"
   [(set_attr "type" "alu")
+   (set_attr "isa" "*,apx_ndd,apx_ndd")
    (set_attr "mode" "SI")])
 
 (define_insn "*<code>si_1_zext_imm"
-  [(set (match_operand:DI 0 "register_operand" "=r")
+  [(set (match_operand:DI 0 "register_operand" "=r,r")
        (any_or:DI
-        (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
-        (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
+        (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0,rm"))
+        (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z,Z")))
    (clobber (reg:CC FLAGS_REG))]
-  "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
-  "<logic>{l}\t{%2, %k0|%k0, %2}"
+  "TARGET_64BIT
+   && ix86_binary_operator_ok (<CODE>, SImode, operands, TARGET_APX_NDD)"
+  "@
+  <logic>{l}\t{%2, %k0|%k0, %2}
+  <logic>{l}\t{%2, %1, %k0|%k0, %1, %2}"
   [(set_attr "type" "alu")
+   (set_attr "isa" "*,apx_ndd")
    (set_attr "mode" "SI")])
 
 (define_insn "*<code>qi_1"
-  [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r,?k")
-       (any_or:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,k")
-                  (match_operand:QI 2 "general_operand" "qn,m,rn,k")))
+  [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r,r,r,?k")
+       (any_or:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,rm,r,k")
+                  (match_operand:QI 2 "general_operand" "qn,m,rn,rn,m,k")))
    (clobber (reg:CC FLAGS_REG))]
-  "ix86_binary_operator_ok (<CODE>, QImode, operands)"
+  "ix86_binary_operator_ok (<CODE>, QImode, operands, TARGET_APX_NDD)"
   "@
    <logic>{b}\t{%2, %0|%0, %2}
    <logic>{b}\t{%2, %0|%0, %2}
    <logic>{l}\t{%k2, %k0|%k0, %k2}
+   <logic>{b}\t{%2, %1, %0|%0, %1, %2}
+   <logic>{b}\t{%2, %1, %0|%0, %1, %2}
    #"
-  [(set_attr "isa" "*,*,*,avx512f")
-   (set_attr "type" "alu,alu,alu,msklog")
+  [(set_attr "isa" "*,*,*,apx_ndd,apx_ndd,avx512f")
+   (set_attr "type" "alu,alu,alu,alu,alu,msklog")
    (set (attr "mode")
        (cond [(eq_attr "alternative" "2")
                 (const_string "SI")
-               (and (eq_attr "alternative" "3")
+               (and (eq_attr "alternative" "5")
                     (match_test "!TARGET_AVX512DQ"))
                 (const_string "HI")
               ]
           (symbol_ref "true")))])
 
 (define_insn_and_split "*notxorqi_1"
-  [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r,?k")
+  [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r,r,r,?k")
        (not:QI
-         (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,k")
-                 (match_operand:QI 2 "general_operand" "qn,m,rn,k"))))
+         (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,rm,r,k")
+                 (match_operand:QI 2 "general_operand" "qn,m,rn,rn,m,k"))))
    (clobber (reg:CC FLAGS_REG))]
-  "ix86_binary_operator_ok (XOR, QImode, operands)"
+  "ix86_binary_operator_ok (XOR, QImode, operands, TARGET_APX_NDD)"
   "#"
   "&& reload_completed"
   [(parallel
       DONE;
     }
 }
-  [(set_attr "isa" "*,*,*,avx512f")
-   (set_attr "type" "alu,alu,alu,msklog")
+  [(set_attr "isa" "*,*,*,apx_ndd,apx_ndd,avx512f")
+   (set_attr "type" "alu,alu,alu,alu,alu,msklog")
    (set (attr "mode")
        (cond [(eq_attr "alternative" "2")
                 (const_string "SI")
-               (and (eq_attr "alternative" "3")
+               (and (eq_attr "alternative" "5")
                     (match_test "!TARGET_AVX512DQ"))
                 (const_string "HI")
               ]
              (symbol_ref "!TARGET_PARTIAL_REG_STALL")]
           (symbol_ref "true")))])
 
-;; Alternative 1 is needed to work around LRA limitation, see PR82524.
-(define_insn_and_split "*<code><mode>_1_slp"
-  [(set (strict_low_part (match_operand:SWI12 0 "register_operand" "+<r>,&<r>"))
-       (any_or:SWI12 (match_operand:SWI12 1 "nonimmediate_operand" "%0,!<r>")
-                     (match_operand:SWI12 2 "general_operand" "<r>mn,<r>mn")))
-   (clobber (reg:CC FLAGS_REG))]
-  "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
-  "@
-   <logic>{<imodesuffix>}\t{%2, %0|%0, %2}
-   #"
-  "&& reload_completed"
-  [(set (strict_low_part (match_dup 0)) (match_dup 1))
-   (parallel
-     [(set (strict_low_part (match_dup 0))
-          (any_or:SWI12 (match_dup 0) (match_dup 2)))
-      (clobber (reg:CC FLAGS_REG))])]
-  ""
-  [(set_attr "type" "alu")
-   (set_attr "mode" "<MODE>")])
-
 ;; convert (sign_extend:WIDE (any_logic:NARROW (memory, immediate)))
 ;; to (any_logic:WIDE (sign_extend (memory)), (sign_extend (immediate))).
 ;; This eliminates sign extension after logic operation.
 (define_insn "*<code><mode>_2"
   [(set (reg FLAGS_REG)
        (compare (any_or:SWI
-                 (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
-                 (match_operand:SWI 2 "<general_operand>" "<r><i>,<m>"))
+                 (match_operand:SWI 1 "nonimmediate_operand" "%0,0,rm,r")
+                 (match_operand:SWI 2 "<general_operand>" "<r><i>,<m>,r<i>,<m>"))
                 (const_int 0)))
-   (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
+   (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>,r,r")
        (any_or:SWI (match_dup 1) (match_dup 2)))]
   "ix86_match_ccmode (insn, CCNOmode)
-   && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
-  "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
+   && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands, TARGET_APX_NDD)"
+  "@
+  <logic>{<imodesuffix>}\t{%2, %0|%0, %2}
+  <logic>{<imodesuffix>}\t{%2, %0|%0, %2}
+  <logic>{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
+  <logic>{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}"
   [(set_attr "type" "alu")
+   (set_attr "isa" "*,*,apx_ndd,apx_ndd")
    (set_attr "mode" "<MODE>")])
 
 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
 ;; ??? Special case for immediate operand is missing - it is tricky.
 (define_insn "*<code>si_2_zext"
   [(set (reg FLAGS_REG)
-       (compare (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
-                           (match_operand:SI 2 "x86_64_general_operand" "rBMe"))
+       (compare (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0,rm,r")
+                           (match_operand:SI 2 "x86_64_general_operand" "rBMe,re,BM"))
                 (const_int 0)))
-   (set (match_operand:DI 0 "register_operand" "=r")
+   (set (match_operand:DI 0 "register_operand" "=r,r,r")
        (zero_extend:DI (any_or:SI (match_dup 1) (match_dup 2))))]
   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
-   && ix86_binary_operator_ok (<CODE>, SImode, operands)"
-  "<logic>{l}\t{%2, %k0|%k0, %2}"
+   && ix86_binary_operator_ok (<CODE>, SImode, operands, TARGET_APX_NDD)"
+  "@
+  <logic>{l}\t{%2, %k0|%k0, %2}
+  <logic>{l}\t{%2, %1, %k0|%k0, %1, %2}
+  <logic>{l}\t{%2, %1, %k0|%k0, %1, %2}"
   [(set_attr "type" "alu")
+   (set_attr "isa" "*,apx_ndd,apx_ndd")
    (set_attr "mode" "SI")])
 
 (define_insn "*<code>si_2_zext_imm"
   [(set (reg FLAGS_REG)
        (compare (any_or:SI
-                 (match_operand:SI 1 "nonimmediate_operand" "%0")
-                 (match_operand:SI 2 "x86_64_zext_immediate_operand" "Z"))
+                 (match_operand:SI 1 "nonimmediate_operand" "%0,rm")
+                 (match_operand:SI 2 "x86_64_zext_immediate_operand" "Z,Z"))
                 (const_int 0)))
-   (set (match_operand:DI 0 "register_operand" "=r")
+   (set (match_operand:DI 0 "register_operand" "=r,r")
        (any_or:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
-   && ix86_binary_operator_ok (<CODE>, SImode, operands)"
-  "<logic>{l}\t{%2, %k0|%k0, %2}"
+   && ix86_binary_operator_ok (<CODE>, SImode, operands, TARGET_APX_NDD)"
+  "@
+  <logic>{l}\t{%2, %k0|%k0, %2}
+  <logic>{l}\t{%2, %1, %k0|%k0, %1, %2}"
   [(set_attr "type" "alu")
+   (set_attr "isa" "*,apx_ndd")
    (set_attr "mode" "SI")])
 
 (define_insn "*<code><mode>_3"
   [(set_attr "type" "alu")
    (set_attr "mode" "<MODE>")])
 
-(define_insn "*<code>qi_ext<mode>_0"
-  [(set (match_operand:QI 0 "nonimm_x64constmem_operand" "=QBc,m")
-       (any_or:QI
-         (subreg:QI
-           (match_operator:SWI248 3 "extract_operator"
-             [(match_operand 2 "int248_register_operand" "Q,Q")
-              (const_int 8)
-              (const_int 8)]) 0)
-         (match_operand:QI 1 "nonimm_x64constmem_operand" "0,0")))
-   (clobber (reg:CC FLAGS_REG))]
-  ""
-  "<logic>{b}\t{%h2, %0|%0, %h2}"
-  [(set_attr "isa" "*,nox64")
-   (set_attr "type" "alu")
-   (set_attr "mode" "QI")])
-
-(define_insn "*<code>qi_ext<mode>_1"
-  [(set (zero_extract:SWI248
-         (match_operand 0 "int248_register_operand" "+Q,Q")
-         (const_int 8)
-         (const_int 8))
-       (subreg:SWI248
-         (any_or:QI
-           (subreg:QI
-             (match_operator:SWI248 3 "extract_operator"
-               [(match_operand 1 "int248_register_operand" "0,0")
-                (const_int 8)
-                (const_int 8)]) 0)
-           (match_operand:QI 2 "general_x64constmem_operand" "QnBc,m")) 0))
-   (clobber (reg:CC FLAGS_REG))]
-  "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
-   /* FIXME: without this LRA can't reload this pattern, see PR82524.  */
-   && rtx_equal_p (operands[0], operands[1])"
-  "<logic>{b}\t{%2, %h0|%h0, %2}"
-  [(set_attr "isa" "*,nox64")
-   (set_attr "type" "alu")
-   (set_attr "mode" "QI")])
-
-(define_insn "*<code>qi_ext<mode>_2"
-  [(set (zero_extract:SWI248
-         (match_operand 0 "int248_register_operand" "+Q")
-         (const_int 8)
-         (const_int 8))
-       (subreg:SWI248
-         (any_or:QI
-           (subreg:QI
-             (match_operator:SWI248 3 "extract_operator"
-               [(match_operand 1 "int248_register_operand" "%0")
-                (const_int 8)
-                (const_int 8)]) 0)
-           (subreg:QI
-             (match_operator:SWI248 4 "extract_operator"
-               [(match_operand 2 "int248_register_operand" "Q")
-                (const_int 8)
-                (const_int 8)]) 0)) 0))
-   (clobber (reg:CC FLAGS_REG))]
-  "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
-   /* FIXME: without this LRA can't reload this pattern, see PR82524.  */
-   && (rtx_equal_p (operands[0], operands[1])
-       || rtx_equal_p (operands[0], operands[2]))"
-  "<logic>{b}\t{%h2, %h0|%h0, %h2}"
-  [(set_attr "type" "alu")
-   (set_attr "mode" "QI")])
-
-(define_insn "*<code>qi_ext<mode>_3"
-  [(set (zero_extract:SWI248
-         (match_operand 0 "int248_register_operand" "+Q")
-         (const_int 8)
-         (const_int 8))
-       (zero_extract:SWI248
-         (any_logic:SWI248
-           (match_operand 1 "int248_register_operand" "%0")
-           (match_operand 2 "int248_register_operand" "Q"))
-         (const_int 8)
-         (const_int 8)))
-   (clobber (reg:CC FLAGS_REG))]
-  "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
-   /* FIXME: without this LRA can't reload this pattern, see PR82524.  */
-   && (rtx_equal_p (operands[0], operands[1])
-       || rtx_equal_p (operands[0], operands[2]))"
-  "<logic>{b}\t{%h2, %h0|%h0, %h2}"
-  [(set_attr "type" "alu")
-   (set_attr "mode" "QI")])
-
 ;; Convert wide OR instructions with immediate operand to shorter QImode
 ;; equivalents when possible.
 ;; Don't do the splitting with memory operands, since it introduces risk
 ;; of memory mismatch stalls.  We may want to do the splitting for optimizing
 ;; for size, but that can (should?) be handled by generic code instead.
+;; Don't do the splitting for APX NDD as NDD does not support *h registers.
 (define_split
   [(set (match_operand:SWI248 0 "QIreg_operand")
        (any_or:SWI248 (match_operand:SWI248 1 "register_operand")
    (clobber (reg:CC FLAGS_REG))]
    "reload_completed
     && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
-    && !(INTVAL (operands[2]) & ~(255 << 8))"
+    && !(INTVAL (operands[2]) & ~(255 << 8))
+    && !(TARGET_APX_NDD && REGNO (operands[0]) != REGNO (operands[1]))"
   [(parallel
      [(set (zero_extract:HI (match_dup 0)
                            (const_int 8)
    "reload_completed
     && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
     && !(INTVAL (operands[2]) & ~255)
-    && (INTVAL (operands[2]) & 128)"
+    && (INTVAL (operands[2]) & 128)
+    && !(TARGET_APX_NDD
+        && !rtx_equal_p (operands[0], operands[1]))"
   [(parallel [(set (strict_low_part (match_dup 0))
                   (any_or:QI (match_dup 1)
                              (match_dup 2)))
                                  (const_int 8)) 0)
             (match_dup 2)) 0))])])
 
-(define_insn "*xorqi_ext<mode>_1_cc"
-  [(set (reg FLAGS_REG)
-       (compare
-         (xor:QI
-           (subreg:QI
-             (match_operator:SWI248 3 "extract_operator"
-               [(match_operand 1 "int248_register_operand" "0,0")
-                (const_int 8)
-                (const_int 8)]) 0)
-           (match_operand:QI 2 "general_x64constmem_operand" "QnBc,m"))
-         (const_int 0)))
-   (set (zero_extract:SWI248
-         (match_operand 0 "int248_register_operand" "+Q,Q")
-         (const_int 8)
-         (const_int 8))
-       (subreg:SWI248
-         (xor:QI
-           (subreg:QI
-             (match_op_dup 3
-               [(match_dup 1)
-                (const_int 8)
-                (const_int 8)]) 0)
-         (match_dup 2)) 0))]
-  "ix86_match_ccmode (insn, CCNOmode)
-   /* FIXME: without this LRA can't reload this pattern, see PR82524.  */
-   && rtx_equal_p (operands[0], operands[1])"
-  "xor{b}\t{%2, %h0|%h0, %2}"
-  [(set_attr "isa" "*,nox64")
-   (set_attr "type" "alu")
-   (set_attr "mode" "QI")])
-
 ;; Peephole2 rega = 0; rega op= regb into rega = regb.
 (define_peephole2
   [(parallel [(set (match_operand:SWI 0 "general_reg_operand")
 })
 
 (define_insn_and_split "*concat<mode><dwi>3_3"
-  [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro,r,r,&r")
+  [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro,r,r,&r,x")
        (any_or_plus:<DWI>
          (ashift:<DWI>
            (zero_extend:<DWI>
-             (match_operand:DWIH 1 "nonimmediate_operand" "r,m,r,m"))
+             (match_operand:DWIH 1 "nonimmediate_operand" "r,m,r,m,x"))
            (match_operand:QI 2 "const_int_operand"))
          (zero_extend:<DWI>
-           (match_operand:DWIH 3 "nonimmediate_operand" "r,r,m,m"))))]
+           (match_operand:DWIH 3 "nonimmediate_operand" "r,r,m,m,0"))))]
   "INTVAL (operands[2]) == <MODE_SIZE> * BITS_PER_UNIT"
   "#"
   "&& reload_completed"
   [(const_int 0)]
 {
-  split_double_concat (<DWI>mode, operands[0], operands[3], operands[1]);
+  if (SSE_REG_P (operands[0]))
+    {
+      rtx tmp = gen_rtx_REG (V2DImode, REGNO (operands[0]));
+      emit_insn (gen_vec_concatv2di (tmp, operands[3], operands[1]));
+    }
+  else
+    split_double_concat (<DWI>mode, operands[0], operands[3], operands[1]);
   DONE;
-})
+}
+  [(set_attr "isa" "*,*,*,x64,x64")])
 
 (define_insn_and_split "*concat<mode><dwi>3_4"
   [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro,r,r,&r")
 {
   split_double_concat (<DWI>mode, operands[0], operands[1], operands[2]);
   DONE;
-})
+}
+  [(set_attr "isa" "*,*,*,x64")])
 
 (define_insn_and_split "*concat<half><mode>3_5"
   [(set (match_operand:DWI 0 "nonimmediate_operand" "=r,o,o")
   [(set (match_operand:SDWIM 0 "nonimmediate_operand")
        (neg:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand")))]
   ""
-  "ix86_expand_unary_operator (NEG, <MODE>mode, operands); DONE;")
+{
+  ix86_expand_unary_operator (NEG, <MODE>mode, operands, TARGET_APX_NDD);
+  DONE;
+})
 
 (define_insn_and_split "*neg<dwi>2_doubleword"
-  [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro")
-       (neg:<DWI> (match_operand:<DWI> 1 "nonimmediate_operand" "0")))
+  [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro,&r")
+       (neg:<DWI> (match_operand:<DWI> 1 "nonimmediate_operand" "0,ro")))
    (clobber (reg:CC FLAGS_REG))]
-  "ix86_unary_operator_ok (NEG, <DWI>mode, operands)"
+  "ix86_unary_operator_ok (NEG, <DWI>mode, operands, TARGET_APX_NDD)"
   "#"
   "&& reload_completed"
   [(parallel
     [(set (match_dup 2)
          (neg:DWIH (match_dup 2)))
      (clobber (reg:CC FLAGS_REG))])]
-  "split_double_mode (<DWI>mode, &operands[0], 2, &operands[0], &operands[2]);")
+  "split_double_mode (<DWI>mode, &operands[0], 2, &operands[0], &operands[2]);"
+  [(set_attr "isa" "*,apx_ndd")])
 
 ;; Convert:
 ;;   mov %esi, %edx
      (clobber (reg:CC FLAGS_REG))])])
 
 (define_insn "*neg<mode>_1"
-  [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
-       (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")))
+  [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,r")
+       (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0,rm")))
    (clobber (reg:CC FLAGS_REG))]
-  "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
-  "neg{<imodesuffix>}\t%0"
+  "ix86_unary_operator_ok (NEG, <MODE>mode, operands, TARGET_APX_NDD)"
+  "@
+  neg{<imodesuffix>}\t%0
+  neg{<imodesuffix>}\t{%1, %0|%0, %1}"
   [(set_attr "type" "negnot")
+   (set_attr "isa" "*,apx_ndd")
    (set_attr "mode" "<MODE>")])
 
 (define_insn "*negsi_1_zext"
-  [(set (match_operand:DI 0 "register_operand" "=r")
+  [(set (match_operand:DI 0 "register_operand" "=r,r")
        (zero_extend:DI
-         (neg:SI (match_operand:SI 1 "register_operand" "0"))))
+         (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0,rm"))))
    (clobber (reg:CC FLAGS_REG))]
-  "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
-  "neg{l}\t%k0"
+  "TARGET_64BIT
+   && ix86_unary_operator_ok (NEG, SImode, operands, TARGET_APX_NDD)"
+  "@
+  neg{l}\t%k0
+  neg{l}\t{%k1, %k0|%k0, %k1}"
   [(set_attr "type" "negnot")
+   (set_attr "isa" "*,apx_ndd")
    (set_attr "mode" "SI")])
 
 ;; Alternative 1 is needed to work around LRA limitation, see PR82524.
   "@
    neg{<imodesuffix>}\t%0
    #"
-  "&& reload_completed"
+  "&& reload_completed
+   && !(rtx_equal_p (operands[0], operands[1]))"
   [(set (strict_low_part (match_dup 0)) (match_dup 1))
    (parallel
      [(set (strict_low_part (match_dup 0))
 (define_insn "*neg<mode>_2"
   [(set (reg FLAGS_REG)
        (compare
-         (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
+         (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0,rm"))
          (const_int 0)))
-   (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
+   (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,r")
        (neg:SWI (match_dup 1)))]
   "ix86_match_ccmode (insn, CCGOCmode)
-   && ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
-  "neg{<imodesuffix>}\t%0"
+   && ix86_unary_operator_ok (NEG, <MODE>mode, operands, TARGET_APX_NDD)"
+  "@
+   neg{<imodesuffix>}\t%0
+   neg{<imodesuffix>}\t{%1, %0|%0, %1}"
   [(set_attr "type" "negnot")
+   (set_attr "isa" "*,apx_ndd")
    (set_attr "mode" "<MODE>")])
 
 (define_insn "*negsi_2_zext"
   [(set (reg FLAGS_REG)
        (compare
-         (neg:SI (match_operand:SI 1 "register_operand" "0"))
+         (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0,rm"))
          (const_int 0)))
-   (set (match_operand:DI 0 "register_operand" "=r")
+   (set (match_operand:DI 0 "register_operand" "=r,r")
        (zero_extend:DI
          (neg:SI (match_dup 1))))]
   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
-   && ix86_unary_operator_ok (NEG, SImode, operands)"
-  "neg{l}\t%k0"
+   && ix86_unary_operator_ok (NEG, SImode, operands, TARGET_APX_NDD)"
+  "@
+   neg{l}\t%k0
+   neg{l}\t{%1, %k0|%k0, %1}"
   [(set_attr "type" "negnot")
+   (set_attr "isa" "*,apx_ndd")
    (set_attr "mode" "SI")])
 
 (define_insn "*neg<mode>_ccc_1"
   [(set (reg:CCC FLAGS_REG)
        (unspec:CCC
-         [(match_operand:SWI 1 "nonimmediate_operand" "0")
+         [(match_operand:SWI 1 "nonimmediate_operand" "0,rm")
           (const_int 0)] UNSPEC_CC_NE))
-   (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
+   (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,r")
        (neg:SWI (match_dup 1)))]
   ""
-  "neg{<imodesuffix>}\t%0"
+  "@
+  neg{<imodesuffix>}\t%0
+  neg{<imodesuffix>}\t{%1, %0|%0, %1}"
   [(set_attr "type" "negnot")
+   (set_attr "isa" "*,apx_ndd")
    (set_attr "mode" "<MODE>")])
 
 (define_insn "*neg<mode>_ccc_2"
   [(set (reg:CCC FLAGS_REG)
        (unspec:CCC
-         [(match_operand:SWI 1 "nonimmediate_operand" "0")
+         [(match_operand:SWI 1 "nonimmediate_operand" "0,rm")
           (const_int 0)] UNSPEC_CC_NE))
-   (clobber (match_scratch:SWI 0 "=<r>"))]
+   (clobber (match_scratch:SWI 0 "=<r>,r"))]
   ""
-  "neg{<imodesuffix>}\t%0"
+  "@
+  neg{<imodesuffix>}\t%0
+  neg{<imodesuffix>}\t{%1, %0|%0, %1}"
   [(set_attr "type" "negnot")
+   (set_attr "isa" "*,apx_ndd")
    (set_attr "mode" "<MODE>")])
 
 (define_expand "x86_neg<mode>_ccc"
      (set (match_operand:SWI48 0 "register_operand")
          (neg:SWI48 (match_dup 1)))])])
 
-(define_insn "*negqi_ext<mode>_2"
+;; Alternative 1 is needed to work around LRA limitation, see PR82524.
+(define_insn_and_split "*negqi_ext<mode>_1"
   [(set (zero_extract:SWI248
-         (match_operand 0 "int248_register_operand" "+Q")
+         (match_operand 0 "int248_register_operand" "+Q,&Q")
          (const_int 8)
          (const_int 8))
        (subreg:SWI248
          (neg:QI
            (subreg:QI
              (match_operator:SWI248 2 "extract_operator"
-               [(match_operand 1 "int248_register_operand" "0")
+               [(match_operand 1 "int248_register_operand" "0,!Q")
                 (const_int 8)
                 (const_int 8)]) 0)) 0))
    (clobber (reg:CC FLAGS_REG))]
-  "/* FIXME: without this LRA can't reload this pattern, see PR82524.  */
-   rtx_equal_p (operands[0], operands[1])"
-  "neg{b}\t%h0"
+  ""
+  "@
+   neg{b}\t%h0
+   #"
+  "reload_completed
+   && !(rtx_equal_p (operands[0], operands[1]))"
+  [(set (zero_extract:SWI248
+         (match_dup 0) (const_int 8) (const_int 8))
+       (zero_extract:SWI248
+         (match_dup 1) (const_int 8) (const_int 8)))
+   (parallel
+     [(set (zero_extract:SWI248
+            (match_dup 0) (const_int 8) (const_int 8))
+          (subreg:SWI248
+            (neg:QI
+              (subreg:QI
+                (match_op_dup 2
+                  [(match_dup 0) (const_int 8) (const_int 8)]) 0)) 0))
+      (clobber (reg:CC FLAGS_REG))])]
+  ""
   [(set_attr "type" "negnot")
    (set_attr "mode" "QI")])
 
   [(set (match_operand:SDWIM 0 "nonimmediate_operand")
        (not:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand")))]
   ""
-  "ix86_expand_unary_operator (NOT, <MODE>mode, operands); DONE;")
+{
+  ix86_expand_unary_operator (NOT, <MODE>mode, operands, TARGET_APX_NDD);
+  DONE;
+})
 
 (define_insn_and_split "*one_cmpl<dwi>2_doubleword"
-  [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro")
-       (not:<DWI> (match_operand:<DWI> 1 "nonimmediate_operand" "0")))]
-  "ix86_unary_operator_ok (NOT, <DWI>mode, operands)"
+  [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro,&r")
+       (not:<DWI> (match_operand:<DWI> 1 "nonimmediate_operand" "0,ro")))]
+  "ix86_unary_operator_ok (NOT, <DWI>mode, operands, TARGET_APX_NDD)"
   "#"
   "&& reload_completed"
   [(set (match_dup 0)
        (not:DWIH (match_dup 1)))
    (set (match_dup 2)
        (not:DWIH (match_dup 3)))]
-  "split_double_mode (<DWI>mode, &operands[0], 2, &operands[0], &operands[2]);")
+  "split_double_mode (<DWI>mode, &operands[0], 2, &operands[0], &operands[2]);"
+  [(set_attr "isa" "*,apx_ndd")])
 
 (define_insn "*one_cmpl<mode>2_1"
-  [(set (match_operand:SWI248 0 "nonimmediate_operand" "=rm,?k")
-       (not:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "0,k")))]
-  "ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
+  [(set (match_operand:SWI248 0 "nonimmediate_operand" "=rm,r,?k")
+       (not:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "0,rm,k")))]
+  "ix86_unary_operator_ok (NOT, <MODE>mode, operands, TARGET_APX_NDD)"
   "@
    not{<imodesuffix>}\t%0
+   not{<imodesuffix>}\t{%1, %0|%0, %1}
    #"
-  [(set (attr "isa")
-       (cond [(eq_attr "alternative" "1")
-                (if_then_else (eq_attr "mode" "SI,DI")
-                  (const_string "avx512bw")
-                  (const_string "avx512f"))
-             ]
-             (const_string "*")))
-   (set_attr "type" "negnot,msklog")
+  [(set_attr "isa" "*,apx_ndd,<kmov_isa>")
+   (set_attr "type" "negnot,negnot,msklog")
    (set_attr "mode" "<MODE>")])
 
 (define_insn "*one_cmplsi2_1_zext"
-  [(set (match_operand:DI 0 "register_operand" "=r,?k")
+  [(set (match_operand:DI 0 "register_operand" "=r,r,?k")
        (zero_extend:DI
-         (not:SI (match_operand:SI 1 "register_operand" "0,k"))))]
-  "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
+         (not:SI (match_operand:SI 1 "nonimmediate_operand" "0,rm,k"))))]
+  "TARGET_64BIT
+   && ix86_unary_operator_ok (NOT, SImode, operands, TARGET_APX_NDD)"
   "@
    not{l}\t%k0
+   not{l}\t{%1, %k0|%k0, %1}
    #"
-  [(set_attr "isa" "x64,avx512bw")
-   (set_attr "type" "negnot,msklog")
-   (set_attr "mode" "SI,SI")])
+  [(set_attr "isa" "x64,apx_ndd,avx512bw")
+   (set_attr "type" "negnot,negnot,msklog")
+   (set_attr "mode" "SI,SI,SI")])
 
 (define_insn "*one_cmplqi2_1"
-  [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,?k")
-       (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,k")))]
-  "ix86_unary_operator_ok (NOT, QImode, operands)"
+  [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,r,?k")
+       (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,rm,k")))]
+  "ix86_unary_operator_ok (NOT, QImode, operands, TARGET_APX_NDD)"
   "@
    not{b}\t%0
    not{l}\t%k0
+   not{b}\t{%1, %0|%0, %1}
    #"
-  [(set_attr "isa" "*,*,avx512f")
-   (set_attr "type" "negnot,negnot,msklog")
+  [(set_attr "isa" "*,*,apx_ndd,avx512f")
+   (set_attr "type" "negnot,negnot,negnot,msklog")
    (set (attr "mode")
        (cond [(eq_attr "alternative" "1")
                 (const_string "SI")
-               (and (eq_attr "alternative" "2")
+               (and (eq_attr "alternative" "3")
                     (match_test "!TARGET_AVX512DQ"))
                 (const_string "HI")
               ]
   "@
    not{<imodesuffix>}\t%0
    #"
-  "&& reload_completed"
+  "&& reload_completed
+   && !(rtx_equal_p (operands[0], operands[1]))"
   [(set (strict_low_part (match_dup 0)) (match_dup 1))
    (set (strict_low_part (match_dup 0))
        (not:SWI12 (match_dup 0)))]
 
 (define_insn "*one_cmpl<mode>2_2"
   [(set (reg FLAGS_REG)
-       (compare (not:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
+       (compare (not:SWI (match_operand:SWI 1 "nonimmediate_operand" "0,rm"))
                 (const_int 0)))
-   (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
+   (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,r")
        (not:SWI (match_dup 1)))]
   "ix86_match_ccmode (insn, CCNOmode)
-   && ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
+   && ix86_unary_operator_ok (NOT, <MODE>mode, operands, TARGET_APX_NDD)"
   "#"
   [(set_attr "type" "alu1")
+   (set_attr "isa" "*,apx_ndd")
    (set_attr "mode" "<MODE>")])
 
 (define_split
 
 (define_insn "*one_cmplsi2_2_zext"
   [(set (reg FLAGS_REG)
-       (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
+       (compare (not:SI (match_operand:SI 1 "nonimmediate_operand" "0,rm"))
                 (const_int 0)))
-   (set (match_operand:DI 0 "register_operand" "=r")
+   (set (match_operand:DI 0 "register_operand" "=r,r")
        (zero_extend:DI (not:SI (match_dup 1))))]
   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
-   && ix86_unary_operator_ok (NOT, SImode, operands)"
+   && ix86_unary_operator_ok (NOT, SImode, operands, TARGET_APX_NDD)"
   "#"
   [(set_attr "type" "alu1")
+   (set_attr "isa" "*,apx_ndd")
    (set_attr "mode" "SI")])
 
 (define_split
   [(set (match_operand 0 "flags_reg_operand")
        (match_operator 2 "compare_operator"
-         [(not:SI (match_operand:SI 3 "register_operand"))
+         [(not:SI (match_operand:SI 3 "nonimmediate_operand"))
           (const_int 0)]))
    (set (match_operand:DI 1 "register_operand")
        (zero_extend:DI (not:SI (match_dup 3))))]
                                    (const_int 0)]))
              (set (match_dup 1)
                   (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])])
+
+;; Alternative 1 is needed to work around LRA limitation, see PR82524.
+(define_insn_and_split "*one_cmplqi_ext<mode>_1"
+  [(set (zero_extract:SWI248
+         (match_operand 0 "int248_register_operand" "+Q,&Q")
+         (const_int 8)
+         (const_int 8))
+       (subreg:SWI248
+         (not:QI
+           (subreg:QI
+             (match_operator:SWI248 2 "extract_operator"
+               [(match_operand 1 "int248_register_operand" "0,!Q")
+                (const_int 8)
+                (const_int 8)]) 0)) 0))]
+  ""
+  "@
+   not{b}\t%h0
+   #"
+  "reload_completed
+   && !(rtx_equal_p (operands[0], operands[1]))"
+  [(set (zero_extract:SWI248
+         (match_dup 0) (const_int 8) (const_int 8))
+       (zero_extract:SWI248
+         (match_dup 1) (const_int 8) (const_int 8)))
+   (set (zero_extract:SWI248
+         (match_dup 0) (const_int 8) (const_int 8))
+       (subreg:SWI248
+         (not:QI
+           (subreg:QI
+             (match_op_dup 2
+               [(match_dup 0) (const_int 8) (const_int 8)]) 0)) 0))]
+  ""
+  [(set_attr "type" "negnot")
+   (set_attr "mode" "QI")])
 \f
 ;; Shift instructions
 
        (ashift:SDWIM (match_operand:SDWIM 1 "<ashl_input_operand>")
                      (match_operand:QI 2 "nonmemory_operand")))]
   ""
-  "ix86_expand_binary_operator (ASHIFT, <MODE>mode, operands); DONE;")
+{
+  ix86_expand_binary_operator (ASHIFT, <MODE>mode, operands, TARGET_APX_NDD);
+  DONE;
+})
 
 (define_insn_and_split "*ashl<dwi>3_doubleword_mask"
   [(set (match_operand:<DWI> 0 "register_operand")
 })
 
 (define_insn "ashl<mode>3_doubleword"
-  [(set (match_operand:DWI 0 "register_operand" "=&r")
-       (ashift:DWI (match_operand:DWI 1 "reg_or_pm1_operand" "0n")
-                   (match_operand:QI 2 "nonmemory_operand" "<S>c")))
+  [(set (match_operand:DWI 0 "register_operand" "=&r,&r")
+       (ashift:DWI (match_operand:DWI 1 "reg_or_pm1_operand" "0n,r")
+                   (match_operand:QI 2 "nonmemory_operand" "<S>c,<S>c")))
    (clobber (reg:CC FLAGS_REG))]
   ""
   "#"
-  [(set_attr "type" "multi")])
+  [(set_attr "type" "multi")
+   (set_attr "isa" "*,apx_ndd")])
 
 (define_split
   [(set (match_operand:DWI 0 "register_operand")
    (clobber (reg:CC FLAGS_REG))]
   "epilogue_completed"
   [(const_int 0)]
-  "ix86_split_ashl (operands, NULL_RTX, <MODE>mode); DONE;")
+{
+  if (TARGET_APX_NDD
+      && !rtx_equal_p (operands[0], operands[1])
+      && REG_P (operands[1]))
+    ix86_split_ashl_ndd (operands, NULL_RTX);
+  else
+    ix86_split_ashl (operands, NULL_RTX, <MODE>mode);
+  DONE;
+})
 
 ;; By default we don't ask for a scratch register, because when DWImode
 ;; values are manipulated, registers are already at a premium.  But if
    (match_dup 3)]
   "TARGET_CMOVE"
   [(const_int 0)]
-  "ix86_split_ashl (operands, operands[3], <DWI>mode); DONE;")
+{
+  if (TARGET_APX_NDD
+      && !rtx_equal_p (operands[0], operands[1])
+      && (REG_P (operands[1])))
+    ix86_split_ashl_ndd (operands, operands[3]);
+  else
+    ix86_split_ashl (operands, operands[3], <DWI>mode);
+  DONE;
+})
 
 (define_insn_and_split "*ashl<dwi>3_doubleword_highpart"
   [(set (match_operand:<DWI> 0 "register_operand" "=r")
 {
   split_double_mode (<DWI>mode, &operands[0], 1, &operands[0], &operands[3]);
   int bits = INTVAL (operands[2]) - (<MODE_SIZE> * BITS_PER_UNIT);
-  if (!rtx_equal_p (operands[3], operands[1]))
-    emit_move_insn (operands[3], operands[1]);
-  if (bits > 0)
-    emit_insn (gen_ashl<mode>3 (operands[3], operands[3], GEN_INT (bits)));
+  bool op_equal_p = rtx_equal_p (operands[3], operands[1]);
+  if (bits == 0)
+    {
+      if (!op_equal_p)
+       emit_move_insn (operands[3], operands[1]);
+    }
+  else
+    {
+      if (!op_equal_p && !TARGET_APX_NDD)
+       emit_move_insn (operands[3], operands[1]);
+      rtx op_tmp = TARGET_APX_NDD ? operands[1] : operands[3];
+      emit_insn (gen_ashl<mode>3 (operands[3], op_tmp, GEN_INT (bits)));
+    }
   ix86_expand_clear (operands[0]);
   DONE;
 })
    (set_attr "amdfam10_decode" "vector")
    (set_attr "bdver1_decode" "vector")])
 
+(define_insn "x86_64_shld_ndd"
+  [(set (match_operand:DI 0 "register_operand" "=r")
+        (ior:DI (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "rm")
+                 (and:QI (match_operand:QI 3 "nonmemory_operand" "Jc")
+                         (const_int 63)))
+               (subreg:DI
+                 (lshiftrt:TI
+                   (zero_extend:TI
+                     (match_operand:DI 2 "register_operand" "r"))
+                   (minus:QI (const_int 64)
+                             (and:QI (match_dup 3) (const_int 63)))) 0)))
+   (clobber (reg:CC FLAGS_REG))]
+  "TARGET_APX_NDD"
+  "shld{q}\t{%s3%2, %1, %0|%0, %1, %2, %3}"
+  [(set_attr "type" "ishift")
+   (set_attr "mode" "DI")])
+
 (define_insn "x86_64_shld_1"
   [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
         (ior:DI (ashift:DI (match_dup 0)
    (set_attr "amdfam10_decode" "vector")
    (set_attr "bdver1_decode" "vector")])
 
+(define_insn "x86_64_shld_ndd_1"
+  [(set (match_operand:DI 0 "register_operand" "=r")
+        (ior:DI (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "rm")
+                          (match_operand:QI 3 "const_0_to_63_operand"))
+               (subreg:DI
+                 (lshiftrt:TI
+                   (zero_extend:TI
+                     (match_operand:DI 2 "register_operand" "r"))
+                   (match_operand:QI 4 "const_0_to_255_operand")) 0)))
+   (clobber (reg:CC FLAGS_REG))]
+  "TARGET_APX_NDD
+   && INTVAL (operands[4]) == 64 - INTVAL (operands[3])"
+  "shld{q}\t{%3, %2, %1, %0|%0, %1, %2, %3}"
+  [(set_attr "type" "ishift")
+   (set_attr "mode" "DI")
+   (set_attr "length_immediate" "1")])
+
+
 (define_insn_and_split "*x86_64_shld_shrd_1_nozext"
   [(set (match_operand:DI 0 "nonimmediate_operand")
        (ior:DI (ashift:DI (match_operand:DI 4 "nonimmediate_operand")
       operands[4] = force_reg (DImode, operands[4]);
       emit_insn (gen_x86_64_shrd_1 (operands[0], operands[4], operands[3], operands[2]));
     }
+  else if (TARGET_APX_NDD)
+    {
+     rtx tmp = gen_reg_rtx (DImode);
+     if (MEM_P (operands[4]))
+       {
+        operands[1] = force_reg (DImode, operands[1]);
+        emit_insn (gen_x86_64_shld_ndd_1 (tmp, operands[4], operands[1],
+                                          operands[2], operands[3]));
+       }
+     else if (MEM_P (operands[1]))
+       emit_insn (gen_x86_64_shrd_ndd_1 (tmp, operands[1], operands[4],
+                                        operands[3], operands[2]));
+     else
+       emit_insn (gen_x86_64_shld_ndd_1 (tmp, operands[4], operands[1],
+                                        operands[2], operands[3]));
+     emit_move_insn (operands[0], tmp);
+    }
   else
    {
      operands[1] = force_reg (DImode, operands[1]);
                                                   (const_int 63)))) 0)))
              (clobber (reg:CC FLAGS_REG))])])
 
+(define_insn_and_split "*x86_64_shld_ndd_2"
+  [(set (match_operand:DI 0 "nonimmediate_operand")
+       (ior:DI (ashift:DI (match_operand:DI 1 "nonimmediate_operand")
+                          (match_operand:QI 3 "nonmemory_operand"))
+               (lshiftrt:DI (match_operand:DI 2 "register_operand")
+                            (minus:QI (const_int 64) (match_dup 3)))))
+   (clobber (reg:CC FLAGS_REG))]
+  "TARGET_APX_NDD
+   && ix86_pre_reload_split ()"
+  "#"
+  "&& 1"
+  [(parallel [(set (match_dup 4)
+                  (ior:DI (ashift:DI (match_dup 1)
+                                     (and:QI (match_dup 3) (const_int 63)))
+                          (subreg:DI
+                            (lshiftrt:TI
+                              (zero_extend:TI (match_dup 2))
+                                (minus:QI (const_int 64)
+                                          (and:QI (match_dup 3)
+                                                  (const_int 63)))) 0)))
+             (clobber (reg:CC FLAGS_REG))
+             (set (match_dup 0) (match_dup 4))])]
+{
+  operands[4] = gen_reg_rtx (DImode);
+  emit_move_insn (operands[4], operands[0]);
+})
+
 (define_insn "x86_shld"
   [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
         (ior:SI (ashift:SI (match_dup 0)
    (set_attr "amdfam10_decode" "vector")
    (set_attr "bdver1_decode" "vector")])
 
+(define_insn "x86_shld_ndd"
+  [(set (match_operand:SI 0 "nonimmediate_operand" "=r")
+        (ior:SI (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
+                 (and:QI (match_operand:QI 3 "nonmemory_operand" "Ic")
+                         (const_int 31)))
+               (subreg:SI
+                 (lshiftrt:DI
+                   (zero_extend:DI
+                     (match_operand:SI 2 "register_operand" "r"))
+                   (minus:QI (const_int 32)
+                             (and:QI (match_dup 3) (const_int 31)))) 0)))
+   (clobber (reg:CC FLAGS_REG))]
+  "TARGET_APX_NDD"
+  "shld{l}\t{%s3%2, %1, %0|%0, %1, %2, %3}"
+  [(set_attr "type" "ishift")
+   (set_attr "mode" "SI")])
+
+
 (define_insn "x86_shld_1"
   [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
         (ior:SI (ashift:SI (match_dup 0)
    (set_attr "amdfam10_decode" "vector")
    (set_attr "bdver1_decode" "vector")])
 
+(define_insn "x86_shld_ndd_1"
+  [(set (match_operand:SI 0 "register_operand" "=r")
+        (ior:SI (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
+                          (match_operand:QI 3 "const_0_to_31_operand"))
+               (subreg:SI
+                 (lshiftrt:DI
+                   (zero_extend:DI
+                     (match_operand:SI 2 "register_operand" "r"))
+                   (match_operand:QI 4 "const_0_to_63_operand")) 0)))
+   (clobber (reg:CC FLAGS_REG))]
+  "TARGET_APX_NDD 
+   && INTVAL (operands[4]) == 32 - INTVAL (operands[3])"
+  "shld{l}\t{%3, %2, %1, %0|%0, %1, %2, %3}"
+  [(set_attr "type" "ishift")
+   (set_attr "length_immediate" "1")
+   (set_attr "mode" "SI")])
+
+
 (define_insn_and_split "*x86_shld_shrd_1_nozext"
   [(set (match_operand:SI 0 "nonimmediate_operand")
        (ior:SI (ashift:SI (match_operand:SI 4 "nonimmediate_operand")
       operands[4] = force_reg (SImode, operands[4]);
       emit_insn (gen_x86_shrd_1 (operands[0], operands[4], operands[3], operands[2]));
     }
-  else
+  else if (TARGET_APX_NDD)
+    {
+     rtx tmp = gen_reg_rtx (SImode);
+     if (MEM_P (operands[4]))
+       {
+        operands[1] = force_reg (SImode, operands[1]);
+        emit_insn (gen_x86_shld_ndd_1 (tmp, operands[4], operands[1],
+                                       operands[2], operands[3]));
+       }
+     else if (MEM_P (operands[1]))
+       emit_insn (gen_x86_shrd_ndd_1 (tmp, operands[1], operands[4],
+                                     operands[3], operands[2]));
+     else
+       emit_insn (gen_x86_shld_ndd_1 (tmp, operands[4], operands[1],
+                                     operands[2], operands[3]));
+     emit_move_insn (operands[0], tmp);
+    }
+ else
    {
      operands[1] = force_reg (SImode, operands[1]);
      rtx tmp = gen_reg_rtx (SImode);
                                                   (const_int 31)))) 0)))
              (clobber (reg:CC FLAGS_REG))])])
 
+(define_insn_and_split "*x86_shld_ndd_2"
+  [(set (match_operand:SI 0 "nonimmediate_operand")
+       (ior:SI (ashift:SI (match_operand:SI 1 "nonimmediate_operand")
+                          (match_operand:QI 3 "nonmemory_operand"))
+               (lshiftrt:SI (match_operand:SI 2 "register_operand")
+                            (minus:QI (const_int 32) (match_dup 3)))))
+   (clobber (reg:CC FLAGS_REG))]
+  "TARGET_APX_NDD
+   && ix86_pre_reload_split ()"
+  "#"
+  "&& 1"
+  [(parallel [(set (match_dup 4)
+                  (ior:SI (ashift:SI (match_dup 1)
+                                     (and:QI (match_dup 3) (const_int 31)))
+                          (subreg:SI
+                            (lshiftrt:DI
+                              (zero_extend:DI (match_dup 2))
+                                (minus:QI (const_int 32)
+                                          (and:QI (match_dup 3)
+                                                  (const_int 31)))) 0)))
+             (clobber (reg:CC FLAGS_REG))
+             (set (match_dup 0) (match_dup 4))])]
+{
+  operands[4] = gen_reg_rtx (SImode);
+  emit_move_insn (operands[4], operands[0]);
+})
+
 (define_expand "@x86_shift<mode>_adj_1"
   [(set (reg:CCZ FLAGS_REG)
        (compare:CCZ (and:QI (match_operand:QI 2 "register_operand")
    (set_attr "mode" "<MODE>")])
 
 (define_insn "*ashl<mode>3_1"
-  [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r,r,?k")
-       (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,l,rm,k")
-                     (match_operand:QI 2 "nonmemory_operand" "c<S>,M,r,<KS>")))
+  [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r,r,?k,r")
+       (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,l,rm,k,rm")
+                     (match_operand:QI 2 "nonmemory_operand" "c<S>,M,r,<KS>,c<S>")))
    (clobber (reg:CC FLAGS_REG))]
-  "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
+  "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands, TARGET_APX_NDD)"
 {
+  bool use_ndd = get_attr_isa (insn) == ISA_APX_NDD;
   switch (get_attr_type (insn))
     {
     case TYPE_LEA:
 
     default:
       if (operands[2] == const1_rtx
-         && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
+         && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
+         /* For NDD form instructions related to TARGET_SHIFT1, the $1
+            immediate do not need to be omitted as assembler will map it
+            to use shorter encoding. */
+         && !use_ndd)
        return "sal{<imodesuffix>}\t%0";
       else
-       return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
+       return use_ndd ? "sal{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}"
+                      : "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
     }
 }
-  [(set_attr "isa" "*,*,bmi2,avx512bw")
+  [(set_attr "isa" "*,*,bmi2,avx512bw,apx_ndd")
    (set (attr "type")
      (cond [(eq_attr "alternative" "1")
              (const_string "lea")
            (eq_attr "alternative" "2")
              (const_string "ishiftx")
+           (eq_attr "alternative" "4")
+             (const_string "ishift")
             (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
                      (match_operand 0 "register_operand"))
                 (match_operand 2 "const1_operand"))
    (set_attr "mode" "SI")])
 
 (define_insn "*ashlsi3_1_zext"
-  [(set (match_operand:DI 0 "register_operand" "=r,r,r")
+  [(set (match_operand:DI 0 "register_operand" "=r,r,r,r")
        (zero_extend:DI
-         (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,l,rm")
-                    (match_operand:QI 2 "nonmemory_operand" "cI,M,r"))))
+         (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,l,rm,rm")
+                    (match_operand:QI 2 "nonmemory_operand" "cI,M,r,cI"))))
    (clobber (reg:CC FLAGS_REG))]
-  "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
+  "TARGET_64BIT
+   && ix86_binary_operator_ok (ASHIFT, SImode, operands, TARGET_APX_NDD)"
 {
+  bool use_ndd = get_attr_isa (insn) == ISA_APX_NDD;
   switch (get_attr_type (insn))
     {
     case TYPE_LEA:
 
     default:
       if (operands[2] == const1_rtx
-         && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
+         && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
+         && !use_ndd)
        return "sal{l}\t%k0";
       else
-       return "sal{l}\t{%2, %k0|%k0, %2}";
+       return use_ndd ? "sal{l}\t{%2, %1, %k0|%k0, %1, %2}"
+                      : "sal{l}\t{%2, %k0|%k0, %2}";
     }
 }
-  [(set_attr "isa" "*,*,bmi2")
+  [(set_attr "isa" "*,*,bmi2,apx_ndd")
    (set (attr "type")
      (cond [(eq_attr "alternative" "1")
              (const_string "lea")
            (eq_attr "alternative" "2")
              (const_string "ishiftx")
+           (eq_attr "alternative" "3")
+             (const_string "ishift")
             (and (match_test "TARGET_DOUBLE_WITH_ADD")
                 (match_operand 2 "const1_operand"))
              (const_string "alu")
   "operands[2] = gen_lowpart (SImode, operands[2]);")
 
 (define_insn "*ashlhi3_1"
-  [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,Yp,?k")
-       (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l,k")
-                  (match_operand:QI 2 "nonmemory_operand" "cI,M,Ww")))
+  [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,Yp,?k,r")
+       (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l,k,rm")
+                  (match_operand:QI 2 "nonmemory_operand" "cI,M,Ww,cI")))
    (clobber (reg:CC FLAGS_REG))]
-  "ix86_binary_operator_ok (ASHIFT, HImode, operands)"
+  "ix86_binary_operator_ok (ASHIFT, HImode, operands, TARGET_APX_NDD)"
 {
+  bool use_ndd = get_attr_isa (insn) == ISA_APX_NDD;
   switch (get_attr_type (insn))
     {
     case TYPE_LEA:
 
     default:
       if (operands[2] == const1_rtx
-         && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
+         && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
+         && !use_ndd)
        return "sal{w}\t%0";
       else
-       return "sal{w}\t{%2, %0|%0, %2}";
+       return use_ndd ? "sal{w}\t{%2, %1, %0|%0, %1, %2}"
+                      : "sal{w}\t{%2, %0|%0, %2}";
     }
 }
-  [(set_attr "isa" "*,*,avx512f")
+  [(set_attr "isa" "*,*,avx512f,apx_ndd")
    (set (attr "type")
      (cond [(eq_attr "alternative" "1")
              (const_string "lea")
            (eq_attr "alternative" "2")
              (const_string "msklog")
+           (eq_attr "alternative" "3")
+             (const_string "ishift")
             (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
                      (match_operand 0 "register_operand"))
                 (match_operand 2 "const1_operand"))
                           (match_test "optimize_function_for_size_p (cfun)")))))
        (const_string "0")
        (const_string "*")))
-   (set_attr "mode" "HI,SI,HI")])
+   (set_attr "mode" "HI,SI,HI,HI")])
 
 (define_insn "*ashlqi3_1"
-  [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,Yp,?k")
-       (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l,k")
-                  (match_operand:QI 2 "nonmemory_operand" "cI,cI,M,Wb")))
+  [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,Yp,?k,r")
+       (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l,k,rm")
+                  (match_operand:QI 2 "nonmemory_operand" "cI,cI,M,Wb,cI")))
    (clobber (reg:CC FLAGS_REG))]
-  "ix86_binary_operator_ok (ASHIFT, QImode, operands)"
+  "ix86_binary_operator_ok (ASHIFT, QImode, operands, TARGET_APX_NDD)"
 {
+  bool use_ndd = get_attr_isa (insn) == ISA_APX_NDD;
   switch (get_attr_type (insn))
     {
     case TYPE_LEA:
 
     default:
       if (operands[2] == const1_rtx
-         && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
+         && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
+         && !use_ndd)
        {
          if (get_attr_mode (insn) == MODE_SI)
            return "sal{l}\t%k0";
          if (get_attr_mode (insn) == MODE_SI)
            return "sal{l}\t{%2, %k0|%k0, %2}";
          else
-           return "sal{b}\t{%2, %0|%0, %2}";
+           return use_ndd ? "sal{b}\t{%2, %1, %0|%0, %1, %2}"
+                          : "sal{b}\t{%2, %0|%0, %2}";
        }
     }
 }
-  [(set_attr "isa" "*,*,*,avx512dq")
+  [(set_attr "isa" "*,*,*,avx512dq,apx_ndd")
    (set (attr "type")
      (cond [(eq_attr "alternative" "2")
              (const_string "lea")
            (eq_attr "alternative" "3")
              (const_string "msklog")
+           (eq_attr "alternative" "4")
+             (const_string "ishift")
             (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
                      (match_operand 0 "register_operand"))
                 (match_operand 2 "const1_operand"))
                           (match_test "optimize_function_for_size_p (cfun)")))))
        (const_string "0")
        (const_string "*")))
-   (set_attr "mode" "QI,SI,SI,QI")
+   (set_attr "mode" "QI,SI,SI,QI,QI")
    ;; Potential partial reg stall on alternative 1.
    (set (attr "preferred_for_speed")
-     (cond [(eq_attr "alternative" "1")
+     (cond [(eq_attr "alternative" "1,4")
              (symbol_ref "!TARGET_PARTIAL_REG_STALL")]
           (symbol_ref "true")))])
 
        return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
     }
 }
-  "&& reload_completed"
+  "&& reload_completed
+   && !(rtx_equal_p (operands[0], operands[1]))"
   [(set (strict_low_part (match_dup 0)) (match_dup 1))
    (parallel
      [(set (strict_low_part (match_dup 0))
 (define_insn "*ashl<mode>3_cmp"
   [(set (reg FLAGS_REG)
        (compare
-         (ashift:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")
-                     (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
+         (ashift:SWI (match_operand:SWI 1 "nonimmediate_operand" "0,rm")
+                     (match_operand:QI 2 "<shift_immediate_operand>" "<S>,<S>"))
          (const_int 0)))
-   (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
+   (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,r")
        (ashift:SWI (match_dup 1) (match_dup 2)))]
   "(optimize_function_for_size_p (cfun)
     || !TARGET_PARTIAL_FLAG_REG_STALL
        && (TARGET_SHIFT1
            || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
    && ix86_match_ccmode (insn, CCGOCmode)
-   && ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
+   && ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands, TARGET_APX_NDD)"
 {
+  bool use_ndd = get_attr_isa (insn) == ISA_APX_NDD;
   switch (get_attr_type (insn))
     {
     case TYPE_ALU:
 
     default:
       if (operands[2] == const1_rtx
-         && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
+         && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
+         && !use_ndd)
        return "sal{<imodesuffix>}\t%0";
       else
-       return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
+       return use_ndd ? "sal{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}"
+                      : "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
     }
 }
-  [(set (attr "type")
-     (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD")
+  [(set_attr "isa" "*,apx_ndd")
+   (set (attr "type")
+     (cond [(eq_attr "alternative" "1")
+             (const_string "ishift")
+           (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
                      (match_operand 0 "register_operand"))
                 (match_operand 2 "const1_operand"))
              (const_string "alu")
 (define_insn "*ashlsi3_cmp_zext"
   [(set (reg FLAGS_REG)
        (compare
-         (ashift:SI (match_operand:SI 1 "register_operand" "0")
+         (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,rm")
                     (match_operand:QI 2 "const_1_to_31_operand"))
          (const_int 0)))
-   (set (match_operand:DI 0 "register_operand" "=r")
+   (set (match_operand:DI 0 "register_operand" "=r,r")
        (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
   "TARGET_64BIT
    && (optimize_function_for_size_p (cfun)
           && (TARGET_SHIFT1
               || TARGET_DOUBLE_WITH_ADD)))
    && ix86_match_ccmode (insn, CCGOCmode)
-   && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
+   && ix86_binary_operator_ok (ASHIFT, SImode, operands, TARGET_APX_NDD)"
 {
+  bool use_ndd = get_attr_isa (insn) == ISA_APX_NDD;
   switch (get_attr_type (insn))
     {
     case TYPE_ALU:
 
     default:
       if (operands[2] == const1_rtx
-         && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
+         && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
+         && !use_ndd)
        return "sal{l}\t%k0";
       else
-       return "sal{l}\t{%2, %k0|%k0, %2}";
+       return use_ndd ? "sal{l}\t{%2, %1, %k0|%k0, %1, %2}"
+                      : "sal{l}\t{%2, %k0|%k0, %2}";
     }
 }
-  [(set (attr "type")
-     (cond [(and (match_test "TARGET_DOUBLE_WITH_ADD")
+  [(set_attr "isa" "*,apx_ndd")
+   (set (attr "type")
+     (cond [(eq_attr "alternative" "1")
+             (const_string "ishift")
+           (and (match_test "TARGET_DOUBLE_WITH_ADD")
                 (match_operand 2 "const1_operand"))
              (const_string "alu")
           ]
 (define_insn "*ashl<mode>3_cconly"
   [(set (reg FLAGS_REG)
        (compare
-         (ashift:SWI (match_operand:SWI 1 "register_operand" "0")
-                     (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
+         (ashift:SWI (match_operand:SWI 1 "nonimmediate_operand" "0,rm")
+                     (match_operand:QI 2 "<shift_immediate_operand>" "<S>,<S>"))
          (const_int 0)))
-   (clobber (match_scratch:SWI 0 "=<r>"))]
+   (clobber (match_scratch:SWI 0 "=<r>,r"))]
   "(optimize_function_for_size_p (cfun)
     || !TARGET_PARTIAL_FLAG_REG_STALL
     || (operands[2] == const1_rtx
            || TARGET_DOUBLE_WITH_ADD)))
    && ix86_match_ccmode (insn, CCGOCmode)"
 {
+  bool use_ndd = get_attr_isa (insn) == ISA_APX_NDD;
   switch (get_attr_type (insn))
     {
     case TYPE_ALU:
       gcc_assert (operands[2] == const1_rtx);
       return "add{<imodesuffix>}\t%0, %0";
 
-    default:
+  default:
       if (operands[2] == const1_rtx
-         && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
+         && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
+         && !use_ndd)
        return "sal{<imodesuffix>}\t%0";
       else
-       return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
+       return use_ndd ? "sal{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}"
+                      : "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
     }
 }
-  [(set (attr "type")
-     (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD")
+  [(set_attr "isa" "*,apx_ndd")
+   (set (attr "type")
+     (cond [(eq_attr "alternative" "1")
+             (const_string "ishift")
+           (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
                      (match_operand 0 "register_operand"))
                 (match_operand 2 "const1_operand"))
              (const_string "alu")
        (const_string "*")))
    (set_attr "mode" "<MODE>")])
 
-(define_insn "*ashlqi_ext<mode>_2"
+;; Alternative 1 is needed to work around LRA limitation, see PR82524.
+(define_insn_and_split "*ashlqi_ext<mode>_1"
   [(set (zero_extract:SWI248
-         (match_operand 0 "int248_register_operand" "+Q")
+         (match_operand 0 "int248_register_operand" "+Q,&Q")
          (const_int 8)
          (const_int 8))
        (subreg:SWI248
          (ashift:QI
            (subreg:QI
              (match_operator:SWI248 3 "extract_operator"
-               [(match_operand 1 "int248_register_operand" "0")
+               [(match_operand 1 "int248_register_operand" "0,!Q")
                 (const_int 8)
                 (const_int 8)]) 0)
-           (match_operand:QI 2 "nonmemory_operand" "cI")) 0))
-  (clobber (reg:CC FLAGS_REG))]
-  "/* FIXME: without this LRA can't reload this pattern, see PR82524.  */
-   rtx_equal_p (operands[0], operands[1])"
+           (match_operand:QI 2 "nonmemory_operand" "cI,cI")) 0))
+   (clobber (reg:CC FLAGS_REG))]
+  ""
 {
+  if (which_alternative)
+    return "#";
+
   switch (get_attr_type (insn))
     {
     case TYPE_ALU:
        return "sal{b}\t{%2, %h0|%h0, %2}";
     }
 }
+  "reload_completed
+   && !(rtx_equal_p (operands[0], operands[1]))"
+  [(set (zero_extract:SWI248
+         (match_dup 0) (const_int 8) (const_int 8))
+       (zero_extract:SWI248
+         (match_dup 1) (const_int 8) (const_int 8)))
+   (parallel
+     [(set (zero_extract:SWI248
+            (match_dup 0) (const_int 8) (const_int 8))
+          (subreg:SWI248
+            (ashift:QI
+              (subreg:QI
+                (match_op_dup 3
+                  [(match_dup 0) (const_int 8) (const_int 8)]) 0)
+              (match_dup 2)) 0))
+      (clobber (reg:CC FLAGS_REG))])]
+  ""
   [(set (attr "type")
      (cond [(and (match_test "TARGET_DOUBLE_WITH_ADD")
                 (match_operand 2 "const1_operand"))
        (any_shiftrt:SDWIM (match_operand:SDWIM 1 "<shift_operand>")
                           (match_operand:QI 2 "nonmemory_operand")))]
   ""
-  "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
+{
+  ix86_expand_binary_operator (<CODE>, <MODE>mode, operands, TARGET_APX_NDD);
+  DONE;
+})
 
 ;; Avoid useless masking of count operand.
 (define_insn_and_split "*<insn><mode>3_mask"
 })
 
 (define_insn_and_split "<insn><mode>3_doubleword"
-  [(set (match_operand:DWI 0 "register_operand" "=&r")
-       (any_shiftrt:DWI (match_operand:DWI 1 "register_operand" "0")
-                        (match_operand:QI 2 "nonmemory_operand" "<S>c")))
+  [(set (match_operand:DWI 0 "register_operand" "=&r,&r")
+       (any_shiftrt:DWI (match_operand:DWI 1 "register_operand" "0,r")
+                        (match_operand:QI 2 "nonmemory_operand" "<S>c,<S>c")))
    (clobber (reg:CC FLAGS_REG))]
   ""
   "#"
   "epilogue_completed"
   [(const_int 0)]
-  "ix86_split_<insn> (operands, NULL_RTX, <MODE>mode); DONE;"
-  [(set_attr "type" "multi")])
+{
+  if (TARGET_APX_NDD
+      && !rtx_equal_p (operands[0], operands[1]))
+    ix86_split_rshift_ndd (<CODE>, operands, NULL_RTX);
+  else
+    ix86_split_<insn> (operands, NULL_RTX, <MODE>mode);
+  DONE;
+}
+  [(set_attr "type" "multi")
+   (set_attr "isa" "*,apx_ndd")])
 
 ;; By default we don't ask for a scratch register, because when DWImode
 ;; values are manipulated, registers are already at a premium.  But if
    (match_dup 3)]
   "TARGET_CMOVE"
   [(const_int 0)]
-  "ix86_split_<insn> (operands, operands[3], <DWI>mode); DONE;")
+{
+  if (TARGET_APX_NDD
+      && !rtx_equal_p (operands[0], operands[1]))
+    ix86_split_rshift_ndd (<CODE>, operands, operands[3]);
+  else
+    ix86_split_<insn> (operands, operands[3], <DWI>mode);
+  DONE;
+})
+
+;; Split truncations of double word right shifts into x86_shrd_1.
+(define_insn_and_split "<insn><dwi>3_doubleword_lowpart"
+  [(set (match_operand:DWIH 0 "register_operand" "=&r")
+       (subreg:DWIH
+         (any_shiftrt:<DWI> (match_operand:<DWI> 1 "register_operand" "r")
+                            (match_operand:QI 2 "const_int_operand")) 0))
+   (clobber (reg:CC FLAGS_REG))]
+  "UINTVAL (operands[2]) < <MODE_SIZE> * BITS_PER_UNIT"
+  "#"
+  "&& reload_completed"
+  [(parallel
+      [(set (match_dup 0)
+           (ior:DWIH (lshiftrt:DWIH (match_dup 0) (match_dup 2))
+                     (subreg:DWIH
+                       (ashift:<DWI> (zero_extend:<DWI> (match_dup 3))
+                                     (match_dup 4)) 0)))
+       (clobber (reg:CC FLAGS_REG))])]
+{
+  split_double_mode (<DWI>mode, &operands[1], 1, &operands[1], &operands[3]);
+  operands[4] = GEN_INT ((<MODE_SIZE> * BITS_PER_UNIT) - INTVAL (operands[2]));
+  if (!rtx_equal_p (operands[0], operands[1]))
+    emit_move_insn (operands[0], operands[1]);
+})
 
 (define_insn "x86_64_shrd"
   [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
    (set_attr "amdfam10_decode" "vector")
    (set_attr "bdver1_decode" "vector")])
 
+(define_insn "x86_64_shrd_ndd"
+  [(set (match_operand:DI 0 "register_operand" "=r")
+        (ior:DI (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "rm")
+                 (and:QI (match_operand:QI 3 "nonmemory_operand" "Jc")
+                         (const_int 63)))
+               (subreg:DI
+                 (ashift:TI
+                   (zero_extend:TI
+                     (match_operand:DI 2 "register_operand" "r"))
+                   (minus:QI (const_int 64)
+                             (and:QI (match_dup 3) (const_int 63)))) 0)))
+   (clobber (reg:CC FLAGS_REG))]
+  "TARGET_APX_NDD"
+  "shrd{q}\t{%s3%2, %1, %0|%0, %1, %2, %3}"
+  [(set_attr "type" "ishift")
+   (set_attr "mode" "DI")])
+
+
 (define_insn "x86_64_shrd_1"
   [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
         (ior:DI (lshiftrt:DI (match_dup 0)
    (set_attr "amdfam10_decode" "vector")
    (set_attr "bdver1_decode" "vector")])
 
+(define_insn "x86_64_shrd_ndd_1"
+  [(set (match_operand:DI 0 "register_operand" "=r")
+        (ior:DI (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "rm")
+                            (match_operand:QI 3 "const_0_to_63_operand"))
+               (subreg:DI
+                 (ashift:TI
+                   (zero_extend:TI
+                     (match_operand:DI 2 "register_operand" "r"))
+                   (match_operand:QI 4 "const_0_to_255_operand")) 0)))
+   (clobber (reg:CC FLAGS_REG))]
+  "TARGET_APX_NDD
+   && INTVAL (operands[4]) == 64 - INTVAL (operands[3])"
+  "shrd{q}\t{%3, %2, %1, %0|%0, %1, %2, %3}"
+  [(set_attr "type" "ishift")
+   (set_attr "length_immediate" "1")
+   (set_attr "mode" "DI")])
+
+
 (define_insn_and_split "*x86_64_shrd_shld_1_nozext"
   [(set (match_operand:DI 0 "nonimmediate_operand")
        (ior:DI (lshiftrt:DI (match_operand:DI 4 "nonimmediate_operand")
       operands[4] = force_reg (DImode, operands[4]);
       emit_insn (gen_x86_64_shld_1 (operands[0], operands[4], operands[3], operands[2]));
     }
+  else if (TARGET_APX_NDD)
+    {
+      rtx tmp = gen_reg_rtx (DImode);
+      if (MEM_P (operands[4]))
+        {
+         operands[1] = force_reg (DImode, operands[1]);
+         emit_insn (gen_x86_64_shrd_ndd_1 (tmp, operands[4], operands[1],
+                                           operands[2], operands[3]));
+        }
+       else if (MEM_P (operands[1]))
+         emit_insn (gen_x86_64_shld_ndd_1 (tmp, operands[1], operands[4],
+                                          operands[3], operands[2]));
+       else
+         emit_insn (gen_x86_64_shrd_ndd_1 (tmp, operands[4], operands[1],
+                                          operands[2], operands[3]));
+       emit_move_insn (operands[0], tmp);
+    }
   else
    {
      operands[1] = force_reg (DImode, operands[1]);
                                                   (const_int 63)))) 0)))
              (clobber (reg:CC FLAGS_REG))])])
 
+(define_insn_and_split "*x86_64_shrd_ndd_2"
+  [(set (match_operand:DI 0 "nonimmediate_operand")
+       (ior:DI (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand")
+                            (match_operand:QI 3 "nonmemory_operand"))
+               (ashift:DI (match_operand:DI 2 "register_operand")
+                          (minus:QI (const_int 64) (match_dup 2)))))
+   (clobber (reg:CC FLAGS_REG))]
+  "TARGET_APX_NDD
+  && ix86_pre_reload_split ()"
+  "#"
+  "&& 1"
+  [(parallel [(set (match_dup 4)
+                  (ior:DI (lshiftrt:DI (match_dup 1)
+                                       (and:QI (match_dup 3) (const_int 63)))
+                          (subreg:DI
+                            (ashift:TI
+                              (zero_extend:TI (match_dup 2))
+                                (minus:QI (const_int 64)
+                                          (and:QI (match_dup 3)
+                                                  (const_int 63)))) 0)))
+             (clobber (reg:CC FLAGS_REG))
+             (set (match_dup 0) (match_dup 4))])]
+{
+  operands[4] = gen_reg_rtx (DImode);
+  emit_move_insn (operands[4], operands[0]);
+})
+
 (define_insn "x86_shrd"
   [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
         (ior:SI (lshiftrt:SI (match_dup 0)
    (set_attr "amdfam10_decode" "vector")
    (set_attr "bdver1_decode" "vector")])
 
+(define_insn "x86_shrd_ndd"
+  [(set (match_operand:SI 0 "register_operand" "=r")
+        (ior:SI (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
+                 (and:QI (match_operand:QI 3 "nonmemory_operand" "Ic")
+                         (const_int 31)))
+               (subreg:SI
+                 (ashift:DI
+                   (zero_extend:DI
+                     (match_operand:SI 2 "register_operand" "r"))
+                   (minus:QI (const_int 32)
+                             (and:QI (match_dup 3) (const_int 31)))) 0)))
+   (clobber (reg:CC FLAGS_REG))]
+  "TARGET_APX_NDD"
+  "shrd{l}\t{%s3%2, %1, %0|%0, %1, %2, %3}"
+  [(set_attr "type" "ishift")
+   (set_attr "mode" "SI")])
+
 (define_insn "x86_shrd_1"
   [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
         (ior:SI (lshiftrt:SI (match_dup 0)
    (set_attr "amdfam10_decode" "vector")
    (set_attr "bdver1_decode" "vector")])
 
+(define_insn "x86_shrd_ndd_1"
+  [(set (match_operand:SI 0 "register_operand" "=r")
+        (ior:SI (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
+                            (match_operand:QI 3 "const_0_to_31_operand"))
+               (subreg:SI
+                 (ashift:DI
+                   (zero_extend:DI
+                     (match_operand:SI 2 "register_operand" "r"))
+                   (match_operand:QI 4 "const_0_to_63_operand")) 0)))
+   (clobber (reg:CC FLAGS_REG))]
+  "TARGET_APX_NDD
+   && (INTVAL (operands[4]) == 32 - INTVAL (operands[3]))"
+  "shrd{l}\t{%3, %2, %1, %0|%0, %1, %2, %3}"
+  [(set_attr "type" "ishift")
+   (set_attr "length_immediate" "1")
+   (set_attr "mode" "SI")])
+
+
 (define_insn_and_split "*x86_shrd_shld_1_nozext"
   [(set (match_operand:SI 0 "nonimmediate_operand")
        (ior:SI (lshiftrt:SI (match_operand:SI 4 "nonimmediate_operand")
       operands[4] = force_reg (SImode, operands[4]);
       emit_insn (gen_x86_shld_1 (operands[0], operands[4], operands[3], operands[2]));
     }
-  else
+  else if (TARGET_APX_NDD)
+    {
+      rtx tmp = gen_reg_rtx (SImode);
+      if (MEM_P (operands[4]))
+        {
+         operands[1] = force_reg (SImode, operands[1]);
+         emit_insn (gen_x86_shrd_ndd_1 (tmp, operands[4], operands[1],
+                                        operands[2], operands[3]));
+        }
+      else if (MEM_P (operands[1]))
+        emit_insn (gen_x86_shld_ndd_1 (tmp, operands[1], operands[4],
+                                      operands[3], operands[2]));
+      else
+        emit_insn (gen_x86_shrd_ndd_1 (tmp, operands[4], operands[1],
+                                      operands[2], operands[3]));
+      emit_move_insn (operands[0], tmp);
+     }
+   else
    {
      operands[1] = force_reg (SImode, operands[1]);
      rtx tmp = gen_reg_rtx (SImode);
                                                   (const_int 31)))) 0)))
              (clobber (reg:CC FLAGS_REG))])])
 
+(define_insn_and_split "*x86_shrd_ndd_2"
+  [(set (match_operand:SI 0 "nonimmediate_operand")
+       (ior:SI (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand")
+                          (match_operand:QI 3 "nonmemory_operand"))
+               (ashift:SI (match_operand:SI 2 "register_operand")
+                          (minus:QI (const_int 32) (match_dup 3)))))
+   (clobber (reg:CC FLAGS_REG))]
+  "TARGET_APX_NDD
+   && ix86_pre_reload_split ()"
+  "#"
+  "&& 1"
+  [(parallel [(set (match_dup 4)
+                  (ior:SI (lshiftrt:SI (match_dup 1)
+                                       (and:QI (match_dup 3) (const_int 31)))
+                          (subreg:SI
+                            (ashift:DI
+                              (zero_extend:DI (match_dup 2))
+                                (minus:QI (const_int 32)
+                                          (and:QI (match_dup 3)
+                                                  (const_int 31)))) 0)))
+             (clobber (reg:CC FLAGS_REG))
+             (set (match_dup 0) (match_dup 4))])]
+{
+  operands[4] = gen_reg_rtx (SImode);
+  emit_move_insn (operands[4], operands[0]);
+})
+
 ;; Base name for insn mnemonic.
 (define_mode_attr cvt_mnemonic
   [(SI "{cltd|cdq}") (DI "{cqto|cqo}")])
 
 (define_insn "ashr<mode>3_cvt"
-  [(set (match_operand:SWI48 0 "nonimmediate_operand" "=*d,rm")
+  [(set (match_operand:SWI48 0 "nonimmediate_operand" "=*d,rm,r")
        (ashiftrt:SWI48
-         (match_operand:SWI48 1 "nonimmediate_operand" "*a,0")
+         (match_operand:SWI48 1 "nonimmediate_operand" "*a,0,rm")
          (match_operand:QI 2 "const_int_operand")))
    (clobber (reg:CC FLAGS_REG))]
   "INTVAL (operands[2]) == GET_MODE_BITSIZE (<MODE>mode)-1
    && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
-   && ix86_binary_operator_ok (ASHIFTRT, <MODE>mode, operands)"
+   && ix86_binary_operator_ok (ASHIFTRT, <MODE>mode, operands, TARGET_APX_NDD)"
   "@
    <cvt_mnemonic>
-   sar{<imodesuffix>}\t{%2, %0|%0, %2}"
-  [(set_attr "type" "imovx,ishift")
-   (set_attr "prefix_0f" "0,*")
-   (set_attr "length_immediate" "0,*")
-   (set_attr "modrm" "0,1")
+   sar{<imodesuffix>}\t{%2, %0|%0, %2}
+   sar{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}"
+  [(set_attr "isa" "*,*,apx_ndd")
+   (set_attr "type" "imovx,ishift,ishift")
+   (set_attr "prefix_0f" "0,*,*")
+   (set_attr "length_immediate" "0,*,*")
+   (set_attr "modrm" "0,1,1")
    (set_attr "mode" "<MODE>")])
 
 (define_insn "*ashrsi3_cvt_zext"
-  [(set (match_operand:DI 0 "register_operand" "=*d,r")
+  [(set (match_operand:DI 0 "register_operand" "=*d,r,r")
        (zero_extend:DI
-         (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
+         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0,rm")
                       (match_operand:QI 2 "const_int_operand"))))
    (clobber (reg:CC FLAGS_REG))]
   "TARGET_64BIT && INTVAL (operands[2]) == 31
    && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
-   && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
+   && ix86_binary_operator_ok (ASHIFTRT, SImode, operands, TARGET_APX_NDD)"
   "@
    {cltd|cdq}
-   sar{l}\t{%2, %k0|%k0, %2}"
-  [(set_attr "type" "imovx,ishift")
-   (set_attr "prefix_0f" "0,*")
-   (set_attr "length_immediate" "0,*")
-   (set_attr "modrm" "0,1")
+   sar{l}\t{%2, %k0|%k0, %2}
+   sar{l}\t{%2, %1, %k0|%k0, %1, %2}"
+  [(set_attr "isa" "*,*,apx_ndd")
+   (set_attr "type" "imovx,ishift,ishift")
+   (set_attr "prefix_0f" "0,*,*")
+   (set_attr "length_immediate" "0,*,*")
+   (set_attr "modrm" "0,1,1")
    (set_attr "mode" "SI")])
 
 (define_expand "@x86_shift<mode>_adj_3"
    (set_attr "mode" "<MODE>")])
 
 (define_insn "*ashr<mode>3_1"
-  [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
+  [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r,r")
        (ashiftrt:SWI48
-         (match_operand:SWI48 1 "nonimmediate_operand" "0,rm")
-         (match_operand:QI 2 "nonmemory_operand" "c<S>,r")))
+         (match_operand:SWI48 1 "nonimmediate_operand" "0,rm,rm")
+         (match_operand:QI 2 "nonmemory_operand" "c<S>,r,c<S>")))
    (clobber (reg:CC FLAGS_REG))]
-  "ix86_binary_operator_ok (ASHIFTRT, <MODE>mode, operands)"
+  "ix86_binary_operator_ok (ASHIFTRT, <MODE>mode, operands, TARGET_APX_NDD)"
 {
+  bool use_ndd = get_attr_isa (insn) == ISA_APX_NDD;
   switch (get_attr_type (insn))
     {
     case TYPE_ISHIFTX:
 
     default:
       if (operands[2] == const1_rtx
-         && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
+         && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
+         && !use_ndd)
        return "sar{<imodesuffix>}\t%0";
       else
-       return "sar{<imodesuffix>}\t{%2, %0|%0, %2}";
+       return use_ndd ? "sar{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}"
+                      : "sar{<imodesuffix>}\t{%2, %0|%0, %2}";
     }
 }
-  [(set_attr "isa" "*,bmi2")
-   (set_attr "type" "ishift,ishiftx")
+  [(set_attr "isa" "*,bmi2,apx_ndd")
+   (set_attr "type" "ishift,ishiftx,ishift")
    (set (attr "length_immediate")
      (if_then_else
        (and (match_operand 2 "const1_operand")
 ;; Specialization of *lshr<mode>3_1 below, extracting the SImode
 ;; highpart of a DI to be extracted, but allowing it to be clobbered.
 (define_insn_and_split "*highpartdisi2"
-  [(set (subreg:DI (match_operand:SI 0 "register_operand" "=r,x,?k") 0)
-        (lshiftrt:DI (match_operand:DI 1 "register_operand" "0,0,k")
+  [(set (subreg:DI (match_operand:SI 0 "register_operand" "=r,x,?k,r") 0)
+        (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0,k,rm")
                     (const_int 32)))
    (clobber (reg:CC FLAGS_REG))]
   "TARGET_64BIT"
       DONE;
     }
   operands[0] = gen_rtx_REG (DImode, REGNO (operands[0]));
-})
+}
+[(set_attr "isa" "*,*,*,apx_ndd")])
+
 
 (define_insn "*lshr<mode>3_1"
-  [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r,?k")
+  [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r,?k,r")
        (lshiftrt:SWI48
-         (match_operand:SWI48 1 "nonimmediate_operand" "0,rm,k")
-         (match_operand:QI 2 "nonmemory_operand" "c<S>,r,<KS>")))
+         (match_operand:SWI48 1 "nonimmediate_operand" "0,rm,k,rm")
+         (match_operand:QI 2 "nonmemory_operand" "c<S>,r,<KS>,c<S>")))
    (clobber (reg:CC FLAGS_REG))]
-  "ix86_binary_operator_ok (LSHIFTRT, <MODE>mode, operands)"
+  "ix86_binary_operator_ok (LSHIFTRT, <MODE>mode, operands, TARGET_APX_NDD)"
 {
+  bool use_ndd = get_attr_isa (insn) == ISA_APX_NDD;
   switch (get_attr_type (insn))
     {
     case TYPE_ISHIFTX:
 
     default:
       if (operands[2] == const1_rtx
-         && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
+         && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
+         && !use_ndd)
        return "shr{<imodesuffix>}\t%0";
       else
-       return "shr{<imodesuffix>}\t{%2, %0|%0, %2}";
+       return use_ndd ? "shr{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}"
+                      : "shr{<imodesuffix>}\t{%2, %0|%0, %2}";
     }
 }
-  [(set_attr "isa" "*,bmi2,avx512bw")
-   (set_attr "type" "ishift,ishiftx,msklog")
+  [(set_attr "isa" "*,bmi2,avx512bw,apx_ndd")
+   (set_attr "type" "ishift,ishiftx,msklog,ishift")
    (set (attr "length_immediate")
      (if_then_else
        (and (and (match_operand 2 "const1_operand")
    (set_attr "mode" "SI")])
 
 (define_insn "*<insn>si3_1_zext"
-  [(set (match_operand:DI 0 "register_operand" "=r,r")
+  [(set (match_operand:DI 0 "register_operand" "=r,r,r")
        (zero_extend:DI
-         (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,rm")
-                         (match_operand:QI 2 "nonmemory_operand" "cI,r"))))
+         (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,rm,rm")
+                         (match_operand:QI 2 "nonmemory_operand" "cI,r,cI"))))
    (clobber (reg:CC FLAGS_REG))]
-  "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
+  "TARGET_64BIT
+   && ix86_binary_operator_ok (<CODE>, SImode, operands, TARGET_APX_NDD)"
 {
+  bool use_ndd = get_attr_isa (insn) == ISA_APX_NDD;
   switch (get_attr_type (insn))
     {
     case TYPE_ISHIFTX:
 
     default:
       if (operands[2] == const1_rtx
-         && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
+         && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
+         && !use_ndd)
        return "<shift>{l}\t%k0";
       else
-       return "<shift>{l}\t{%2, %k0|%k0, %2}";
+       return use_ndd ? "<shift>{l}\t{%2, %1, %k0|%k0, %1, %2}"
+                      : "<shift>{l}\t{%2, %k0|%k0, %2}";
     }
 }
-  [(set_attr "isa" "*,bmi2")
-   (set_attr "type" "ishift,ishiftx")
+  [(set_attr "isa" "*,bmi2,apx_ndd")
+   (set_attr "type" "ishift,ishiftx,ishift")
    (set (attr "length_immediate")
      (if_then_else
        (and (match_operand 2 "const1_operand")
   "operands[2] = gen_lowpart (SImode, operands[2]);")
 
 (define_insn "*ashr<mode>3_1"
-  [(set (match_operand:SWI12 0 "nonimmediate_operand" "=<r>m")
+  [(set (match_operand:SWI12 0 "nonimmediate_operand" "=<r>m, r")
        (ashiftrt:SWI12
-         (match_operand:SWI12 1 "nonimmediate_operand" "0")
-         (match_operand:QI 2 "nonmemory_operand" "c<S>")))
+         (match_operand:SWI12 1 "nonimmediate_operand" "0, rm")
+         (match_operand:QI 2 "nonmemory_operand" "c<S>, c<S>")))
    (clobber (reg:CC FLAGS_REG))]
-  "ix86_binary_operator_ok (ASHIFTRT, <MODE>mode, operands)"
+  "ix86_binary_operator_ok (ASHIFTRT, <MODE>mode, operands, TARGET_APX_NDD)"
 {
+  bool use_ndd = get_attr_isa (insn) == ISA_APX_NDD;
   if (operands[2] == const1_rtx
-      && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
+      && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
+      && !use_ndd)
     return "sar{<imodesuffix>}\t%0";
   else
-    return "sar{<imodesuffix>}\t{%2, %0|%0, %2}";
+    return use_ndd ? "sar{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}"
+                  : "sar{<imodesuffix>}\t{%2, %0|%0, %2}";
 }
-  [(set_attr "type" "ishift")
+  [(set_attr "isa" "*, apx_ndd")
+   (set_attr "type" "ishift")
    (set (attr "length_immediate")
      (if_then_else
        (and (match_operand 2 "const1_operand")
    (set_attr "mode" "<MODE>")])
 
 (define_insn "*lshrqi3_1"
-  [(set (match_operand:QI 0 "nonimmediate_operand"  "=qm,?k")
+  [(set (match_operand:QI 0 "nonimmediate_operand"  "=qm,?k,r")
        (lshiftrt:QI
-         (match_operand:QI 1 "nonimmediate_operand" "0, k")
-         (match_operand:QI 2 "nonmemory_operand"    "cI,Wb")))
+         (match_operand:QI 1 "nonimmediate_operand" "0, k, rm")
+         (match_operand:QI 2 "nonmemory_operand"    "cI,Wb,cI")))
    (clobber (reg:CC FLAGS_REG))]
-  "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
+  "ix86_binary_operator_ok (LSHIFTRT, QImode, operands, TARGET_APX_NDD)"
 {
+  bool use_ndd = get_attr_isa (insn) == ISA_APX_NDD;
   switch (get_attr_type (insn))
     {
     case TYPE_ISHIFT:
       if (operands[2] == const1_rtx
-         && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
+         && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
+         && !use_ndd)
        return "shr{b}\t%0";
       else
-       return "shr{b}\t{%2, %0|%0, %2}";
+       return use_ndd ? "shr{b}\t{%2, %1, %0|%0, %1, %2}"
+                      : "shr{b}\t{%2, %0|%0, %2}";
     case TYPE_MSKLOG:
       return "#";
     default:
       gcc_unreachable ();
     }
 }
-  [(set_attr "isa" "*,avx512dq")
-   (set_attr "type" "ishift,msklog")
+  [(set_attr "isa" "*,avx512dq,apx_ndd")
+   (set_attr "type" "ishift,msklog,ishift")
    (set (attr "length_immediate")
      (if_then_else
        (and (and (match_operand 2 "const1_operand")
    (set_attr "mode" "QI")])
 
 (define_insn "*lshrhi3_1"
-  [(set (match_operand:HI 0 "nonimmediate_operand" "=rm, ?k")
+  [(set (match_operand:HI 0 "nonimmediate_operand" "=rm, ?k, r")
        (lshiftrt:HI
-         (match_operand:HI 1 "nonimmediate_operand" "0, k")
-         (match_operand:QI 2 "nonmemory_operand" "cI, Ww")))
+         (match_operand:HI 1 "nonimmediate_operand" "0, k, rm")
+         (match_operand:QI 2 "nonmemory_operand" "cI, Ww, cI")))
    (clobber (reg:CC FLAGS_REG))]
-  "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
+  "ix86_binary_operator_ok (LSHIFTRT, HImode, operands, TARGET_APX_NDD)"
 {
+  bool use_ndd = get_attr_isa (insn) == ISA_APX_NDD;
   switch (get_attr_type (insn))
     {
     case TYPE_ISHIFT:
       if (operands[2] == const1_rtx
-         && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
+         && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
+         && !use_ndd)
        return "shr{w}\t%0";
       else
-       return "shr{w}\t{%2, %0|%0, %2}";
+       return use_ndd ? "shr{w}\t{%2, %1, %0|%0, %1, %2}"
+                      : "shr{w}\t{%2, %0|%0, %2}";
     case TYPE_MSKLOG:
       return "#";
     default:
       gcc_unreachable ();
     }
 }
-  [(set_attr "isa" "*, avx512f")
-   (set_attr "type" "ishift,msklog")
+  [(set_attr "isa" "*, avx512f, apx_ndd")
+   (set_attr "type" "ishift,msklog,ishift")
    (set (attr "length_immediate")
      (if_then_else
        (and (and (match_operand 2 "const1_operand")
   else
     return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
 }
-  "&& reload_completed"
+  "&& reload_completed
+   && !(rtx_equal_p (operands[0], operands[1]))"
   [(set (strict_low_part (match_dup 0)) (match_dup 1))
    (parallel
      [(set (strict_low_part (match_dup 0))
   [(set (reg FLAGS_REG)
        (compare
          (any_shiftrt:SWI
-           (match_operand:SWI 1 "nonimmediate_operand" "0")
-           (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
+           (match_operand:SWI 1 "nonimmediate_operand" "0,rm")
+           (match_operand:QI 2 "<shift_immediate_operand>" "<S>,<S>"))
          (const_int 0)))
-   (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
+   (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,r")
        (any_shiftrt:SWI (match_dup 1) (match_dup 2)))]
   "(optimize_function_for_size_p (cfun)
     || !TARGET_PARTIAL_FLAG_REG_STALL
     || (operands[2] == const1_rtx
        && TARGET_SHIFT1))
    && ix86_match_ccmode (insn, CCGOCmode)
-   && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
+   && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands, TARGET_APX_NDD)"
 {
+  bool use_ndd = get_attr_isa (insn) == ISA_APX_NDD;
   if (operands[2] == const1_rtx
-      && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
+      && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
+      && !use_ndd)
     return "<shift>{<imodesuffix>}\t%0";
   else
-    return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
+    return use_ndd ? "<shift>{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}"
+                  : "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
 }
-  [(set_attr "type" "ishift")
+  [(set_attr "isa" "*,apx_ndd")
+   (set_attr "type" "ishift")
    (set (attr "length_immediate")
      (if_then_else
        (and (match_operand 2 "const1_operand")
 (define_insn "*<insn>si3_cmp_zext"
   [(set (reg FLAGS_REG)
        (compare
-         (any_shiftrt:SI (match_operand:SI 1 "register_operand" "0")
+         (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,rm")
                          (match_operand:QI 2 "const_1_to_31_operand"))
          (const_int 0)))
-   (set (match_operand:DI 0 "register_operand" "=r")
+   (set (match_operand:DI 0 "register_operand" "=r,r")
        (zero_extend:DI (any_shiftrt:SI (match_dup 1) (match_dup 2))))]
   "TARGET_64BIT
    && (optimize_function_for_size_p (cfun)
        || (operands[2] == const1_rtx
           && TARGET_SHIFT1))
    && ix86_match_ccmode (insn, CCGOCmode)
-   && ix86_binary_operator_ok (<CODE>, SImode, operands)"
+   && ix86_binary_operator_ok (<CODE>, SImode, operands, TARGET_APX_NDD)"
 {
+  bool use_ndd = get_attr_isa (insn) == ISA_APX_NDD;
   if (operands[2] == const1_rtx
-      && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
+      && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
+      && !use_ndd)
     return "<shift>{l}\t%k0";
   else
-    return "<shift>{l}\t{%2, %k0|%k0, %2}";
+    return use_ndd ? "<shift>{l}\t{%2, %1, %k0|%k0, %1, %2}"
+                  : "<shift>{l}\t{%2, %k0|%k0, %2}";
 }
-  [(set_attr "type" "ishift")
+  [(set_attr "isa" "*,apx_ndd")
+   (set_attr "type" "ishift")
    (set (attr "length_immediate")
      (if_then_else
        (and (match_operand 2 "const1_operand")
   [(set (reg FLAGS_REG)
        (compare
          (any_shiftrt:SWI
-           (match_operand:SWI 1 "register_operand" "0")
-           (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
+           (match_operand:SWI 1 "nonimmediate_operand" "0,rm")
+           (match_operand:QI 2 "<shift_immediate_operand>" "<S>,<S>"))
          (const_int 0)))
-   (clobber (match_scratch:SWI 0 "=<r>"))]
+   (clobber (match_scratch:SWI 0 "=<r>,r"))]
   "(optimize_function_for_size_p (cfun)
     || !TARGET_PARTIAL_FLAG_REG_STALL
     || (operands[2] == const1_rtx
        && TARGET_SHIFT1))
    && ix86_match_ccmode (insn, CCGOCmode)"
 {
+  bool use_ndd = get_attr_isa (insn) == ISA_APX_NDD;
   if (operands[2] == const1_rtx
-      && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
+      && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
+      && !use_ndd)
     return "<shift>{<imodesuffix>}\t%0";
   else
-    return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
+    return use_ndd
+          ? "<shift>{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}"
+          : "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
 }
-  [(set_attr "type" "ishift")
+  [(set_attr "isa" "*,apx_ndd")
+   (set_attr "type" "ishift")
    (set (attr "length_immediate")
      (if_then_else
        (and (match_operand 2 "const1_operand")
        (const_string "*")))
    (set_attr "mode" "<MODE>")])
 
-(define_insn "*<insn>qi_ext<mode>_2"
+;; Alternative 1 is needed to work around LRA limitation, see PR82524.
+(define_insn_and_split "*<insn>qi_ext<mode>_1"
   [(set (zero_extract:SWI248
-         (match_operand 0 "int248_register_operand" "+Q")
+         (match_operand 0 "int248_register_operand" "+Q,&Q")
          (const_int 8)
          (const_int 8))
        (subreg:SWI248
          (any_shiftrt:QI
            (subreg:QI
              (match_operator:SWI248 3 "extract_operator"
-               [(match_operand 1 "int248_register_operand" "0")
+               [(match_operand 1 "int248_register_operand" "0,!Q")
                 (const_int 8)
                 (const_int 8)]) 0)
-           (match_operand:QI 2 "nonmemory_operand" "cI")) 0))
-  (clobber (reg:CC FLAGS_REG))]
-  "/* FIXME: without this LRA can't reload this pattern, see PR82524.  */
-   rtx_equal_p (operands[0], operands[1])"
+           (match_operand:QI 2 "nonmemory_operand" "cI,cI")) 0))
+   (clobber (reg:CC FLAGS_REG))]
+  ""
 {
+  if (which_alternative)
+    return "#";
+
   if (operands[2] == const1_rtx
       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
     return "<shift>{b}\t%h0";
   else
     return "<shift>{b}\t{%2, %h0|%h0, %2}";
 }
+  "reload_completed
+   && !(rtx_equal_p (operands[0], operands[1]))"
+  [(set (zero_extract:SWI248
+         (match_dup 0) (const_int 8) (const_int 8))
+       (zero_extract:SWI248
+         (match_dup 1) (const_int 8) (const_int 8)))
+   (parallel
+     [(set (zero_extract:SWI248
+            (match_dup 0) (const_int 8) (const_int 8))
+          (subreg:SWI248
+            (any_shiftrt:QI
+              (subreg:QI
+                (match_op_dup 3
+                  [(match_dup 0) (const_int 8) (const_int 8)]) 0)
+              (match_dup 2)) 0))
+      (clobber (reg:CC FLAGS_REG))])]
+  ""
   [(set_attr "type" "ishift")
    (set (attr "length_immediate")
      (if_then_else
        (const_string "0")
        (const_string "*")))
    (set_attr "mode" "QI")])
+
+(define_insn_and_split "*extend<dwi>2_doubleword_highpart"
+  [(set (match_operand:<DWI> 0 "register_operand" "=r")
+       (ashiftrt:<DWI>
+         (ashift:<DWI> (match_operand:<DWI> 1 "nonimmediate_operand" "0")
+                       (match_operand:QI 2 "const_int_operand"))
+         (match_operand:QI 3 "const_int_operand")))
+   (clobber (reg:CC FLAGS_REG))]
+  "INTVAL (operands[2]) == INTVAL (operands[3])
+   && UINTVAL (operands[2]) < <MODE_SIZE> * BITS_PER_UNIT"
+  "#"
+  "&& reload_completed"
+  [(parallel [(set (match_dup 4)
+                  (ashift:DWIH (match_dup 4) (match_dup 2)))
+             (clobber (reg:CC FLAGS_REG))])
+   (parallel [(set (match_dup 4)
+                  (ashiftrt:DWIH (match_dup 4) (match_dup 2)))
+             (clobber (reg:CC FLAGS_REG))])]
+  "split_double_mode (<DWI>mode, &operands[0], 1, &operands[0], &operands[4]);")
+
+(define_insn_and_split "*extendv2di2_highpart_stv"
+  [(set (match_operand:V2DI 0 "register_operand" "=v")
+       (ashiftrt:V2DI
+         (ashift:V2DI (match_operand:V2DI 1 "nonimmediate_operand" "vm")
+                      (match_operand:QI 2 "const_int_operand"))
+         (match_operand:QI 3 "const_int_operand")))]
+  "!TARGET_64BIT && TARGET_STV && TARGET_AVX512VL
+   && INTVAL (operands[2]) == INTVAL (operands[3])
+   && UINTVAL (operands[2]) < 32"
+  "#"
+  "&& reload_completed"
+  [(set (match_dup 0)
+       (ashift:V2DI (match_dup 1) (match_dup 2)))
+   (set (match_dup 0)
+       (ashiftrt:V2DI (match_dup 0) (match_dup 2)))])
 \f
 ;; Rotate instructions
 
     emit_insn (gen_ix86_<insn>ti3_doubleword
                (operands[0], operands[1], operands[2]));
   else if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) == 64)
-    emit_insn (gen_<insn>64ti2_doubleword (operands[0], operands[1]));
+    {
+      operands[1] = force_reg (TImode, operands[1]);
+      emit_insn (gen_<insn>64ti2_doubleword (operands[0], operands[1]));
+    }
   else
     {
       rtx amount = force_reg (QImode, operands[2]);
  ""
 {
   if (TARGET_64BIT)
-    ix86_expand_binary_operator (<CODE>, DImode, operands);
+    ix86_expand_binary_operator (<CODE>, DImode, operands, TARGET_APX_NDD);
   else if (const_1_to_31_operand (operands[2], VOIDmode))
     emit_insn (gen_ix86_<insn>di3_doubleword
                (operands[0], operands[1], operands[2]));
   else if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) == 32)
-    emit_insn (gen_<insn>32di2_doubleword (operands[0], operands[1]));
+    {
+      operands[1] = force_reg (DImode, operands[1]);
+      emit_insn (gen_<insn>32di2_doubleword (operands[0], operands[1]));
+    }
   else
     FAIL;
 
        (any_rotate:SWIM124 (match_operand:SWIM124 1 "nonimmediate_operand")
                            (match_operand:QI 2 "nonmemory_operand")))]
   ""
-  "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
+{
+  ix86_expand_binary_operator (<CODE>, <MODE>mode, operands, TARGET_APX_NDD);
+  DONE;
+})
 
 ;; Avoid useless masking of count operand.
 (define_insn_and_split "*<insn><mode>3_mask"
 })
 
 (define_insn_and_split "<insn>32di2_doubleword"
- [(set (match_operand:DI 0 "register_operand" "=r,r,r")
-       (any_rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0,r,o")
+ [(set (match_operand:DI 0 "register_operand" "=r,r")
+       (any_rotate:DI (match_operand:DI 1 "register_operand" "0,r")
                       (const_int 32)))]
  "!TARGET_64BIT"
  "#"
 })
 
 (define_insn_and_split "<insn>64ti2_doubleword"
- [(set (match_operand:TI 0 "register_operand" "=r,r,r")
-       (any_rotate:TI (match_operand:TI 1 "nonimmediate_operand" "0,r,o")
+ [(set (match_operand:TI 0 "register_operand" "=r,r")
+       (any_rotate:TI (match_operand:TI 1 "register_operand" "0,r")
                       (const_int 64)))]
  "TARGET_64BIT"
  "#"
    (set_attr "mode" "<MODE>")])
 
 (define_insn "*<insn><mode>3_1"
-  [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
+  [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r,r")
        (any_rotate:SWI48
-         (match_operand:SWI48 1 "nonimmediate_operand" "0,rm")
-         (match_operand:QI 2 "nonmemory_operand" "c<S>,<S>")))
+         (match_operand:SWI48 1 "nonimmediate_operand" "0,rm,rm")
+         (match_operand:QI 2 "nonmemory_operand" "c<S>,<S>,c<S>")))
    (clobber (reg:CC FLAGS_REG))]
-  "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
+  "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands, TARGET_APX_NDD)"
 {
+  bool use_ndd = get_attr_isa (insn) == ISA_APX_NDD;
   switch (get_attr_type (insn))
     {
     case TYPE_ROTATEX:
 
     default:
       if (operands[2] == const1_rtx
-         && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
+         && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
+         && !use_ndd)
        return "<rotate>{<imodesuffix>}\t%0";
       else
-       return "<rotate>{<imodesuffix>}\t{%2, %0|%0, %2}";
+       return use_ndd ? "<rotate>{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}"
+                      : "<rotate>{<imodesuffix>}\t{%2, %0|%0, %2}";
     }
 }
-  [(set_attr "isa" "*,bmi2")
-   (set_attr "type" "rotate,rotatex")
+  [(set_attr "isa" "*,bmi2,apx_ndd")
+   (set_attr "type" "rotate,rotatex,rotate")
    (set (attr "preferred_for_size")
      (cond [(eq_attr "alternative" "0")
              (symbol_ref "true")]
    (set_attr "mode" "SI")])
 
 (define_insn "*<insn>si3_1_zext"
-  [(set (match_operand:DI 0 "register_operand" "=r,r")
+  [(set (match_operand:DI 0 "register_operand" "=r,r,r")
        (zero_extend:DI
-         (any_rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,rm")
-                        (match_operand:QI 2 "nonmemory_operand" "cI,I"))))
+         (any_rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,rm,rm")
+                        (match_operand:QI 2 "nonmemory_operand" "cI,I,cI"))))
    (clobber (reg:CC FLAGS_REG))]
   "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
 {
+  bool use_ndd = get_attr_isa (insn) == ISA_APX_NDD;
   switch (get_attr_type (insn))
     {
     case TYPE_ROTATEX:
 
     default:
       if (operands[2] == const1_rtx
-         && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
+         && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
+         && !use_ndd)
        return "<rotate>{l}\t%k0";
       else
-       return "<rotate>{l}\t{%2, %k0|%k0, %2}";
+       return use_ndd ? "<rotate>{l}\t{%2, %1, %k0|%k0, %1, %2}"
+                      : "<rotate>{l}\t{%2, %k0|%k0, %2}";
     }
 }
-  [(set_attr "isa" "*,bmi2")
-   (set_attr "type" "rotate,rotatex")
+  [(set_attr "isa" "*,bmi2,apx_ndd")
+   (set_attr "type" "rotate,rotatex,rotate")
    (set (attr "preferred_for_size")
      (cond [(eq_attr "alternative" "0")
              (symbol_ref "true")]
        (zero_extend:DI (rotatert:SI (match_dup 1) (match_dup 2))))])
 
 (define_insn "*<insn><mode>3_1"
-  [(set (match_operand:SWI12 0 "nonimmediate_operand" "=<r>m")
-       (any_rotate:SWI12 (match_operand:SWI12 1 "nonimmediate_operand" "0")
-                         (match_operand:QI 2 "nonmemory_operand" "c<S>")))
+  [(set (match_operand:SWI12 0 "nonimmediate_operand" "=<r>m,r")
+       (any_rotate:SWI12 (match_operand:SWI12 1 "nonimmediate_operand" "0,rm")
+                         (match_operand:QI 2 "nonmemory_operand" "c<S>,c<S>")))
    (clobber (reg:CC FLAGS_REG))]
-  "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
+  "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands, TARGET_APX_NDD)"
 {
+  bool use_ndd = get_attr_isa (insn) == ISA_APX_NDD;
   if (operands[2] == const1_rtx
-      && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
+      && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
+      && !use_ndd)
     return "<rotate>{<imodesuffix>}\t%0";
   else
-    return "<rotate>{<imodesuffix>}\t{%2, %0|%0, %2}";
+    return use_ndd
+          ? "<rotate>{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}"
+          : "<rotate>{<imodesuffix>}\t{%2, %0|%0, %2}";
 }
-  [(set_attr "type" "rotate")
+  [(set_attr "isa" "*,apx_ndd")
+   (set_attr "type" "rotate")
    (set (attr "length_immediate")
      (if_then_else
        (and (match_operand 2 "const1_operand")
   else
     return "<rotate>{<imodesuffix>}\t{%2, %0|%0, %2}";
 }
-  "&& reload_completed"
+  "&& reload_completed
+   && !(rtx_equal_p (operands[0], operands[1]))"
   [(set (strict_low_part (match_dup 0)) (match_dup 1))
    (parallel
      [(set (strict_low_part (match_dup 0))
  [(parallel [(set (strict_low_part (match_dup 0))
                  (bswap:HI (match_dup 0)))
             (clobber (reg:CC FLAGS_REG))])])
+
+;; Rotations through carry flag
+(define_insn "rcrsi2"
+  [(set (match_operand:SI 0 "register_operand" "=r,r")
+       (plus:SI
+         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,rm")
+                      (const_int 1))
+         (ashift:SI (ltu:SI (reg:CCC FLAGS_REG) (const_int 0))
+                    (const_int 31))))
+   (clobber (reg:CC FLAGS_REG))]
+  ""
+  "@
+   rcr{l}\t%0
+   rcr{l}\t{%1, %0|%0, %1}"
+  [(set_attr "isa" "*,apx_ndd")
+   (set_attr "type" "ishift1")
+   (set_attr "memory" "none")
+   (set_attr "length_immediate" "0")
+   (set_attr "mode" "SI")])
+
+(define_insn "rcrdi2"
+  [(set (match_operand:DI 0 "register_operand" "=r,r")
+       (plus:DI
+         (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,rm")
+                      (const_int 1))
+         (ashift:DI (ltu:DI (reg:CCC FLAGS_REG) (const_int 0))
+                    (const_int 63))))
+   (clobber (reg:CC FLAGS_REG))]
+  "TARGET_64BIT"
+  "@
+   rcr{q}\t%0
+   rcr{q}\t{%1, %0|%0, %1}"
+  [(set_attr "isa" "*,apx_ndd")
+   (set_attr "type" "ishift1")
+   (set_attr "length_immediate" "0")
+   (set_attr "mode" "DI")])
+
+;; Versions of sar and shr that set the carry flag.
+(define_insn "<insn><mode>3_carry"
+  [(set (reg:CCC FLAGS_REG)
+       (unspec:CCC [(and:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,rm")
+                               (const_int 1))
+                    (const_int 0)] UNSPEC_CC_NE))
+   (set (match_operand:SWI48 0 "register_operand" "=r,r")
+       (any_shiftrt:SWI48 (match_dup 1) (const_int 1)))]
+  ""
+{
+  bool use_ndd = get_attr_isa (insn) == ISA_APX_NDD;
+  if ((TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
+      && !use_ndd)
+    return "<shift>{<imodesuffix>}\t%0";
+  return use_ndd ? "<shift>{<imodesuffix>}\t{$1, %1, %0|%0, %1, 1}"
+                : "<shift>{<imodesuffix>}\t{$1, %0|%0, 1}";
+}
+  [(set_attr "isa" "*, apx_ndd")
+   (set_attr "type" "ishift1")
+   (set (attr "length_immediate")
+     (if_then_else
+       (ior (match_test "TARGET_SHIFT1")
+           (match_test "optimize_function_for_size_p (cfun)"))
+       (const_string "0")
+       (const_string "*")))
+   (set_attr "mode" "<MODE>")])
 \f
 ;; Bit set / bit test instructions
 
   [(set (zero_extract:HI
          (match_operand:SWI12 0 "nonimmediate_operand")
          (const_int 1)
-         (zero_extend:SI (match_operand:QI 1 "register_operand")))
+         (match_operand:QI 1 "register_operand"))
        (const_int 0))
    (clobber (reg:CC FLAGS_REG))]
   "TARGET_USE_BT && ix86_pre_reload_split ()"
   [(set (zero_extract:HI
          (match_operand:SWI12 0 "register_operand")
          (const_int 1)
-         (zero_extend:SI (match_operand:QI 1 "register_operand")))
+         (match_operand:QI 1 "register_operand"))
        (const_int 0))
    (clobber (reg:CC FLAGS_REG))]
   "TARGET_USE_BT && ix86_pre_reload_split ()"
 (define_insn "*btsq_imm"
   [(set (zero_extract:DI (match_operand:DI 0 "nonimmediate_operand" "+rm")
                         (const_int 1)
-                        (match_operand 1 "const_0_to_63_operand"))
+                        (match_operand:QI 1 "const_0_to_63_operand"))
        (const_int 1))
    (clobber (reg:CC FLAGS_REG))]
   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
 (define_insn "*btrq_imm"
   [(set (zero_extract:DI (match_operand:DI 0 "nonimmediate_operand" "+rm")
                         (const_int 1)
-                        (match_operand 1 "const_0_to_63_operand"))
+                        (match_operand:QI 1 "const_0_to_63_operand"))
        (const_int 0))
    (clobber (reg:CC FLAGS_REG))]
   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
 (define_insn "*btcq_imm"
   [(set (zero_extract:DI (match_operand:DI 0 "nonimmediate_operand" "+rm")
                         (const_int 1)
-                        (match_operand 1 "const_0_to_63_operand"))
+                        (match_operand:QI 1 "const_0_to_63_operand"))
        (not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1))))
    (clobber (reg:CC FLAGS_REG))]
   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
    (parallel [(set (zero_extract:DI
                     (match_operand:DI 0 "nonimmediate_operand")
                     (const_int 1)
-                    (match_operand 1 "const_0_to_63_operand"))
+                    (match_operand:QI 1 "const_0_to_63_operand"))
                   (const_int 1))
              (clobber (reg:CC FLAGS_REG))])]
   "TARGET_64BIT && !TARGET_USE_BT"
    (parallel [(set (zero_extract:DI
                     (match_operand:DI 0 "nonimmediate_operand")
                     (const_int 1)
-                    (match_operand 1 "const_0_to_63_operand"))
+                    (match_operand:QI 1 "const_0_to_63_operand"))
                   (const_int 0))
              (clobber (reg:CC FLAGS_REG))])]
   "TARGET_64BIT && !TARGET_USE_BT"
    (parallel [(set (zero_extract:DI
                     (match_operand:DI 0 "nonimmediate_operand")
                     (const_int 1)
-                    (match_operand 1 "const_0_to_63_operand"))
+                    (match_operand:QI 1 "const_0_to_63_operand"))
              (not:DI (zero_extract:DI
                        (match_dup 0) (const_int 1) (match_dup 1))))
              (clobber (reg:CC FLAGS_REG))])]
          (zero_extract:SWI48
            (match_operand:SWI48 0 "nonimmediate_operand" "r,m")
            (const_int 1)
-           (match_operand:SI 1 "nonmemory_operand" "r<S>,<S>"))
+           (match_operand:QI 1 "nonmemory_operand" "q<S>,<S>"))
          (const_int 0)))]
   ""
 {
   switch (get_attr_mode (insn))
     {
     case MODE_SI:
-      return "bt{l}\t{%1, %k0|%k0, %1}";
+      return "bt{l}\t{%k1, %k0|%k0, %k1}";
 
     case MODE_DI:
       return "bt{q}\t{%q1, %0|%0, %q1}";
          (const_string "SI")
          (const_string "<MODE>")))])
 
+(define_insn_and_split "*bt<SWI48:mode>_mask"
+  [(set (reg:CCC FLAGS_REG)
+        (compare:CCC
+          (zero_extract:SWI48
+            (match_operand:SWI48 0 "nonimmediate_operand" "r,m")
+            (const_int 1)
+           (subreg:QI
+             (and:SWI248
+               (match_operand:SWI248 1 "register_operand")
+               (match_operand 2 "const_int_operand")) 0))
+          (const_int 0)))]
+  "TARGET_USE_BT
+   && (INTVAL (operands[2]) & (GET_MODE_BITSIZE (<SWI48:MODE>mode)-1))
+      == GET_MODE_BITSIZE (<SWI48:MODE>mode)-1
+   && ix86_pre_reload_split ()"
+  "#"
+  "&& 1"
+  [(set (reg:CCC FLAGS_REG)
+        (compare:CCC
+         (zero_extract:SWI48 (match_dup 0) (const_int 1) (match_dup 1))
+         (const_int 0)))]
+  "operands[1] = gen_lowpart (QImode, operands[1]);")
+
 (define_insn_and_split "*jcc_bt<mode>"
   [(set (pc)
        (if_then_else (match_operator 0 "bt_comparison_operator"
                        [(zero_extract:SWI48
                           (match_operand:SWI48 1 "nonimmediate_operand")
                           (const_int 1)
-                          (match_operand:SI 2 "nonmemory_operand"))
+                          (match_operand:QI 2 "nonmemory_operand"))
                         (const_int 0)])
                      (label_ref (match_operand 3))
                      (pc)))
   PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
 })
 
-(define_insn_and_split "*jcc_bt<mode>_1"
-  [(set (pc)
-       (if_then_else (match_operator 0 "bt_comparison_operator"
-                       [(zero_extract:SWI48
-                          (match_operand:SWI48 1 "register_operand")
-                          (const_int 1)
-                          (zero_extend:SI
-                            (match_operand:QI 2 "register_operand")))
-                        (const_int 0)])
-                     (label_ref (match_operand 3))
-                     (pc)))
-   (clobber (reg:CC FLAGS_REG))]
-  "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
-   && ix86_pre_reload_split ()"
-  "#"
-  "&& 1"
-  [(set (reg:CCC FLAGS_REG)
-       (compare:CCC
-         (zero_extract:SWI48
-           (match_dup 1)
-           (const_int 1)
-           (match_dup 2))
-         (const_int 0)))
-   (set (pc)
-       (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
-                     (label_ref (match_dup 3))
-                     (pc)))]
-{
-  operands[2] = lowpart_subreg (SImode, operands[2], QImode);
-  operands[0] = shallow_copy_rtx (operands[0]);
-  PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
-})
-
 ;; Avoid useless masking of bit offset operand.
 (define_insn_and_split "*jcc_bt<mode>_mask"
   [(set (pc)
                        [(zero_extract:SWI48
                           (match_operand:SWI48 1 "register_operand")
                           (const_int 1)
-                          (and:SI
-                            (match_operand:SI 2 "register_operand")
-                            (match_operand 3 "const_int_operand")))])
+                          (and:QI
+                            (match_operand:QI 2 "register_operand")
+                            (match_operand 3 "const_int_operand")))
+                        (const_int 0)])
                      (label_ref (match_operand 4))
                      (pc)))
    (clobber (reg:CC FLAGS_REG))]
   PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
 })
 
-(define_insn_and_split "*jcc_bt<mode>_mask_1"
+;; Avoid useless masking of bit offset operand.
+(define_insn_and_split "*jcc_bt<SWI48:mode>_mask_1"
   [(set (pc)
-       (if_then_else (match_operator 0 "bt_comparison_operator"
+       (if_then_else (match_operator 0 "bt_comparison_operator"
                        [(zero_extract:SWI48
                           (match_operand:SWI48 1 "register_operand")
                           (const_int 1)
-                          (zero_extend:SI
-                            (subreg:QI
-                              (and
-                                (match_operand 2 "int248_register_operand")
-                                (match_operand 3 "const_int_operand")) 0)))])
+                          (subreg:QI
+                            (and:SWI248
+                              (match_operand:SWI248 2 "register_operand")
+                              (match_operand 3 "const_int_operand")) 0))
+                        (const_int 0)])
                      (label_ref (match_operand 4))
                      (pc)))
    (clobber (reg:CC FLAGS_REG))]
   "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
-   && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
-      == GET_MODE_BITSIZE (<MODE>mode)-1
+   && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<SWI48:MODE>mode)-1))
+      == GET_MODE_BITSIZE (<SWI48:MODE>mode)-1
    && ix86_pre_reload_split ()"
   "#"
   "&& 1"
                      (label_ref (match_dup 4))
                      (pc)))]
 {
-  operands[2] = force_reg (GET_MODE (operands[2]), operands[2]);
-  operands[2] = gen_lowpart (SImode, operands[2]);
   operands[0] = shallow_copy_rtx (operands[0]);
   PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
+  operands[2] = gen_lowpart (QImode, operands[2]);
 })
 
 ;; Help combine recognize bt followed by cmov
          [(zero_extract:SWI48
            (match_operand:SWI48 1 "register_operand")
            (const_int 1)
-           (zero_extend:SI (match_operand:QI 2 "register_operand")))
+           (match_operand:QI 2 "register_operand"))
           (const_int 0)])
         (match_operand:SWI248 3 "nonimmediate_operand")
         (match_operand:SWI248 4 "nonimmediate_operand")))]
 {
   if (GET_CODE (operands[5]) == EQ)
     std::swap (operands[3], operands[4]);
-  operands[2] = lowpart_subreg (SImode, operands[2], QImode);
 })
 
 ;; Help combine recognize bt followed by setc
         (zero_extract:SWI48
          (match_operand:SWI48 1 "register_operand")
          (const_int 1)
-         (zero_extend:SI (match_operand:QI 2 "register_operand"))))
+         (match_operand:QI 2 "register_operand")))
    (clobber (reg:CC FLAGS_REG))]
   "TARGET_USE_BT && ix86_pre_reload_split ()"
   "#"
          (zero_extract:SWI48 (match_dup 1) (const_int 1) (match_dup 2))
          (const_int 0)))
    (set (match_dup 0)
-        (eq:QI (reg:CCC FLAGS_REG) (const_int 0)))]
-{
-  operands[2] = lowpart_subreg (SImode, operands[2], QImode);
-})
+        (eq:QI (reg:CCC FLAGS_REG) (const_int 0)))])
+
+;; Help combine recognize bt followed by setnc
+(define_insn_and_split "*bt<mode>_setncqi"
+  [(set (match_operand:QI 0 "register_operand")
+       (and:QI
+        (not:QI
+         (subreg:QI
+          (lshiftrt:SWI48 (match_operand:SWI48 1 "register_operand")
+                          (match_operand:QI 2 "register_operand")) 0))
+        (const_int 1)))
+   (clobber (reg:CC FLAGS_REG))]
+  "TARGET_USE_BT && ix86_pre_reload_split ()"
+  "#"
+  "&& 1"
+  [(set (reg:CCC FLAGS_REG)
+        (compare:CCC
+         (zero_extract:SWI48 (match_dup 1) (const_int 1) (match_dup 2))
+         (const_int 0)))
+   (set (match_dup 0)
+        (ne:QI (reg:CCC FLAGS_REG) (const_int 0)))])
+
+(define_insn_and_split "*bt<mode>_setnc<mode>"
+  [(set (match_operand:SWI48 0 "register_operand")
+       (and:SWI48
+        (not:SWI48
+         (lshiftrt:SWI48 (match_operand:SWI48 1 "register_operand")
+                         (match_operand:QI 2 "register_operand")))
+        (const_int 1)))
+   (clobber (reg:CC FLAGS_REG))]
+  "TARGET_USE_BT && ix86_pre_reload_split ()"
+  "#"
+  "&& 1"
+  [(set (reg:CCC FLAGS_REG)
+        (compare:CCC
+         (zero_extract:SWI48 (match_dup 1) (const_int 1) (match_dup 2))
+         (const_int 0)))
+   (set (match_dup 3)
+        (ne:QI (reg:CCC FLAGS_REG) (const_int 0)))
+   (set (match_dup 0) (zero_extend:SWI48 (match_dup 3)))]
+  "operands[3] = gen_reg_rtx (QImode);")
 
-;; Help combine recognize bt followed by setnc
-(define_insn_and_split "*bt<mode>_setncqi"
+;; Help combine recognize bt followed by setnc (PR target/110588)
+(define_insn_and_split "*bt<mode>_setncqi_2"
   [(set (match_operand:QI 0 "register_operand")
-       (and:QI
-        (not:QI
-         (subreg:QI
-          (lshiftrt:SWI48 (match_operand:SWI48 1 "register_operand")
-                          (match_operand:QI 2 "register_operand")) 0))
-        (const_int 1)))
+       (eq:QI
+         (zero_extract:SWI48
+           (match_operand:SWI48 1 "register_operand")
+           (const_int 1)
+           (match_operand:QI 2 "register_operand"))
+         (const_int 0)))
    (clobber (reg:CC FLAGS_REG))]
   "TARGET_USE_BT && ix86_pre_reload_split ()"
   "#"
          (zero_extract:SWI48 (match_dup 1) (const_int 1) (match_dup 2))
          (const_int 0)))
    (set (match_dup 0)
-        (ne:QI (reg:CCC FLAGS_REG) (const_int 0)))]
-{
-  operands[2] = lowpart_subreg (SImode, operands[2], QImode);
-})
+        (ne:QI (reg:CCC FLAGS_REG) (const_int 0)))])
 
-(define_insn_and_split "*bt<mode>_setnc<mode>"
+;; Help combine recognize bt followed by setc
+(define_insn_and_split "*bt<mode>_setc<mode>_mask"
   [(set (match_operand:SWI48 0 "register_operand")
-       (and:SWI48
-        (not:SWI48
-         (lshiftrt:SWI48 (match_operand:SWI48 1 "register_operand")
-                         (match_operand:QI 2 "register_operand")))
-        (const_int 1)))
+       (zero_extract:SWI48
+         (match_operand:SWI48 1 "register_operand")
+         (const_int 1)
+         (subreg:QI
+           (and:SWI48
+             (match_operand:SWI48 2 "register_operand")
+             (match_operand 3 "const_int_operand")) 0)))
    (clobber (reg:CC FLAGS_REG))]
-  "TARGET_USE_BT && ix86_pre_reload_split ()"
+  "TARGET_USE_BT
+   && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
+      == GET_MODE_BITSIZE (<MODE>mode)-1
+   && ix86_pre_reload_split ()"
   "#"
   "&& 1"
   [(set (reg:CCC FLAGS_REG)
          (zero_extract:SWI48 (match_dup 1) (const_int 1) (match_dup 2))
          (const_int 0)))
    (set (match_dup 3)
-        (ne:QI (reg:CCC FLAGS_REG) (const_int 0)))
+        (eq:QI (reg:CCC FLAGS_REG) (const_int 0)))
    (set (match_dup 0) (zero_extend:SWI48 (match_dup 3)))]
 {
-  operands[2] = lowpart_subreg (SImode, operands[2], QImode);
+  operands[2] = gen_lowpart (QImode, operands[2]);
   operands[3] = gen_reg_rtx (QImode);
 })
 \f
     FAIL;
 })
 
+;; Eliminate redundant compare between set{z,nz} and j{z,nz}:
+;; setz %al; test %al,%al; jz <...> -> setz %al; jnz <...> and
+;; setnz %al, test %al,%al; jz <...> -> setnz %al; jz <...>.
+(define_peephole2
+  [(set (match_operand:QI 0 "nonimmediate_operand")
+       (match_operator:QI 1 "bt_comparison_operator"
+         [(reg:CCZ FLAGS_REG) (const_int 0)]))
+   (set (reg:CCZ FLAGS_REG)
+       (compare:CCZ (match_dup 0) (const_int 0)))
+   (set (pc)
+       (if_then_else (match_operator 2 "bt_comparison_operator"
+                       [(reg:CCZ FLAGS_REG) (const_int 0)])
+                     (match_operand 3)
+                     (pc)))]
+  "peep2_regno_dead_p (3, FLAGS_REG)"
+  [(set (match_dup 0)
+       (match_op_dup 1 [(reg:CCZ FLAGS_REG) (const_int 0)]))
+   (set (pc)
+       (if_then_else (match_dup 2)
+                     (match_dup 3)
+                     (pc)))]
+{
+  if (GET_CODE (operands[1]) == EQ)
+    {
+      operands[2] = shallow_copy_rtx (operands[2]);
+      PUT_CODE (operands[2], reverse_condition (GET_CODE (operands[2])));
+    }
+})
+
 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
 ;; subsequent logical operations are used to imitate conditional moves.
 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
   [(set (match_operand:MODEF 0 "register_operand" "=x,x")
        (match_operator:MODEF 3 "sse_comparison_operator"
          [(match_operand:MODEF 1 "register_operand" "0,x")
-          (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]))]
+          (match_operand:MODEF 2 "nonimmediate_operand" "xm,xjm")]))]
   "SSE_FLOAT_MODE_P (<MODE>mode)"
   "@
    cmp%D3<ssemodesuffix>\t{%2, %0|%0, %2}
    vcmp%D3<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
   [(set_attr "isa" "noavx,avx")
+   (set_attr "addr" "*,gpr16")
    (set_attr "type" "ssecmp")
    (set_attr "length_immediate" "1")
    (set_attr "prefix" "orig,vex")
   [(parallel
     [(set (match_operand:SWI48 0 "register_operand")
          (if_then_else:SWI48
-           (ne:QI (and:SWI48 (match_operand:SWI48 2 "register_operand")
-                             (const_int 255))
+           (ne:QI (match_operand:QI 2 "register_operand")
                   (const_int 0))
            (zero_extract:SWI48
              (match_operand:SWI48 1 "nonimmediate_operand")
-             (umin:SWI48 (and:SWI48 (match_dup 2) (const_int 255))
-                         (match_dup 3))
+             (umin:QI (match_dup 2) (match_dup 3))
              (const_int 0))
            (const_int 0)))
      (clobber (reg:CC FLAGS_REG))])]
   "TARGET_BMI2"
-  "operands[3] = GEN_INT (<MODE_SIZE> * BITS_PER_UNIT);")
+{
+  operands[2] = gen_lowpart (QImode, operands[2]);
+  operands[3] = GEN_INT (<MODE_SIZE> * BITS_PER_UNIT);
+})
 
 (define_insn "*bmi2_bzhi_<mode>3"
   [(set (match_operand:SWI48 0 "register_operand" "=r")
        (if_then_else:SWI48
-         (ne:QI (and:SWI48 (match_operand:SWI48 2 "register_operand" "r")
-                           (const_int 255))
+         (ne:QI (match_operand:QI 2 "register_operand" "q")
                 (const_int 0))
          (zero_extract:SWI48
            (match_operand:SWI48 1 "nonimmediate_operand" "rm")
-           (umin:SWI48 (and:SWI48 (match_dup 2) (const_int 255))
-                       (match_operand:SWI48 3 "const_int_operand"))
-           (const_int 0))
-         (const_int 0)))
-   (clobber (reg:CC FLAGS_REG))]
-  "TARGET_BMI2 && INTVAL (operands[3]) == <MODE_SIZE> * BITS_PER_UNIT"
-  "bzhi\t{%2, %1, %0|%0, %1, %2}"
-  [(set_attr "type" "bitmanip")
-   (set_attr "prefix" "vex")
-   (set_attr "mode" "<MODE>")])
-
-(define_insn "*bmi2_bzhi_<mode>3_1"
-  [(set (match_operand:SWI48 0 "register_operand" "=r")
-       (if_then_else:SWI48
-         (ne:QI (match_operand:QI 2 "register_operand" "r") (const_int 0))
-         (zero_extract:SWI48
-           (match_operand:SWI48 1 "nonimmediate_operand" "rm")
-           (umin:SWI48 (zero_extend:SWI48 (match_dup 2))
-                       (match_operand:SWI48 3 "const_int_operand"))
+           (umin:QI (match_dup 2)
+                    (match_operand:QI 3 "const_int_operand"))
            (const_int 0))
          (const_int 0)))
    (clobber (reg:CC FLAGS_REG))]
            (ne:QI (match_operand:QI 2 "register_operand" "r") (const_int 0))
            (zero_extract:SWI48
              (match_operand:SWI48 1 "nonimmediate_operand" "rm")
-             (umin:SWI48 (zero_extend:SWI48 (match_dup 2))
-                         (match_operand:SWI48 3 "const_int_operand"))
+             (umin:QI (match_dup 2)
+                      (match_operand:QI 3 "const_int_operand"))
              (const_int 0))
            (const_int 0))
        (const_int 0)))
   [(set (match_operand:SWI48 0 "register_operand" "=r")
         (zero_extract:SWI48
           (match_operand:SWI48 1 "nonimmediate_operand" "rm")
-          (match_operand 2 "const_0_to_255_operand")
-          (match_operand 3 "const_0_to_255_operand")))
+          (match_operand:QI 2 "const_0_to_255_operand")
+          (match_operand:QI 3 "const_0_to_255_operand")))
    (clobber (reg:CC FLAGS_REG))]
    "TARGET_TBM"
 {
   "! TARGET_POPCNT"
 {
   rtx scratch = gen_reg_rtx (QImode);
+  rtx tmp = gen_reg_rtx (HImode);
 
-  emit_insn (gen_parityhi2_cmp (operands[1]));
+  emit_move_insn (tmp, operands[1]);
+  emit_insn (gen_parityhi2_cmp (tmp));
 
   ix86_expand_setcc (scratch, ORDERED,
                     gen_rtx_REG (CCmode, FLAGS_REG), const0_rtx);
    (set_attr "mode" "HF")])
 
 (define_insn "*rcpsf2_sse"
-  [(set (match_operand:SF 0 "register_operand" "=x,x,x")
-       (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "0,x,m")]
+  [(set (match_operand:SF 0 "register_operand" "=x,x,x,x")
+       (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "0,x,m,ja")]
                   UNSPEC_RCP))]
   "TARGET_SSE && TARGET_SSE_MATH"
   "@
    %vrcpss\t{%d1, %0|%0, %d1}
    %vrcpss\t{%d1, %0|%0, %d1}
-   %vrcpss\t{%1, %d0|%d0, %1}"
-  [(set_attr "type" "sse")
+   rcpss\t{%1, %d0|%d0, %1}
+   vrcpss\t{%1, %d0|%d0, %1}"
+  [(set_attr "isa" "*,*,noavx,avx")
+   (set_attr "addr" "*,*,*,gpr16")
+   (set_attr "type" "sse")
    (set_attr "atom_sse_attr" "rcp")
    (set_attr "btver2_sse_attr" "rcp")
    (set_attr "prefix" "maybe_vex")
    (set_attr "mode" "SF")
-   (set_attr "avx_partial_xmm_update" "false,false,true")
+   (set_attr "avx_partial_xmm_update" "false,false,true,true")
    (set (attr "preferred_for_speed")
       (cond [(match_test "TARGET_AVX")
               (symbol_ref "true")
-            (eq_attr "alternative" "1,2")
+            (eq_attr "alternative" "1,2,3")
               (symbol_ref "!TARGET_SSE_PARTIAL_REG_DEPENDENCY")
            ]
            (symbol_ref "true")))])
    (set_attr "bdver1_decode" "direct")])
 
 (define_insn "*rsqrtsf2_sse"
-  [(set (match_operand:SF 0 "register_operand" "=x,x,x")
-       (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "0,x,m")]
+  [(set (match_operand:SF 0 "register_operand" "=x,x,x,x")
+       (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "0,x,m,ja")]
                   UNSPEC_RSQRT))]
   "TARGET_SSE && TARGET_SSE_MATH"
   "@
    %vrsqrtss\t{%d1, %0|%0, %d1}
    %vrsqrtss\t{%d1, %0|%0, %d1}
-   %vrsqrtss\t{%1, %d0|%d0, %1}"
-  [(set_attr "type" "sse")
+   rsqrtss\t{%1, %d0|%d0, %1}
+   vrsqrtss\t{%1, %d0|%d0, %1}"
+  [(set_attr "isa" "*,*,noavx,avx")
+   (set_attr "addr" "*,*,*,gpr16")
+   (set_attr "type" "sse")
    (set_attr "atom_sse_attr" "rcp")
    (set_attr "btver2_sse_attr" "rcp")
    (set_attr "prefix" "maybe_vex")
    (set_attr "mode" "SF")
-   (set_attr "avx_partial_xmm_update" "false,false,true")
+   (set_attr "avx_partial_xmm_update" "false,false,true,true")
    (set (attr "preferred_for_speed")
       (cond [(match_test "TARGET_AVX")
               (symbol_ref "true")
-            (eq_attr "alternative" "1,2")
+            (eq_attr "alternative" "1,2,3")
               (symbol_ref "!TARGET_SSE_PARTIAL_REG_DEPENDENCY")
            ]
            (symbol_ref "true")))])
 (define_insn "sse4_1_round<mode>2"
   [(set (match_operand:MODEFH 0 "register_operand" "=x,x,x,v,v")
        (unspec:MODEFH
-         [(match_operand:MODEFH 1 "nonimmediate_operand" "0,x,m,v,m")
+         [(match_operand:MODEFH 1 "nonimmediate_operand" "0,x,jm,v,m")
           (match_operand:SI 2 "const_0_to_15_operand")]
          UNSPEC_ROUND))]
   "TARGET_SSE4_1"
    vrndscale<ssemodesuffix>\t{%2, %1, %d0|%d0, %1, %2}"
   [(set_attr "type" "ssecvt")
    (set_attr "prefix_extra" "1,1,1,*,*")
-   (set_attr "length_immediate" "*,*,*,1,1")
+   (set_attr "length_immediate" "1")
+   (set_attr "addr" "*,*,gpr16,*,*")
    (set_attr "prefix" "maybe_vex,maybe_vex,maybe_vex,evex,evex")
    (set_attr "isa" "noavx512f,noavx512f,noavx512f,avx512f,avx512f")
    (set_attr "avx_partial_xmm_update" "false,false,true,false,true")
   DONE;
 })
 
+(define_expand "roundhf2"
+  [(match_operand:HF 0 "register_operand")
+   (match_operand:HF 1 "register_operand")]
+  "TARGET_AVX512FP16 && !flag_trapping_math && !flag_rounding_math"
+{
+  ix86_expand_round_sse4 (operands[0], operands[1]);
+  DONE;
+})
+
 (define_expand "round<mode>2"
   [(match_operand:X87MODEF 0 "register_operand")
    (match_operand:X87MODEF 1 "nonimmediate_operand")]
   [(set_attr "type" "fpspc")
    (set_attr "mode" "<MODE>")])
 
+(define_expand "lroundhf<mode>2"
+  [(set (match_operand:SWI248 0 "register_operand")
+     (unspec:SWI248 [(match_operand:HF 1 "nonimmediate_operand")]
+                  UNSPEC_FIX_NOTRUNC))]
+  "TARGET_AVX512FP16 && !flag_trapping_math && !flag_rounding_math"
+{
+  ix86_expand_lround (operands[0], operands[1]);
+  DONE;
+})
+
+(define_expand "lrinthf<mode>2"
+  [(set (match_operand:SWI48 0 "register_operand")
+     (unspec:SWI48 [(match_operand:HF 1 "nonimmediate_operand")]
+                  UNSPEC_FIX_NOTRUNC))]
+  "TARGET_AVX512FP16")
+
 (define_expand "lrint<MODEF:mode><SWI48:mode>2"
   [(set (match_operand:SWI48 0 "register_operand")
      (unspec:SWI48 [(match_operand:MODEF 1 "nonimmediate_operand")]
    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
    && flag_unsafe_math_optimizations")
 
+(define_expand "l<rounding_insn>hf<mode>2"
+  [(set (match_operand:SWI48 0 "nonimmediate_operand")
+       (unspec:SWI48 [(match_operand:HF 1 "register_operand")]
+                   FIST_ROUNDING))]
+  "TARGET_AVX512FP16"
+{
+  rtx tmp = gen_reg_rtx (HFmode);
+  emit_insn (gen_sse4_1_roundhf2 (tmp, operands[1],
+                                GEN_INT (ROUND_<ROUNDING> | ROUND_NO_EXC)));
+  emit_insn (gen_fix_trunchf<mode>2 (operands[0], tmp));
+  DONE;
+})
+
 (define_expand "l<rounding_insn><MODEF:mode><SWI48:mode>2"
   [(parallel [(set (match_operand:SWI48 0 "nonimmediate_operand")
                   (unspec:SWI48 [(match_operand:MODEF 1 "register_operand")]
 })
 
 (define_insn "movmsk_df"
-  [(set (match_operand:SI 0 "register_operand" "=r")
+  [(set (match_operand:SI 0 "register_operand" "=r,jr")
        (unspec:SI
-         [(match_operand:DF 1 "register_operand" "x")]
+         [(match_operand:DF 1 "register_operand" "x,x")]
          UNSPEC_MOVMSK))]
   "SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH"
   "%vmovmskpd\t{%1, %0|%0, %1}"
-  [(set_attr "type" "ssemov")
-   (set_attr "prefix" "maybe_vex")
+  [(set_attr "isa" "noavx,avx")
+   (set_attr "type" "ssemov")
+   (set_attr "prefix" "maybe_evex")
    (set_attr "mode" "DF")])
 
 ;; Use movmskpd in SSE mode to avoid store forwarding stall
                                     (const_int 0))
                  (compare:CC (match_operand 4 "memory_operand")
                              (match_operand 5 "memory_operand"))
-                 (const_int 0)))
+                 (reg:CC FLAGS_REG)))
              (use (match_operand:SI 3 "immediate_operand"))
-             (use (reg:CC FLAGS_REG))
              (clobber (match_operand 0 "register_operand"))
              (clobber (match_operand 1 "register_operand"))
              (clobber (match_dup 2))])]
                             (const_int 0))
          (compare:CC (mem:BLK (match_operand:P 4 "register_operand" "0"))
                      (mem:BLK (match_operand:P 5 "register_operand" "1")))
-         (const_int 0)))
+         (reg:CC FLAGS_REG)))
    (use (match_operand:SI 3 "immediate_operand" "i"))
-   (use (reg:CC FLAGS_REG))
    (clobber (match_operand:P 0 "register_operand" "=S"))
    (clobber (match_operand:P 1 "register_operand" "=D"))
    (clobber (match_operand:P 2 "register_operand" "=c"))]
                               (const_int 0))
            (compare:CC (mem:BLK (match_operand 4 "register_operand"))
                        (mem:BLK (match_operand 5 "register_operand")))
-           (const_int 0)))
+           (reg:CC FLAGS_REG)))
      (use (match_operand:SI 3 "immediate_operand"))
-     (use (reg:CC FLAGS_REG))
      (clobber (match_operand 0 "register_operand"))
      (clobber (match_operand 1 "register_operand"))
      (clobber (match_operand 2 "register_operand"))])
                               (const_int 0))
            (compare:CC (mem:BLK (match_dup 4))
                        (mem:BLK (match_dup 5)))
-           (const_int 0)))
+           (reg:CC FLAGS_REG)))
      (use (match_dup 3))
-     (use (reg:CC FLAGS_REG))
      (clobber (match_dup 0))
      (clobber (match_dup 1))
      (clobber (match_dup 2))])])
        (neg:SWI (ltu:SWI (reg:CCC FLAGS_REG) (const_int 0))))])
 
 (define_insn "*mov<mode>cc_noc"
-  [(set (match_operand:SWI248 0 "register_operand" "=r,r")
+  [(set (match_operand:SWI248 0 "register_operand" "=r,r,r,r")
        (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
                               [(reg FLAGS_REG) (const_int 0)])
-         (match_operand:SWI248 2 "nonimmediate_operand" "rm,0")
-         (match_operand:SWI248 3 "nonimmediate_operand" "0,rm")))]
+         (match_operand:SWI248 2 "nonimmediate_operand" "rm,0,rm,r")
+         (match_operand:SWI248 3 "nonimmediate_operand" "0,rm,r,rm")))]
   "TARGET_CMOVE && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
   "@
    cmov%O2%C1\t{%2, %0|%0, %2}
-   cmov%O2%c1\t{%3, %0|%0, %3}"
-  [(set_attr "type" "icmov")
+   cmov%O2%c1\t{%3, %0|%0, %3}
+   cmov%O2%C1\t{%2, %3, %0|%0, %3, %2}
+   cmov%O2%c1\t{%3, %2, %0|%0, %2, %3}"
+  [(set_attr "isa" "*,*,apx_ndd,apx_ndd")
+   (set_attr "type" "icmov")
    (set_attr "mode" "<MODE>")])
 
 (define_insn "*movsicc_noc_zext"
-  [(set (match_operand:DI 0 "register_operand" "=r,r")
+  [(set (match_operand:DI 0 "register_operand" "=r,r,r,r")
        (if_then_else:DI (match_operator 1 "ix86_comparison_operator"
                           [(reg FLAGS_REG) (const_int 0)])
          (zero_extend:DI
-           (match_operand:SI 2 "nonimmediate_operand" "rm,0"))
+           (match_operand:SI 2 "nonimmediate_operand" "rm,0,rm,r"))
          (zero_extend:DI
-           (match_operand:SI 3 "nonimmediate_operand" "0,rm"))))]
+           (match_operand:SI 3 "nonimmediate_operand" "0,rm,r,rm"))))]
   "TARGET_64BIT
    && TARGET_CMOVE && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
   "@
    cmov%O2%C1\t{%2, %k0|%k0, %2}
-   cmov%O2%c1\t{%3, %k0|%k0, %3}"
-  [(set_attr "type" "icmov")
+   cmov%O2%c1\t{%3, %k0|%k0, %3}
+   cmov%O2%C1\t{%2, %3, %k0|%k0, %3, %2}
+   cmov%O2%c1\t{%3, %2, %k0|%k0, %2, %3}"
+  [(set_attr "isa" "*,*,apx_ndd,apx_ndd")
+   (set_attr "type" "icmov")
    (set_attr "mode" "SI")])
 
 (define_insn "*movsicc_noc_zext_1"
-  [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r")
+  [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,r,r")
        (zero_extend:DI
          (if_then_else:SI (match_operator 1 "ix86_comparison_operator"
                             [(reg FLAGS_REG) (const_int 0)])
-            (match_operand:SI 2 "nonimmediate_operand" "rm,0")
-            (match_operand:SI 3 "nonimmediate_operand" "0,rm"))))]
+            (match_operand:SI 2 "nonimmediate_operand" "rm,0,rm,r")
+            (match_operand:SI 3 "nonimmediate_operand" "0,rm,r,rm"))))]
   "TARGET_64BIT
    && TARGET_CMOVE && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
   "@
    cmov%O2%C1\t{%2, %k0|%k0, %2}
-   cmov%O2%c1\t{%3, %k0|%k0, %3}"
-  [(set_attr "type" "icmov")
+   cmov%O2%c1\t{%3, %k0|%k0, %3}
+   cmov%O2%C1\t{%2, %3, %k0|%k0, %3, %2}
+   cmov%O2%c1\t{%3, %2, %k0|%k0, %2, %3}"
+  [(set_attr "isa" "*,*,apx_ndd,apx_ndd")
+   (set_attr "type" "icmov")
    (set_attr "mode" "SI")])
 
 
 })
 
 (define_insn "*movqicc_noc"
-  [(set (match_operand:QI 0 "register_operand" "=r,r")
+  [(set (match_operand:QI 0 "register_operand" "=r,r,r")
        (if_then_else:QI (match_operator 1 "ix86_comparison_operator"
                           [(reg FLAGS_REG) (const_int 0)])
-                     (match_operand:QI 2 "register_operand" "r,0")
-                     (match_operand:QI 3 "register_operand" "0,r")))]
+                     (match_operand:QI 2 "register_operand" "r,0,r")
+                     (match_operand:QI 3 "register_operand" "0,r,r")))]
   "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
   "#"
-  [(set_attr "type" "icmov")
+  [(set_attr "isa" "*,*,apx_ndd")
+   (set_attr "type" "icmov")
    (set_attr "mode" "QI")])
 
 (define_split
          (match_operand:MODEF 3 "register_operand" "x")))]
   "TARGET_XOP"
   "vpcmov\t{%1, %3, %2, %0|%0, %2, %3, %1}"
-  [(set_attr "type" "sse4arg")])
+  [(set_attr "type" "sse4arg")
+   (set_attr "mode" "TI")])
 
 ;; These versions of the min/max patterns are intentionally ignorant of
 ;; their behavior wrt -0.0 and NaN (via the commutative operand mark).
 {
   rtx stack_slot;
 
-  if (flag_cf_protection & CF_RETURN)
-    {
-      /* Copy shadow stack pointer to the first slot
-        and stack pointer to the second slot.  */
-      rtx ssp_slot = adjust_address (operands[0], word_mode, 0);
-      stack_slot = adjust_address (operands[0], Pmode, UNITS_PER_WORD);
+  if (flag_cf_protection & CF_RETURN)
+    {
+      /* Copy shadow stack pointer to the first slot
+        and stack pointer to the second slot.  */
+      rtx ssp_slot = adjust_address (operands[0], word_mode, 0);
+      stack_slot = adjust_address (operands[0], Pmode, UNITS_PER_WORD);
+
+      rtx reg_ssp = force_reg (word_mode, const0_rtx);
+      emit_insn (gen_rdssp (word_mode, reg_ssp, reg_ssp));
+      emit_move_insn (ssp_slot, reg_ssp);
+    }
+  else
+    stack_slot = adjust_address (operands[0], Pmode, 0);
+  emit_move_insn (stack_slot, operands[1]);
+  DONE;
+})
+
+(define_expand "restore_stack_nonlocal"
+  [(set (match_operand 0 "register_operand" "")
+       (match_operand 1 "memory_operand" ""))]
+  ""
+{
+  rtx stack_slot;
+
+  if (flag_cf_protection & CF_RETURN)
+    {
+      /* Restore shadow stack pointer from the first slot
+        and stack pointer from the second slot.  */
+      rtx ssp_slot = adjust_address (operands[1], word_mode, 0);
+      stack_slot = adjust_address (operands[1], Pmode, UNITS_PER_WORD);
+
+      /* Get the current shadow stack pointer.  The code below will check if
+        SHSTK feature is enabled.  If it is not enabled the RDSSP instruction
+        is a NOP.  */
+      rtx reg_ssp = force_reg (word_mode, const0_rtx);
+      emit_insn (gen_rdssp (word_mode, reg_ssp, reg_ssp));
+
+      /* Compare through subtraction the saved and the current ssp
+        to decide if ssp has to be adjusted.  */
+      reg_ssp = expand_simple_binop (word_mode, MINUS,
+                                    reg_ssp, ssp_slot,
+                                    reg_ssp, 1, OPTAB_DIRECT);
+
+      /* Compare and jump over adjustment code.  */
+      rtx noadj_label = gen_label_rtx ();
+      emit_cmp_and_jump_insns (reg_ssp, const0_rtx, EQ, NULL_RTX,
+                              word_mode, 1, noadj_label);
+
+      /* Compute the number of frames to adjust.  */
+      rtx reg_adj = gen_lowpart (ptr_mode, reg_ssp);
+      rtx reg_adj_neg = expand_simple_unop (ptr_mode, NEG, reg_adj,
+                                           NULL_RTX, 1);
+
+      reg_adj = expand_simple_binop (ptr_mode, LSHIFTRT, reg_adj_neg,
+                                    GEN_INT (exact_log2 (UNITS_PER_WORD)),
+                                    reg_adj, 1, OPTAB_DIRECT);
+
+      /* Check if number of frames <= 255 so no loop is needed.  */
+      rtx inc_label = gen_label_rtx ();
+      emit_cmp_and_jump_insns (reg_adj, GEN_INT (255), LEU, NULL_RTX,
+                              ptr_mode, 1, inc_label);
+
+      /* Adjust the ssp in a loop.  */
+      rtx loop_label = gen_label_rtx ();
+      emit_label (loop_label);
+      LABEL_NUSES (loop_label) = 1;
+
+      rtx reg_255 = force_reg (word_mode, GEN_INT (255));
+      emit_insn (gen_incssp (word_mode, reg_255));
+
+      reg_adj = expand_simple_binop (ptr_mode, MINUS,
+                                    reg_adj, GEN_INT (255),
+                                    reg_adj, 1, OPTAB_DIRECT);
+
+      /* Compare and jump to the loop label.  */
+      emit_cmp_and_jump_insns (reg_adj, GEN_INT (255), GTU, NULL_RTX,
+                              ptr_mode, 1, loop_label);
+
+      emit_label (inc_label);
+      LABEL_NUSES (inc_label) = 1;
+
+      emit_insn (gen_incssp (word_mode, reg_ssp));
+
+      emit_label (noadj_label);
+      LABEL_NUSES (noadj_label) = 1;
+    }
+  else
+    stack_slot = adjust_address (operands[1], Pmode, 0);
+  emit_move_insn (operands[0], stack_slot);
+  DONE;
+})
+
+(define_expand "stack_protect_set"
+  [(match_operand 0 "memory_operand")
+   (match_operand 1 "memory_operand")]
+  ""
+{
+  rtx scratch = gen_reg_rtx (word_mode);
+
+  emit_insn (gen_stack_protect_set_1
+            (ptr_mode, word_mode, operands[0], operands[1], scratch));
+  DONE;
+})
+
+(define_insn "@stack_protect_set_1_<PTR:mode>_<W:mode>"
+  [(set (match_operand:PTR 0 "memory_operand" "=m")
+       (unspec:PTR [(match_operand:PTR 1 "memory_operand" "m")]
+                   UNSPEC_SP_SET))
+   (set (match_operand:W 2 "register_operand" "=&r") (const_int 0))
+   (clobber (reg:CC FLAGS_REG))]
+  ""
+{
+  output_asm_insn ("mov{<PTR:imodesuffix>}\t{%1, %<PTR:k>2|%<PTR:k>2, %1}",
+                  operands);
+  output_asm_insn ("mov{<PTR:imodesuffix>}\t{%<PTR:k>2, %0|%0, %<PTR:k>2}",
+                  operands);
+  if (!TARGET_USE_MOV0 || optimize_insn_for_size_p ())
+    return "xor{l}\t%k2, %k2";
+  else
+    return "mov{l}\t{$0, %k2|%k2, 0}";
+}
+  [(set_attr "type" "multi")])
+
+;; Patterns and peephole2s to optimize stack_protect_set_1_<mode>
+;; immediately followed by *mov{s,d}i_internal, where we can avoid
+;; the xor{l} above.  We don't split this, so that scheduling or
+;; anything else doesn't separate the *stack_protect_set* pattern from
+;; the set of the register that overwrites the register with a new value.
+
+(define_peephole2
+  [(parallel [(set (match_operand:PTR 0 "memory_operand")
+                  (unspec:PTR [(match_operand:PTR 1 "memory_operand")]
+                              UNSPEC_SP_SET))
+             (set (match_operand 2 "general_reg_operand") (const_int 0))
+             (clobber (reg:CC FLAGS_REG))])
+   (set (match_operand 3 "general_reg_operand")
+       (match_operand 4 "const0_operand"))]
+  "GET_MODE (operands[2]) == word_mode
+   && GET_MODE_SIZE (GET_MODE (operands[3])) <= UNITS_PER_WORD
+   && peep2_reg_dead_p (0, operands[3])
+   && peep2_reg_dead_p (1, operands[2])"
+  [(parallel [(set (match_dup 0)
+                  (unspec:PTR [(match_dup 1)] UNSPEC_SP_SET))
+             (set (match_dup 3) (const_int 0))
+             (clobber (reg:CC FLAGS_REG))])]
+  "operands[3] = gen_lowpart (word_mode, operands[3]);")
+
+(define_insn "*stack_protect_set_2_<mode>_si"
+  [(set (match_operand:PTR 0 "memory_operand" "=m")
+       (unspec:PTR [(match_operand:PTR 3 "memory_operand" "m")]
+                   UNSPEC_SP_SET))
+   (set (match_operand:SI 1 "register_operand" "=&r")
+       (match_operand:SI 2 "general_operand" "g"))]
+  "reload_completed"
+{
+  output_asm_insn ("mov{<imodesuffix>}\t{%3, %<k>1|%<k>1, %3}", operands);
+  output_asm_insn ("mov{<imodesuffix>}\t{%<k>1, %0|%0, %<k>1}", operands);
+  if (pic_32bit_operand (operands[2], SImode)
+      || ix86_use_lea_for_mov (insn, operands + 1))
+    return "lea{l}\t{%E2, %1|%1, %E2}";
+  else
+    return "mov{l}\t{%2, %1|%1, %2}";
+}
+  [(set_attr "type" "multi")
+   (set_attr "length" "24")])
+
+(define_insn "*stack_protect_set_2_<mode>_di"
+  [(set (match_operand:PTR 0 "memory_operand" "=m,m,m")
+       (unspec:PTR [(match_operand:PTR 3 "memory_operand" "m,m,m")]
+                   UNSPEC_SP_SET))
+   (set (match_operand:DI 1 "register_operand" "=&r,&r,&r")
+       (match_operand:DI 2 "general_operand" "Z,rem,i"))]
+  "TARGET_64BIT && reload_completed"
+{
+  output_asm_insn ("mov{<imodesuffix>}\t{%3, %<k>1|%<k>1, %3}", operands);
+  output_asm_insn ("mov{<imodesuffix>}\t{%<k>1, %0|%0, %<k>1}", operands);
+  if (pic_32bit_operand (operands[2], DImode))
+    return "lea{q}\t{%E2, %1|%1, %E2}";
+  else if (which_alternative == 0)
+    return "mov{l}\t{%k2, %k1|%k1, %k2}";
+  else if (which_alternative == 2)
+    return "movabs{q}\t{%2, %1|%1, %2}";
+  else if (ix86_use_lea_for_mov (insn, operands + 1))
+    return "lea{q}\t{%E2, %1|%1, %E2}";
+  else
+    return "mov{q}\t{%2, %1|%1, %2}";
+}
+  [(set_attr "type" "multi")
+   (set_attr "length" "24")])
+
+(define_peephole2
+  [(parallel [(set (match_operand:PTR 0 "memory_operand")
+                  (unspec:PTR [(match_operand:PTR 1 "memory_operand")]
+                              UNSPEC_SP_SET))
+             (set (match_operand 2 "general_reg_operand") (const_int 0))
+             (clobber (reg:CC FLAGS_REG))])
+   (set (match_operand:SWI48 3 "general_reg_operand")
+       (match_operand:SWI48 4 "general_gr_operand"))]
+  "GET_MODE (operands[2]) == word_mode
+   && peep2_reg_dead_p (0, operands[3])
+   && peep2_reg_dead_p (1, operands[2])"
+  [(parallel [(set (match_dup 0)
+                  (unspec:PTR [(match_dup 1)] UNSPEC_SP_SET))
+             (set (match_dup 3) (match_dup 4))])])
 
-      rtx reg_ssp = force_reg (word_mode, const0_rtx);
-      emit_insn (gen_rdssp (word_mode, reg_ssp, reg_ssp));
-      emit_move_insn (ssp_slot, reg_ssp);
-    }
-  else
-    stack_slot = adjust_address (operands[0], Pmode, 0);
-  emit_move_insn (stack_slot, operands[1]);
-  DONE;
-})
+(define_peephole2
+  [(set (match_operand:SWI48 3 "general_reg_operand")
+       (match_operand:SWI48 4 "general_gr_operand"))
+   (parallel [(set (match_operand:PTR 0 "memory_operand")
+                  (unspec:PTR [(match_operand:PTR 1 "memory_operand")]
+                              UNSPEC_SP_SET))
+             (set (match_operand 2 "general_reg_operand") (const_int 0))
+             (clobber (reg:CC FLAGS_REG))])]
+  "GET_MODE (operands[2]) == word_mode
+   && peep2_reg_dead_p (0, operands[3])
+   && peep2_reg_dead_p (2, operands[2])
+   && !reg_mentioned_p (operands[3], operands[0])
+   && !reg_mentioned_p (operands[3], operands[1])"
+  [(parallel [(set (match_dup 0)
+                  (unspec:PTR [(match_dup 1)] UNSPEC_SP_SET))
+             (set (match_dup 3) (match_dup 4))])])
 
-(define_expand "restore_stack_nonlocal"
-  [(set (match_operand 0 "register_operand" "")
-       (match_operand 1 "memory_operand" ""))]
+(define_insn "*stack_protect_set_3_<PTR:mode>_<SWI48:mode>"
+  [(set (match_operand:PTR 0 "memory_operand" "=m")
+       (unspec:PTR [(match_operand:PTR 3 "memory_operand" "m")]
+                   UNSPEC_SP_SET))
+   (set (match_operand:SWI48 1 "register_operand" "=&r")
+       (match_operand:SWI48 2 "address_no_seg_operand" "Ts"))]
   ""
 {
-  rtx stack_slot;
-
-  if (flag_cf_protection & CF_RETURN)
+  output_asm_insn ("mov{<PTR:imodesuffix>}\t{%3, %<PTR:k>1|%<PTR:k>1, %3}",
+                  operands);
+  output_asm_insn ("mov{<PTR:imodesuffix>}\t{%<PTR:k>1, %0|%0, %<PTR:k>1}",
+                  operands);
+  if (SImode_address_operand (operands[2], VOIDmode))
     {
-      /* Restore shadow stack pointer from the first slot
-        and stack pointer from the second slot.  */
-      rtx ssp_slot = adjust_address (operands[1], word_mode, 0);
-      stack_slot = adjust_address (operands[1], Pmode, UNITS_PER_WORD);
-
-      /* Get the current shadow stack pointer.  The code below will check if
-        SHSTK feature is enabled.  If it is not enabled the RDSSP instruction
-        is a NOP.  */
-      rtx reg_ssp = force_reg (word_mode, const0_rtx);
-      emit_insn (gen_rdssp (word_mode, reg_ssp, reg_ssp));
-
-      /* Compare through subtraction the saved and the current ssp
-        to decide if ssp has to be adjusted.  */
-      reg_ssp = expand_simple_binop (word_mode, MINUS,
-                                    reg_ssp, ssp_slot,
-                                    reg_ssp, 1, OPTAB_DIRECT);
-
-      /* Compare and jump over adjustment code.  */
-      rtx noadj_label = gen_label_rtx ();
-      emit_cmp_and_jump_insns (reg_ssp, const0_rtx, EQ, NULL_RTX,
-                              word_mode, 1, noadj_label);
-
-      /* Compute the number of frames to adjust.  */
-      rtx reg_adj = gen_lowpart (ptr_mode, reg_ssp);
-      rtx reg_adj_neg = expand_simple_unop (ptr_mode, NEG, reg_adj,
-                                           NULL_RTX, 1);
-
-      reg_adj = expand_simple_binop (ptr_mode, LSHIFTRT, reg_adj_neg,
-                                    GEN_INT (exact_log2 (UNITS_PER_WORD)),
-                                    reg_adj, 1, OPTAB_DIRECT);
-
-      /* Check if number of frames <= 255 so no loop is needed.  */
-      rtx inc_label = gen_label_rtx ();
-      emit_cmp_and_jump_insns (reg_adj, GEN_INT (255), LEU, NULL_RTX,
-                              ptr_mode, 1, inc_label);
+      gcc_assert (TARGET_64BIT);
+      return "lea{l}\t{%E2, %k1|%k1, %E2}";
+    }
+  else
+    return "lea{<SWI48:imodesuffix>}\t{%E2, %1|%1, %E2}";
+}
+  [(set_attr "type" "multi")
+   (set_attr "length" "24")])
 
-      /* Adjust the ssp in a loop.  */
-      rtx loop_label = gen_label_rtx ();
-      emit_label (loop_label);
-      LABEL_NUSES (loop_label) = 1;
+(define_peephole2
+  [(parallel [(set (match_operand:PTR 0 "memory_operand")
+                  (unspec:PTR [(match_operand:PTR 1 "memory_operand")]
+                              UNSPEC_SP_SET))
+             (set (match_operand 2 "general_reg_operand") (const_int 0))
+             (clobber (reg:CC FLAGS_REG))])
+   (set (match_operand:SWI48 3 "general_reg_operand")
+       (match_operand:SWI48 4 "address_no_seg_operand"))]
+  "GET_MODE (operands[2]) == word_mode
+   && peep2_reg_dead_p (0, operands[3])
+   && peep2_reg_dead_p (1, operands[2])"
+  [(parallel [(set (match_dup 0)
+                  (unspec:PTR [(match_dup 1)] UNSPEC_SP_SET))
+             (set (match_dup 3) (match_dup 4))])])
 
-      rtx reg_255 = force_reg (word_mode, GEN_INT (255));
-      emit_insn (gen_incssp (word_mode, reg_255));
+(define_insn "*stack_protect_set_4z_<mode>_di"
+  [(set (match_operand:PTR 0 "memory_operand" "=m")
+       (unspec:PTR [(match_operand:PTR 3 "memory_operand" "m")]
+                   UNSPEC_SP_SET))
+   (set (match_operand:DI 1 "register_operand" "=&r")
+       (zero_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm")))]
+  "TARGET_64BIT && reload_completed"
+{
+  output_asm_insn ("mov{<imodesuffix>}\t{%3, %<k>1|%<k>1, %3}", operands);
+  output_asm_insn ("mov{<imodesuffix>}\t{%<k>1, %0|%0, %<k>1}", operands);
+  if (ix86_use_lea_for_mov (insn, operands + 1))
+    return "lea{l}\t{%E2, %k1|%k1, %E2}";
+  else
+    return "mov{l}\t{%2, %k1|%k1, %2}";
+}
+  [(set_attr "type" "multi")
+   (set_attr "length" "24")])
 
-      reg_adj = expand_simple_binop (ptr_mode, MINUS,
-                                    reg_adj, GEN_INT (255),
-                                    reg_adj, 1, OPTAB_DIRECT);
+(define_insn "*stack_protect_set_4s_<mode>_di"
+  [(set (match_operand:PTR 0 "memory_operand" "=m")
+       (unspec:PTR [(match_operand:PTR 3 "memory_operand" "m")]
+                   UNSPEC_SP_SET))
+   (set (match_operand:DI 1 "register_operand" "=&r")
+       (sign_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm")))]
+  "TARGET_64BIT && reload_completed"
+{
+  output_asm_insn ("mov{<imodesuffix>}\t{%3, %<k>1|%<k>1, %3}", operands);
+  output_asm_insn ("mov{<imodesuffix>}\t{%<k>1, %0|%0, %<k>1}", operands);
+  return "movs{lq|x}\t{%2, %1|%1, %2}";
+}
+  [(set_attr "type" "multi")
+   (set_attr "length" "24")])
 
-      /* Compare and jump to the loop label.  */
-      emit_cmp_and_jump_insns (reg_adj, GEN_INT (255), GTU, NULL_RTX,
-                              ptr_mode, 1, loop_label);
+(define_peephole2
+  [(parallel [(set (match_operand:PTR 0 "memory_operand")
+                  (unspec:PTR [(match_operand:PTR 1 "memory_operand")]
+                              UNSPEC_SP_SET))
+             (set (match_operand 2 "general_reg_operand") (const_int 0))
+             (clobber (reg:CC FLAGS_REG))])
+   (set (match_operand:DI 3 "general_reg_operand")
+       (any_extend:DI
+         (match_operand:SI 4 "nonimmediate_gr_operand")))]
+  "TARGET_64BIT
+   && GET_MODE (operands[2]) == word_mode
+   && peep2_reg_dead_p (0, operands[3])
+   && peep2_reg_dead_p (1, operands[2])"
+  [(parallel [(set (match_dup 0)
+                  (unspec:PTR [(match_dup 1)] UNSPEC_SP_SET))
+             (set (match_dup 3)
+                  (any_extend:DI (match_dup 4)))])])
 
-      emit_label (inc_label);
-      LABEL_NUSES (inc_label) = 1;
+(define_expand "stack_protect_test"
+  [(match_operand 0 "memory_operand")
+   (match_operand 1 "memory_operand")
+   (match_operand 2)]
+  ""
+{
+  rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG);
 
-      emit_insn (gen_incssp (word_mode, reg_ssp));
+  emit_insn (gen_stack_protect_test_1
+            (ptr_mode, flags, operands[0], operands[1]));
 
-      emit_label (noadj_label);
-      LABEL_NUSES (noadj_label) = 1;
-    }
-  else
-    stack_slot = adjust_address (operands[1], Pmode, 0);
-  emit_move_insn (operands[0], stack_slot);
+  emit_jump_insn (gen_cbranchcc4 (gen_rtx_EQ (VOIDmode, flags, const0_rtx),
+                                 flags, const0_rtx, operands[2]));
   DONE;
 })
 
+(define_insn "@stack_protect_test_1_<mode>"
+  [(set (match_operand:CCZ 0 "flags_reg_operand")
+       (unspec:CCZ [(match_operand:PTR 1 "memory_operand" "m")
+                    (match_operand:PTR 2 "memory_operand" "m")]
+                   UNSPEC_SP_TEST))
+   (clobber (match_scratch:PTR 3 "=&r"))]
+  ""
+{
+  output_asm_insn ("mov{<imodesuffix>}\t{%1, %3|%3, %1}", operands);
+  return "sub{<imodesuffix>}\t{%2, %3|%3, %2}";
+}
+  [(set_attr "type" "multi")])
 
 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
 ;; Do not split instructions with mask registers.
        (symbol_ref "memory_address_length (operands[0], false)"))
    (set_attr "memory" "none")])
 
-(define_expand "stack_protect_set"
-  [(match_operand 0 "memory_operand")
-   (match_operand 1 "memory_operand")]
-  ""
-{
-  emit_insn (gen_stack_protect_set_1
-            (ptr_mode, operands[0], operands[1]));
-  DONE;
-})
-
-(define_insn "@stack_protect_set_1_<mode>"
-  [(set (match_operand:PTR 0 "memory_operand" "=m")
-       (unspec:PTR [(match_operand:PTR 1 "memory_operand" "m")]
-                   UNSPEC_SP_SET))
-   (set (match_scratch:PTR 2 "=&r") (const_int 0))
-   (clobber (reg:CC FLAGS_REG))]
-  ""
-{
-  output_asm_insn ("mov{<imodesuffix>}\t{%1, %2|%2, %1}", operands);
-  output_asm_insn ("mov{<imodesuffix>}\t{%2, %0|%0, %2}", operands);
-  return "xor{l}\t%k2, %k2";
-}
-  [(set_attr "type" "multi")])
-
-;; Patterns and peephole2s to optimize stack_protect_set_1_<mode>
-;; immediately followed by *mov{s,d}i_internal to the same register,
-;; where we can avoid the xor{l} above.  We don't split this, so that
-;; scheduling or anything else doesn't separate the *stack_protect_set*
-;; pattern from the set of the register that overwrites the register
-;; with a new value.
-(define_insn "*stack_protect_set_2_<mode>"
-  [(set (match_operand:PTR 0 "memory_operand" "=m")
-       (unspec:PTR [(match_operand:PTR 3 "memory_operand" "m")]
-                   UNSPEC_SP_SET))
-   (set (match_operand:SI 1 "register_operand" "=&r")
-       (match_operand:SI 2 "general_operand" "g"))
-   (clobber (reg:CC FLAGS_REG))]
-  "reload_completed
-   && !reg_overlap_mentioned_p (operands[1], operands[2])"
-{
-  output_asm_insn ("mov{<imodesuffix>}\t{%3, %<k>1|%<k>1, %3}", operands);
-  output_asm_insn ("mov{<imodesuffix>}\t{%<k>1, %0|%0, %<k>1}", operands);
-  if (pic_32bit_operand (operands[2], SImode)
-      || ix86_use_lea_for_mov (insn, operands + 1))
-    return "lea{l}\t{%E2, %1|%1, %E2}";
-  else
-    return "mov{l}\t{%2, %1|%1, %2}";
-}
-  [(set_attr "type" "multi")
-   (set_attr "length" "24")])
-
-(define_peephole2
- [(parallel [(set (match_operand:PTR 0 "memory_operand")
-                 (unspec:PTR [(match_operand:PTR 1 "memory_operand")]
-                             UNSPEC_SP_SET))
-            (set (match_operand:PTR 2 "general_reg_operand") (const_int 0))
-            (clobber (reg:CC FLAGS_REG))])
-  (set (match_operand:SI 3 "general_reg_operand")
-       (match_operand:SI 4))]
- "REGNO (operands[2]) == REGNO (operands[3])
-  && general_operand (operands[4], SImode)
-  && (general_reg_operand (operands[4], SImode)
-      || memory_operand (operands[4], SImode)
-      || immediate_operand (operands[4], SImode))
-  && !reg_overlap_mentioned_p (operands[3], operands[4])"
- [(parallel [(set (match_dup 0)
-                 (unspec:PTR [(match_dup 1)] UNSPEC_SP_SET))
-            (set (match_dup 3) (match_dup 4))
-            (clobber (reg:CC FLAGS_REG))])])
-
-(define_insn "*stack_protect_set_3"
-  [(set (match_operand:DI 0 "memory_operand" "=m,m,m")
-       (unspec:DI [(match_operand:DI 3 "memory_operand" "m,m,m")]
-                  UNSPEC_SP_SET))
-   (set (match_operand:DI 1 "register_operand" "=&r,r,r")
-       (match_operand:DI 2 "general_operand" "Z,rem,i"))
-   (clobber (reg:CC FLAGS_REG))]
-  "TARGET_64BIT
-   && reload_completed
-   && !reg_overlap_mentioned_p (operands[1], operands[2])"
-{
-  output_asm_insn ("mov{q}\t{%3, %1|%1, %3}", operands);
-  output_asm_insn ("mov{q}\t{%1, %0|%0, %1}", operands);
-  if (pic_32bit_operand (operands[2], DImode))
-    return "lea{q}\t{%E2, %1|%1, %E2}";
-  else if (which_alternative == 0)
-    return "mov{l}\t{%k2, %k1|%k1, %k2}";
-  else if (which_alternative == 2)
-    return "movabs{q}\t{%2, %1|%1, %2}";
-  else if (ix86_use_lea_for_mov (insn, operands + 1))
-    return "lea{q}\t{%E2, %1|%1, %E2}";
-  else
-    return "mov{q}\t{%2, %1|%1, %2}";
-}
-  [(set_attr "type" "multi")
-   (set_attr "length" "24")])
-
-(define_peephole2
- [(parallel [(set (match_operand:DI 0 "memory_operand")
-                 (unspec:DI [(match_operand:DI 1 "memory_operand")]
-                            UNSPEC_SP_SET))
-            (set (match_operand:DI 2 "general_reg_operand") (const_int 0))
-            (clobber (reg:CC FLAGS_REG))])
-  (set (match_dup 2) (match_operand:DI 3))]
- "TARGET_64BIT
-  && general_operand (operands[3], DImode)
-  && (general_reg_operand (operands[3], DImode)
-      || memory_operand (operands[3], DImode)
-      || x86_64_zext_immediate_operand (operands[3], DImode)
-      || x86_64_immediate_operand (operands[3], DImode)
-      || (CONSTANT_P (operands[3])
-         && (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[3]))))
-  && !reg_overlap_mentioned_p (operands[2], operands[3])"
- [(parallel [(set (match_dup 0)
-                 (unspec:PTR [(match_dup 1)] UNSPEC_SP_SET))
-            (set (match_dup 2) (match_dup 3))
-            (clobber (reg:CC FLAGS_REG))])])
-
-(define_expand "stack_protect_test"
-  [(match_operand 0 "memory_operand")
-   (match_operand 1 "memory_operand")
-   (match_operand 2)]
-  ""
-{
-  rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG);
-
-  emit_insn (gen_stack_protect_test_1
-            (ptr_mode, flags, operands[0], operands[1]));
-
-  emit_jump_insn (gen_cbranchcc4 (gen_rtx_EQ (VOIDmode, flags, const0_rtx),
-                                 flags, const0_rtx, operands[2]));
-  DONE;
-})
-
-(define_insn "@stack_protect_test_1_<mode>"
-  [(set (match_operand:CCZ 0 "flags_reg_operand")
-       (unspec:CCZ [(match_operand:PTR 1 "memory_operand" "m")
-                    (match_operand:PTR 2 "memory_operand" "m")]
-                   UNSPEC_SP_TEST))
-   (clobber (match_scratch:PTR 3 "=&r"))]
-  ""
-{
-  output_asm_insn ("mov{<imodesuffix>}\t{%1, %3|%3, %1}", operands);
-  return "sub{<imodesuffix>}\t{%2, %3|%3, %2}";
-}
-  [(set_attr "type" "multi")])
-
 (define_insn "sse4_2_crc32<mode>"
   [(set (match_operand:SI 0 "register_operand" "=r")
        (unspec:SI
         (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
 
 (define_insn "fxsave64"
-  [(set (match_operand:BLK 0 "memory_operand" "=m")
+  [(set (match_operand:BLK 0 "memory_operand" "=jm")
        (unspec_volatile:BLK [(const_int 0)] UNSPECV_FXSAVE64))]
   "TARGET_64BIT && TARGET_FXSR"
   "fxsave64\t%0"
   [(set_attr "type" "other")
+   (set_attr "addr" "gpr16")
    (set_attr "memory" "store")
    (set (attr "length")
         (symbol_ref "ix86_attr_length_address_default (insn) + 4"))])
         (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
 
 (define_insn "fxrstor64"
-  [(unspec_volatile [(match_operand:BLK 0 "memory_operand" "m")]
+  [(unspec_volatile [(match_operand:BLK 0 "memory_operand" "jm")]
                    UNSPECV_FXRSTOR64)]
   "TARGET_64BIT && TARGET_FXSR"
   "fxrstor64\t%0"
   [(set_attr "type" "other")
+   (set_attr "addr" "gpr16")
    (set_attr "memory" "load")
    (set (attr "length")
         (symbol_ref "ix86_attr_length_address_default (insn) + 4"))])
         (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
 
 (define_insn "<xsave>_rex64"
-  [(set (match_operand:BLK 0 "memory_operand" "=m")
+  [(set (match_operand:BLK 0 "memory_operand" "=jm")
        (unspec_volatile:BLK
         [(match_operand:SI 1 "register_operand" "a")
          (match_operand:SI 2 "register_operand" "d")]
   "<xsave>\t%0"
   [(set_attr "type" "other")
    (set_attr "memory" "store")
+   (set_attr "addr" "gpr16")
    (set (attr "length")
         (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
 
 (define_insn "<xsave>"
-  [(set (match_operand:BLK 0 "memory_operand" "=m")
+  [(set (match_operand:BLK 0 "memory_operand" "=jm")
        (unspec_volatile:BLK
         [(match_operand:SI 1 "register_operand" "a")
          (match_operand:SI 2 "register_operand" "d")]
   "<xsave>\t%0"
   [(set_attr "type" "other")
    (set_attr "memory" "store")
+   (set_attr "addr" "gpr16")
    (set (attr "length")
         (symbol_ref "ix86_attr_length_address_default (insn) + 4"))])
 
 
 (define_insn "<xrstor>_rex64"
    [(unspec_volatile:BLK
-     [(match_operand:BLK 0 "memory_operand" "m")
+     [(match_operand:BLK 0 "memory_operand" "jm")
       (match_operand:SI 1 "register_operand" "a")
       (match_operand:SI 2 "register_operand" "d")]
      ANY_XRSTOR)]
   "<xrstor>\t%0"
   [(set_attr "type" "other")
    (set_attr "memory" "load")
+   (set_attr "addr" "gpr16")
    (set (attr "length")
         (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
 
 (define_insn "<xrstor>64"
    [(unspec_volatile:BLK
-     [(match_operand:BLK 0 "memory_operand" "m")
+     [(match_operand:BLK 0 "memory_operand" "jm")
       (match_operand:SI 1 "register_operand" "a")
       (match_operand:SI 2 "register_operand" "d")]
      ANY_XRSTOR64)]
   "<xrstor>64\t%0"
   [(set_attr "type" "other")
    (set_attr "memory" "load")
+   (set_attr "addr" "gpr16")
    (set (attr "length")
         (symbol_ref "ix86_attr_length_address_default (insn) + 4"))])
 
   "TARGET_64BIT && TARGET_FSGSBASE"
   "rd<fsgs>base\t%0"
   [(set_attr "type" "other")
-   (set_attr "prefix_extra" "2")])
+   (set_attr "prefix_0f" "1")
+   (set_attr "prefix_rep" "1")])
 
 (define_insn "wr<fsgs>base<mode>"
   [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")]
   "TARGET_64BIT && TARGET_FSGSBASE"
   "wr<fsgs>base\t%0"
   [(set_attr "type" "other")
-   (set_attr "prefix_extra" "2")])
+   (set_attr "prefix_0f" "1")
+   (set_attr "prefix_rep" "1")])
 
 (define_insn "ptwrite<mode>"
   [(unspec_volatile [(match_operand:SWI48 0 "nonimmediate_operand" "rm")]
   "TARGET_PTWRITE"
   "ptwrite\t%0"
   [(set_attr "type" "other")
-   (set_attr "prefix_extra" "2")])
+   (set_attr "prefix_0f" "1")
+   (set_attr "prefix_rep" "1")])
 
 (define_insn "@rdrand<mode>"
   [(set (match_operand:SWI248 0 "register_operand" "=r")
   "TARGET_RDRND"
   "rdrand\t%0"
   [(set_attr "type" "other")
-   (set_attr "prefix_extra" "1")])
+   (set_attr "prefix_0f" "1")])
 
 (define_insn "@rdseed<mode>"
   [(set (match_operand:SWI248 0 "register_operand" "=r")
   "TARGET_RDSEED"
   "rdseed\t%0"
   [(set_attr "type" "other")
-   (set_attr "prefix_extra" "1")])
+   (set_attr "prefix_0f" "1")])
 
 (define_expand "pause"
   [(set (match_dup 0)
   DONE;
 })
 
+(define_insn "urdmsr"
+  [(set (match_operand:DI 0 "register_operand" "=r")
+    (unspec_volatile:DI
+      [(match_operand:DI 1 "x86_64_szext_nonmemory_operand" "reZ")]
+      UNSPECV_URDMSR))]
+  "TARGET_USER_MSR && TARGET_64BIT"
+  "urdmsr\t{%1, %0|%0, %1}"
+  [(set_attr "prefix" "vex")
+   (set_attr "type" "other")])
+
+(define_insn "uwrmsr"
+  [(unspec_volatile
+    [(match_operand:DI 0 "x86_64_szext_nonmemory_operand" "reZ")
+      (match_operand:DI 1 "register_operand" "r")]
+      UNSPECV_UWRMSR)]
+  "TARGET_USER_MSR && TARGET_64BIT"
+  "uwrmsr\t{%1, %0|%0, %1}"
+  [(set_attr "prefix" "vex")
+   (set_attr "type" "other")])
+
 (include "mmx.md")
 (include "sse.md")
 (include "sync.md")