[PATCH] i386/x86_64 get_attr_length bugfixes

Jakub Jelinek jakub@redhat.com
Wed May 20 18:15:00 GMT 2009


Hi!

I've used attached script on -S -dp compiled i386/x86_64 sources to find
various bugs in config/i386/ instruction length computation.
This patch fixes all bugs found in -O2 {-m32,-m64} insn-attrtab.i
compilation and most bugs found in -O3 -fpic {-m32,-m64} tramp3d-v4.ii
compilation.  The script isn't perfect, e.g. it doesn't handle multi-insn
instructions (like return_long_internal, which contain \;, or e.g. set_got
(which is wrong anyway, 11 bytes actual vs. 12 bytes returned by
get_attr_length)), but for finding bugs in length computations is quite useful.
The script is invoked with a list of -S -dp compiled files, like:
./analyze.S.-dp.sh *.s
(or
asflags=-32 ./analyze.S.-dp.sh *.s
for -m32 compiled stuff).

I've also run the vanilla and patched gcc on a collection of preprocessed
gcc sources, with -O2 {-m32,-m64} and -O3 -fpic {-m32 -march=core2,-m64},
results of the script attached.  There is still work to do, but the patch
already grew quite a bit, so I'd prefer to do further bugfixes in followup
patches.  From the results* tarball it is clear that the patch does
substantial improvements in the insn length computation, especially for -m64
compiled code.

My primary reason for working on this is to make get_attr_length good enough
to be usable in min_insn_size for non-jump insns other than
TYPE_MULTI/TYPE_OTHER.

Bootstrapped/regtested on x86_64-linux and i686-linux.  Ok for trunk?

	Jakub
-------------- next part --------------
2009-05-20  Jakub Jelinek  <jakub@redhat.com>

	* config/i386/i386.c (memory_address_length): Handle %r12
	the same as %rsp and %r13 the same as %rbp.  For %rsp and %rbp
	also check REGNO.
	(ix86_attr_length_address_default): For MODE_SI lea in 64-bit
	mode look through optional ZERO_EXTEND and SUBREG.
	* config/i386/i386.md (R12_REG): New define_constant.
	(prefix_data16): For sse unit set also for MODE_TI insns.
	(prefix_rex): For -m32 always return 0.  For TYPE_IMOVX
	insns set if operand 1 is ext_QIreg_operand.
	(modrm): For TYPE_IMOV clear only if not MODE_DI.  For
	TYPE_{ALU{,1},ICMP,TEST} insn clear if there is non-shortened
	immediate.
	(*movdi_extzv_1, zero_extendhidi2, zero_extendqidi2): Change
	mode from MODE_DI to MODE_SI.
	(movdi_1_rex64): Override modrm and length_immediate attributes
	only for movabs (TYPE_IMOV, alternative 2).
	(zero_extendsidi2_rex64): Clear prefix_0f attribute if TYPE_IMOVX.
	(*float<SSEMODEI24:mode><MODEF:mode>2_mixed_interunit,
	*float<SSEMODEI24:mode><MODEF:mode>2_mixed_nointerunit,
	*float<SSEMODEI24:mode><MODEF:mode>2_sse_interunit,
	*float<SSEMODEI24:mode><MODEF:mode>2_sse_nointerunit): Set
	prefix_rex attribute if DImode.
	(*adddi_1_rex64, *adddi_2_rex64, *adddi_3_rex64, *adddi_5_rex64,
	*addsi_1, *addsi_1_zext, *addsi_2, *addsi_2_zext, *addsi_3,
	*addsi_3_zext, *addsi_5, *addhi_1_lea, *addhi_1, *addhi_2, *addhi_3,
	*addhi_5, *addqi_1_lea, *addqi_1): Override length_immediate
	attribute to 1 if TYPE_ALU and operand 2 is const128_operand.
	(pro_epilogue_adjust_stack_1, pro_epilogue_adjust_stack_rex64):
	Likewise.  For TYPE_IMOV clear length_immediate attribute.
	(*ashldi3_1_rex64, *ashldi3_cmp_rex64, *ashldi3_cconly_rex64,
	*ashlsi3_1, *ashlsi3_1_zext, *ashlsi3_cmp, **ashlsi3_cconly,
	*ashlsi3_cmp_zext, *ashlhi3_1_lea, *ashlhi3_1, *ashlhi3_cmp,
	*ashlhi3_cconly, *ashlqi3_1_lea, *ashlqi3_1, *ashlqi3_cmp,
	*ashlqi3_cconly): Override length_immediate attribute to 0 if TYPE_ALU
	or one operand TYPE_ISHIFT.
	(*ashrdi3_1_one_bit_rex64, *ashrdi3_one_bit_cmp_rex64,
	*ashrdi3_one_bit_cconly_rex64, *ashrsi3_1_one_bit,
	*ashrsi3_1_one_bit_zext, *ashrsi3_one_bit_cmp,
	*ashrsi3_one_bit_cconly, *ashrsi3_one_bit_cmp_zext,
	*ashrhi3_1_one_bit, *ashrhi3_one_bit_cmp, *ashrhi3_one_bit_cconly,
	*ashrqi3_1_one_bit, *ashrqi3_1_one_bit_slp, *ashrqi3_one_bit_cmp,
	*ashrqi3_one_bit_cconly, *lshrdi3_1_one_bit_rex64,
	*lshrdi3_cmp_one_bit_rex64, *lshrdi3_cconly_one_bit_rex64,
	*lshrsi3_1_one_bit, *lshrsi3_1_one_bit_zext, *lshrsi3_one_bit_cmp,
	*lshrsi3_one_bit_cconly, *lshrsi3_cmp_one_bit_zext,
	*lshrhi3_1_one_bit, *lshrhi3_one_bit_cmp, *lshrhi3_one_bit_cconly,
	*lshrqi3_1_one_bit, *lshrqi3_1_one_bit_slp, *lshrqi2_one_bit_cmp,
	*lshrqi2_one_bit_cconly, *rotlsi3_1_one_bit_rex64, *rotlsi3_1_one_bit,
	*rotlsi3_1_one_bit_zext, *rotlhi3_1_one_bit, *rotlqi3_1_one_bit_slp,
	*rotlqi3_1_one_bit, *rotrdi3_1_one_bit_rex64, *rotrsi3_1_one_bit,
	*rotrsi3_1_one_bit_zext, *rotrhi3_one_bit, *rotrqi3_1_one_bit,
	*rotrqi3_1_one_bit_slp): Override length_immediate attribute to 0,
	set mode attribute, don't override length attribute.
	(*btsq, *btrq, *btcq, *btdi_rex64, *btsi): Set prefix_0f attribute
	to 1.
	(return_internal_long): Set length attribute to 2 instead of 1.
	(*strmovqi_rex_1, *strsetqi_rex_1, *rep_stosqi_rex64,
	*cmpstrnqi_nz_rex_1, *cmpstrnqi_rex_1, *strlenqi_rex_1): Clear
	prefix_rex attribute.
	* config/i386/predicates.md (ext_QIreg_operand,
	const128_operand): New predicates.
	(memory_displacement_only_operand): Always return 0 for
	TARGET_64BIT.

--- gcc/config/i386/i386.c	(revision 147701)
+++ gcc/config/i386/i386.c	(working copy)
@@ -19308,17 +19308,23 @@ memory_address_length (rtx addr)
 
   /* Rule of thumb:
        - esp as the base always wants an index,
-       - ebp as the base always wants a displacement.  */
+       - ebp as the base always wants a displacement,
+       - r12 as the base always wants an index,
+       - r13 as the base always wants a displacement.  */
 
   /* Register Indirect.  */
   if (base && !index && !disp)
     {
       /* esp (for its index) and ebp (for its displacement) need
-	 the two-byte modrm form.  */
-      if (addr == stack_pointer_rtx
-	  || addr == arg_pointer_rtx
-	  || addr == frame_pointer_rtx
-	  || addr == hard_frame_pointer_rtx)
+	 the two-byte modrm form.  Similarly for r12 and r13 in 64-bit
+	 code.  */
+      if (REG_P (addr)
+	  && (addr == arg_pointer_rtx
+	      || addr == frame_pointer_rtx
+	      || REGNO (addr) == SP_REG
+	      || REGNO (addr) == BP_REG
+	      || REGNO (addr) == R12_REG
+	      || REGNO (addr) == R13_REG))
 	len = 1;
     }
 
@@ -19336,16 +19342,18 @@ memory_address_length (rtx addr)
 	  else
 	    len = 4;
 	}
-      /* ebp always wants a displacement.  */
-      else if (base == hard_frame_pointer_rtx)
+      /* ebp always wants a displacement.  Similarly r13.  */
+      else if (REG_P (base)
+	       && (REGNO (base) == BP_REG || REGNO (base) == R13_REG))
         len = 1;
 
       /* An index requires the two-byte modrm form....  */
       if (index
-	  /* ...like esp, which always wants an index.  */
-	  || base == stack_pointer_rtx
+	  /* ...like esp (or r12), which always wants an index.  */
 	  || base == arg_pointer_rtx
-	  || base == frame_pointer_rtx)
+	  || base == frame_pointer_rtx
+	  || (REG_P (base)
+	      && (REGNO (base) == SP_REG || REGNO (base) == R12_REG)))
 	len += 1;
     }
 
@@ -19398,14 +19406,23 @@ ix86_attr_length_address_default (rtx in
 
   if (get_attr_type (insn) == TYPE_LEA)
     {
-      rtx set = PATTERN (insn);
+      rtx set = PATTERN (insn), addr;
 
       if (GET_CODE (set) == PARALLEL)
 	set = XVECEXP (set, 0, 0);
 
       gcc_assert (GET_CODE (set) == SET);
 
-      return memory_address_length (SET_SRC (set));
+      addr = SET_SRC (set);
+      if (TARGET_64BIT && get_attr_mode (insn) == MODE_SI)
+	{
+	  if (GET_CODE (addr) == ZERO_EXTEND)
+	    addr = XEXP (addr, 0);
+	  if (GET_CODE (addr) == SUBREG)
+	    addr = SUBREG_REG (addr);
+	}
+
+      return memory_address_length (addr);
     }
 
   extract_insn_cached (insn);
--- gcc/config/i386/i386.md	(revision 147701)
+++ gcc/config/i386/i386.md	(working copy)
@@ -312,6 +312,7 @@ (define_constants
    (R9_REG			38)
    (R10_REG			39)
    (R11_REG			40)
+   (R12_REG			41)
    (R13_REG			42)
    (XMM8_REG			45)
    (XMM9_REG			46)
@@ -416,7 +417,7 @@ (define_attr "length_address" ""
 ;; 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")))
+		     (and (eq_attr "unit" "sse") (eq_attr "mode" "V2DF,TI")))
     (const_int 1)
     (const_int 0)))
 
@@ -436,7 +437,9 @@ (define_attr "prefix_0f" ""
 
 ;; Set when REX opcode prefix is used.
 (define_attr "prefix_rex" ""
-  (cond [(and (eq_attr "mode" "DI")
+  (cond [(ne (symbol_ref "!TARGET_64BIT") (const_int 0))
+	   (const_int 0)
+	 (and (eq_attr "mode" "DI")
   	      (eq_attr "type" "!push,pop,call,callv,leave,ibr"))
 	   (const_int 1)
 	 (and (eq_attr "mode" "QI")
@@ -446,6 +449,9 @@ (define_attr "prefix_rex" ""
 	 (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)))
 
@@ -491,12 +497,13 @@ (define_attr "modrm" ""
 	      (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" ""))
@@ -504,6 +511,9 @@ (define_attr "modrm" ""
 	 (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)))
 
@@ -2283,7 +2293,7 @@ (define_insn "*movdi_extzv_1"
   "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")
@@ -2631,8 +2641,16 @@ (define_insn "*movdi_1_rex64"
 	      (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")
      (if_then_else (eq_attr "alternative" "11,12,13,14,15,16")
        (const_string "maybe_vex")
@@ -4101,6 +4119,7 @@ (define_insn "zero_extendsidi2_rex64"
    %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
@@ -4135,7 +4154,7 @@ (define_insn "zero_extendhidi2"
   "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")
@@ -4143,7 +4162,7 @@ (define_insn "zero_extendqidi2"
   "TARGET_64BIT"
   "movz{bl|x}\t{%1, %k0|%k0, %1}"
   [(set_attr "type" "imovx")
-   (set_attr "mode" "DI")])
+   (set_attr "mode" "SI")])
 
 ;; Sign extension instructions
 
@@ -5488,6 +5507,12 @@ (define_insn "*float<SSEMODEI24:mode><MO
   [(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")
@@ -5506,6 +5531,12 @@ (define_insn "*float<SSEMODEI24:mode><MO
   [(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")])
@@ -5682,6 +5713,12 @@ (define_insn "*float<SSEMODEI24:mode><MO
   [(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")])
@@ -5711,6 +5748,12 @@ (define_insn "*float<SSEMODEI24:mode><MO
   [(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")])
@@ -6430,6 +6473,11 @@ (define_insn "*adddi_1_rex64"
 	      (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.
@@ -6494,6 +6542,11 @@ (define_insn "*adddi_2_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")])
 
 (define_insn "*adddi_3_rex64"
@@ -6543,6 +6596,11 @@ (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
@@ -6639,6 +6697,11 @@ (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")])
 
 
@@ -6699,6 +6762,11 @@ (define_insn "*addsi_1"
 	      (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.
@@ -6779,6 +6847,11 @@ (define_insn "addsi_1_zext"
 	      (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.
@@ -6842,6 +6915,11 @@ (define_insn "*addsi_2"
      (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
@@ -6888,6 +6966,11 @@ (define_insn "*addsi_2_zext"
      (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"
@@ -6932,6 +7015,11 @@ (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
@@ -6976,6 +7064,11 @@ (define_insn "*addsi_3_zext"
      (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
@@ -7067,6 +7160,11 @@ (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"
@@ -7121,6 +7219,11 @@ (define_insn "*addhi_1_lea"
 	(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"
@@ -7160,6 +7263,11 @@ (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"
@@ -7202,6 +7310,11 @@ (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"
@@ -7241,6 +7354,11 @@ (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.
@@ -7321,6 +7439,11 @@ (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"
@@ -7379,6 +7502,11 @@ (define_insn "*addqi_1_lea"
 	(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"
@@ -7425,6 +7553,11 @@ (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"
@@ -11513,6 +11646,15 @@ (define_insn "*ashldi3_1_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")])
 
 ;; Convert lea to the lea pattern to avoid flags dependency.
@@ -11572,6 +11714,15 @@ (define_insn "*ashldi3_cmp_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_cconly_rex64"
@@ -11614,6 +11765,15 @@ (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"
@@ -11753,6 +11913,15 @@ (define_insn "*ashlsi3_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.
@@ -11837,6 +12006,15 @@ (define_insn "*ashlsi3_1_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")])
 
 ;; Convert lea to the lea pattern to avoid flags dependency.
@@ -11898,6 +12076,15 @@ (define_insn "*ashlsi3_cmp"
 	      (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"
@@ -11939,6 +12126,15 @@ (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"
@@ -11981,6 +12177,15 @@ (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"
@@ -12026,6 +12231,15 @@ (define_insn "*ashlhi3_1_lea"
 	      (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"
@@ -12060,6 +12274,15 @@ (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
@@ -12105,6 +12328,15 @@ (define_insn "*ashlhi3_cmp"
 	      (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"
@@ -12146,6 +12378,15 @@ (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"
@@ -12211,6 +12452,15 @@ (define_insn "*ashlqi3_1_lea"
 	      (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"
@@ -12263,6 +12513,15 @@ (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
@@ -12308,6 +12567,15 @@ (define_insn "*ashlqi3_cmp"
 	      (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"
@@ -12349,6 +12617,15 @@ (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.
@@ -12467,10 +12744,8 @@ (define_insn "*ashrdi3_1_one_bit_rex64"
    && 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")
@@ -12501,10 +12776,8 @@ (define_insn "*ashrdi3_one_bit_cmp_rex64
    && 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)
@@ -12519,7 +12792,8 @@ (define_insn "*ashrdi3_one_bit_cconly_re
    && 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
@@ -12687,10 +12961,8 @@ (define_insn "*ashrsi3_1_one_bit"
    && 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")
@@ -12702,7 +12974,8 @@ (define_insn "*ashrsi3_1_one_bit_zext"
    && 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")
@@ -12744,10 +13017,8 @@ (define_insn "*ashrsi3_one_bit_cmp"
    && 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)
@@ -12761,7 +13032,8 @@ (define_insn "*ashrsi3_one_bit_cconly"
    && 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)
@@ -12777,7 +13049,8 @@ (define_insn "*ashrsi3_one_bit_cmp_zext"
    && 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
@@ -12843,10 +13116,8 @@ (define_insn "*ashrhi3_1_one_bit"
    && 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")
@@ -12876,10 +13147,8 @@ (define_insn "*ashrhi3_one_bit_cmp"
    && 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)
@@ -12893,7 +13162,8 @@ (define_insn "*ashrhi3_one_bit_cconly"
    && 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
@@ -12943,10 +13213,8 @@ (define_insn "*ashrqi3_1_one_bit"
    && 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"))
@@ -12958,10 +13226,8 @@ (define_insn "*ashrqi3_1_one_bit_slp"
    && 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")
@@ -13004,10 +13270,8 @@ (define_insn "*ashrqi3_one_bit_cmp"
    && 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)
@@ -13021,7 +13285,8 @@ (define_insn "*ashrqi3_one_bit_cconly"
    && 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
@@ -13143,10 +13408,8 @@ (define_insn "*lshrdi3_1_one_bit_rex64"
    && 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")
@@ -13177,10 +13440,8 @@ (define_insn "*lshrdi3_cmp_one_bit_rex64
    && 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)
@@ -13195,7 +13456,8 @@ (define_insn "*lshrdi3_cconly_one_bit_re
    && 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
@@ -13280,10 +13542,8 @@ (define_insn "*lshrsi3_1_one_bit"
    && 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")
@@ -13295,7 +13555,8 @@ (define_insn "*lshrsi3_1_one_bit_zext"
    && 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")
@@ -13338,10 +13599,8 @@ (define_insn "*lshrsi3_one_bit_cmp"
    && 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)
@@ -13355,7 +13614,8 @@ (define_insn "*lshrsi3_one_bit_cconly"
    && 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)
@@ -13371,7 +13631,8 @@ (define_insn "*lshrsi3_cmp_one_bit_zext"
    && 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
@@ -13437,10 +13698,8 @@ (define_insn "*lshrhi3_1_one_bit"
    && 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")
@@ -13470,10 +13729,8 @@ (define_insn "*lshrhi3_one_bit_cmp"
    && 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)
@@ -13487,7 +13744,8 @@ (define_insn "*lshrhi3_one_bit_cconly"
    && 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
@@ -13537,10 +13795,8 @@ (define_insn "*lshrqi3_1_one_bit"
    && 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"))
@@ -13551,10 +13807,8 @@ (define_insn "*lshrqi3_1_one_bit_slp"
    && (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")
@@ -13597,10 +13851,8 @@ (define_insn "*lshrqi2_one_bit_cmp"
    && 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)
@@ -13614,7 +13866,8 @@ (define_insn "*lshrqi2_one_bit_cconly"
    && 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
@@ -13703,10 +13956,8 @@ (define_insn "*rotlsi3_1_one_bit_rex64"
    && 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")
@@ -13736,10 +13987,8 @@ (define_insn "*rotlsi3_1_one_bit"
    && 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")
@@ -13752,7 +14001,8 @@ (define_insn "*rotlsi3_1_one_bit_zext"
    && 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")
@@ -13795,10 +14045,8 @@ (define_insn "*rotlhi3_1_one_bit"
    && 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")
@@ -13838,10 +14086,8 @@ (define_insn "*rotlqi3_1_one_bit_slp"
    && (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")
@@ -13852,10 +14098,8 @@ (define_insn "*rotlqi3_1_one_bit"
    && 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"))
@@ -13935,10 +14179,8 @@ (define_insn "*rotrdi3_1_one_bit_rex64"
    && 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")
@@ -13968,10 +14210,8 @@ (define_insn "*rotrsi3_1_one_bit"
    && 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")
@@ -13984,10 +14224,8 @@ (define_insn "*rotrsi3_1_one_bit_zext"
    && 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")
@@ -14030,10 +14268,8 @@ (define_insn "*rotrhi3_one_bit"
    && 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")
@@ -14073,10 +14309,8 @@ (define_insn "*rotrqi3_1_one_bit"
    && 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"))
@@ -14087,10 +14321,8 @@ (define_insn "*rotrqi3_1_one_bit_slp"
    && (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")
@@ -14198,7 +14430,8 @@ (define_insn "*btsq"
    (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")])
 
 (define_insn "*btrq"
   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
@@ -14208,7 +14441,8 @@ (define_insn "*btrq"
    (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")])
 
 (define_insn "*btcq"
   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
@@ -14218,7 +14452,8 @@ (define_insn "*btcq"
    (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")])
 
 ;; Allow Nocona to avoid these instructions if a register is available.
 
@@ -14329,7 +14564,8 @@ (define_insn "*btdi_rex64"
 	  (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")])
 
 (define_insn "*btsi"
   [(set (reg:CCC FLAGS_REG)
@@ -14341,7 +14577,8 @@ (define_insn "*btsi"
 	  (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")])
 
 ;; Store-flag instructions.
 
@@ -15487,7 +15724,7 @@ (define_insn "return_internal_long"
    (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")
@@ -19365,6 +19602,7 @@ (define_insn "*strmovqi_rex_1"
   "movsb"
   [(set_attr "type" "str")
    (set_attr "memory" "both")
+   (set_attr "prefix_rex" "0")
    (set_attr "mode" "QI")])
 
 (define_expand "rep_mov"
@@ -19621,6 +19859,7 @@ (define_insn "*strsetqi_rex_1"
   "stosb"
   [(set_attr "type" "str")
    (set_attr "memory" "store")
+   (set_attr "prefix_rex" "0")
    (set_attr "mode" "QI")])
 
 (define_expand "rep_stos"
@@ -19714,6 +19953,7 @@ (define_insn "*rep_stosqi_rex64"
   [(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"
@@ -19840,6 +20080,7 @@ (define_insn "*cmpstrnqi_nz_rex_1"
   "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.
@@ -19893,6 +20134,7 @@ (define_insn "*cmpstrnqi_rex_1"
   "repz cmpsb"
   [(set_attr "type" "str")
    (set_attr "mode" "QI")
+   (set_attr "prefix_rex" "0")
    (set_attr "prefix_rep" "1")])
 
 (define_expand "strlensi"
@@ -19954,6 +20196,7 @@ (define_insn "*strlenqi_rex_1"
   "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
@@ -20474,6 +20717,14 @@ (define_insn "pro_epilogue_adjust_stack_
 		 (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"
@@ -20518,6 +20769,14 @@ (define_insn "pro_epilogue_adjust_stack_
 		 (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"
--- gcc/config/i386/predicates.md	(revision 147701)
+++ gcc/config/i386/predicates.md	(working copy)
@@ -76,6 +76,14 @@ (define_predicate "flags_reg_operand"
   (and (match_code "reg")
        (match_test "REGNO (op) == FLAGS_REG")))
 
+;; Return true if op is a QImode register operand other than
+;; %[abcd][hl].
+(define_predicate "ext_QIreg_operand"
+  (and (match_code "reg")
+       (match_test "TARGET_64BIT
+		    && GET_MODE (op) == QImode
+		    && REGNO (op) > BX_REG")))
+
 ;; Return true if op is not xmm0 register.
 (define_predicate "reg_not_xmm0_operand"
    (and (match_operand 0 "register_operand")
@@ -574,6 +582,11 @@ (define_predicate "const8_operand"
   (and (match_code "const_int")
        (match_test "INTVAL (op) == 8")))
 
+;; Match exactly 128.
+(define_predicate "const128_operand"
+  (and (match_code "const_int")
+       (match_test "INTVAL (op) == 128")))
+
 ;; Match 2, 4, or 8.  Used for leal multiplicands.
 (define_predicate "const248_operand"
   (match_code "const_int")
@@ -878,6 +891,9 @@ (define_predicate "memory_displacement_o
   struct ix86_address parts;
   int ok;
 
+  if (TARGET_64BIT)
+    return 0;
+
   ok = ix86_decompose_address (XEXP (op, 0), &parts);
   gcc_assert (ok);
 
-------------- next part --------------
A non-text attachment was scrubbed...
Name: analyze.S.-dp.sh
Type: application/x-sh
Size: 920 bytes
Desc: not available
URL: <http://gcc.gnu.org/pipermail/gcc-patches/attachments/20090520/6bb58c19/attachment.sh>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: results.S.-dp.tar.bz2
Type: application/x-bzip2
Size: 40454 bytes
Desc: not available
URL: <http://gcc.gnu.org/pipermail/gcc-patches/attachments/20090520/6bb58c19/attachment.bz2>


More information about the Gcc-patches mailing list