This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[Patch RFC IA64] Fixing predication & autoinc interaction


I would like to get some feedback on this proposed patch to fix an IA64
bug that is caused by the interaction of predication and autoincrement.

The problem is that GCC is generating predicated instructions that
use autoincrement but if the predicated instruction is not executed
then the autoincrement does not happen and we get incorrect results.

My fix is to break the instructions that allow both predication and
autoincrement modes into two insructions, one that does not allow
autoincrement (but is otherwise identical) and one that allows 
autoincrement but has the "predicable" attibute set to "no" so that
it won't be used as a predicated instruction.  This seems to be working
but I thought I would see if anyone had any comments on my approach
or ideas on a better way to do this.

I haven't yet addressed the speculative and advanced loads but I think
I need to do those too.  Can they be used as predicated instructions?
And I did not create predicated versions of the spill and restore
instructions used by the function prologue and epilogue since I didn't
think those would ever be used in a situation where they would be predicated.
I did explicitly set 'predicable' to no for them though just to be sure they
wouldn't get used this way.

Comments?

Steve Ellcey
sje@cup.hp.com



2009-09-24  Steve Ellcey  <sje@cup.hp.com>

	PR target/41365 
	* config/ia64/predicates.md (not_postinc_destination_operand): New.
	(not_postinc_general_operand): New.
	(not_postinc_move_operand): New.
	(not_postinc_gr_nonimmediate_operand): New.
	(not_postinc_grfr_nonimmediate_operand): New.
	* config/ia64/vect.md (*mov<mode>_internal): Disallow autoinc.
	(*movv2sf_internal): Ditto.
	(*mov<mode>_internal_2): New.
	(*movv2sf_internal_2): New.
	* config/ia64/ia64.md (movbi, movqi_internal, movhi_internal,
	movsi_internal, movdi_internal, movti_internal, movsf_internal,
	movdf_internal, movxf_internal, movrf_internal, zero_extendqidi2,
	zero_extendhidi2, zero_extendsidi2, *cmovdi_internal,
	*cmovsi_internal, gr_spill_internal, gr_restore, fr_spill,
	fr_restore): Disallow autoincrement.
	(movbi_2, movqi_internal_2, movhi_internal_2, movsi_internal_2,
	movdi_internal_2, movti_internal_2, movsf_internal_2, movdf_internal_2,
	movxf_internal_2, movrf_internal_2, zero_extendqidi2_2,
	zero_extendhidi2_2, zero_extendsidi2_2): New.

Index: config/ia64/predicates.md
===================================================================
--- config/ia64/predicates.md	(revision 152088)
+++ config/ia64/predicates.md	(working copy)
@@ -281,11 +281,23 @@ (define_predicate "destination_operand"
 		    || GET_CODE (XEXP (op, 0)) != POST_MODIFY
 		    || GET_CODE (XEXP (XEXP (XEXP (op, 0), 1), 1)) != REG")))
 
+;; Like destination_operand, but don't allow any post-increments.
+(define_predicate "not_postinc_destination_operand"
+  (and (match_operand 0 "nonimmediate_operand")
+       (match_test "GET_CODE (op) != MEM
+        || GET_RTX_CLASS (GET_CODE (XEXP (op, 0))) != RTX_AUTOINC")))
+
 ;; Like memory_operand, but don't allow post-increments.
 (define_predicate "not_postinc_memory_operand"
   (and (match_operand 0 "memory_operand")
        (match_test "GET_RTX_CLASS (GET_CODE (XEXP (op, 0))) != RTX_AUTOINC")))
 
+;; Like general_operand but don't allow post-increments.
+(define_predicate "not_postinc_general_operand"
+  (and (match_operand 0 "general_operand")
+       (match_test "GET_CODE (op) != MEM
+        || GET_RTX_CLASS (GET_CODE (XEXP (op, 0))) != RTX_AUTOINC")))
+
 ;; True if OP is a general operand, with some restrictions on symbols.
 (define_predicate "move_operand"
   (match_operand 0 "general_operand")
@@ -332,6 +344,12 @@ (define_predicate "move_operand"
     }
 })
 
+;; Like move_operand but don't allow post-increments.
+(define_predicate "not_postinc_move_operand"
+  (and (match_operand 0 "move_operand")
+       (match_test "GET_CODE (op) != MEM
+        || GET_RTX_CLASS (GET_CODE (XEXP (op, 0))) != RTX_AUTOINC")))
+
 ;; True if OP is a register operand that is (or could be) a GR reg.
 (define_predicate "gr_register_operand"
   (match_operand 0 "register_operand")
@@ -385,6 +403,12 @@ (define_predicate "gr_nonimmediate_opera
   return (regno >= FIRST_PSEUDO_REGISTER || GENERAL_REGNO_P (regno));
 })
 
+;; Like gr_nonimmediate_operand, but don't allow any post-increments.
+(define_predicate "not_postinc_gr_nonimmediate_operand"
+  (and (match_operand 0 "gr_nonimmediate_operand")
+       (match_test "GET_CODE (op) != MEM
+        || GET_RTX_CLASS (GET_CODE (XEXP (op, 0))) != RTX_AUTOINC")))
+
 ;; True if OP is a nonimmediate operand that is (or could be) a FR reg.
 (define_predicate "fr_nonimmediate_operand"
   (match_operand 0 "nonimmediate_operand")
@@ -417,6 +441,12 @@ (define_predicate "grfr_nonimmediate_ope
 	  || FR_REGNO_P (regno));
 })
 
+;; Like grfr_nonimmediate_operand, but don't allow any post-increments.
+(define_predicate "not_postinc_grfr_nonimmediate_operand"
+  (and (match_operand 0 "grfr_nonimmediate_operand")
+       (match_test "GET_CODE (op) != MEM
+        || GET_RTX_CLASS (GET_CODE (XEXP (op, 0))) != RTX_AUTOINC")))
+
 ;; True if OP is a GR register operand, or zero.
 (define_predicate "gr_reg_or_0_operand"
   (ior (match_operand 0 "gr_register_operand")
Index: config/ia64/vect.md
===================================================================
--- config/ia64/vect.md	(revision 152088)
+++ config/ia64/vect.md	(working copy)
@@ -37,24 +37,38 @@ (define_expand "mov<mode>"
 })
 
 (define_insn "*mov<mode>_internal"
-  [(set (match_operand:VECINT 0 "destination_operand"
+  [(set (match_operand:VECINT 0 "not_postinc_destination_operand"
 					"=r,r,r,r,m ,*f ,*f,Q ,r ,*f")
-	(match_operand:VECINT 1 "move_operand"
+	(match_operand:VECINT 1 "not_postinc_move_operand"
 					"rU,W,i,m,rU,U*f,Q ,*f,*f,r "))]
   "ia64_move_ok (operands[0], operands[1])"
   "@
    mov %0 = %r1
    addl %0 = %v1, r0
    movl %0 = %v1
-   ld8%O1 %0 = %1%P1
-   st8%Q0 %0 = %r1%P0
+   ld8%O1 %0 = %1
+   st8%Q0 %0 = %r1
    mov %0 = %F1
-   ldf8 %0 = %1%P1
-   stf8 %0 = %1%P0
+   ldf8 %0 = %1
+   stf8 %0 = %1
    getf.sig %0 = %1
    setf.sig %0 = %1"
   [(set_attr "itanium_class" "ialu,ialu,long_i,ld,st,fmisc,fld,stf,frfr,tofr")])
 
+(define_insn "*mov<mode>_internal_2"
+  [(set (match_operand:VECINT 0 "destination_operand"
+					"=r,m ,*f,Q")
+	(match_operand:VECINT 1 "move_operand"
+					"m,rU,Q ,*f"))]
+  "ia64_move_ok (operands[0], operands[1])"
+  "@
+   ld8%O1 %0 = %1%P1
+   st8%Q0 %0 = %r1%P0
+   ldf8 %0 = %1%P1
+   stf8 %0 = %1%P0"
+  [(set_attr "itanium_class" "ld,st,fld,stf")
+   (set_attr "predicable" "no")])
+
 (define_insn "one_cmpl<mode>2"
   [(set (match_operand:VECINT 0 "gr_register_operand" "=r")
 	(not:VECINT (match_operand:VECINT 1 "gr_register_operand" "r")))]
@@ -851,22 +865,22 @@ (define_expand "movv2sf"
 })
 
 (define_insn "*movv2sf_internal"
-  [(set (match_operand:V2SF 0 "destination_operand"
+  [(set (match_operand:V2SF 0 "not_postinc_destination_operand"
 					"=f,f,f,Q,*r ,*r,*r,*r,m ,f ,*r")
-	(match_operand:V2SF 1 "move_operand"
+	(match_operand:V2SF 1 "not_postinc_move_operand"
 					"fU,Y,Q,f,U*r,W ,i ,m ,*r,*r,f "))]
   "ia64_move_ok (operands[0], operands[1])"
 {
   static const char * const alt[] = {
     "%,mov %0 = %F1",
     "%,fpack %0 = %F2, %F1",
-    "%,ldf8 %0 = %1%P1",
-    "%,stf8 %0 = %1%P0",
+    "%,ldf8 %0 = %1%",
+    "%,stf8 %0 = %1%",
     "%,mov %0 = %r1",
     "%,addl %0 = %v1, r0",
     "%,movl %0 = %v1",
-    "%,ld8%O1 %0 = %1%P1",
-    "%,st8%Q0 %0 = %r1%P0",
+    "%,ld8%O1 %0 = %1%",
+    "%,st8%Q0 %0 = %r1%",
     "%,setf.sig %0 = %1",
     "%,getf.sig %0 = %1"
   };
@@ -881,6 +895,31 @@ (define_insn "*movv2sf_internal"
 }
   [(set_attr "itanium_class" "fmisc,fmisc,fld,stf,ialu,ialu,long_i,ld,st,tofr,frfr")])
 
+(define_insn "*movv2sf_internal_2"
+  [(set (match_operand:V2SF 0 "destination_operand"
+					"=f,Q,*r, m")
+	(match_operand:V2SF 1 "move_operand"
+					"Q,f, m,*r"))]
+  "ia64_move_ok (operands[0], operands[1])"
+{
+  static const char * const alt[] = {
+    "%,ldf8 %0 = %1%P1",
+    "%,stf8 %0 = %1%P0",
+    "%,ld8%O1 %0 = %1%P1",
+    "%,st8%Q0 %0 = %r1%P0",
+  };
+
+  if (which_alternative == 1)
+    {
+      operands[2] = XVECEXP (operands[1], 0, TARGET_BIG_ENDIAN ? 0 : 1);
+      operands[1] = XVECEXP (operands[1], 0, TARGET_BIG_ENDIAN ? 1 : 0);
+    }
+
+  return alt[which_alternative];
+}
+  [(set_attr "itanium_class" "fld,stf,ld,st")
+   (set_attr "predicable" "no")])
+
 (define_insn "absv2sf2"
   [(set (match_operand:V2SF 0 "fr_register_operand" "=f")
 	(abs:V2SF (match_operand:V2SF 1 "fr_register_operand" "f")))]
Index: config/ia64/ia64.md
===================================================================
--- config/ia64/ia64.md	(revision 152088)
+++ config/ia64/ia64.md	(working copy)
@@ -230,8 +230,8 @@ (define_insn "*movcci"
    (set_attr "predicable" "no")])
 
 (define_insn "movbi"
-  [(set (match_operand:BI 0 "destination_operand" "=c,c,?c,?*r, c,*r,*r,*m,*r")
-	(match_operand:BI 1 "move_operand"        " O,n, c,  c,*r, n,*m,*r,*r"))]
+  [(set (match_operand:BI 0 "not_postinc_destination_operand" "=c,c,?c,?*r, c,*r,*r,*m,*r")
+	(match_operand:BI 1 "not_postinc_move_operand"        " O,n, c,  c,*r, n,*m,*r,*r"))]
   ""
   "@
    cmp.ne %0, %I0 = r0, r0
@@ -240,13 +240,25 @@ (define_insn "movbi"
    #
    tbit.nz %0, %I0 = %1, 0
    adds %0 = %1, r0
-   ld1%O1 %0 = %1%P1
-   st1%Q0 %0 = %1%P0
+   ld1%O1 %0 = %1
+   st1%Q0 %0 = %1
    mov %0 = %1"
   [(set_attr "itanium_class" "icmp,icmp,unknown,unknown,tbit,ialu,ld,st,ialu")
    (set_attr "speculable1"   "yes")
    (set_attr "speculable2"   "no,  no,  no,     no,     no,  no, yes,no,no")])
 
+(define_insn "movbi_2"
+  [(set (match_operand:BI 0 "destination_operand" "=*r,*m")
+	(match_operand:BI 1 "move_operand"        "*m, *r"))]
+  ""
+  "@
+   ld1%O1 %0 = %1%P1
+   st1%Q0 %0 = %1%P0"
+  [(set_attr "itanium_class" "ld, st")
+   (set_attr "speculable1"   "yes")
+   (set_attr "speculable2"   "yes,no")
+   (set_attr "predicable"    "no")])
+
 (define_split
   [(set (match_operand:BI 0 "register_operand" "")
 	(match_operand:BI 1 "register_operand" ""))]
@@ -285,14 +297,14 @@ (define_expand "movqi"
 })
 
 (define_insn "movqi_internal"
-  [(set (match_operand:QI 0 "destination_operand" "=r,r,r, m, r,*f,*f")
-	(match_operand:QI 1 "move_operand"        "rO,J,m,rO,*f,rO,*f"))]
+  [(set (match_operand:QI 0 "not_postinc_destination_operand" "=r,r,r, m, r,*f,*f")
+	(match_operand:QI 1 "not_postinc_move_operand"        "rO,J,m,rO,*f,rO,*f"))]
   "ia64_move_ok (operands[0], operands[1])"
   "@
    mov %0 = %r1
    addl %0 = %1, r0
-   ld1%O1 %0 = %1%P1
-   st1%Q0 %0 = %r1%P0
+   ld1%O1 %0 = %1
+   st1%Q0 %0 = %r1
    getf.sig %0 = %1
    setf.sig %0 = %r1
    mov %0 = %1"
@@ -300,6 +312,18 @@ (define_insn "movqi_internal"
    (set_attr "speculable1"   "yes")
    (set_attr "speculable2"   "no,  no, yes,no,no,  no,  no")])
 
+(define_insn "movqi_internal_2"
+  [(set (match_operand:QI 0 "destination_operand" "=r,m")
+	(match_operand:QI 1 "move_operand"        "m, rO"))]
+  "ia64_move_ok (operands[0], operands[1])"
+  "@
+   ld1%O1 %0 = %1%P1
+   st1%Q0 %0 = %r1%P0"
+  [(set_attr "itanium_class" "ld, st")
+   (set_attr "speculable1"   "yes")
+   (set_attr "speculable2"   "yes,no")
+   (set_attr "predicable"    "no")])
+
 (define_expand "movhi"
   [(set (match_operand:HI 0 "general_operand" "")
 	(match_operand:HI 1 "general_operand" ""))]
@@ -312,14 +336,14 @@ (define_expand "movhi"
 })
 
 (define_insn "movhi_internal"
-  [(set (match_operand:HI 0 "destination_operand" "=r,r,r, m, r,*f,*f")
-	(match_operand:HI 1 "move_operand"        "rO,J,m,rO,*f,rO,*f"))]
+  [(set (match_operand:HI 0 "not_postinc_destination_operand" "=r,r,r, m, r,*f,*f")
+	(match_operand:HI 1 "not_postinc_move_operand"        "rO,J,m,rO,*f,rO,*f"))]
   "ia64_move_ok (operands[0], operands[1])"
   "@
    mov %0 = %r1
    addl %0 = %1, r0
-   ld2%O1 %0 = %1%P1
-   st2%Q0 %0 = %r1%P0
+   ld2%O1 %0 = %1
+   st2%Q0 %0 = %r1
    getf.sig %0 = %1
    setf.sig %0 = %r1
    mov %0 = %1"
@@ -327,6 +351,18 @@ (define_insn "movhi_internal"
    (set_attr "speculable1"   "yes")
    (set_attr "speculable2"   "no,  no, yes,no,no,  no,  no")])
 
+(define_insn "movhi_internal_2"
+  [(set (match_operand:HI 0 "destination_operand" "=r,m")
+	(match_operand:HI 1 "move_operand"        "m,rO"))]
+  "ia64_move_ok (operands[0], operands[1])"
+  "@
+   ld2%O1 %0 = %1%P1
+   st2%Q0 %0 = %r1%P0"
+  [(set_attr "itanium_class" "ld,st")
+   (set_attr "speculable1"   "yes")
+   (set_attr "speculable2"   "yes,no")
+   (set_attr "predicable"    "no")])
+
 (define_expand "movsi"
   [(set (match_operand:SI 0 "general_operand" "")
 	(match_operand:SI 1 "general_operand" ""))]
@@ -339,16 +375,16 @@ (define_expand "movsi"
 })
 
 (define_insn "movsi_internal"
-  [(set (match_operand:SI 0 "destination_operand" "=r,r,r,r,r, m, r,*f,*f, r,*d")
-	(match_operand:SI 1 "move_operand"        "rO,J,j,i,m,rO,*f,rO,*f,*d,rK"))]
+  [(set (match_operand:SI 0 "not_postinc_destination_operand" "=r,r,r,r,r, m, r,*f,*f, r,*d")
+	(match_operand:SI 1 "not_postinc_move_operand"        "rO,J,j,i,m,rO,*f,rO,*f,*d,rK"))]
   "ia64_move_ok (operands[0], operands[1])"
   "@
   mov %0 = %r1
   addl %0 = %1, r0
   addp4 %0 = %1 - 0x100000000, r0
   movl %0 = %1
-  ld4%O1 %0 = %1%P1
-  st4%Q0 %0 = %r1%P0
+  ld4%O1 %0 = %1
+  st4%Q0 %0 = %r1
   getf.sig %0 = %1
   setf.sig %0 = %r1
   mov %0 = %1
@@ -359,6 +395,18 @@ (define_insn "movsi_internal"
    (set_attr "speculable1"   "yes")
    (set_attr "speculable2"   "no,  no,  no,  no,   yes,no,no,  no,  no,   no,    no")])
 
+(define_insn "movsi_internal_2"
+  [(set (match_operand:SI 0 "destination_operand" "=r, m")
+	(match_operand:SI 1 "move_operand"        " m,rO"))]
+  "ia64_move_ok (operands[0], operands[1])"
+  "@
+  ld4%O1 %0 = %1%P1
+  st4%Q0 %0 = %r1%P0"
+  [(set_attr "itanium_class" "ld,st")
+   (set_attr "speculable1"   "yes")
+   (set_attr "speculable2"   "yes,no")
+   (set_attr "predicable"    "no")])
+
 (define_expand "movdi"
   [(set (match_operand:DI 0 "general_operand" "")
 	(match_operand:DI 1 "general_operand" ""))]
@@ -371,9 +419,9 @@ (define_expand "movdi"
 })
 
 (define_insn "movdi_internal"
-  [(set (match_operand:DI 0 "destination_operand"
+  [(set (match_operand:DI 0 "not_postinc_destination_operand"
 		    "=r,r,r,r,r, m, r,*f,*f,*f, Q, r,*b, r,*e, r,*d, r,*c")
-	(match_operand:DI 1 "move_operand"
+	(match_operand:DI 1 "not_postinc_move_operand"
 		    "rO,JT,j,i,m,rO,*f,rO,*f, Q,*f,*b,rO,*e,rK,*d,rK,*c,rO"))]
   "ia64_move_ok (operands[0], operands[1])"
 {
@@ -382,13 +430,13 @@ (define_insn "movdi_internal"
     "%,addl %0 = %1, r0",
     "%,addp4 %0 = %1 - 0x100000000, r0",
     "%,movl %0 = %1",
-    "%,ld8%O1 %0 = %1%P1",
-    "%,st8%Q0 %0 = %r1%P0",
+    "%,ld8%O1 %0 = %1",
+    "%,st8%Q0 %0 = %r1",
     "%,getf.sig %0 = %1",
     "%,setf.sig %0 = %r1",
     "%,mov %0 = %1",
-    "%,ldf8 %0 = %1%P1",
-    "%,stf8 %0 = %1%P0",
+    "%,ldf8 %0 = %1",
+    "%,stf8 %0 = %1",
     "%,mov %0 = %1",
     "%,mov %0 = %r1",
     "%,mov %0 = %1",
@@ -408,6 +456,26 @@ (define_insn "movdi_internal"
    (set_attr "speculable1"   "yes")
    (set_attr "speculable2"   "no,  no,  no,  no,   yes,no,no,  no,  no,   yes,no, no,  no,  no,    no,    no,    no,    no,  no")])
 
+(define_insn "movdi_internal_2"
+  [(set (match_operand:DI 0 "destination_operand"
+		    "=r, m, *f, Q")
+	(match_operand:DI 1 "move_operand"
+		    "m,rO, Q,*f"))]
+  "ia64_move_ok (operands[0], operands[1])"
+{
+  static const char * const alt[] = {
+    "ld8%O1 %0 = %1%P1",
+    "st8%Q0 %0 = %r1%P0",
+    "ldf8 %0 = %1%P1",
+    "stf8 %0 = %1%P0",
+  };
+  return alt[which_alternative];
+}
+  [(set_attr "itanium_class" "ld, st,fld,stf")
+   (set_attr "speculable1"   "yes")
+   (set_attr "speculable2"   "yes,no,yes,no")
+   (set_attr "predicable"    "no")])
+
 (define_mode_iterator MODE [BI QI HI SI DI SF DF XF TI])
 (define_mode_iterator MODE_FOR_CMP [BI SI DI SF DF XF (TF "TARGET_HPUX")])
 (define_mode_iterator MODE_FOR_EXTEND [QI HI SI])
@@ -951,13 +1019,13 @@ (define_expand "movti"
 })
 
 (define_insn_and_split "movti_internal"
-  [(set (match_operand:TI 0 "destination_operand" "=r,   *fm,*x,*f,  Q")
-	(match_operand:TI 1 "general_operand"     "r*fim,r,  Q, *fOQ,*f"))]
+  [(set (match_operand:TI 0 "not_postinc_destination_operand" "=r,   *fm,*x,*f,  Q")
+	(match_operand:TI 1 "not_postinc_general_operand"     "r*fim,r,  Q, *fOQ,*f"))]
   "ia64_move_ok (operands[0], operands[1])"
   "@
    #
    #
-   ldfp8 %X0 = %1%P1
+   ldfp8 %X0 = %1
    #
    #"
   "reload_completed && !ia64_load_pair_ok(operands[0], operands[1])"
@@ -970,6 +1038,23 @@ (define_insn_and_split "movti_internal"
    (set_attr "speculable1"   "yes")
    (set_attr "speculable2"   "no,     no,     yes, no,     no")])
 
+(define_insn_and_split "movti_internal_2"
+  [(set (match_operand:TI 0 "destination_operand" "=*x")
+	(match_operand:TI 1 "general_operand"     "Q"))]
+  "ia64_move_ok (operands[0], operands[1])"
+  "@
+   ldfp8 %X0 = %1%P1"
+  "reload_completed && !ia64_load_pair_ok(operands[0], operands[1])"
+  [(const_int 0)]
+{
+  ia64_split_tmode_move (operands);
+  DONE;
+}
+  [(set_attr "itanium_class" "fldp")
+   (set_attr "speculable1"   "yes")
+   (set_attr "speculable2"   "yes")
+   (set_attr "predicable"    "no")])
+
 ;; Floating Point Moves
 ;;
 ;; Note - Patterns for SF mode moves are compulsory, but
@@ -987,23 +1072,36 @@ (define_expand "movsf"
 })
 
 (define_insn "movsf_internal"
-  [(set (match_operand:SF 0 "destination_operand" "=f,f, Q,*r, f,*r,*r, m,*r")
-	(match_operand:SF 1 "general_operand"     "fG,Q,fG,fG,*r,*r, m,*r, F"))]
+  [(set (match_operand:SF 0 "not_postinc_destination_operand" "=f,f, Q,*r, f,*r,*r, m,*r")
+	(match_operand:SF 1 "not_postinc_general_operand"     "fG,Q,fG,fG,*r,*r, m,*r, F"))]
   "ia64_move_ok (operands[0], operands[1])"
   "@
    mov %0 = %F1
-   ldfs %0 = %1%P1
-   stfs %0 = %F1%P0
+   ldfs %0 = %1
+   stfs %0 = %F1
    getf.s %0 = %F1
    setf.s %0 = %1
    mov %0 = %1
-   ld4%O1 %0 = %1%P1
-   st4%Q0 %0 = %1%P0
+   ld4%O1 %0 = %1
+   st4%Q0 %0 = %1
    movl %0 = %G1"
   [(set_attr "itanium_class" "fmisc,fld,stf,frfr,tofr,ialu,ld,st,long_i")
    (set_attr "speculable1"   "yes")
    (set_attr "speculable2"   "no,   yes,no, no,  no,  no, yes,no,no")])
 
+(define_insn "movsf_internal_2"
+  [(set (match_operand:SF 0 "destination_operand" "=f, Q,*r, m")
+	(match_operand:SF 1 "general_operand"     "Q, fG, m,*r"))]
+  "ia64_move_ok (operands[0], operands[1])"
+  "@
+   ldfs %0 = %1%P1
+   stfs %0 = %F1%P0
+   ld4%O1 %0 = %1%P1
+   st4%Q0 %0 = %1%P0"
+  [(set_attr "itanium_class" "fld,stf,ld, st")
+   (set_attr "speculable1"   "yes")
+   (set_attr "speculable2"   "yes,no, yes,no")])
+
 (define_expand "movdf"
   [(set (match_operand:DF 0 "general_operand" "")
 	(match_operand:DF 1 "general_operand" ""))]
@@ -1016,23 +1114,37 @@ (define_expand "movdf"
 })
 
 (define_insn "movdf_internal"
-  [(set (match_operand:DF 0 "destination_operand" "=f,f, Q,*r, f,*r,*r, m,*r")
-	(match_operand:DF 1 "general_operand"     "fG,Q,fG,fG,*r,*r, m,*r, F"))]
+  [(set (match_operand:DF 0 "not_postinc_destination_operand" "=f,f, Q,*r, f,*r,*r, m,*r")
+	(match_operand:DF 1 "not_postinc_general_operand"     "fG,Q,fG,fG,*r,*r, m,*r, F"))]
   "ia64_move_ok (operands[0], operands[1])"
   "@
    mov %0 = %F1
-   ldfd %0 = %1%P1
-   stfd %0 = %F1%P0
+   ldfd %0 = %1
+   stfd %0 = %F1
    getf.d %0 = %F1
    setf.d %0 = %1
    mov %0 = %1
-   ld8%O1 %0 = %1%P1
-   st8%Q0 %0 = %1%P0
+   ld8%O1 %0 = %1
+   st8%Q0 %0 = %1
    movl %0 = %G1"
   [(set_attr "itanium_class" "fmisc,fld,stf,frfr,tofr,ialu,ld,st,long_i")
    (set_attr "speculable1"   "yes")
    (set_attr "speculable2"   "no,   yes,no, no,  no,  no, yes,no,no")])
 
+(define_insn "movdf_internal_2"
+  [(set (match_operand:DF 0 "destination_operand" "=f,Q,*r, m")
+	(match_operand:DF 1 "general_operand"     "Q, fG,m,*r"))]
+  "ia64_move_ok (operands[0], operands[1])"
+  "@
+   ldfd %0 = %1%P1
+   stfd %0 = %F1%P0
+   ld8%O1 %0 = %1%P1
+   st8%Q0 %0 = %1%P0"
+  [(set_attr "itanium_class" "fld,stf,ld,st")
+   (set_attr "speculable1"   "yes")
+   (set_attr "speculable2"   "yes,no, yes,no")
+   (set_attr "predicable"    "no")])
+
 ;; With no offsettable memory references, we've got to have a scratch
 ;; around to play with the second word if the variable winds up in GRs.
 (define_expand "movxf"
@@ -1047,17 +1159,29 @@ (define_expand "movxf"
 ;; ??? There's no easy way to mind volatile acquire/release semantics.
 
 (define_insn "movxf_internal"
-  [(set (match_operand:XF 0 "destination_operand" "=f,f, m")
-	(match_operand:XF 1 "general_operand"     "fG,m,fG"))]
+  [(set (match_operand:XF 0 "not_postinc_destination_operand" "=f,f, m")
+	(match_operand:XF 1 "not_postinc_general_operand"     "fG,m,fG"))]
   "ia64_move_ok (operands[0], operands[1])"
   "@
    mov %0 = %F1
-   ldfe %0 = %1%P1
-   stfe %0 = %F1%P0"
+   ldfe %0 = %1
+   stfe %0 = %F1"
   [(set_attr "itanium_class" "fmisc,fld,stf")
    (set_attr "speculable1"   "yes")
    (set_attr "speculable2"   "no,   yes,no")])
 
+(define_insn "movxf_internal_2"
+  [(set (match_operand:XF 0 "destination_operand" "=f, m")
+	(match_operand:XF 1 "general_operand"     "m,fG"))]
+  "ia64_move_ok (operands[0], operands[1])"
+  "@
+   ldfe %0 = %1%P1
+   stfe %0 = %F1%P0"
+  [(set_attr "itanium_class" "fld,stf")
+   (set_attr "speculable1"   "yes")
+   (set_attr "speculable2"   "yes,no")
+   (set_attr "predicable"    "no")])
+
 ;; Same as for movxf, but for RFmode.
 (define_expand "movrf"
   [(set (match_operand:RF 0 "general_operand" "")
@@ -1069,14 +1193,24 @@ (define_expand "movrf"
 })
 
 (define_insn "*movrf_internal"
-  [(set (match_operand:RF 0 "destination_operand" "=f,f, m")
-	(match_operand:RF 1 "general_operand"     "fG,m,fG"))]
+  [(set (match_operand:RF 0 "not_postinc_destination_operand" "=f,f, m")
+	(match_operand:RF 1 "not_postinc_general_operand"     "fG,m,fG"))]
   "ia64_move_ok (operands[0], operands[1])"
   "@
    mov %0 = %F1
+   ldf.fill %0 = %1
+   stf.spill %0 = %F1"
+  [(set_attr "itanium_class" "fmisc,fld,stf")])
+
+(define_insn "*movrf_internal_2"
+  [(set (match_operand:RF 0 "destination_operand" "=f, m")
+	(match_operand:RF 1 "general_operand"     "m,fG"))]
+  "ia64_move_ok (operands[0], operands[1])"
+  "@
    ldf.fill %0 = %1%P1
    stf.spill %0 = %F1%P0"
-  [(set_attr "itanium_class" "fmisc,fld,stf")])
+  [(set_attr "itanium_class" "fld,stf")
+   (set_attr "predicable"    "no")])
 
 ;; Better code generation via insns that deal with TFmode register pairs
 ;; directly.  Same concerns apply as for TImode.
@@ -1141,39 +1275,73 @@ (define_insn "extendsidi2"
 
 (define_insn "zero_extendqidi2"
   [(set (match_operand:DI 0 "gr_register_operand" "=r,r")
-	(zero_extend:DI (match_operand:QI 1 "gr_nonimmediate_operand" "r,m")))]
+	(zero_extend:DI (match_operand:QI 1 "not_postinc_gr_nonimmediate_operand" "r,m")))]
   ""
   "@
    zxt1 %0 = %1
-   ld1%O1 %0 = %1%P1"
+   ld1%O1 %0 = %1"
   [(set_attr "itanium_class" "xtd,ld")
    (set_attr "speculable1"   "yes")
    (set_attr "speculable2"   "no, yes")])
 
+(define_insn "zero_extendqidi2_2"
+  [(set (match_operand:DI 0 "gr_register_operand" "=r")
+	(zero_extend:DI (match_operand:QI 1 "gr_nonimmediate_operand" "m")))]
+  ""
+  "@
+   ld1%O1 %0 = %1%P1"
+  [(set_attr "itanium_class" "ld")
+   (set_attr "speculable1"   "yes")
+   (set_attr "speculable2"   "yes")
+   (set_attr "predicable"    "no")])
+
 (define_insn "zero_extendhidi2"
   [(set (match_operand:DI 0 "gr_register_operand" "=r,r")
-	(zero_extend:DI (match_operand:HI 1 "gr_nonimmediate_operand" "r,m")))]
+	(zero_extend:DI (match_operand:HI 1 "not_postinc_gr_nonimmediate_operand" "r,m")))]
   ""
   "@
    zxt2 %0 = %1
-   ld2%O1 %0 = %1%P1"
+   ld2%O1 %0 = %1"
   [(set_attr "itanium_class" "xtd,ld")
    (set_attr "speculable1"   "yes")
    (set_attr "speculable2"   "no, yes")])
 
+(define_insn "zero_extendhidi2_2"
+  [(set (match_operand:DI 0 "gr_register_operand" "=r")
+	(zero_extend:DI (match_operand:HI 1 "gr_nonimmediate_operand" "m")))]
+  ""
+  "@
+   ld2%O1 %0 = %1%P1"
+  [(set_attr "itanium_class" "ld")
+   (set_attr "speculable1"   "yes")
+   (set_attr "speculable2"   "yes")
+   (set_attr "predicable"    "no")])
+
 (define_insn "zero_extendsidi2"
   [(set (match_operand:DI 0 "grfr_register_operand" "=r,r,?f")
 	(zero_extend:DI
-	  (match_operand:SI 1 "grfr_nonimmediate_operand" "r,m,f")))]
+	  (match_operand:SI 1 "not_postinc_grfr_nonimmediate_operand" "r,m,f")))]
   ""
   "@
    addp4 %0 = %1, r0
-   ld4%O1 %0 = %1%P1
+   ld4%O1 %0 = %1
    fmix.r %0 = f0, %1"
   [(set_attr "itanium_class" "ialu,ld,fmisc")
    (set_attr "speculable1"   "yes")
    (set_attr "speculable2"   "no, yes,no")])
 
+(define_insn "zero_extendsidi2_2"
+  [(set (match_operand:DI 0 "grfr_register_operand" "=r")
+	(zero_extend:DI
+	  (match_operand:SI 1 "grfr_nonimmediate_operand" "m")))]
+  ""
+  "@
+   ld4%O1 %0 = %1%P1"
+  [(set_attr "itanium_class" "ld")
+   (set_attr "speculable1"   "yes")
+   (set_attr "speculable2"   "yes")
+   (set_attr "predicable"    "no")])
+
 ;; Convert between floating point types of different sizes.
 
 ;; At first glance, it would appear that emitting fnorm for an extending
@@ -4083,16 +4251,16 @@ (define_insn_and_split "*seq_internal"
 ;;
 
 (define_insn "*cmovdi_internal"
-  [(set (match_operand:DI 0 "destination_operand"
+  [(set (match_operand:DI 0 "not_postinc_destination_operand"
 	   "= r,  r,  r,   r,  r,  r,   r, r, r,   r, m, Q, *f,*b,*d*e")
 	(if_then_else:DI
 	  (match_operator 4 "predicate_operator"
 	    [(match_operand:BI 1 "register_operand"
 		"c,c,c,c,c,c,c,c,c,c,c,c,c,c,c")
 	     (const_int 0)])
-	  (match_operand:DI 2 "move_operand"
+	  (match_operand:DI 2 "not_postinc_move_operand"
 	   "rim, *f, *b,*d*e,rim,rim, rim,*f,*b,*d*e,rO,*f,rOQ,rO,  rK")
-	  (match_operand:DI 3 "move_operand"
+	  (match_operand:DI 3 "not_postinc_move_operand"
 	   "rim,rim,rim, rim, *f, *b,*d*e,*f,*b,*d*e,rO,*f,rOQ,rO,  rK")))]
   "ia64_move_ok (operands[0], operands[2])
    && ia64_move_ok (operands[0], operands[3])"
@@ -4100,13 +4268,13 @@ (define_insn "*cmovdi_internal"
   [(set_attr "predicable" "no")])
 
 (define_split
-  [(set (match_operand 0 "destination_operand" "")
+  [(set (match_operand 0 "not_postinc_destination_operand" "")
 	(if_then_else
 	  (match_operator 4 "predicate_operator"
 	    [(match_operand:BI 1 "register_operand" "")
 	     (const_int 0)])
-	  (match_operand 2 "move_operand" "")
-	  (match_operand 3 "move_operand" "")))]
+	  (match_operand 2 "not_postinc_move_operand" "")
+	  (match_operand 3 "not_postinc_move_operand" "")))]
   "reload_completed"
   [(const_int 0)]
 {
@@ -4188,14 +4356,14 @@ (define_split
 ;;
 
 (define_insn "*cmovsi_internal"
-  [(set (match_operand:SI 0 "destination_operand" "=r,m,*f,r,m,*f,r,m,*f")
+  [(set (match_operand:SI 0 "not_postinc_destination_operand" "=r,m,*f,r,m,*f,r,m,*f")
 	(if_then_else:SI
 	  (match_operator 4 "predicate_operator"
 	    [(match_operand:BI 1 "register_operand" "c,c,c,c,c,c,c,c,c")
 	     (const_int 0)])
-	  (match_operand:SI 2 "move_operand"
+	  (match_operand:SI 2 "not_postinc_move_operand"
 		    "0,0,0,rim*f,rO,rO,rim*f,rO,rO")
-	  (match_operand:SI 3 "move_operand"
+	  (match_operand:SI 3 "not_postinc_move_operand"
 		    "rim*f,rO,rO,0,0,0,rim*f,rO,rO")))]
   "ia64_move_ok (operands[0], operands[2])
    && ia64_move_ok (operands[0], operands[3])"
@@ -4724,7 +4892,8 @@ (define_insn "gr_spill_internal"
      being automatically added before the .mem.offset directive.  */
   return ".mem.offset %2, 0\;%,st8.spill %0 = %1%P0";
 }
-  [(set_attr "itanium_class" "st")])
+  [(set_attr "itanium_class" "st")
+   (set_attr "predicable"    "no")])
 
 ;; Reads ar.unat
 (define_expand "gr_restore"
@@ -4744,7 +4913,8 @@ (define_insn "gr_restore_internal"
    (use (match_operand:DI 3 "register_operand" ""))]
   ""
   { return ".mem.offset %2, 0\;%,ld8.fill %0 = %1%P1"; }
-  [(set_attr "itanium_class" "ld")])
+  [(set_attr "itanium_class" "ld")
+   (set_attr "predicable"    "no")])
 
 (define_insn "fr_spill"
   [(set (match_operand:XF 0 "destination_operand" "=m")
@@ -4752,7 +4922,8 @@ (define_insn "fr_spill"
 		   UNSPEC_FR_SPILL))]
   ""
   "stf.spill %0 = %1%P0"
-  [(set_attr "itanium_class" "stf")])
+  [(set_attr "itanium_class" "stf")
+   (set_attr "predicable"    "no")])
 
 (define_insn "fr_restore"
   [(set (match_operand:XF 0 "register_operand" "=f")
@@ -4760,7 +4931,8 @@ (define_insn "fr_restore"
 		   UNSPEC_FR_RESTORE))]
   ""
   "ldf.fill %0 = %1%P1"
-  [(set_attr "itanium_class" "fld")])
+  [(set_attr "itanium_class" "fld")
+   (set_attr "predicable"    "no")])
 
 ;; ??? The explicit stop is not ideal.  It would be better if
 ;; rtx_needs_barrier took care of this, but this is something that can be


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]