OSDN Git Service

PR target/40718
[pf3gnuchains/gcc-fork.git] / gcc / config / i386 / i386.md
index 2979431..0735d5e 100644 (file)
    (UNSPEC_ADD_CARRY           34)
    (UNSPEC_FLDCW               35)
    (UNSPEC_REP                 36)
-   (UNSPEC_EH_RETURN           37)
    (UNSPEC_LD_MPIC             38)     ; load_macho_picbase
    (UNSPEC_TRUNC_NOOP          39)
 
    (UNSPECV_CLD                        15)
    (UNSPECV_VZEROALL           16)
    (UNSPECV_VZEROUPPER         17)
+   (UNSPECV_RDTSC              18)
+   (UNSPECV_RDTSCP             19)
+   (UNSPECV_RDPMC              20)
   ])
 
 ;; Constants to represent pcomtrue/pcomfalse variants
    (R9_REG                     38)
    (R10_REG                    39)
    (R11_REG                    40)
+   (R12_REG                    41)
    (R13_REG                    42)
    (XMM8_REG                   45)
    (XMM9_REG                   46)
 
 ;; Set when length prefix is used.
 (define_attr "prefix_data16" ""
-  (if_then_else (ior (eq_attr "mode" "HI")
-                    (and (eq_attr "unit" "sse") (eq_attr "mode" "V2DF")))
-    (const_int 1)
-    (const_int 0)))
+  (cond [(eq_attr "type" "ssemuladd,sse4arg,sseiadd1,ssecvt1")
+          (const_int 0)
+        (eq_attr "mode" "HI")
+          (const_int 1)
+        (and (eq_attr "unit" "sse") (eq_attr "mode" "V2DF,TI"))
+          (const_int 1)
+       ]
+       (const_int 0)))
 
 ;; Set when string REP prefix is used.
 (define_attr "prefix_rep" ""
-  (if_then_else (and (eq_attr "unit" "sse") (eq_attr "mode" "SF,DF"))
-    (const_int 1)
-    (const_int 0)))
+  (cond [(eq_attr "type" "ssemuladd,sse4arg,sseiadd1,ssecvt1")
+          (const_int 0)
+        (and (eq_attr "unit" "sse") (eq_attr "mode" "SF,DF"))
+          (const_int 1)
+       ]
+       (const_int 0)))
 
 ;; Set when 0f opcode prefix is used.
 (define_attr "prefix_0f" ""
 
 ;; Set when REX opcode prefix is used.
 (define_attr "prefix_rex" ""
-  (cond [(and (eq_attr "mode" "DI")
-             (eq_attr "type" "!push,pop,call,callv,leave,ibr"))
+  (cond [(ne (symbol_ref "!TARGET_64BIT") (const_int 0))
+          (const_int 0)
+        (and (eq_attr "mode" "DI")
+             (and (eq_attr "type" "!push,pop,call,callv,leave,ibr")
+                  (eq_attr "unit" "!mmx")))
           (const_int 1)
         (and (eq_attr "mode" "QI")
              (ne (symbol_ref "x86_extended_QIreg_mentioned_p (insn)")
         (ne (symbol_ref "x86_extended_reg_mentioned_p (insn)")
             (const_int 0))
           (const_int 1)
+        (and (eq_attr "type" "imovx")
+             (match_operand:QI 1 "ext_QIreg_operand" ""))
+          (const_int 1)
        ]
        (const_int 0)))
 
-;; There are also additional prefixes in SSSE3.
-(define_attr "prefix_extra" "" (const_int 0))
+;; There are also additional prefixes in 3DNOW, SSSE3 or SSE5.
+;; 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.
+(define_attr "prefix_extra" ""
+  (cond [(eq_attr "type" "ssemuladd,sse4arg")
+          (const_int 2)
+        (eq_attr "type" "sseiadd1,ssecvt1")
+          (const_int 1)
+       ]
+       (const_int 0)))
 
 ;; Prefix used: original, VEX or maybe VEX.
 (define_attr "prefix" "orig,vex,maybe_vex"
     (const_string "vex")
     (const_string "orig")))
 
-;; There is a 8bit immediate for VEX.
-(define_attr "prefix_vex_imm8" "" (const_int 0))
-
 ;; VEX W bit is used.
 (define_attr "prefix_vex_w" "" (const_int 0))
 
 ;; The length of VEX prefix
+;; Only instructions with 0f prefix can have 2 byte VEX prefix,
+;; 0f38/0f3a prefixes can't.  In i386.md 0f3[8a] is
+;; still prefix_0f 1, with prefix_extra 1.
 (define_attr "length_vex" ""
-  (if_then_else (eq_attr "prefix_0f" "1")
+  (if_then_else (and (eq_attr "prefix_0f" "1")
+                    (eq_attr "prefix_extra" "0"))
     (if_then_else (eq_attr "prefix_vex_w" "1")
       (symbol_ref "ix86_attr_length_vex_default (insn, 1, 1)")
       (symbol_ref "ix86_attr_length_vex_default (insn, 1, 0)"))
         (eq_attr "unit" "i387")
           (const_int 0)
          (and (eq_attr "type" "incdec")
-             (ior (match_operand:SI 1 "register_operand" "")
-                  (match_operand:HI 1 "register_operand" "")))
+             (and (eq (symbol_ref "TARGET_64BIT") (const_int 0))
+                  (ior (match_operand:SI 1 "register_operand" "")
+                       (match_operand:HI 1 "register_operand" ""))))
           (const_int 0)
         (and (eq_attr "type" "push")
              (not (match_operand 1 "memory_operand" "")))
              (not (match_operand 0 "memory_operand" "")))
           (const_int 0)
         (and (eq_attr "type" "imov")
-             (ior (and (match_operand 0 "register_operand" "")
-                       (match_operand 1 "immediate_operand" ""))
-                  (ior (and (match_operand 0 "ax_reg_operand" "")
-                            (match_operand 1 "memory_displacement_only_operand" ""))
-                       (and (match_operand 0 "memory_displacement_only_operand" "")
-                            (match_operand 1 "ax_reg_operand" "")))))
+             (and (not (eq_attr "mode" "DI"))
+                  (ior (and (match_operand 0 "register_operand" "")
+                            (match_operand 1 "immediate_operand" ""))
+                       (ior (and (match_operand 0 "ax_reg_operand" "")
+                                 (match_operand 1 "memory_displacement_only_operand" ""))
+                            (and (match_operand 0 "memory_displacement_only_operand" "")
+                                 (match_operand 1 "ax_reg_operand" ""))))))
           (const_int 0)
         (and (eq_attr "type" "call")
              (match_operand 0 "constant_call_address_operand" ""))
         (and (eq_attr "type" "callv")
              (match_operand 1 "constant_call_address_operand" ""))
             (const_int 0)
+        (and (eq_attr "type" "alu,alu1,icmp,test")
+             (match_operand 0 "ax_reg_operand" ""))
+            (symbol_ref "(get_attr_length_immediate (insn) <= (get_attr_mode (insn) != MODE_QI))")
         ]
         (const_int 1)))
 
              (and (eq_attr "prefix" "maybe_vex")
                    (ne (symbol_ref "TARGET_AVX") (const_int 0))))
           (plus (attr "length_vex")
-                (plus (attr "prefix_vex_imm8")
+                (plus (attr "length_immediate")
                       (plus (attr "modrm")
                             (attr "length_address"))))]
         (plus (plus (attr "modrm")
 (include "constraints.md")
 
 \f
-;; Compare instructions.
+;; Compare and branch/compare and store instructions.
+
+(define_expand "cbranchti4"
+  [(set (reg:CC FLAGS_REG)
+       (compare:CC (match_operand:TI 1 "nonimmediate_operand" "")
+                   (match_operand:TI 2 "x86_64_general_operand" "")))
+   (set (pc) (if_then_else
+              (match_operator 0 "comparison_operator"
+               [(reg:CC FLAGS_REG)
+                (const_int 0)])
+              (label_ref (match_operand 3 "" ""))
+              (pc)))]
+  "TARGET_64BIT"
+{
+  if (MEM_P (operands[1]) && MEM_P (operands[2]))
+    operands[1] = force_reg (TImode, operands[1]);
+  ix86_compare_op0 = operands[1];
+  ix86_compare_op1 = operands[2];
+  ix86_expand_branch (GET_CODE (operands[0]), operands[3]);
+  DONE;
+})
 
-;; All compare insns have expanders that save the operands away without
-;; actually generating RTL.  The bCOND or sCOND (emitted immediately
-;; after the cmp) will actually emit the cmpM.
+(define_expand "cbranchdi4"
+  [(set (reg:CC FLAGS_REG)
+       (compare:CC (match_operand:DI 1 "nonimmediate_operand" "")
+                   (match_operand:DI 2 "x86_64_general_operand" "")))
+   (set (pc) (if_then_else
+              (match_operator 0 "comparison_operator"
+               [(reg:CC FLAGS_REG)
+                (const_int 0)])
+              (label_ref (match_operand 3 "" ""))
+              (pc)))]
+  ""
+{
+  if (MEM_P (operands[1]) && MEM_P (operands[2]))
+    operands[1] = force_reg (DImode, operands[1]);
+  ix86_compare_op0 = operands[1];
+  ix86_compare_op1 = operands[2];
+  ix86_expand_branch (GET_CODE (operands[0]), operands[3]);
+  DONE;
+})
 
-(define_expand "cmpti"
+(define_expand "cstoredi4"
   [(set (reg:CC FLAGS_REG)
-       (compare:CC (match_operand:TI 0 "nonimmediate_operand" "")
-                   (match_operand:TI 1 "x86_64_general_operand" "")))]
+       (compare:CC (match_operand:DI 2 "nonimmediate_operand" "")
+                   (match_operand:DI 3 "x86_64_general_operand" "")))
+   (set (match_operand:QI 0 "register_operand" "")
+              (match_operator 1 "comparison_operator"
+               [(reg:CC FLAGS_REG)
+                (const_int 0)]))]
   "TARGET_64BIT"
 {
-  if (MEM_P (operands[0]) && MEM_P (operands[1]))
-    operands[0] = force_reg (TImode, operands[0]);
-  ix86_compare_op0 = operands[0];
-  ix86_compare_op1 = operands[1];
+  if (MEM_P (operands[2]) && MEM_P (operands[3]))
+    operands[2] = force_reg (DImode, operands[2]);
+  ix86_compare_op0 = operands[2];
+  ix86_compare_op1 = operands[3];
+  ix86_expand_setcc (GET_CODE (operands[1]), operands[0]);
   DONE;
 })
 
-(define_expand "cmpdi"
+(define_expand "cbranchsi4"
   [(set (reg:CC FLAGS_REG)
-       (compare:CC (match_operand:DI 0 "nonimmediate_operand" "")
-                   (match_operand:DI 1 "x86_64_general_operand" "")))]
+       (compare:CC (match_operand:SI 1 "cmpsi_operand" "")
+                   (match_operand:SI 2 "general_operand" "")))
+   (set (pc) (if_then_else
+              (match_operator 0 "comparison_operator"
+               [(reg:CC FLAGS_REG)
+                (const_int 0)])
+              (label_ref (match_operand 3 "" ""))
+              (pc)))]
   ""
 {
-  if (MEM_P (operands[0]) && MEM_P (operands[1]))
-    operands[0] = force_reg (DImode, operands[0]);
-  ix86_compare_op0 = operands[0];
-  ix86_compare_op1 = operands[1];
+  if (MEM_P (operands[1]) && MEM_P (operands[2]))
+    operands[1] = force_reg (SImode, operands[1]);
+  ix86_compare_op0 = operands[1];
+  ix86_compare_op1 = operands[2];
+  ix86_expand_branch (GET_CODE (operands[0]), operands[3]);
   DONE;
 })
 
-(define_expand "cmpsi"
+(define_expand "cstoresi4"
   [(set (reg:CC FLAGS_REG)
-       (compare:CC (match_operand:SI 0 "cmpsi_operand" "")
-                   (match_operand:SI 1 "general_operand" "")))]
+       (compare:CC (match_operand:SI 2 "cmpsi_operand" "")
+                   (match_operand:SI 3 "general_operand" "")))
+   (set (match_operand:QI 0 "register_operand" "")
+              (match_operator 1 "comparison_operator"
+               [(reg:CC FLAGS_REG)
+                (const_int 0)]))]
   ""
 {
-  if (MEM_P (operands[0]) && MEM_P (operands[1]))
-    operands[0] = force_reg (SImode, operands[0]);
-  ix86_compare_op0 = operands[0];
-  ix86_compare_op1 = operands[1];
+  if (MEM_P (operands[2]) && MEM_P (operands[3]))
+    operands[2] = force_reg (SImode, operands[2]);
+  ix86_compare_op0 = operands[2];
+  ix86_compare_op1 = operands[3];
+  ix86_expand_setcc (GET_CODE (operands[1]), operands[0]);
   DONE;
 })
 
-(define_expand "cmphi"
+(define_expand "cbranchhi4"
   [(set (reg:CC FLAGS_REG)
-       (compare:CC (match_operand:HI 0 "nonimmediate_operand" "")
-                   (match_operand:HI 1 "general_operand" "")))]
+       (compare:CC (match_operand:HI 1 "nonimmediate_operand" "")
+                   (match_operand:HI 2 "general_operand" "")))
+   (set (pc) (if_then_else
+              (match_operator 0 "comparison_operator"
+               [(reg:CC FLAGS_REG)
+                (const_int 0)])
+              (label_ref (match_operand 3 "" ""))
+              (pc)))]
   ""
 {
-  if (MEM_P (operands[0]) && MEM_P (operands[1]))
-    operands[0] = force_reg (HImode, operands[0]);
-  ix86_compare_op0 = operands[0];
-  ix86_compare_op1 = operands[1];
+  if (MEM_P (operands[1]) && MEM_P (operands[2]))
+    operands[1] = force_reg (HImode, operands[1]);
+  ix86_compare_op0 = operands[1];
+  ix86_compare_op1 = operands[2];
+  ix86_expand_branch (GET_CODE (operands[0]), operands[3]);
   DONE;
 })
 
-(define_expand "cmpqi"
+(define_expand "cstorehi4"
   [(set (reg:CC FLAGS_REG)
-       (compare:CC (match_operand:QI 0 "nonimmediate_operand" "")
-                   (match_operand:QI 1 "general_operand" "")))]
-  "TARGET_QIMODE_MATH"
+       (compare:CC (match_operand:HI 2 "nonimmediate_operand" "")
+                   (match_operand:HI 3 "general_operand" "")))
+   (set (match_operand:QI 0 "register_operand" "")
+              (match_operator 1 "comparison_operator"
+               [(reg:CC FLAGS_REG)
+                (const_int 0)]))]
+  ""
 {
-  if (MEM_P (operands[0]) && MEM_P (operands[1]))
-    operands[0] = force_reg (QImode, operands[0]);
-  ix86_compare_op0 = operands[0];
-  ix86_compare_op1 = operands[1];
+  if (MEM_P (operands[2]) && MEM_P (operands[3]))
+    operands[2] = force_reg (HImode, operands[2]);
+  ix86_compare_op0 = operands[2];
+  ix86_compare_op1 = operands[3];
+  ix86_expand_setcc (GET_CODE (operands[1]), operands[0]);
+  DONE;
+})
+
+
+(define_expand "cbranchqi4"
+  [(set (reg:CC FLAGS_REG)
+       (compare:CC (match_operand:QI 1 "nonimmediate_operand" "")
+                   (match_operand:QI 2 "general_operand" "")))
+   (set (pc) (if_then_else
+              (match_operator 0 "comparison_operator"
+               [(reg:CC FLAGS_REG)
+                (const_int 0)])
+              (label_ref (match_operand 3 "" ""))
+              (pc)))]
+  ""
+{
+  if (MEM_P (operands[1]) && MEM_P (operands[2]))
+    operands[1] = force_reg (QImode, operands[1]);
+  ix86_compare_op0 = operands[1];
+  ix86_compare_op1 = operands[2];
+  ix86_expand_branch (GET_CODE (operands[0]), operands[3]);
   DONE;
 })
 
+
+(define_expand "cstoreqi4"
+  [(set (reg:CC FLAGS_REG)
+       (compare:CC (match_operand:QI 2 "nonimmediate_operand" "")
+                   (match_operand:QI 3 "general_operand" "")))
+   (set (match_operand:QI 0 "register_operand" "")
+              (match_operator 1 "comparison_operator"
+               [(reg:CC FLAGS_REG)
+                (const_int 0)]))]
+  ""
+{
+  if (MEM_P (operands[2]) && MEM_P (operands[3]))
+    operands[2] = force_reg (QImode, operands[2]);
+  ix86_compare_op0 = operands[2];
+  ix86_compare_op1 = operands[3];
+  ix86_expand_setcc (GET_CODE (operands[1]), operands[0]);
+  DONE;
+})
+
+
 (define_insn "cmpdi_ccno_1_rex64"
   [(set (reg FLAGS_REG)
        (compare (match_operand:DI 0 "nonimmediate_operand" "r,?mr")
   "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
   "cmp{b}\t{%1, %h0|%h0, %1}"
   [(set_attr "type" "icmp")
+   (set_attr "modrm" "1")
    (set_attr "mode" "QI")])
 
 (define_insn "cmpqi_ext_3_insn_rex64"
   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
   "cmp{b}\t{%1, %h0|%h0, %1}"
   [(set_attr "type" "icmp")
+   (set_attr "modrm" "1")
    (set_attr "mode" "QI")])
 
 (define_insn "*cmpqi_ext_4"
 ;; which would allow mix and match FP modes on the compares.  Which is what
 ;; the old patterns did, but with many more of them.
 
-(define_expand "cmpxf"
+(define_expand "cbranchxf4"
   [(set (reg:CC FLAGS_REG)
-       (compare:CC (match_operand:XF 0 "nonmemory_operand" "")
-                   (match_operand:XF 1 "nonmemory_operand" "")))]
+       (compare:CC (match_operand:XF 1 "nonmemory_operand" "")
+                   (match_operand:XF 2 "nonmemory_operand" "")))
+   (set (pc) (if_then_else
+              (match_operator 0 "ix86_fp_comparison_operator"
+               [(reg:CC FLAGS_REG)
+                (const_int 0)])
+              (label_ref (match_operand 3 "" ""))
+              (pc)))]
   "TARGET_80387"
 {
-  ix86_compare_op0 = operands[0];
-  ix86_compare_op1 = operands[1];
+  ix86_compare_op0 = operands[1];
+  ix86_compare_op1 = operands[2];
+  ix86_expand_branch (GET_CODE (operands[0]), operands[3]);
   DONE;
 })
 
-(define_expand "cmp<mode>"
+(define_expand "cstorexf4"
   [(set (reg:CC FLAGS_REG)
-       (compare:CC (match_operand:MODEF 0 "cmp_fp_expander_operand" "")
-                   (match_operand:MODEF 1 "cmp_fp_expander_operand" "")))]
+       (compare:CC (match_operand:XF 2 "nonmemory_operand" "")
+                   (match_operand:XF 3 "nonmemory_operand" "")))
+   (set (match_operand:QI 0 "register_operand" "")
+              (match_operator 1 "ix86_fp_comparison_operator"
+               [(reg:CC FLAGS_REG)
+                (const_int 0)]))]
+  "TARGET_80387"
+{
+  ix86_compare_op0 = operands[2];
+  ix86_compare_op1 = operands[3];
+  ix86_expand_setcc (GET_CODE (operands[1]), operands[0]);
+  DONE;
+})
+
+(define_expand "cbranch<mode>4"
+  [(set (reg:CC FLAGS_REG)
+       (compare:CC (match_operand:MODEF 1 "cmp_fp_expander_operand" "")
+                   (match_operand:MODEF 2 "cmp_fp_expander_operand" "")))
+   (set (pc) (if_then_else
+              (match_operator 0 "ix86_fp_comparison_operator"
+               [(reg:CC FLAGS_REG)
+                (const_int 0)])
+              (label_ref (match_operand 3 "" ""))
+              (pc)))]
   "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
 {
-  ix86_compare_op0 = operands[0];
-  ix86_compare_op1 = operands[1];
+  ix86_compare_op0 = operands[1];
+  ix86_compare_op1 = operands[2];
+  ix86_expand_branch (GET_CODE (operands[0]), operands[3]);
   DONE;
 })
 
-(define_expand "cmpcc"
+(define_expand "cstore<mode>4"
   [(set (reg:CC FLAGS_REG)
-        (compare:CC (match_operand 0 "flags_reg_operand" "")
-                    (match_operand 1 "general_operand" "")))]
+       (compare:CC (match_operand:MODEF 2 "cmp_fp_expander_operand" "")
+                   (match_operand:MODEF 3 "cmp_fp_expander_operand" "")))
+   (set (match_operand:QI 0 "register_operand" "")
+              (match_operator 1 "ix86_fp_comparison_operator"
+               [(reg:CC FLAGS_REG)
+                (const_int 0)]))]
+  "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
+{
+  ix86_compare_op0 = operands[2];
+  ix86_compare_op1 = operands[3];
+  ix86_expand_setcc (GET_CODE (operands[1]), operands[0]);
+  DONE;
+})
+
+(define_expand "cbranchcc4"
+  [(set (pc) (if_then_else
+              (match_operator 0 "comparison_operator"
+               [(match_operand 1 "flags_reg_operand" "")
+                (match_operand 2 "const0_operand" "")])
+              (label_ref (match_operand 3 "" ""))
+              (pc)))]
+  ""
+{
+  ix86_compare_op0 = operands[1];
+  ix86_compare_op1 = operands[2];
+  ix86_expand_branch (GET_CODE (operands[0]), operands[3]);
+  DONE;
+})
+
+(define_expand "cstorecc4"
+  [(set (match_operand:QI 0 "register_operand" "")
+              (match_operator 1 "comparison_operator"
+               [(match_operand 2 "flags_reg_operand" "")
+                (match_operand 3 "const0_operand" "")]))]
   ""
 {
-  ix86_compare_op0 = operands[0];
-  ix86_compare_op1 = operands[1];
+  ix86_compare_op0 = operands[2];
+  ix86_compare_op1 = operands[3];
+  ix86_expand_setcc (GET_CODE (operands[1]), operands[0]);
   DONE;
 })
 
+
 ;; FP compares, step 1:
 ;; Set the FP condition codes.
 ;;
        (unspec:HI [(reg:CCFP FPSR_REG)] UNSPEC_FNSTSW))]
   "TARGET_80387"
   "fnstsw\t%0"
-  [(set_attr "length" "2")
+  [(set (attr "length") (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
    (set_attr "mode" "SI")
    (set_attr "unit" "i387")])
 
 #ifdef HAVE_AS_IX86_SAHF
   return "sahf";
 #else
-  return ".byte\t0x9e";
+  return ASM_BYTE "0x9e";
 #endif
 }
   [(set_attr "length" "1")
      (if_then_else (match_operand:SF 1 "" "")
         (const_string "SF")
         (const_string "DF")))
+   (set (attr "prefix_rep")
+       (if_then_else (eq_attr "type" "ssecomi")
+                     (const_string "0")
+                     (const_string "*")))
+   (set (attr "prefix_data16")
+       (cond [(eq_attr "type" "fcmp")
+                (const_string "*")
+              (eq_attr "mode" "DF")
+                (const_string "1")
+             ]
+             (const_string "0")))
    (set_attr "athlon_decode" "vector")
    (set_attr "amdfam10_decode" "direct")])
 
      (if_then_else (match_operand:SF 1 "" "")
         (const_string "SF")
         (const_string "DF")))
+   (set_attr "prefix_rep" "0")
+   (set (attr "prefix_data16")
+       (if_then_else (eq_attr "mode" "DF")
+                     (const_string "1")
+                     (const_string "0")))
    (set_attr "athlon_decode" "vector")
    (set_attr "amdfam10_decode" "direct")])
 
      (if_then_else (match_operand:SF 1 "" "")
         (const_string "SF")
         (const_string "DF")))
+   (set (attr "prefix_rep")
+       (if_then_else (eq_attr "type" "ssecomi")
+                     (const_string "0")
+                     (const_string "*")))
+   (set (attr "prefix_data16")
+       (cond [(eq_attr "type" "fcmp")
+                (const_string "*")
+              (eq_attr "mode" "DF")
+                (const_string "1")
+             ]
+             (const_string "0")))
    (set_attr "athlon_decode" "vector")
    (set_attr "amdfam10_decode" "direct")])
 
      (if_then_else (match_operand:SF 1 "" "")
         (const_string "SF")
         (const_string "DF")))
+   (set_attr "prefix_rep" "0")
+   (set (attr "prefix_data16")
+       (if_then_else (eq_attr "mode" "DF")
+                     (const_string "1")
+                     (const_string "0")))
    (set_attr "athlon_decode" "vector")
    (set_attr "amdfam10_decode" "direct")])
 
      (if_then_else (eq_attr "alternative" "0,1,2,3,4,5")
        (const_string "orig")
        (const_string "maybe_vex")))
+   (set (attr "prefix_data16")
+     (if_then_else (and (eq_attr "type" "ssemov") (eq_attr "mode" "SI"))
+       (const_string "1")
+       (const_string "*")))
    (set (attr "mode")
      (cond [(eq_attr "alternative" "2,3")
              (const_string "DI")
   "TARGET_64BIT"
   "movz{bl|x}\t{%h1, %k0|%k0, %h1}"
   [(set_attr "type" "imovx")
-   (set_attr "mode" "DI")])
+   (set_attr "mode" "SI")])
 
 (define_insn "*movsi_extzv_1"
   [(set (match_operand:SI 0 "register_operand" "=R")
              (const_string "lea")
           ]
           (const_string "imov")))
-   (set_attr "modrm" "*,0,0,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*")
-   (set_attr "length_immediate" "*,4,8,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*")
+   (set (attr "modrm")
+     (if_then_else
+       (and (eq_attr "alternative" "2") (eq_attr "type" "imov"))
+        (const_string "0")
+        (const_string "*")))
+   (set (attr "length_immediate")
+     (if_then_else
+       (and (eq_attr "alternative" "2") (eq_attr "type" "imov"))
+        (const_string "8")
+        (const_string "*")))
+   (set_attr "prefix_rex" "*,*,*,*,*,*,*,1,*,1,*,*,*,*,*,*,*,*,*")
+   (set_attr "prefix_data16" "*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,1,*,*,*")
    (set (attr "prefix")
      (if_then_else (eq_attr "alternative" "11,12,13,14,15,16")
        (const_string "maybe_vex")
      (if_then_else (eq_attr "alternative" "0,1,2,3,4")
        (const_string "orig")
        (const_string "maybe_vex")))
+   (set (attr "prefix_data16")
+     (if_then_else (eq_attr "mode" "V1DF")
+       (const_string "1")
+       (const_string "*")))
    (set (attr "mode")
         (cond [(eq_attr "alternative" "0,1,2")
                 (const_string "DF")
      (if_then_else (eq_attr "alternative" "0,1,2,3,4")
        (const_string "orig")
        (const_string "maybe_vex")))
+   (set (attr "prefix_data16")
+     (if_then_else (eq_attr "mode" "V1DF")
+       (const_string "1")
+       (const_string "*")))
    (set (attr "mode")
         (cond [(eq_attr "alternative" "0,1,2")
                 (const_string "DF")
     }
 }
   [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov")
+   (set (attr "prefix_data16")
+     (if_then_else (eq_attr "mode" "V1DF")
+       (const_string "1")
+       (const_string "*")))
    (set (attr "mode")
         (cond [(eq_attr "alternative" "0,1,2")
                 (const_string "DF")
    %vmovd\t{%1, %0|%0, %1}"
   [(set_attr "type" "imovx,imov,mmxmov,mmxmov,ssemov,ssemov")
    (set_attr "prefix" "orig,*,orig,orig,maybe_vex,maybe_vex")
+   (set_attr "prefix_0f" "0,*,*,*,*,*")
    (set_attr "mode" "SI,DI,DI,DI,TI,TI")])
 
 (define_split
   "TARGET_64BIT"
   "movz{wl|x}\t{%1, %k0|%k0, %1}"
   [(set_attr "type" "imovx")
-   (set_attr "mode" "DI")])
+   (set_attr "mode" "SI")])
 
 (define_insn "zero_extendqidi2"
   [(set (match_operand:DI 0 "register_operand" "=r")
   "TARGET_64BIT"
   "movz{bl|x}\t{%1, %k0|%k0, %1}"
   [(set_attr "type" "imovx")
-   (set_attr "mode" "DI")])
+   (set_attr "mode" "SI")])
 \f
 ;; Sign extension instructions
 
   "TARGET_64BIT"
   "@
    {cltq|cdqe}
-   movs{lq|x}\t{%1,%0|%0, %1}"
+   movs{lq|x}\t{%1, %0|%0, %1}"
   [(set_attr "type" "imovx")
    (set_attr "mode" "DI")
    (set_attr "prefix_0f" "0")
   [(set (match_operand:DI 0 "register_operand" "=r")
        (sign_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
   "TARGET_64BIT"
-  "movs{wq|x}\t{%1,%0|%0, %1}"
+  "movs{wq|x}\t{%1, %0|%0, %1}"
   [(set_attr "type" "imovx")
    (set_attr "mode" "DI")])
 
   [(set (match_operand:DI 0 "register_operand" "=r")
        (sign_extend:DI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
   "TARGET_64BIT"
-  "movs{bq|x}\t{%1,%0|%0, %1}"
+  "movs{bq|x}\t{%1, %0|%0, %1}"
    [(set_attr "type" "imovx")
     (set_attr "mode" "DI")])
 
     case 0:
       return "{cwtl|cwde}";
     default:
-      return "movs{wl|x}\t{%1,%0|%0, %1}";
+      return "movs{wl|x}\t{%1, %0|%0, %1}";
     }
 }
   [(set_attr "type" "imovx")
     case 0:
       return "{cwtl|cwde}";
     default:
-      return "movs{wl|x}\t{%1,%k0|%k0, %1}";
+      return "movs{wl|x}\t{%1, %k0|%k0, %1}";
     }
 }
   [(set_attr "type" "imovx")
     case 0:
       return "{cbtw|cbw}";
     default:
-      return "movs{bw|x}\t{%1,%0|%0, %1}";
+      return "movs{bw|x}\t{%1, %0|%0, %1}";
     }
 }
   [(set_attr "type" "imovx")
   [(set (match_operand:SI 0 "register_operand" "=r")
        (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
   ""
-  "movs{bl|x}\t{%1,%0|%0, %1}"
+  "movs{bl|x}\t{%1, %0|%0, %1}"
    [(set_attr "type" "imovx")
     (set_attr "mode" "SI")])
 
        (zero_extend:DI
          (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
   "TARGET_64BIT"
-  "movs{bl|x}\t{%1,%k0|%k0, %1}"
+  "movs{bl|x}\t{%1, %k0|%k0, %1}"
    [(set_attr "type" "imovx")
     (set_attr "mode" "SI")])
 \f
   "%vcvtts<ssemodefsuffix>2si{q}\t{%1, %0|%0, %1}"
   [(set_attr "type" "sseicvt")
    (set_attr "prefix" "maybe_vex")
+   (set_attr "prefix_rex" "1")
    (set_attr "mode" "<MODE>")
    (set_attr "athlon_decode" "double,vector")
    (set_attr "amdfam10_decode" "double,double")])
    && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
         && (TARGET_64BIT || <MODE>mode != DImode))
        && TARGET_SSE_MATH)
-   && !(reload_completed || reload_in_progress)"
+   && can_create_pseudo_p ()"
   "#"
   "&& 1"
   [(const_int 0)]
    && !TARGET_FISTTP
    && !(SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
         && (TARGET_64BIT || <MODE>mode != DImode))
-   && !(reload_completed || reload_in_progress)"
+   && can_create_pseudo_p ()"
   "#"
   "&& 1"
   [(const_int 0)]
        (unspec:HI [(reg:HI FPCR_REG)] UNSPEC_FSTCW))]
   "TARGET_80387"
   "fnstcw\t%0"
-  [(set_attr "length" "2")
+  [(set (attr "length") (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
    (set_attr "mode" "HI")
    (set_attr "unit" "i387")])
 
        (unspec:HI [(match_operand:HI 0 "memory_operand" "m")] UNSPEC_FLDCW))]
   "TARGET_80387"
   "fldcw\t%0"
-  [(set_attr "length" "2")
+  [(set (attr "length") (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
    (set_attr "mode" "HI")
    (set_attr "unit" "i387")
    (set_attr "athlon_decode" "vector")
   "TARGET_80387
    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
        || TARGET_MIX_SSE_I387)
-   && !(reload_completed || reload_in_progress)"
+   && can_create_pseudo_p ()"
   "#"
   "&& 1"
   [(parallel [(set (match_dup 0)
             && flag_trapping_math)
            || !(TARGET_INTER_UNIT_CONVERSIONS
                 || optimize_function_for_size_p (cfun)))))
-   && !(reload_completed || reload_in_progress)"
+   && can_create_pseudo_p ()"
   "#"
   "&& 1"
   [(parallel [(set (match_dup 0) (float:X87MODEF (match_dup 1)))
   [(set_attr "type" "fmov,sseicvt,sseicvt")
    (set_attr "prefix" "orig,maybe_vex,maybe_vex")
    (set_attr "mode" "<MODEF:MODE>")
+   (set (attr "prefix_rex")
+     (if_then_else
+       (and (eq_attr "prefix" "maybe_vex")
+           (ne (symbol_ref "<SSEMODEI24:MODE>mode == DImode") (const_int 0)))
+       (const_string "1")
+       (const_string "*")))
    (set_attr "unit" "i387,*,*")
    (set_attr "athlon_decode" "*,double,direct")
    (set_attr "amdfam10_decode" "*,vector,double")
   [(set_attr "type" "fmov,sseicvt")
    (set_attr "prefix" "orig,maybe_vex")
    (set_attr "mode" "<MODEF:MODE>")
+   (set (attr "prefix_rex")
+     (if_then_else
+       (and (eq_attr "prefix" "maybe_vex")
+           (ne (symbol_ref "<SSEMODEI24:MODE>mode == DImode") (const_int 0)))
+       (const_string "1")
+       (const_string "*")))
    (set_attr "athlon_decode" "*,direct")
    (set_attr "amdfam10_decode" "*,double")
    (set_attr "fp_int_src" "true")])
   [(set_attr "type" "sseicvt")
    (set_attr "prefix" "maybe_vex")
    (set_attr "mode" "<MODEF:MODE>")
+   (set (attr "prefix_rex")
+     (if_then_else
+       (and (eq_attr "prefix" "maybe_vex")
+           (ne (symbol_ref "<SSEMODEI24:MODE>mode == DImode") (const_int 0)))
+       (const_string "1")
+       (const_string "*")))
    (set_attr "athlon_decode" "double,direct")
    (set_attr "amdfam10_decode" "vector,double")
    (set_attr "fp_int_src" "true")])
   [(set_attr "type" "sseicvt")
    (set_attr "prefix" "maybe_vex")
    (set_attr "mode" "<MODEF:MODE>")
+   (set (attr "prefix_rex")
+     (if_then_else
+       (and (eq_attr "prefix" "maybe_vex")
+           (ne (symbol_ref "<SSEMODEI24:MODE>mode == DImode") (const_int 0)))
+       (const_string "1")
+       (const_string "*")))
    (set_attr "athlon_decode" "direct")
    (set_attr "amdfam10_decode" "double")
    (set_attr "fp_int_src" "true")])
              (const_string "incdec")
           ]
           (const_string "alu")))
+   (set (attr "length_immediate")
+      (if_then_else
+       (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
+       (const_string "1")
+       (const_string "*")))
    (set_attr "mode" "DI")])
 
 ;; Convert lea to the lea pattern to avoid flags dependency.
      (if_then_else (match_operand:DI 2 "incdec_operand" "")
        (const_string "incdec")
        (const_string "alu")))
+   (set (attr "length_immediate")
+      (if_then_else
+       (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
+       (const_string "1")
+       (const_string "*")))
    (set_attr "mode" "DI")])
 
 (define_insn "*adddi_3_rex64"
      (if_then_else (match_operand:DI 2 "incdec_operand" "")
        (const_string "incdec")
        (const_string "alu")))
+   (set (attr "length_immediate")
+      (if_then_else
+       (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
+       (const_string "1")
+       (const_string "*")))
    (set_attr "mode" "DI")])
 
 ; For comparisons against 1, -1 and 128, we may generate better code
      (if_then_else (match_operand:DI 2 "incdec_operand" "")
        (const_string "incdec")
        (const_string "alu")))
+   (set (attr "length_immediate")
+      (if_then_else
+       (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
+       (const_string "1")
+       (const_string "*")))
    (set_attr "mode" "DI")])
 
 (define_insn "*adddi_5_rex64"
      (if_then_else (match_operand:DI 2 "incdec_operand" "")
        (const_string "incdec")
        (const_string "alu")))
+   (set (attr "length_immediate")
+      (if_then_else
+       (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
+       (const_string "1")
+       (const_string "*")))
    (set_attr "mode" "DI")])
 
 
              (const_string "incdec")
           ]
           (const_string "alu")))
+   (set (attr "length_immediate")
+      (if_then_else
+       (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
+       (const_string "1")
+       (const_string "*")))
    (set_attr "mode" "SI")])
 
 ;; Convert lea to the lea pattern to avoid flags dependency.
              (const_string "incdec")
           ]
           (const_string "alu")))
+   (set (attr "length_immediate")
+      (if_then_else
+       (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
+       (const_string "1")
+       (const_string "*")))
    (set_attr "mode" "SI")])
 
 ;; Convert lea to the lea pattern to avoid flags dependency.
      (if_then_else (match_operand:SI 2 "incdec_operand" "")
        (const_string "incdec")
        (const_string "alu")))
+   (set (attr "length_immediate")
+      (if_then_else
+       (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
+       (const_string "1")
+       (const_string "*")))
    (set_attr "mode" "SI")])
 
 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
      (if_then_else (match_operand:SI 2 "incdec_operand" "")
        (const_string "incdec")
        (const_string "alu")))
+   (set (attr "length_immediate")
+      (if_then_else
+       (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
+       (const_string "1")
+       (const_string "*")))
    (set_attr "mode" "SI")])
 
 (define_insn "*addsi_3"
      (if_then_else (match_operand:SI 2 "incdec_operand" "")
        (const_string "incdec")
        (const_string "alu")))
+   (set (attr "length_immediate")
+      (if_then_else
+       (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
+       (const_string "1")
+       (const_string "*")))
    (set_attr "mode" "SI")])
 
 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
      (if_then_else (match_operand:SI 2 "incdec_operand" "")
        (const_string "incdec")
        (const_string "alu")))
+   (set (attr "length_immediate")
+      (if_then_else
+       (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
+       (const_string "1")
+       (const_string "*")))
    (set_attr "mode" "SI")])
 
 ; For comparisons against 1, -1 and 128, we may generate better code
      (if_then_else (match_operand:SI 2 "incdec_operand" "")
        (const_string "incdec")
        (const_string "alu")))
+   (set (attr "length_immediate")
+      (if_then_else
+       (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
+       (const_string "1")
+       (const_string "*")))
    (set_attr "mode" "SI")])
 
 (define_insn "*addsi_5"
      (if_then_else (match_operand:SI 2 "incdec_operand" "")
        (const_string "incdec")
        (const_string "alu")))
+   (set (attr "length_immediate")
+      (if_then_else
+       (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
+       (const_string "1")
+       (const_string "*")))
    (set_attr "mode" "SI")])
 
 (define_expand "addhi3"
        (if_then_else (match_operand:HI 2 "incdec_operand" "")
           (const_string "incdec")
           (const_string "alu"))))
+   (set (attr "length_immediate")
+      (if_then_else
+       (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
+       (const_string "1")
+       (const_string "*")))
    (set_attr "mode" "HI,HI,SI")])
 
 (define_insn "*addhi_1"
      (if_then_else (match_operand:HI 2 "incdec_operand" "")
        (const_string "incdec")
        (const_string "alu")))
+   (set (attr "length_immediate")
+      (if_then_else
+       (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
+       (const_string "1")
+       (const_string "*")))
    (set_attr "mode" "HI")])
 
 (define_insn "*addhi_2"
      (if_then_else (match_operand:HI 2 "incdec_operand" "")
        (const_string "incdec")
        (const_string "alu")))
+   (set (attr "length_immediate")
+      (if_then_else
+       (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
+       (const_string "1")
+       (const_string "*")))
    (set_attr "mode" "HI")])
 
 (define_insn "*addhi_3"
      (if_then_else (match_operand:HI 2 "incdec_operand" "")
        (const_string "incdec")
        (const_string "alu")))
+   (set (attr "length_immediate")
+      (if_then_else
+       (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
+       (const_string "1")
+       (const_string "*")))
    (set_attr "mode" "HI")])
 
 ; See comments above addsi_4 for details.
      (if_then_else (match_operand:HI 2 "incdec_operand" "")
        (const_string "incdec")
        (const_string "alu")))
-   (set_attr "mode" "SI")])
+   (set (attr "length_immediate")
+      (if_then_else
+       (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
+       (const_string "1")
+       (const_string "*")))
+   (set_attr "mode" "HI")])
 
 
 (define_insn "*addhi_5"
      (if_then_else (match_operand:HI 2 "incdec_operand" "")
        (const_string "incdec")
        (const_string "alu")))
+   (set (attr "length_immediate")
+      (if_then_else
+       (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
+       (const_string "1")
+       (const_string "*")))
    (set_attr "mode" "HI")])
 
 (define_expand "addqi3"
        (if_then_else (match_operand:QI 2 "incdec_operand" "")
           (const_string "incdec")
           (const_string "alu"))))
+   (set (attr "length_immediate")
+      (if_then_else
+       (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
+       (const_string "1")
+       (const_string "*")))
    (set_attr "mode" "QI,QI,SI,SI")])
 
 (define_insn "*addqi_1"
      (if_then_else (match_operand:QI 2 "incdec_operand" "")
        (const_string "incdec")
        (const_string "alu")))
+   (set (attr "length_immediate")
+      (if_then_else
+       (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
+       (const_string "1")
+       (const_string "*")))
    (set_attr "mode" "QI,QI,SI")])
 
 (define_insn "*addqi_1_slp"
      (if_then_else (match_operand:QI 2 "incdec_operand" "")
        (const_string "incdec")
        (const_string "alu")))
+   (set_attr "modrm" "1")
    (set_attr "mode" "QI")])
 
 (define_insn "*addqi_ext_1_rex64"
      (if_then_else (match_operand:QI 2 "incdec_operand" "")
        (const_string "incdec")
        (const_string "alu")))
+   (set_attr "modrm" "1")
    (set_attr "mode" "QI")])
 
 (define_insn "*addqi_ext_2"
   [(set_attr "type" "test")
    (set_attr "mode" "QI")
    (set_attr "length_immediate" "1")
+   (set_attr "modrm" "1")
    (set_attr "pent_pair" "np")])
 
 (define_insn "*testqi_ext_1"
 
        operands[1] = gen_lowpart (mode, operands[1]);
        if (mode == QImode)
-         return "movz{bq|x}\t{%1,%0|%0, %1}";
+         return "movz{bl|x}\t{%1, %k0|%k0, %1}";
        else
-         return "movz{wq|x}\t{%1,%0|%0, %1}";
+         return "movz{wl|x}\t{%1, %k0|%k0, %1}";
       }
 
     default:
 }
   [(set_attr "type" "alu,alu,alu,imovx")
    (set_attr "length_immediate" "*,*,*,0")
-   (set_attr "mode" "SI,DI,DI,DI")])
+   (set (attr "prefix_rex")
+     (if_then_else
+       (and (eq_attr "type" "imovx")
+           (and (ne (symbol_ref "INTVAL (operands[2]) == 0xff") (const_int 0))
+                (match_operand 1 "ext_QIreg_nomode_operand" "")))
+       (const_string "1")
+       (const_string "*")))
+   (set_attr "mode" "SI,DI,DI,SI")])
 
 (define_insn "*anddi_2"
   [(set (reg FLAGS_REG)
 
        operands[1] = gen_lowpart (mode, operands[1]);
        if (mode == QImode)
-         return "movz{bl|x}\t{%1,%0|%0, %1}";
+         return "movz{bl|x}\t{%1, %0|%0, %1}";
        else
-         return "movz{wl|x}\t{%1,%0|%0, %1}";
+         return "movz{wl|x}\t{%1, %0|%0, %1}";
       }
 
     default:
     }
 }
   [(set_attr "type" "alu,alu,imovx")
+   (set (attr "prefix_rex")
+     (if_then_else
+       (and (eq_attr "type" "imovx")
+           (and (ne (symbol_ref "INTVAL (operands[2]) == 0xff") (const_int 0))
+                (match_operand 1 "ext_QIreg_nomode_operand" "")))
+       (const_string "1")
+       (const_string "*")))
    (set_attr "length_immediate" "*,*,0")
    (set_attr "mode" "SI")])
 
 }
   [(set_attr "type" "alu,alu,imovx")
    (set_attr "length_immediate" "*,*,0")
+   (set (attr "prefix_rex")
+     (if_then_else
+       (and (eq_attr "type" "imovx")
+           (match_operand 1 "ext_QIreg_nomode_operand" ""))
+       (const_string "1")
+       (const_string "*")))
    (set_attr "mode" "HI,HI,SI")])
 
 (define_insn "*andhi_2"
   "and{b}\t{%2, %h0|%h0, %2}"
   [(set_attr "type" "alu")
    (set_attr "length_immediate" "1")
+   (set_attr "modrm" "1")
    (set_attr "mode" "QI")])
 
 ;; Generated by peephole translating test to and.  This shows up
   "and{b}\t{%2, %h0|%h0, %2}"
   [(set_attr "type" "alu")
    (set_attr "length_immediate" "1")
+   (set_attr "modrm" "1")
    (set_attr "mode" "QI")])
 
 (define_insn "*andqi_ext_1"
   "or{b}\t{%2, %h0|%h0, %2}"
   [(set_attr "type" "alu")
    (set_attr "length_immediate" "1")
+   (set_attr "modrm" "1")
    (set_attr "mode" "QI")])
 
 (define_insn "*iorqi_ext_1"
   "xor{b}\t{%2, %h0|%h0, %2}"
   [(set_attr "type" "alu")
    (set_attr "length_immediate" "1")
+   (set_attr "modrm" "1")
    (set_attr "mode" "QI")])
 
 (define_insn "*xorqi_ext_1"
   "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
   "xor{b}\t{%2, %h0|%h0, %2}"
   [(set_attr "type" "alu")
+   (set_attr "modrm" "1")
    (set_attr "mode" "QI")])
 
 (define_insn "*xorqi_cc_ext_1_rex64"
   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
   "xor{b}\t{%2, %h0|%h0, %2}"
   [(set_attr "type" "alu")
+   (set_attr "modrm" "1")
    (set_attr "mode" "QI")])
 
 (define_expand "xorqi_cc_ext_1"
 }
   [(set_attr "type" "sseishft")
    (set_attr "prefix" "vex")
+   (set_attr "length_immediate" "1")
    (set_attr "mode" "TI")])
 
 (define_insn "sse2_ashlti3"
 }
   [(set_attr "type" "sseishft")
    (set_attr "prefix_data16" "1")
+   (set_attr "length_immediate" "1")
    (set_attr "mode" "TI")])
 
 (define_insn "*ashlti3_1"
              (const_string "alu")
           ]
           (const_string "ishift")))
+   (set (attr "length_immediate")
+     (if_then_else
+       (ior (eq_attr "type" "alu")
+           (and (eq_attr "type" "ishift")
+                (and (match_operand 2 "const1_operand" "")
+                     (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
+                         (const_int 0)))))
+       (const_string "0")
+       (const_string "*")))
    (set_attr "mode" "DI")])
 
 ;; Convert lea to the lea pattern to avoid flags dependency.
              (const_string "alu")
           ]
           (const_string "ishift")))
+   (set (attr "length_immediate")
+     (if_then_else
+       (ior (eq_attr "type" "alu")
+           (and (eq_attr "type" "ishift")
+                (and (match_operand 2 "const1_operand" "")
+                     (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
+                         (const_int 0)))))
+       (const_string "0")
+       (const_string "*")))
    (set_attr "mode" "DI")])
 
 (define_insn "*ashldi3_cconly_rex64"
              (const_string "alu")
           ]
           (const_string "ishift")))
+   (set (attr "length_immediate")
+     (if_then_else
+       (ior (eq_attr "type" "alu")
+           (and (eq_attr "type" "ishift")
+                (and (match_operand 2 "const1_operand" "")
+                     (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
+                         (const_int 0)))))
+       (const_string "0")
+       (const_string "*")))
    (set_attr "mode" "DI")])
 
 (define_insn "*ashldi3_1"
              (const_string "alu")
           ]
           (const_string "ishift")))
+   (set (attr "length_immediate")
+     (if_then_else
+       (ior (eq_attr "type" "alu")
+           (and (eq_attr "type" "ishift")
+                (and (match_operand 2 "const1_operand" "")
+                     (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
+                         (const_int 0)))))
+       (const_string "0")
+       (const_string "*")))
    (set_attr "mode" "SI")])
 
 ;; Convert lea to the lea pattern to avoid flags dependency.
              (const_string "alu")
           ]
           (const_string "ishift")))
+   (set (attr "length_immediate")
+     (if_then_else
+       (ior (eq_attr "type" "alu")
+           (and (eq_attr "type" "ishift")
+                (and (match_operand 2 "const1_operand" "")
+                     (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
+                         (const_int 0)))))
+       (const_string "0")
+       (const_string "*")))
    (set_attr "mode" "SI")])
 
 ;; Convert lea to the lea pattern to avoid flags dependency.
              (const_string "alu")
           ]
           (const_string "ishift")))
+   (set (attr "length_immediate")
+     (if_then_else
+       (ior (eq_attr "type" "alu")
+           (and (eq_attr "type" "ishift")
+                (and (match_operand 2 "const1_operand" "")
+                     (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
+                         (const_int 0)))))
+       (const_string "0")
+       (const_string "*")))
    (set_attr "mode" "SI")])
 
 (define_insn "*ashlsi3_cconly"
              (const_string "alu")
           ]
           (const_string "ishift")))
+   (set (attr "length_immediate")
+     (if_then_else
+       (ior (eq_attr "type" "alu")
+           (and (eq_attr "type" "ishift")
+                (and (match_operand 2 "const1_operand" "")
+                     (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
+                         (const_int 0)))))
+       (const_string "0")
+       (const_string "*")))
    (set_attr "mode" "SI")])
 
 (define_insn "*ashlsi3_cmp_zext"
              (const_string "alu")
           ]
           (const_string "ishift")))
+   (set (attr "length_immediate")
+     (if_then_else
+       (ior (eq_attr "type" "alu")
+           (and (eq_attr "type" "ishift")
+                (and (match_operand 2 "const1_operand" "")
+                     (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
+                         (const_int 0)))))
+       (const_string "0")
+       (const_string "*")))
    (set_attr "mode" "SI")])
 
 (define_expand "ashlhi3"
              (const_string "alu")
           ]
           (const_string "ishift")))
+   (set (attr "length_immediate")
+     (if_then_else
+       (ior (eq_attr "type" "alu")
+           (and (eq_attr "type" "ishift")
+                (and (match_operand 2 "const1_operand" "")
+                     (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
+                         (const_int 0)))))
+       (const_string "0")
+       (const_string "*")))
    (set_attr "mode" "HI,SI")])
 
 (define_insn "*ashlhi3_1"
              (const_string "alu")
           ]
           (const_string "ishift")))
+   (set (attr "length_immediate")
+     (if_then_else
+       (ior (eq_attr "type" "alu")
+           (and (eq_attr "type" "ishift")
+                (and (match_operand 2 "const1_operand" "")
+                     (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
+                         (const_int 0)))))
+       (const_string "0")
+       (const_string "*")))
    (set_attr "mode" "HI")])
 
 ;; This pattern can't accept a variable shift count, since shifts by
              (const_string "alu")
           ]
           (const_string "ishift")))
+   (set (attr "length_immediate")
+     (if_then_else
+       (ior (eq_attr "type" "alu")
+           (and (eq_attr "type" "ishift")
+                (and (match_operand 2 "const1_operand" "")
+                     (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
+                         (const_int 0)))))
+       (const_string "0")
+       (const_string "*")))
    (set_attr "mode" "HI")])
 
 (define_insn "*ashlhi3_cconly"
              (const_string "alu")
           ]
           (const_string "ishift")))
+   (set (attr "length_immediate")
+     (if_then_else
+       (ior (eq_attr "type" "alu")
+           (and (eq_attr "type" "ishift")
+                (and (match_operand 2 "const1_operand" "")
+                     (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
+                         (const_int 0)))))
+       (const_string "0")
+       (const_string "*")))
    (set_attr "mode" "HI")])
 
 (define_expand "ashlqi3"
              (const_string "alu")
           ]
           (const_string "ishift")))
+   (set (attr "length_immediate")
+     (if_then_else
+       (ior (eq_attr "type" "alu")
+           (and (eq_attr "type" "ishift")
+                (and (match_operand 2 "const1_operand" "")
+                     (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
+                         (const_int 0)))))
+       (const_string "0")
+       (const_string "*")))
    (set_attr "mode" "QI,SI,SI")])
 
 (define_insn "*ashlqi3_1"
              (const_string "alu")
           ]
           (const_string "ishift")))
+   (set (attr "length_immediate")
+     (if_then_else
+       (ior (eq_attr "type" "alu")
+           (and (eq_attr "type" "ishift")
+                (and (match_operand 2 "const1_operand" "")
+                     (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
+                         (const_int 0)))))
+       (const_string "0")
+       (const_string "*")))
    (set_attr "mode" "QI,SI")])
 
 ;; This pattern can't accept a variable shift count, since shifts by
              (const_string "alu")
           ]
           (const_string "ishift")))
+   (set (attr "length_immediate")
+     (if_then_else
+       (ior (eq_attr "type" "alu")
+           (and (eq_attr "type" "ishift")
+                (and (match_operand 2 "const1_operand" "")
+                     (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
+                         (const_int 0)))))
+       (const_string "0")
+       (const_string "*")))
    (set_attr "mode" "QI")])
 
 (define_insn "*ashlqi3_cconly"
              (const_string "alu")
           ]
           (const_string "ishift")))
+   (set (attr "length_immediate")
+     (if_then_else
+       (ior (eq_attr "type" "alu")
+           (and (eq_attr "type" "ishift")
+                (and (match_operand 2 "const1_operand" "")
+                     (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
+                         (const_int 0)))))
+       (const_string "0")
+       (const_string "*")))
    (set_attr "mode" "QI")])
 
 ;; See comment above `ashldi3' about how this works.
    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
   "sar{q}\t%0"
   [(set_attr "type" "ishift")
-   (set (attr "length")
-     (if_then_else (match_operand:DI 0 "register_operand" "")
-       (const_string "2")
-       (const_string "*")))])
+   (set_attr "length_immediate" "0")
+   (set_attr "mode" "DI")])
 
 (define_insn "*ashrdi3_1_rex64"
   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
   "sar{q}\t%0"
   [(set_attr "type" "ishift")
-   (set (attr "length")
-     (if_then_else (match_operand:DI 0 "register_operand" "")
-       (const_string "2")
-       (const_string "*")))])
+   (set_attr "length_immediate" "0")
+   (set_attr "mode" "DI")])
 
 (define_insn "*ashrdi3_one_bit_cconly_rex64"
   [(set (reg FLAGS_REG)
    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
   "sar{q}\t%0"
   [(set_attr "type" "ishift")
-   (set_attr "length" "2")])
+   (set_attr "length_immediate" "0")
+   (set_attr "mode" "DI")])
 
 ;; This pattern can't accept a variable shift count, since shifts by
 ;; zero don't affect the flags.  We assume that shifts by constant
    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
   "sar{l}\t%0"
   [(set_attr "type" "ishift")
-   (set (attr "length")
-     (if_then_else (match_operand:SI 0 "register_operand" "")
-       (const_string "2")
-       (const_string "*")))])
+   (set_attr "length_immediate" "0")
+   (set_attr "mode" "SI")])
 
 (define_insn "*ashrsi3_1_one_bit_zext"
   [(set (match_operand:DI 0 "register_operand" "=r")
    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
   "sar{l}\t%k0"
   [(set_attr "type" "ishift")
-   (set_attr "length" "2")])
+   (set_attr "length_immediate" "0")
+   (set_attr "mode" "SI")])
 
 (define_insn "*ashrsi3_1"
   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
   "sar{l}\t%0"
   [(set_attr "type" "ishift")
-   (set (attr "length")
-     (if_then_else (match_operand:SI 0 "register_operand" "")
-       (const_string "2")
-       (const_string "*")))])
+   (set_attr "length_immediate" "0")
+   (set_attr "mode" "SI")])
 
 (define_insn "*ashrsi3_one_bit_cconly"
   [(set (reg FLAGS_REG)
    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
   "sar{l}\t%0"
   [(set_attr "type" "ishift")
-   (set_attr "length" "2")])
+   (set_attr "length_immediate" "0")
+   (set_attr "mode" "SI")])
 
 (define_insn "*ashrsi3_one_bit_cmp_zext"
   [(set (reg FLAGS_REG)
    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
   "sar{l}\t%k0"
   [(set_attr "type" "ishift")
-   (set_attr "length" "2")])
+   (set_attr "length_immediate" "0")
+   (set_attr "mode" "SI")])
 
 ;; This pattern can't accept a variable shift count, since shifts by
 ;; zero don't affect the flags.  We assume that shifts by constant
    && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
   "sar{w}\t%0"
   [(set_attr "type" "ishift")
-   (set (attr "length")
-     (if_then_else (match_operand 0 "register_operand" "")
-       (const_string "2")
-       (const_string "*")))])
+   (set_attr "length_immediate" "0")
+   (set_attr "mode" "HI")])
 
 (define_insn "*ashrhi3_1"
   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
    && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
   "sar{w}\t%0"
   [(set_attr "type" "ishift")
-   (set (attr "length")
-     (if_then_else (match_operand 0 "register_operand" "")
-       (const_string "2")
-       (const_string "*")))])
+   (set_attr "length_immediate" "0")
+   (set_attr "mode" "HI")])
 
 (define_insn "*ashrhi3_one_bit_cconly"
   [(set (reg FLAGS_REG)
    && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
   "sar{w}\t%0"
   [(set_attr "type" "ishift")
-   (set_attr "length" "2")])
+   (set_attr "length_immediate" "0")
+   (set_attr "mode" "HI")])
 
 ;; This pattern can't accept a variable shift count, since shifts by
 ;; zero don't affect the flags.  We assume that shifts by constant
    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
   "sar{b}\t%0"
   [(set_attr "type" "ishift")
-   (set (attr "length")
-     (if_then_else (match_operand 0 "register_operand" "")
-       (const_string "2")
-       (const_string "*")))])
+   (set_attr "length_immediate" "0")
+   (set_attr "mode" "QI")])
 
 (define_insn "*ashrqi3_1_one_bit_slp"
   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
   "sar{b}\t%0"
   [(set_attr "type" "ishift1")
-   (set (attr "length")
-     (if_then_else (match_operand 0 "register_operand" "")
-       (const_string "2")
-       (const_string "*")))])
+   (set_attr "length_immediate" "0")
+   (set_attr "mode" "QI")])
 
 (define_insn "*ashrqi3_1"
   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
   "sar{b}\t%0"
   [(set_attr "type" "ishift")
-   (set (attr "length")
-     (if_then_else (match_operand 0 "register_operand" "")
-       (const_string "2")
-       (const_string "*")))])
+   (set_attr "length_immediate" "0")
+   (set_attr "mode" "QI")])
 
 (define_insn "*ashrqi3_one_bit_cconly"
   [(set (reg FLAGS_REG)
    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
   "sar{b}\t%0"
   [(set_attr "type" "ishift")
-   (set_attr "length" "2")])
+   (set_attr "length_immediate" "0")
+   (set_attr "mode" "QI")])
 
 ;; This pattern can't accept a variable shift count, since shifts by
 ;; zero don't affect the flags.  We assume that shifts by constant
 }
   [(set_attr "type" "sseishft")
    (set_attr "prefix" "vex")
+   (set_attr "length_immediate" "1")
    (set_attr "mode" "TI")])
 
 (define_insn "sse2_lshrti3"
 }
   [(set_attr "type" "sseishft")
    (set_attr "prefix_data16" "1")
+   (set_attr "length_immediate" "1")
    (set_attr "mode" "TI")])
 
 (define_insn "*lshrti3_1"
    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
   "shr{q}\t%0"
   [(set_attr "type" "ishift")
-   (set (attr "length")
-     (if_then_else (match_operand:DI 0 "register_operand" "")
-       (const_string "2")
-       (const_string "*")))])
+   (set_attr "length_immediate" "0")
+   (set_attr "mode" "DI")])
 
 (define_insn "*lshrdi3_1_rex64"
   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
   "shr{q}\t%0"
   [(set_attr "type" "ishift")
-   (set (attr "length")
-     (if_then_else (match_operand:DI 0 "register_operand" "")
-       (const_string "2")
-       (const_string "*")))])
+   (set_attr "length_immediate" "0")
+   (set_attr "mode" "DI")])
 
 (define_insn "*lshrdi3_cconly_one_bit_rex64"
   [(set (reg FLAGS_REG)
    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
   "shr{q}\t%0"
   [(set_attr "type" "ishift")
-   (set_attr "length" "2")])
+   (set_attr "length_immediate" "0")
+   (set_attr "mode" "DI")])
 
 ;; This pattern can't accept a variable shift count, since shifts by
 ;; zero don't affect the flags.  We assume that shifts by constant
    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
   "shr{l}\t%0"
   [(set_attr "type" "ishift")
-   (set (attr "length")
-     (if_then_else (match_operand:SI 0 "register_operand" "")
-       (const_string "2")
-       (const_string "*")))])
+   (set_attr "length_immediate" "0")
+   (set_attr "mode" "SI")])
 
 (define_insn "*lshrsi3_1_one_bit_zext"
   [(set (match_operand:DI 0 "register_operand" "=r")
    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
   "shr{l}\t%k0"
   [(set_attr "type" "ishift")
-   (set_attr "length" "2")])
+   (set_attr "length_immediate" "0")
+   (set_attr "mode" "SI")])
 
 (define_insn "*lshrsi3_1"
   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
   "shr{l}\t%0"
   [(set_attr "type" "ishift")
-   (set (attr "length")
-     (if_then_else (match_operand:SI 0 "register_operand" "")
-       (const_string "2")
-       (const_string "*")))])
+   (set_attr "length_immediate" "0")
+   (set_attr "mode" "SI")])
 
 (define_insn "*lshrsi3_one_bit_cconly"
   [(set (reg FLAGS_REG)
    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
   "shr{l}\t%0"
   [(set_attr "type" "ishift")
-   (set_attr "length" "2")])
+   (set_attr "length_immediate" "0")
+   (set_attr "mode" "SI")])
 
 (define_insn "*lshrsi3_cmp_one_bit_zext"
   [(set (reg FLAGS_REG)
    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
   "shr{l}\t%k0"
   [(set_attr "type" "ishift")
-   (set_attr "length" "2")])
+   (set_attr "length_immediate" "0")
+   (set_attr "mode" "SI")])
 
 ;; This pattern can't accept a variable shift count, since shifts by
 ;; zero don't affect the flags.  We assume that shifts by constant
    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
   "shr{w}\t%0"
   [(set_attr "type" "ishift")
-   (set (attr "length")
-     (if_then_else (match_operand 0 "register_operand" "")
-       (const_string "2")
-       (const_string "*")))])
+   (set_attr "length_immediate" "0")
+   (set_attr "mode" "HI")])
 
 (define_insn "*lshrhi3_1"
   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
   "shr{w}\t%0"
   [(set_attr "type" "ishift")
-   (set (attr "length")
-     (if_then_else (match_operand:SI 0 "register_operand" "")
-       (const_string "2")
-       (const_string "*")))])
+   (set_attr "length_immediate" "0")
+   (set_attr "mode" "HI")])
 
 (define_insn "*lshrhi3_one_bit_cconly"
   [(set (reg FLAGS_REG)
    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
   "shr{w}\t%0"
   [(set_attr "type" "ishift")
-   (set_attr "length" "2")])
+   (set_attr "length_immediate" "0")
+   (set_attr "mode" "HI")])
 
 ;; This pattern can't accept a variable shift count, since shifts by
 ;; zero don't affect the flags.  We assume that shifts by constant
    && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
   "shr{b}\t%0"
   [(set_attr "type" "ishift")
-   (set (attr "length")
-     (if_then_else (match_operand 0 "register_operand" "")
-       (const_string "2")
-       (const_string "*")))])
+   (set_attr "length_immediate" "0")
+   (set_attr "mode" "QI")])
 
 (define_insn "*lshrqi3_1_one_bit_slp"
   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
    && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))"
   "shr{b}\t%0"
   [(set_attr "type" "ishift1")
-   (set (attr "length")
-     (if_then_else (match_operand 0 "register_operand" "")
-       (const_string "2")
-       (const_string "*")))])
+   (set_attr "length_immediate" "0")
+   (set_attr "mode" "QI")])
 
 (define_insn "*lshrqi3_1"
   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
    && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
   "shr{b}\t%0"
   [(set_attr "type" "ishift")
-   (set (attr "length")
-     (if_then_else (match_operand:SI 0 "register_operand" "")
-       (const_string "2")
-       (const_string "*")))])
+   (set_attr "length_immediate" "0")
+   (set_attr "mode" "QI")])
 
 (define_insn "*lshrqi2_one_bit_cconly"
   [(set (reg FLAGS_REG)
    && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
   "shr{b}\t%0"
   [(set_attr "type" "ishift")
-   (set_attr "length" "2")])
+   (set_attr "length_immediate" "0")
+   (set_attr "mode" "QI")])
 
 ;; This pattern can't accept a variable shift count, since shifts by
 ;; zero don't affect the flags.  We assume that shifts by constant
    && ix86_binary_operator_ok (ROTATE, DImode, operands)"
   "rol{q}\t%0"
   [(set_attr "type" "rotate")
-   (set (attr "length")
-     (if_then_else (match_operand:DI 0 "register_operand" "")
-       (const_string "2")
-       (const_string "*")))])
+   (set_attr "length_immediate" "0")
+   (set_attr "mode" "DI")])
 
 (define_insn "*rotldi3_1_rex64"
   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
    && ix86_binary_operator_ok (ROTATE, SImode, operands)"
   "rol{l}\t%0"
   [(set_attr "type" "rotate")
-   (set (attr "length")
-     (if_then_else (match_operand:SI 0 "register_operand" "")
-       (const_string "2")
-       (const_string "*")))])
+   (set_attr "length_immediate" "0")
+   (set_attr "mode" "SI")])
 
 (define_insn "*rotlsi3_1_one_bit_zext"
   [(set (match_operand:DI 0 "register_operand" "=r")
    && ix86_binary_operator_ok (ROTATE, SImode, operands)"
   "rol{l}\t%k0"
   [(set_attr "type" "rotate")
-   (set_attr "length" "2")])
+   (set_attr "length_immediate" "0")
+   (set_attr "mode" "SI")])
 
 (define_insn "*rotlsi3_1"
   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
    && ix86_binary_operator_ok (ROTATE, HImode, operands)"
   "rol{w}\t%0"
   [(set_attr "type" "rotate")
-   (set (attr "length")
-     (if_then_else (match_operand 0 "register_operand" "")
-       (const_string "2")
-       (const_string "*")))])
+   (set_attr "length_immediate" "0")
+   (set_attr "mode" "HI")])
 
 (define_insn "*rotlhi3_1"
   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
    && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))"
   "rol{b}\t%0"
   [(set_attr "type" "rotate1")
-   (set (attr "length")
-     (if_then_else (match_operand 0 "register_operand" "")
-       (const_string "2")
-       (const_string "*")))])
+   (set_attr "length_immediate" "0")
+   (set_attr "mode" "QI")])
 
 (define_insn "*rotlqi3_1_one_bit"
   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
    && ix86_binary_operator_ok (ROTATE, QImode, operands)"
   "rol{b}\t%0"
   [(set_attr "type" "rotate")
-   (set (attr "length")
-     (if_then_else (match_operand 0 "register_operand" "")
-       (const_string "2")
-       (const_string "*")))])
+   (set_attr "length_immediate" "0")
+   (set_attr "mode" "QI")])
 
 (define_insn "*rotlqi3_1_slp"
   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
    && ix86_binary_operator_ok (ROTATERT, DImode, operands)"
   "ror{q}\t%0"
   [(set_attr "type" "rotate")
-   (set (attr "length")
-     (if_then_else (match_operand:DI 0 "register_operand" "")
-       (const_string "2")
-       (const_string "*")))])
+   (set_attr "length_immediate" "0")
+   (set_attr "mode" "DI")])
 
 (define_insn "*rotrdi3_1_rex64"
   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
    && ix86_binary_operator_ok (ROTATERT, SImode, operands)"
   "ror{l}\t%0"
   [(set_attr "type" "rotate")
-   (set (attr "length")
-     (if_then_else (match_operand:SI 0 "register_operand" "")
-       (const_string "2")
-       (const_string "*")))])
+   (set_attr "length_immediate" "0")
+   (set_attr "mode" "SI")])
 
 (define_insn "*rotrsi3_1_one_bit_zext"
   [(set (match_operand:DI 0 "register_operand" "=r")
    && ix86_binary_operator_ok (ROTATERT, SImode, operands)"
   "ror{l}\t%k0"
   [(set_attr "type" "rotate")
-   (set (attr "length")
-     (if_then_else (match_operand:SI 0 "register_operand" "")
-       (const_string "2")
-       (const_string "*")))])
+   (set_attr "length_immediate" "0")
+   (set_attr "mode" "SI")])
 
 (define_insn "*rotrsi3_1"
   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
    && ix86_binary_operator_ok (ROTATERT, HImode, operands)"
   "ror{w}\t%0"
   [(set_attr "type" "rotate")
-   (set (attr "length")
-     (if_then_else (match_operand 0 "register_operand" "")
-       (const_string "2")
-       (const_string "*")))])
+   (set_attr "length_immediate" "0")
+   (set_attr "mode" "HI")])
 
 (define_insn "*rotrhi3_1"
   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
    && ix86_binary_operator_ok (ROTATERT, QImode, operands)"
   "ror{b}\t%0"
   [(set_attr "type" "rotate")
-   (set (attr "length")
-     (if_then_else (match_operand 0 "register_operand" "")
-       (const_string "2")
-       (const_string "*")))])
+   (set_attr "length_immediate" "0")
+   (set_attr "mode" "QI")])
 
 (define_insn "*rotrqi3_1_one_bit_slp"
   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
    && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))"
   "ror{b}\t%0"
   [(set_attr "type" "rotate1")
-   (set (attr "length")
-     (if_then_else (match_operand 0 "register_operand" "")
-       (const_string "2")
-       (const_string "*")))])
+   (set_attr "length_immediate" "0")
+   (set_attr "mode" "QI")])
 
 (define_insn "*rotrqi3_1"
   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
    (clobber (reg:CC FLAGS_REG))]
   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
   "bts{q}\t{%1, %0|%0, %1}"
-  [(set_attr "type" "alu1")])
+  [(set_attr "type" "alu1")
+   (set_attr "prefix_0f" "1")
+   (set_attr "mode" "DI")])
 
 (define_insn "*btrq"
   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
    (clobber (reg:CC FLAGS_REG))]
   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
   "btr{q}\t{%1, %0|%0, %1}"
-  [(set_attr "type" "alu1")])
+  [(set_attr "type" "alu1")
+   (set_attr "prefix_0f" "1")
+   (set_attr "mode" "DI")])
 
 (define_insn "*btcq"
   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
    (clobber (reg:CC FLAGS_REG))]
   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
   "btc{q}\t{%1, %0|%0, %1}"
-  [(set_attr "type" "alu1")])
+  [(set_attr "type" "alu1")
+   (set_attr "prefix_0f" "1")
+   (set_attr "mode" "DI")])
 
 ;; Allow Nocona to avoid these instructions if a register is available.
 
          (const_int 0)))]
   "TARGET_64BIT && (TARGET_USE_BT || optimize_function_for_size_p (cfun))"
   "bt{q}\t{%1, %0|%0, %1}"
-  [(set_attr "type" "alu1")])
+  [(set_attr "type" "alu1")
+   (set_attr "prefix_0f" "1")
+   (set_attr "mode" "DI")])
 
 (define_insn "*btsi"
   [(set (reg:CCC FLAGS_REG)
          (const_int 0)))]
   "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
   "bt{l}\t{%1, %0|%0, %1}"
-  [(set_attr "type" "alu1")])
+  [(set_attr "type" "alu1")
+   (set_attr "prefix_0f" "1")
+   (set_attr "mode" "SI")])
 \f
 ;; Store-flag instructions.
 
 ;; to avoid partial register stalls.  Otherwise do things the setcc+movzx
 ;; way, which can later delete the movzx if only QImode is needed.
 
-(define_expand "s<code>"
-  [(set (match_operand:QI 0 "register_operand" "")
-        (int_cond:QI (reg:CC FLAGS_REG) (const_int 0)))]
-  ""
-  "if (ix86_expand_setcc (<CODE>, operands[0])) DONE; else FAIL;")
-
-(define_expand "s<code>"
-  [(set (match_operand:QI 0 "register_operand" "")
-        (fp_cond:QI (reg:CC FLAGS_REG) (const_int 0)))]
-  "TARGET_80387 || TARGET_SSE"
-  "if (ix86_expand_setcc (<CODE>, operands[0])) DONE; else FAIL;")
-
 (define_insn "*setcc_1"
   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
        (match_operator:QI 1 "ix86_comparison_operator"
   "vcmp%D1s<ssemodefsuffix>\t{%3, %2, %0|%0, %2, %3}"
   [(set_attr "type" "ssecmp")
    (set_attr "prefix" "vex")
+   (set_attr "length_immediate" "1")
    (set_attr "mode" "<MODE>")])
 
 (define_insn "*sse_setcc<mode>"
   "SSE_FLOAT_MODE_P (<MODE>mode) && !TARGET_SSE5"
   "cmp%D1s<ssemodefsuffix>\t{%3, %0|%0, %3}"
   [(set_attr "type" "ssecmp")
+   (set_attr "length_immediate" "1")
    (set_attr "mode" "<MODE>")])
 
 (define_insn "*sse5_setcc<mode>"
   "TARGET_SSE5"
   "com%Y1s<ssemodefsuffix>\t{%3, %2, %0|%0, %2, %3}"
   [(set_attr "type" "sse4arg")
+   (set_attr "length_immediate" "1")
    (set_attr "mode" "<MODE>")])
 
 \f
 ;; Basic conditional jump instructions.
 ;; We ignore the overflow flag for signed branch instructions.
 
-;; For all bCOND expanders, also expand the compare or test insn that
-;; generates reg FLAGS_REG.  Generate an equality comparison if `beq' or `bne'.
-
-(define_expand "b<code>"
-  [(set (pc)
-       (if_then_else (int_cond:CC (reg:CC FLAGS_REG)
-                                  (const_int 0))
-                     (label_ref (match_operand 0 ""))
-                     (pc)))]
-  ""
-  "ix86_expand_branch (<CODE>, operands[0]); DONE;")
-
-(define_expand "b<code>"
-  [(set (pc)
-       (if_then_else (fp_cond:CC (reg:CC FLAGS_REG)
-                                 (const_int 0))
-                     (label_ref (match_operand 0 ""))
-                     (pc)))]
-  "TARGET_80387 || TARGET_SSE_MATH"
-  "ix86_expand_branch (<CODE>, operands[0]); DONE;")
-
 (define_insn "*jcc_1"
   [(set (pc)
        (if_then_else (match_operator 1 "ix86_comparison_operator"
                      (pc)))]
   "PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));")
 
-;; Define combination compare-and-branch fp compare instructions to use
-;; during early optimization.  Splitting the operation apart early makes
-;; for bad code when we want to reverse the operation.
-
-(define_insn "*fp_jcc_1_mixed"
-  [(set (pc)
-       (if_then_else (match_operator 0 "comparison_operator"
-                       [(match_operand 1 "register_operand" "f,x")
-                        (match_operand 2 "nonimmediate_operand" "f,xm")])
-         (label_ref (match_operand 3 "" ""))
-         (pc)))
-   (clobber (reg:CCFP FPSR_REG))
-   (clobber (reg:CCFP FLAGS_REG))]
-  "TARGET_MIX_SSE_I387
-   && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
-   && GET_MODE (operands[1]) == GET_MODE (operands[2])
-   && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
-  "#")
-
-(define_insn "*fp_jcc_1_sse"
-  [(set (pc)
-       (if_then_else (match_operator 0 "comparison_operator"
-                       [(match_operand 1 "register_operand" "x")
-                        (match_operand 2 "nonimmediate_operand" "xm")])
-         (label_ref (match_operand 3 "" ""))
-         (pc)))
-   (clobber (reg:CCFP FPSR_REG))
-   (clobber (reg:CCFP FLAGS_REG))]
-  "TARGET_SSE_MATH
-   && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
-   && GET_MODE (operands[1]) == GET_MODE (operands[2])
-   && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
-  "#")
-
-(define_insn "*fp_jcc_1_387"
-  [(set (pc)
-       (if_then_else (match_operator 0 "comparison_operator"
-                       [(match_operand 1 "register_operand" "f")
-                        (match_operand 2 "register_operand" "f")])
-         (label_ref (match_operand 3 "" ""))
-         (pc)))
-   (clobber (reg:CCFP FPSR_REG))
-   (clobber (reg:CCFP FLAGS_REG))]
-  "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
-   && TARGET_CMOVE
-   && GET_MODE (operands[1]) == GET_MODE (operands[2])
-   && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
-  "#")
-
-(define_insn "*fp_jcc_2_mixed"
-  [(set (pc)
-       (if_then_else (match_operator 0 "comparison_operator"
-                       [(match_operand 1 "register_operand" "f,x")
-                        (match_operand 2 "nonimmediate_operand" "f,xm")])
-         (pc)
-         (label_ref (match_operand 3 "" ""))))
-   (clobber (reg:CCFP FPSR_REG))
-   (clobber (reg:CCFP FLAGS_REG))]
-  "TARGET_MIX_SSE_I387
-   && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
-   && GET_MODE (operands[1]) == GET_MODE (operands[2])
-   && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
-  "#")
-
-(define_insn "*fp_jcc_2_sse"
-  [(set (pc)
-       (if_then_else (match_operator 0 "comparison_operator"
-                       [(match_operand 1 "register_operand" "x")
-                        (match_operand 2 "nonimmediate_operand" "xm")])
-         (pc)
-         (label_ref (match_operand 3 "" ""))))
-   (clobber (reg:CCFP FPSR_REG))
-   (clobber (reg:CCFP FLAGS_REG))]
-  "TARGET_SSE_MATH
-   && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
-   && GET_MODE (operands[1]) == GET_MODE (operands[2])
-   && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
-  "#")
-
-(define_insn "*fp_jcc_2_387"
-  [(set (pc)
-       (if_then_else (match_operator 0 "comparison_operator"
-                       [(match_operand 1 "register_operand" "f")
-                        (match_operand 2 "register_operand" "f")])
-         (pc)
-         (label_ref (match_operand 3 "" ""))))
-   (clobber (reg:CCFP FPSR_REG))
-   (clobber (reg:CCFP FLAGS_REG))]
-  "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
-   && TARGET_CMOVE
-   && GET_MODE (operands[1]) == GET_MODE (operands[2])
-   && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
-  "#")
+;; Define combination compare-and-branch fp compare instructions to help
+;; combine.
 
 (define_insn "*fp_jcc_3_387"
   [(set (pc)
-       (if_then_else (match_operator 0 "comparison_operator"
+       (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
                        [(match_operand 1 "register_operand" "f")
                         (match_operand 2 "nonimmediate_operand" "fm")])
          (label_ref (match_operand 3 "" ""))
   "TARGET_80387
    && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
    && GET_MODE (operands[1]) == GET_MODE (operands[2])
-   && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
    && SELECT_CC_MODE (GET_CODE (operands[0]),
                      operands[1], operands[2]) == CCFPmode
-   && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
+   && !TARGET_CMOVE"
   "#")
 
 (define_insn "*fp_jcc_4_387"
   [(set (pc)
-       (if_then_else (match_operator 0 "comparison_operator"
+       (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
                        [(match_operand 1 "register_operand" "f")
                         (match_operand 2 "nonimmediate_operand" "fm")])
          (pc)
   "TARGET_80387
    && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
    && GET_MODE (operands[1]) == GET_MODE (operands[2])
-   && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
    && SELECT_CC_MODE (GET_CODE (operands[0]),
                      operands[1], operands[2]) == CCFPmode
-   && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
+   && !TARGET_CMOVE"
   "#")
 
 (define_insn "*fp_jcc_5_387"
   [(set (pc)
-       (if_then_else (match_operator 0 "comparison_operator"
+       (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
                        [(match_operand 1 "register_operand" "f")
                         (match_operand 2 "register_operand" "f")])
          (label_ref (match_operand 3 "" ""))
    (clobber (match_scratch:HI 4 "=a"))]
   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
    && GET_MODE (operands[1]) == GET_MODE (operands[2])
-   && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
+   && !TARGET_CMOVE"
   "#")
 
 (define_insn "*fp_jcc_6_387"
   [(set (pc)
-       (if_then_else (match_operator 0 "comparison_operator"
+       (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
                        [(match_operand 1 "register_operand" "f")
                         (match_operand 2 "register_operand" "f")])
          (pc)
    (clobber (match_scratch:HI 4 "=a"))]
   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
    && GET_MODE (operands[1]) == GET_MODE (operands[2])
-   && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
+   && !TARGET_CMOVE"
   "#")
 
 (define_insn "*fp_jcc_7_387"
   [(set (pc)
-       (if_then_else (match_operator 0 "comparison_operator"
+       (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
                        [(match_operand 1 "register_operand" "f")
                         (match_operand 2 "const0_operand" "")])
          (label_ref (match_operand 3 "" ""))
    (clobber (match_scratch:HI 4 "=a"))]
   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
    && GET_MODE (operands[1]) == GET_MODE (operands[2])
-   && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
    && SELECT_CC_MODE (GET_CODE (operands[0]),
                      operands[1], operands[2]) == CCFPmode
-   && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
+   && !TARGET_CMOVE"
   "#")
 
 ;; The order of operands in *fp_jcc_8_387 is forced by combine in
 
 (define_insn "*fp_jcc_8<mode>_387"
   [(set (pc)
-       (if_then_else (match_operator 0 "comparison_operator"
+       (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
                        [(match_operator 1 "float_operator"
                           [(match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r")])
                           (match_operand 3 "register_operand" "f,f")])
   "X87_FLOAT_MODE_P (GET_MODE (operands[3]))
    && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
    && GET_MODE (operands[1]) == GET_MODE (operands[3])
-   && !ix86_use_fcomi_compare (swap_condition (GET_CODE (operands[0])))
    && ix86_fp_compare_mode (swap_condition (GET_CODE (operands[0]))) == CCFPmode
-   && ix86_fp_jump_nontrivial_p (swap_condition (GET_CODE (operands[0])))"
+   && !TARGET_CMOVE"
   "#")
 
 (define_split
   [(set (pc)
-       (if_then_else (match_operator 0 "comparison_operator"
+       (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
                        [(match_operand 1 "register_operand" "")
                         (match_operand 2 "nonimmediate_operand" "")])
          (match_operand 3 "" "")
 
 (define_split
   [(set (pc)
-       (if_then_else (match_operator 0 "comparison_operator"
+       (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
                        [(match_operand 1 "register_operand" "")
                         (match_operand 2 "general_operand" "")])
          (match_operand 3 "" "")
 
 (define_split
   [(set (pc)
-       (if_then_else (match_operator 0 "comparison_operator"
+       (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
                        [(match_operator 1 "float_operator"
                           [(match_operand:X87MODEI12 2 "memory_operand" "")])
                           (match_operand 3 "register_operand" "")])
 ;; %%% Kill this when reload knows how to do it.
 (define_split
   [(set (pc)
-       (if_then_else (match_operator 0 "comparison_operator"
+       (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
                        [(match_operator 1 "float_operator"
                           [(match_operand:X87MODEI12 2 "register_operand" "")])
                           (match_operand 3 "register_operand" "")])
         (match_operand:SI 1 "" ""))
    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
                            (match_operand:SI 2 "immediate_operand" "i")))]
-  "!TARGET_64BIT"
+  "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
 {
   if (constant_call_address_operand (operands[0], Pmode))
-    {
-      if (SIBLING_CALL_P (insn))
-       return "jmp\t%P0";
-      else
-       return "call\t%P0";
-    }
-  if (SIBLING_CALL_P (insn))
-    return "jmp\t%A0";
-  else
-    return "call\t%A0";
+    return "call\t%P0";
+  return "call\t%A0";
 }
   [(set_attr "type" "call")])
 
+(define_insn "*sibcall_pop_1"
+  [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "s,U"))
+        (match_operand:SI 1 "" ""))
+   (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
+                           (match_operand:SI 2 "immediate_operand" "i,i")))]
+  "SIBLING_CALL_P (insn) && !TARGET_64BIT"
+  "@
+   jmp\t%P0
+   jmp\t%A0"
+  [(set_attr "type" "call")])
+
 (define_expand "call"
   [(call (match_operand:QI 0 "" "")
         (match_operand 1 "" ""))
   [(set_attr "type" "call")])
 
 (define_insn "*sibcall_1"
-  [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "s,c,d,a"))
+  [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "s,U"))
         (match_operand 1 "" ""))]
   "SIBLING_CALL_P (insn) && !TARGET_64BIT"
-{
-  if (constant_call_address_operand (operands[0], Pmode))
-    return "jmp\t%P0";
-  return "jmp\t%A0";
-}
+  "@
+   jmp\t%P0
+   jmp\t%A0"
   [(set_attr "type" "call")])
 
 (define_insn "*call_1_rex64"
   [(set_attr "type" "call")])
 
 (define_insn "*sibcall_1_rex64"
-  [(call (mem:QI (match_operand:DI 0 "constant_call_address_operand" ""))
+  [(call (mem:QI (match_operand:DI 0 "sibcall_insn_operand" "s,U"))
         (match_operand 1 "" ""))]
   "SIBLING_CALL_P (insn) && TARGET_64BIT"
-  "jmp\t%P0"
-  [(set_attr "type" "call")])
-
-(define_insn "*sibcall_1_rex64_v"
-  [(call (mem:QI (reg:DI R11_REG))
-        (match_operand 0 "" ""))]
-  "SIBLING_CALL_P (insn) && TARGET_64BIT"
-  "jmp\t{*%%}r11"
+  "@
+   jmp\t%P0
+   jmp\t%A0"
   [(set_attr "type" "call")])
 
-
 ;; Call subroutine, returning value in operand 0
-
 (define_expand "call_value_pop"
   [(parallel [(set (match_operand 0 "" "")
                   (call (match_operand:QI 1 "" "")
                    GEN_INT ((TARGET_64BIT
                              ? (ix86_abi == SYSV_ABI
                                 ? X86_64_SSE_REGPARM_MAX
-                                : X64_SSE_REGPARM_MAX)
+                                : X86_64_MS_SSE_REGPARM_MAX)
                              : X86_32_SSE_REGPARM_MAX)
                             - 1),
                    NULL, 0);
    (unspec [(const_int 0)] UNSPEC_REP)]
   "reload_completed"
   "rep\;ret"
-  [(set_attr "length" "1")
+  [(set_attr "length" "2")
    (set_attr "atom_unit" "jeu")
    (set_attr "length_immediate" "0")
    (set_attr "prefix_rep" "1")
    (set_attr "length_immediate" "0")
    (set_attr "modrm" "0")])
 
-;; Align to 16-byte boundary, max skip in op0.  Used to avoid
+;; Pad to 16-byte boundary, max skip in op0.  Used to avoid
 ;; branch prediction penalty for the third jump in a 16-byte
 ;; block on K8.
 
-(define_insn "align"
+(define_insn "pad"
   [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_ALIGN)]
   ""
 {
-#ifdef ASM_OUTPUT_MAX_SKIP_ALIGN
-  ASM_OUTPUT_MAX_SKIP_ALIGN (asm_out_file, 4, (int)INTVAL (operands[0]));
+#ifdef ASM_OUTPUT_MAX_SKIP_PAD
+  ASM_OUTPUT_MAX_SKIP_PAD (asm_out_file, 4, (int)INTVAL (operands[0]));
 #else
   /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
      The align insn is used to avoid 3 jump instructions in the row to improve
   "TARGET_64BIT"
   "lea{q}\t{_GLOBAL_OFFSET_TABLE_(%%rip), %0|%0, _GLOBAL_OFFSET_TABLE_[rip]}"
   [(set_attr "type" "lea")
-   (set_attr "length" "6")])
+   (set_attr "length_address" "4")
+   (set_attr "mode" "DI")])
 
 (define_insn "set_rip_rex64"
   [(set (match_operand:DI 0 "register_operand" "=r")
   "TARGET_64BIT"
   "lea{q}\t{%l1(%%rip), %0|%0, %l1[rip]}"
   [(set_attr "type" "lea")
-   (set_attr "length" "6")])
+   (set_attr "length_address" "4")
+   (set_attr "mode" "DI")])
 
 (define_insn "set_got_offset_rex64"
   [(set (match_operand:DI 0 "register_operand" "=r")
   "TARGET_64BIT"
   "movabs{q}\t{$_GLOBAL_OFFSET_TABLE_-%l1, %0|%0, OFFSET FLAT:_GLOBAL_OFFSET_TABLE_-%l1}"
   [(set_attr "type" "imov")
-   (set_attr "length" "11")])
+   (set_attr "length_immediate" "0")
+   (set_attr "length_address" "8")
+   (set_attr "mode" "DI")])
 
 (define_expand "epilogue"
   [(const_int 0)]
   tmp = gen_rtx_MEM (Pmode, tmp);
   emit_move_insn (tmp, ra);
 
-  if (Pmode == SImode)
-    emit_jump_insn (gen_eh_return_si (sa));
-  else
-    emit_jump_insn (gen_eh_return_di (sa));
+  emit_jump_insn (gen_eh_return_internal ());
   emit_barrier ();
   DONE;
 })
 
-(define_insn_and_split "eh_return_<mode>"
-  [(set (pc)
-        (unspec [(match_operand:P 0 "register_operand" "c")]
-                UNSPEC_EH_RETURN))]
+(define_insn_and_split "eh_return_internal"
+  [(eh_return)]
   ""
   "#"
-  "reload_completed"
+  "epilogue_completed"
   [(const_int 0)]
   "ix86_expand_epilogue (2); DONE;")
 
        (ctz:SI (match_dup 1)))]
   ""
   "bsf{l}\t{%1, %0|%0, %1}"
-  [(set_attr "prefix_0f" "1")])
+  [(set_attr "type" "alu1")
+   (set_attr "prefix_0f" "1")
+   (set_attr "mode" "SI")])
 
 (define_expand "ffsdi2"
   [(set (match_dup 2) (const_int -1))
        (ctz:DI (match_dup 1)))]
   "TARGET_64BIT"
   "bsf{q}\t{%1, %0|%0, %1}"
-  [(set_attr "prefix_0f" "1")])
+  [(set_attr "type" "alu1")
+   (set_attr "prefix_0f" "1")
+   (set_attr "mode" "DI")])
 
 (define_insn "ctzsi2"
   [(set (match_operand:SI 0 "register_operand" "=r")
    (clobber (reg:CC FLAGS_REG))]
   ""
   "bsf{l}\t{%1, %0|%0, %1}"
-  [(set_attr "prefix_0f" "1")])
+  [(set_attr "type" "alu1")
+   (set_attr "prefix_0f" "1")
+   (set_attr "mode" "SI")])
 
 (define_insn "ctzdi2"
   [(set (match_operand:DI 0 "register_operand" "=r")
    (clobber (reg:CC FLAGS_REG))]
   "TARGET_64BIT"
   "bsf{q}\t{%1, %0|%0, %1}"
-  [(set_attr "prefix_0f" "1")])
+  [(set_attr "type" "alu1")
+   (set_attr "prefix_0f" "1")
+   (set_attr "mode" "DI")])
 
 (define_expand "clzsi2"
   [(parallel
    (set_attr "type" "bitmanip")
    (set_attr "mode" "SI")])
 
-(define_insn "*bsr"
+(define_insn "bsr"
   [(set (match_operand:SI 0 "register_operand" "=r")
        (minus:SI (const_int 31)
                  (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
    (clobber (reg:CC FLAGS_REG))]
   ""
   "bsr{l}\t{%1, %0|%0, %1}"
-  [(set_attr "prefix_0f" "1")
+  [(set_attr "type" "alu1")
+   (set_attr "prefix_0f" "1")
    (set_attr "mode" "SI")])
 
 (define_insn "popcount<mode>2"
        (bswap:SI (match_operand:SI 1 "register_operand" "")))]
   ""
 {
-  if (!TARGET_BSWAP)
+  if (!(TARGET_BSWAP || TARGET_MOVBE))
     {
       rtx x = operands[0];
 
     }
 })
 
+(define_insn "*bswapsi_movbe"
+  [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,m")
+       (bswap:SI (match_operand:SI 1 "nonimmediate_operand" "0,m,r")))]
+  "TARGET_MOVBE && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
+  "@
+    bswap\t%0
+    movbe\t{%1, %0|%0, %1}
+    movbe\t{%1, %0|%0, %1}"
+  [(set_attr "type" "*,imov,imov")
+   (set_attr "modrm" "*,1,1")
+   (set_attr "prefix_0f" "1")
+   (set_attr "prefix_extra" "*,1,1")
+   (set_attr "length" "2,*,*")
+   (set_attr "mode" "SI")])
+
 (define_insn "*bswapsi_1"
   [(set (match_operand:SI 0 "register_operand" "=r")
        (bswap:SI (match_operand:SI 1 "register_operand" "0")))]
   [(set_attr "length" "4")
    (set_attr "mode" "HI")])
 
-(define_insn "bswapdi2"
+(define_expand "bswapdi2"
+  [(set (match_operand:DI 0 "register_operand" "")
+       (bswap:DI (match_operand:DI 1 "register_operand" "")))]
+  "TARGET_64BIT"
+  "")
+
+(define_insn "*bswapdi_movbe"
+  [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,m")
+       (bswap:DI (match_operand:DI 1 "nonimmediate_operand" "0,m,r")))]
+  "TARGET_64BIT && TARGET_MOVBE
+   && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
+  "@
+    bswap\t%0
+    movbe\t{%1, %0|%0, %1}
+    movbe\t{%1, %0|%0, %1}"
+  [(set_attr "type" "*,imov,imov")
+   (set_attr "modrm" "*,1,1")
+   (set_attr "prefix_0f" "1")
+   (set_attr "prefix_extra" "*,1,1")
+   (set_attr "length" "3,*,*")
+   (set_attr "mode" "DI")])
+
+(define_insn "*bswapdi_1"
   [(set (match_operand:DI 0 "register_operand" "=r")
        (bswap:DI (match_operand:DI 1 "register_operand" "0")))]
   "TARGET_64BIT"
    (set_attr "type" "bitmanip")
    (set_attr "mode" "DI")])
 
-(define_insn "*bsr_rex64"
+(define_insn "bsr_rex64"
   [(set (match_operand:DI 0 "register_operand" "=r")
        (minus:DI (const_int 63)
                  (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
    (clobber (reg:CC FLAGS_REG))]
   "TARGET_64BIT"
   "bsr{q}\t{%1, %0|%0, %1}"
-  [(set_attr "prefix_0f" "1")
+  [(set_attr "type" "alu1")
+   (set_attr "prefix_0f" "1")
    (set_attr "mode" "DI")])
 
 (define_expand "clzhi2"
    (clobber (reg:CC FLAGS_REG))]
   ""
   "bsr{w}\t{%1, %0|%0, %1}"
-  [(set_attr "prefix_0f" "1")
+  [(set_attr "type" "alu1")
+   (set_attr "prefix_0f" "1")
    (set_attr "mode" "HI")])
 
 (define_expand "paritydi2"
    (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
              UNSPEC_TLS_GD)]
   "TARGET_64BIT"
-  ".byte\t0x66\;lea{q}\t{%a1@TLSGD(%%rip), %%rdi|rdi, %a1@TLSGD[rip]}\;.word\t0x6666\;rex64\;call\t%P2"
+  { return ASM_BYTE "0x66\n\tlea{q}\t{%a1@TLSGD(%%rip), %%rdi|rdi, %a1@TLSGD[rip]}\n" ASM_SHORT "0x6666\n\trex64\n\tcall\t%P2"; }
   [(set_attr "type" "multi")
    (set_attr "length" "16")])
 
      (clobber (reg:CC FLAGS_REG))])]
   "!TARGET_64BIT && TARGET_GNU2_TLS"
 {
-  operands[3] = !can_create_pseudo_p () ? operands[0] : gen_reg_rtx (Pmode);
+  operands[3] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
   ix86_tls_descriptor_calls_expanded_in_cfun = true;
 })
 
   ""
   [(set (match_dup 0) (match_dup 5))]
 {
-  operands[5] = !can_create_pseudo_p () ? operands[0] : gen_reg_rtx (Pmode);
+  operands[5] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
   emit_insn (gen_tls_dynamic_gnu2_32 (operands[5], operands[1], operands[2]));
 })
 
      (clobber (reg:CC FLAGS_REG))])]
   "TARGET_64BIT && TARGET_GNU2_TLS"
 {
-  operands[2] = !can_create_pseudo_p () ? operands[0] : gen_reg_rtx (Pmode);
+  operands[2] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
   ix86_tls_descriptor_calls_expanded_in_cfun = true;
 })
 
   ""
   [(set (match_dup 0) (match_dup 4))]
 {
-  operands[4] = !can_create_pseudo_p () ? operands[0] : gen_reg_rtx (Pmode);
+  operands[4] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
   emit_insn (gen_tls_dynamic_gnu2_64 (operands[4], operands[1]));
 })
 
 (define_expand "scalb<mode>3"
   [(use (match_operand:MODEF 0 "register_operand" ""))
    (use (match_operand:MODEF 1 "general_operand" ""))
-   (use (match_operand:MODEF 2 "register_operand" ""))]
+   (use (match_operand:MODEF 2 "general_operand" ""))]
  "TARGET_USE_FANCY_MATH_387
    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
        || TARGET_MIX_SSE_I387)
   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
   DONE;
 })
+
+(define_expand "significandxf2"
+  [(parallel [(set (match_operand:XF 0 "register_operand" "")
+                  (unspec:XF [(match_operand:XF 1 "register_operand" "")]
+                             UNSPEC_XTRACT_FRACT))
+             (set (match_dup 2)
+                  (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
+  "TARGET_USE_FANCY_MATH_387
+   && flag_unsafe_math_optimizations"
+{
+  operands[2] = gen_reg_rtx (XFmode);
+})
+
+(define_expand "significand<mode>2"
+  [(use (match_operand:MODEF 0 "register_operand" ""))
+   (use (match_operand:MODEF 1 "register_operand" ""))]
+  "TARGET_USE_FANCY_MATH_387
+   && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
+       || TARGET_MIX_SSE_I387)
+   && flag_unsafe_math_optimizations"
+{
+  rtx op0 = gen_reg_rtx (XFmode);
+  rtx op1 = gen_reg_rtx (XFmode);
+
+  emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
+  emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
+  DONE;
+})
 \f
 
 (define_insn "sse4_1_round<mode>2"
        (unspec:DI [(match_operand:XF 1 "register_operand" "")]
                   UNSPEC_FIST))]
   "TARGET_USE_FANCY_MATH_387
-   && !(reload_completed || reload_in_progress)"
+   && can_create_pseudo_p ()"
   "#"
   "&& 1"
   [(const_int 0)]
        (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
                           UNSPEC_FIST))]
   "TARGET_USE_FANCY_MATH_387
-   && !(reload_completed || reload_in_progress)"
+   && can_create_pseudo_p ()"
   "#"
   "&& 1"
   [(const_int 0)]
    (clobber (reg:CC FLAGS_REG))]
   "TARGET_USE_FANCY_MATH_387
    && flag_unsafe_math_optimizations
-   && !(reload_completed || reload_in_progress)"
+   && can_create_pseudo_p ()"
   "#"
   "&& 1"
   [(const_int 0)]
    (clobber (reg:CC FLAGS_REG))]
   "TARGET_USE_FANCY_MATH_387
    && flag_unsafe_math_optimizations
-   && !(reload_completed || reload_in_progress)"
+   && can_create_pseudo_p ()"
   "#"
   "&& 1"
   [(const_int 0)]
    (clobber (reg:CC FLAGS_REG))]
   "TARGET_USE_FANCY_MATH_387
    && flag_unsafe_math_optimizations
-   && !(reload_completed || reload_in_progress)"
+   && can_create_pseudo_p ()"
   "#"
   "&& 1"
   [(const_int 0)]
    (clobber (reg:CC FLAGS_REG))]
   "TARGET_USE_FANCY_MATH_387
    && flag_unsafe_math_optimizations
-   && !(reload_completed || reload_in_progress)"
+   && can_create_pseudo_p ()"
   "#"
   "&& 1"
   [(const_int 0)]
    (clobber (reg:CC FLAGS_REG))]
   "TARGET_USE_FANCY_MATH_387
    && flag_unsafe_math_optimizations
-   && !(reload_completed || reload_in_progress)"
+   && can_create_pseudo_p ()"
   "#"
   "&& 1"
   [(const_int 0)]
    (clobber (reg:CC FLAGS_REG))]
   "TARGET_USE_FANCY_MATH_387
    && flag_unsafe_math_optimizations
-   && !(reload_completed || reload_in_progress)"
+   && can_create_pseudo_p ()"
   "#"
   "&& 1"
   [(const_int 0)]
   "TARGET_USE_FANCY_MATH_387"
   "fxam\n\tfnstsw\t%0"
   [(set_attr "type" "multi")
+   (set_attr "length" "4")
    (set_attr "unit" "i387")
    (set_attr "mode" "<MODE>")])
 
          [(match_operand:MODEF 1 "memory_operand" "")]
          UNSPEC_FXAM_MEM))]
   "TARGET_USE_FANCY_MATH_387
-   && !(reload_completed || reload_in_progress)"
+   && can_create_pseudo_p ()"
   "#"
   "&& 1"
   [(set (match_dup 2)(match_dup 1))
   "movsb"
   [(set_attr "type" "str")
    (set_attr "memory" "both")
+   (set_attr "prefix_rex" "0")
    (set_attr "mode" "QI")])
 
 (define_expand "rep_mov"
   "stosb"
   [(set_attr "type" "str")
    (set_attr "memory" "store")
+   (set_attr "prefix_rex" "0")
    (set_attr "mode" "QI")])
 
 (define_expand "rep_stos"
   [(set_attr "type" "str")
    (set_attr "prefix_rep" "1")
    (set_attr "memory" "store")
+   (set_attr "prefix_rex" "0")
    (set_attr "mode" "QI")])
 
 (define_expand "cmpstrnsi"
   "repz cmpsb"
   [(set_attr "type" "str")
    (set_attr "mode" "QI")
+   (set_attr "prefix_rex" "0")
    (set_attr "prefix_rep" "1")])
 
 ;; The same, but the count is not known to not be zero.
   "repz cmpsb"
   [(set_attr "type" "str")
    (set_attr "mode" "QI")
+   (set_attr "prefix_rex" "0")
    (set_attr "prefix_rep" "1")])
 
 (define_expand "strlensi"
   "repnz scasb"
   [(set_attr "type" "str")
    (set_attr "mode" "QI")
+   (set_attr "prefix_rex" "0")
    (set_attr "prefix_rep" "1")])
 
 ;; Peephole optimizations to clean up after cmpstrn*.  This should be
 (define_expand "mov<mode>cc"
   [(set (match_operand:X87MODEF 0 "register_operand" "")
        (if_then_else:X87MODEF
-         (match_operand 1 "comparison_operator" "")
+         (match_operand 1 "ix86_fp_comparison_operator" "")
          (match_operand:X87MODEF 2 "register_operand" "")
          (match_operand:X87MODEF 3 "register_operand" "")))]
   "(TARGET_80387 && TARGET_CMOVE)
                 (const_string "imov")
              ]
              (const_string "lea")))
+   (set (attr "length_immediate")
+       (cond [(eq_attr "type" "imov")
+                (const_string "0")
+              (and (eq_attr "type" "alu")
+                   (match_operand 2 "const128_operand" ""))
+                (const_string "1")
+             ]
+             (const_string "*")))
    (set_attr "mode" "SI")])
 
 (define_insn "pro_epilogue_adjust_stack_rex64"
                 (const_string "imov")
              ]
              (const_string "lea")))
+   (set (attr "length_immediate")
+       (cond [(eq_attr "type" "imov")
+                (const_string "0")
+              (and (eq_attr "type" "alu")
+                   (match_operand 2 "const128_operand" ""))
+                (const_string "1")
+             ]
+             (const_string "*")))
    (set_attr "mode" "DI")])
 
 (define_insn "pro_epilogue_adjust_stack_rex64_2"
        (match_operator 1 "compare_operator"
          [(match_operand 2 "register_operand" "")
           (match_operand 3 "const_int_operand" "")]))]
-  "(((!TARGET_FUSE_CMP_AND_BRANCH || optimize_size)
+  "(((!TARGET_FUSE_CMP_AND_BRANCH || optimize_insn_for_size_p ())
      && incdec_operand (operands[3], GET_MODE (operands[3])))
     || (!TARGET_FUSE_CMP_AND_BRANCH
        && INTVAL (operands[3]) == 128))
              (match_operand:SI 2 "" "")))
    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
                            (match_operand:SI 3 "immediate_operand" "i")))]
-  "!TARGET_64BIT"
+  "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
 {
   if (constant_call_address_operand (operands[1], Pmode))
-    {
-      if (SIBLING_CALL_P (insn))
-       return "jmp\t%P1";
-      else
-       return "call\t%P1";
-    }
-  if (SIBLING_CALL_P (insn))
-    return "jmp\t%A1";
-  else
-    return "call\t%A1";
+    return "call\t%P1";
+  return "call\t%A1";
 }
   [(set_attr "type" "callv")])
 
+(define_insn "*sibcall_value_pop_1"
+  [(set (match_operand 0 "" "")
+       (call (mem:QI (match_operand:SI 1 "call_insn_operand" "s,U"))
+             (match_operand:SI 2 "" "")))
+   (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
+                           (match_operand:SI 3 "immediate_operand" "i,i")))]
+  "SIBLING_CALL_P (insn) && !TARGET_64BIT"
+  "@
+   jmp\t%P1
+   jmp\t%A1"
+  [(set_attr "type" "callv")])
+
 (define_insn "*call_value_0"
   [(set (match_operand 0 "" "")
        (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
 
 (define_insn "*sibcall_value_1"
   [(set (match_operand 0 "" "")
-       (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,c,d,a"))
+       (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,U"))
              (match_operand:SI 2 "" "")))]
   "SIBLING_CALL_P (insn) && !TARGET_64BIT"
-{
-  if (constant_call_address_operand (operands[1], Pmode))
-    return "jmp\t%P1";
-  return "jmp\t%A1";
-}
+  "@
+   jmp\t%P1
+   jmp\t%A1"
   [(set_attr "type" "callv")])
 
 (define_insn "*call_value_1_rex64"
 
 (define_insn "*sibcall_value_1_rex64"
   [(set (match_operand 0 "" "")
-       (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
+       (call (mem:QI (match_operand:DI 1 "sibcall_insn_operand" "s,U"))
              (match_operand:DI 2 "" "")))]
   "SIBLING_CALL_P (insn) && TARGET_64BIT"
-  "jmp\t%P1"
-  [(set_attr "type" "callv")])
-
-(define_insn "*sibcall_value_1_rex64_v"
-  [(set (match_operand 0 "" "")
-       (call (mem:QI (reg:DI R11_REG))
-             (match_operand:DI 1 "" "")))]
-  "SIBLING_CALL_P (insn) && TARGET_64BIT"
-  "jmp\t{*%%}r11"
+  "@
+   jmp\t%P1
+   jmp\t%A1"
   [(set_attr "type" "callv")])
 \f
 ;; We used to use "int $5", in honor of #BR which maps to interrupt vector 5.
 }
   [(set_attr "type" "sse")
    (set_attr "atom_sse_attr" "prefetch")
+   (set (attr "length_address") (symbol_ref "memory_address_length (operands[0])"))
    (set_attr "memory" "none")])
 
 (define_insn "*prefetch_sse_rex"
 }
   [(set_attr "type" "sse")
    (set_attr "atom_sse_attr" "prefetch")
+   (set (attr "length_address") (symbol_ref "memory_address_length (operands[0])"))
    (set_attr "memory" "none")])
 
 (define_insn "*prefetch_3dnow"
     return "prefetchw\t%a0";
 }
   [(set_attr "type" "mmx")
+   (set (attr "length_address") (symbol_ref "memory_address_length (operands[0])"))
    (set_attr "memory" "none")])
 
 (define_insn "*prefetch_3dnow_rex"
     return "prefetchw\t%a0";
 }
   [(set_attr "type" "mmx")
+   (set (attr "length_address") (symbol_ref "memory_address_length (operands[0])"))
    (set_attr "memory" "none")])
 
 (define_expand "stack_protect_set"
     emit_insn (gen_stack_protect_test_si (flags, operands[0], operands[1]));
 #endif
 
-  ix86_compare_op0 = flags;
-  ix86_compare_op1 = const0_rtx;
-  emit_jump_insn (gen_beq (operands[2]));
+  emit_jump_insn (gen_cbranchcc4 (gen_rtx_EQ (VOIDmode, flags, const0_rtx),
+                                 flags, const0_rtx, operands[2]));
   DONE;
 })
 
          [(match_operand:SI 1 "register_operand" "0")
           (match_operand:CRC32MODE 2 "nonimmediate_operand" "<crc32modeconstraint>")]
          UNSPEC_CRC32))]
-  "TARGET_SSE4_2"
+  "TARGET_SSE4_2 || TARGET_CRC32"
   "crc32<crc32modesuffix>\t{%2, %0|%0, %2}"
   [(set_attr "type" "sselog1")
    (set_attr "prefix_rep" "1")
    (set_attr "prefix_extra" "1")
+   (set (attr "prefix_data16")
+     (if_then_else (match_operand:HI 2 "" "")
+       (const_string "1")
+       (const_string "*")))
+   (set (attr "prefix_rex")
+     (if_then_else (match_operand:QI 2 "ext_QIreg_operand" "")
+       (const_string "1")
+       (const_string "*")))
    (set_attr "mode" "SI")])
 
 (define_insn "sse4_2_crc32di"
          [(match_operand:DI 1 "register_operand" "0")
           (match_operand:DI 2 "nonimmediate_operand" "rm")]
          UNSPEC_CRC32))]
-  "TARGET_SSE4_2 && TARGET_64BIT"
+  "TARGET_64BIT && (TARGET_SSE4_2 || TARGET_CRC32)"
   "crc32q\t{%2, %0|%0, %2}"
   [(set_attr "type" "sselog1")
    (set_attr "prefix_rep" "1")
    (set_attr "prefix_extra" "1")
    (set_attr "mode" "DI")])
 
+(define_expand "rdpmc"
+  [(match_operand:DI 0 "register_operand" "")
+   (match_operand:SI 1 "register_operand" "")]
+  ""
+{
+  rtx reg = gen_reg_rtx (DImode);
+  rtx si;
+
+  /* Force operand 1 into ECX.  */
+  rtx ecx = gen_rtx_REG (SImode, CX_REG);
+  emit_insn (gen_rtx_SET (VOIDmode, ecx, operands[1]));
+  si = gen_rtx_UNSPEC_VOLATILE (DImode, gen_rtvec (1, ecx),
+                               UNSPECV_RDPMC);
+
+  if (TARGET_64BIT)
+    {
+      rtvec vec = rtvec_alloc (2);
+      rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
+      rtx upper = gen_reg_rtx (DImode);
+      rtx di = gen_rtx_UNSPEC_VOLATILE (DImode,
+                                       gen_rtvec (1, const0_rtx),
+                                       UNSPECV_RDPMC);
+      RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, si);
+      RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, di);
+      emit_insn (load);
+      upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
+                                  NULL, 1, OPTAB_DIRECT);
+      reg = expand_simple_binop (DImode, IOR, reg, upper, reg, 1,
+                                OPTAB_DIRECT);
+    }
+  else
+    emit_insn (gen_rtx_SET (VOIDmode, reg, si));
+  emit_insn (gen_rtx_SET (VOIDmode, operands[0], reg));
+  DONE;
+})
+
+(define_insn "*rdpmc"
+  [(set (match_operand:DI 0 "register_operand" "=A")
+       (unspec_volatile:DI [(match_operand:SI 1 "register_operand" "c")]
+                           UNSPECV_RDPMC))]
+  "!TARGET_64BIT"
+  "rdpmc"
+  [(set_attr "type" "other")
+   (set_attr "length" "2")])
+
+(define_insn "*rdpmc_rex64"
+  [(set (match_operand:DI 0 "register_operand" "=a")
+       (unspec_volatile:DI [(match_operand:SI 2 "register_operand" "c")]
+                           UNSPECV_RDPMC))
+  (set (match_operand:DI 1 "register_operand" "=d")
+       (unspec_volatile:DI [(const_int 0)] UNSPECV_RDPMC))]
+  "TARGET_64BIT"
+  "rdpmc"
+  [(set_attr "type" "other")
+   (set_attr "length" "2")])
+
+(define_expand "rdtsc"
+  [(set (match_operand:DI 0 "register_operand" "")
+       (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
+  ""
+{
+  if (TARGET_64BIT)
+    {
+      rtvec vec = rtvec_alloc (2);
+      rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
+      rtx upper = gen_reg_rtx (DImode);
+      rtx lower = gen_reg_rtx (DImode);
+      rtx src = gen_rtx_UNSPEC_VOLATILE (DImode,
+                                        gen_rtvec (1, const0_rtx),
+                                        UNSPECV_RDTSC);
+      RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, lower, src);
+      RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, src);
+      emit_insn (load);
+      upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
+                                  NULL, 1, OPTAB_DIRECT);
+      lower = expand_simple_binop (DImode, IOR, lower, upper, lower, 1,
+                                  OPTAB_DIRECT);
+      emit_insn (gen_rtx_SET (VOIDmode, operands[0], lower));
+      DONE;
+    }
+})
+
+(define_insn "*rdtsc"
+  [(set (match_operand:DI 0 "register_operand" "=A")
+       (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
+  "!TARGET_64BIT"
+  "rdtsc"
+  [(set_attr "type" "other")
+   (set_attr "length" "2")])
+
+(define_insn "*rdtsc_rex64"
+  [(set (match_operand:DI 0 "register_operand" "=a")
+       (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))
+   (set (match_operand:DI 1 "register_operand" "=d")
+       (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
+  "TARGET_64BIT"
+  "rdtsc"
+  [(set_attr "type" "other")
+   (set_attr "length" "2")])
+
+(define_expand "rdtscp"
+  [(match_operand:DI 0 "register_operand" "")
+   (match_operand:SI 1 "memory_operand" "")]
+  ""
+{
+  rtx di = gen_rtx_UNSPEC_VOLATILE (DImode,
+                                   gen_rtvec (1, const0_rtx),
+                                   UNSPECV_RDTSCP);
+  rtx si = gen_rtx_UNSPEC_VOLATILE (SImode,
+                                   gen_rtvec (1, const0_rtx),
+                                   UNSPECV_RDTSCP);
+  rtx reg = gen_reg_rtx (DImode);
+  rtx tmp = gen_reg_rtx (SImode);
+
+  if (TARGET_64BIT)
+    {
+      rtvec vec = rtvec_alloc (3);
+      rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
+      rtx upper = gen_reg_rtx (DImode);
+      RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, di);
+      RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, di);
+      RTVEC_ELT (vec, 2) = gen_rtx_SET (VOIDmode, tmp, si);
+      emit_insn (load);
+      upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
+                                  NULL, 1, OPTAB_DIRECT);
+      reg = expand_simple_binop (DImode, IOR, reg, upper, reg, 1,
+                                OPTAB_DIRECT);
+    }
+  else
+    {
+      rtvec vec = rtvec_alloc (2);
+      rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
+      RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, di);
+      RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, tmp, si);
+      emit_insn (load);
+    }
+  emit_insn (gen_rtx_SET (VOIDmode, operands[0], reg));
+  emit_insn (gen_rtx_SET (VOIDmode, operands[1], tmp));
+  DONE;
+})
+
+(define_insn "*rdtscp"
+  [(set (match_operand:DI 0 "register_operand" "=A")
+       (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
+   (set (match_operand:SI 1 "register_operand" "=c")
+       (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
+  "!TARGET_64BIT"
+  "rdtscp"
+  [(set_attr "type" "other")
+   (set_attr "length" "3")])
+
+(define_insn "*rdtscp_rex64"
+  [(set (match_operand:DI 0 "register_operand" "=a")
+       (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
+   (set (match_operand:DI 1 "register_operand" "=d")
+        (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
+   (set (match_operand:SI 2 "register_operand" "=c")
+       (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
+  "TARGET_64BIT"
+  "rdtscp"
+  [(set_attr "type" "other")
+   (set_attr "length" "3")])
+
 (include "mmx.md")
 (include "sse.md")
 (include "sync.md")