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] S/390: better load/store multiple handling


Hello,

this patch improves handling of load/store multiple operations in 
the S/390 back end. The patch introduces splitters to emit the
rtl patterns which match the respective parallels of the
load and store multiple insn definitions.
In order to allow for better scheduling I've introduced the regcount
insn attribute which is set to the number registers moved by a load/store
multiple.

This patch has the following patch as prerequisite:
http://gcc.gnu.org/ml/gcc-patches/2005-09/msg00320.html

Bootstrapped on s390 and s390x. No testsuite regressions.

Ok for mainline?

Bye,

-Andreas-


2005-09-19  Andreas Krebbel  <krebbel1@de.ibm.com>

	* config/s390/2084.md ("x_lm_stm1", "x_lm_stm2", "x_lm_stm3", 
	"x_lm_stm4", "x_lm_stm5", "x_lm_stm6", "x_lm_stm7", "x_lm_stm8", 
	"x_lm_stm9", "x_lm_stm10", "x_lm_stm11", "x_lm_stm12", "x_lm_stm13", 
	"x_lm_stm14", "x_lm_stm15"): New insn reservations.
	("x_stm", "x_lm"): Insn reservations removed.
	(bypasses 3, 4, 5): Insn reservations x_lm_stm* added.
	* config/s390/predicates.md (load_multiple_operation, 
	store_multiple_operation): Calculate offsets using simplify rtx.
	* config/s390/s390.md ("regcount"): New insn attribute.
	(after: "movti", "movdi_31", "movdf_31"): New splitters.
	("*load_multiple_di", "*load_multiple_di", "*store_multiple_di"):
	Register operand constraints removed.


Index: gcc-4.1/gcc/config/s390/2084.md
===================================================================
--- gcc-4.1.orig/gcc/config/s390/2084.md	2005-09-15 10:08:02.000000000 +0200
+++ gcc-4.1/gcc/config/s390/2084.md	2005-09-15 10:08:19.000000000 +0200
@@ -132,6 +132,99 @@
 ;; Multicycle insns
 ;;
 
+;; store/load multiple instructions
+
+(define_insn_reservation "x_lm_stm1" 1 
+  (and (and (eq_attr "cpu" "z990,z9_109")
+	    (eq_attr "type" "lm,stm"))
+       (eq_attr "regcount" "1"))
+  "x-e1-np*2,x-wr-np")
+
+(define_insn_reservation "x_lm_stm2" 1 
+  (and (and (eq_attr "cpu" "z990,z9_109")
+	    (eq_attr "type" "lm,stm"))
+       (eq_attr "regcount" "2"))
+  "x-e1-np*3,x-wr-np")
+
+(define_insn_reservation "x_lm_stm3" 1 
+  (and (and (eq_attr "cpu" "z990,z9_109")
+	    (eq_attr "type" "lm,stm"))
+       (eq_attr "regcount" "3"))
+  "x-e1-np*4,x-wr-np")
+
+(define_insn_reservation "x_lm_stm4" 1 
+  (and (and (eq_attr "cpu" "z990,z9_109")
+	    (eq_attr "type" "lm,stm"))
+       (eq_attr "regcount" "4"))
+  "x-e1-np*5,x-wr-np")
+
+(define_insn_reservation "x_lm_stm5" 1
+  (and (and (eq_attr "cpu" "z990,z9_109")
+	    (eq_attr "type" "lm,stm"))
+       (eq_attr "regcount" "5"))
+  "x-e1-np*6,x-wr-np")
+
+(define_insn_reservation "x_lm_stm6" 1 
+  (and (and (eq_attr "cpu" "z990,z9_109")
+	    (eq_attr "type" "lm,stm"))
+       (eq_attr "regcount" "6"))
+  "x-e1-np*7,x-wr-np")
+
+(define_insn_reservation "x_lm_stm7" 1 
+  (and (and (eq_attr "cpu" "z990,z9_109")
+	    (eq_attr "type" "lm,stm"))
+       (eq_attr "regcount" "7"))
+  "x-e1-np*8,x-wr-np")
+
+(define_insn_reservation "x_lm_stm8" 1 
+  (and (and (eq_attr "cpu" "z990,z9_109")
+	    (eq_attr "type" "lm,stm"))
+       (eq_attr "regcount" "8"))
+  "x-e1-np*9,x-wr-np")
+
+(define_insn_reservation "x_lm_stm9" 1 
+  (and (and (eq_attr "cpu" "z990,z9_109")
+	    (eq_attr "type" "lm,stm"))
+       (eq_attr "regcount" "9"))
+  "x-e1-np*10,x-wr-np")
+
+(define_insn_reservation "x_lm_stm10" 1 
+  (and (and (eq_attr "cpu" "z990,z9_109")
+	    (eq_attr "type" "lm,stm"))
+       (eq_attr "regcount" "10"))
+  "x-e1-np*11,x-wr-np")
+
+(define_insn_reservation "x_lm_stm11" 1 
+  (and (and (eq_attr "cpu" "z990,z9_109")
+	    (eq_attr "type" "lm,stm"))
+       (eq_attr "regcount" "11"))
+  "x-e1-np*12,x-wr-np")
+
+(define_insn_reservation "x_lm_stm12" 1 
+  (and (and (eq_attr "cpu" "z990,z9_109")
+	    (eq_attr "type" "lm,stm"))
+       (eq_attr "regcount" "12"))
+  "x-e1-np*13,x-wr-np")
+
+(define_insn_reservation "x_lm_stm13" 1 
+  (and (and (eq_attr "cpu" "z990,z9_109")
+	    (eq_attr "type" "lm,stm"))
+       (eq_attr "regcount" "13"))
+  "x-e1-np*14,x-wr-np")
+
+(define_insn_reservation "x_lm_stm14" 1 
+  (and (and (eq_attr "cpu" "z990,z9_109")
+	    (eq_attr "type" "lm,stm"))
+       (eq_attr "regcount" "14"))
+  "x-e1-np*15,x-wr-np")
+
+(define_insn_reservation "x_lm_stm15" 1 
+  (and (and (eq_attr "cpu" "z990,z9_109")
+	    (eq_attr "type" "lm,stm"))
+       (eq_attr "regcount" "15"))
+  "x-e1-np*16,x-wr-np")
+
+
 (define_insn_reservation "x_cs" 1 
   (and (eq_attr "cpu" "z990,z9_109")
        (eq_attr "type" "cs"))
@@ -142,16 +235,6 @@
        (eq_attr "type" "vs"))
   "x-e1-np*10,x-wr-np") 
 
-(define_insn_reservation "x_stm" 1 
-  (and (eq_attr "cpu" "z990,z9_109")
-       (eq_attr "type" "stm"))
-  "(x-e1-np+x_store_tok)*10,x-wr-np") 
-
-(define_insn_reservation "x_lm" 1 
-  (and (eq_attr "cpu" "z990,z9_109")
-       (eq_attr "type" "lm"))
-  "x-e1-np*10,x-wr-np") 
-
 (define_insn_reservation "x_other" 1 
   (and (eq_attr "cpu" "z990,z9_109")
        (eq_attr "type" "other"))
@@ -230,7 +313,10 @@
 ;; 
 
 (define_bypass 5 "x_int,x_agen,x_lr" 
-                 "x_agen,x_la,x_branch,x_call,x_load,x_store,x_cs,x_stm,x_lm,x_other"
+                 "x_agen,x_la,x_branch,x_call,x_load,x_store,x_cs,x_other,\
+                  x_lm_stm1,x_lm_stm2,x_lm_stm3,x_lm_stm4,x_lm_stm5,x_lm_stm6, \
+                  x_lm_stm7,x_lm_stm8,x_lm_stm9,x_lm_stm10,x_lm_stm11, \
+                  x_lm_stm12,x_lm_stm13,x_lm_stm14,x_lm_stm15"
 	         "s390_agen_dep_p")
 
 (define_bypass 9 "x_int,x_agen,x_lr" 
@@ -243,7 +329,10 @@
 ;;
 
 (define_bypass 4 "x_load"    
-                 "x_agen,x_la,x_branch,x_call,x_load,x_store,x_cs,x_stm,x_lm,x_other"
+                 "x_agen,x_la,x_branch,x_call,x_load,x_store,x_cs,x_other,\
+                  x_lm_stm1,x_lm_stm2,x_lm_stm3,x_lm_stm4,x_lm_stm5,x_lm_stm6, \
+                  x_lm_stm7,x_lm_stm8,x_lm_stm9,x_lm_stm10,x_lm_stm11, \
+                  x_lm_stm12,x_lm_stm13,x_lm_stm14,x_lm_stm15"
 	         "s390_agen_dep_p")
 
 (define_bypass 5 "x_load"
@@ -257,7 +346,10 @@
 ;;
 
 (define_bypass 3 "x_larl,x_la" 
-                 "x_agen,x_la,x_branch,x_call,x_load,x_store,x_cs,x_stm,x_lm,x_other"
+                 "x_agen,x_la,x_branch,x_call,x_load,x_store,x_cs,x_other,\
+                  x_lm_stm1,x_lm_stm2,x_lm_stm3,x_lm_stm4,x_lm_stm5,x_lm_stm6, \
+                  x_lm_stm7,x_lm_stm8,x_lm_stm9,x_lm_stm10,x_lm_stm11, \
+                  x_lm_stm12,x_lm_stm13,x_lm_stm14,x_lm_stm15"
 	         "s390_agen_dep_p")
 
 (define_bypass 5 "x_larl, x_la"
Index: gcc-4.1/gcc/config/s390/predicates.md
===================================================================
--- gcc-4.1.orig/gcc/config/s390/predicates.md	2005-09-15 10:08:02.000000000 +0200
+++ gcc-4.1/gcc/config/s390/predicates.md	2005-09-15 10:08:19.000000000 +0200
@@ -333,8 +333,8 @@
   enum machine_mode elt_mode;
   int count = XVECLEN (op, 0);
   unsigned int dest_regno;
-  rtx src_addr;
-  int i, off;
+  rtx first_src_addr;
+  int i;
 
   /* Perform a quick check so we don't blow up below.  */
   if (count <= 1
@@ -344,38 +344,30 @@
     return false;
 
   dest_regno = REGNO (SET_DEST (XVECEXP (op, 0, 0)));
-  src_addr = XEXP (SET_SRC (XVECEXP (op, 0, 0)), 0);
+  first_src_addr = XEXP (SET_SRC (XVECEXP (op, 0, 0)), 0);
   elt_mode = GET_MODE (SET_DEST (XVECEXP (op, 0, 0)));
 
-  /* Check, is base, or base + displacement.  */
-
-  if (GET_CODE (src_addr) == REG)
-    off = 0;
-  else if (GET_CODE (src_addr) == PLUS
-	   && GET_CODE (XEXP (src_addr, 0)) == REG
-	   && GET_CODE (XEXP (src_addr, 1)) == CONST_INT)
-    {
-      off = INTVAL (XEXP (src_addr, 1));
-      src_addr = XEXP (src_addr, 0);
-    }
-  else
-    return false;
-
   for (i = 1; i < count; i++)
     {
       rtx elt = XVECEXP (op, 0, i);
+      rtx src_addr;
+      rtx addr_delta;
 
       if (GET_CODE (elt) != SET
-	  || GET_CODE (SET_DEST (elt)) != REG
-	  || GET_MODE (SET_DEST (elt)) != elt_mode
-	  || REGNO (SET_DEST (elt)) != dest_regno + i
-	  || GET_CODE (SET_SRC (elt)) != MEM
-	  || GET_MODE (SET_SRC (elt)) != elt_mode
-	  || GET_CODE (XEXP (SET_SRC (elt), 0)) != PLUS
-	  || ! rtx_equal_p (XEXP (XEXP (SET_SRC (elt), 0), 0), src_addr)
-	  || GET_CODE (XEXP (XEXP (SET_SRC (elt), 0), 1)) != CONST_INT
-	  || INTVAL (XEXP (XEXP (SET_SRC (elt), 0), 1))
-	     != off + i * GET_MODE_SIZE (elt_mode))
+          || GET_CODE (SET_DEST (elt)) != REG
+          || GET_CODE (SET_SRC (elt)) != MEM)
+        return false;
+
+      if (dest_regno + i != REGNO (SET_DEST (elt)))
+        return false;
+
+      src_addr = XEXP (SET_SRC (elt), 0); 
+      addr_delta = simplify_binary_operation (MINUS, Pmode, 
+                                              src_addr, first_src_addr);
+
+      if (!addr_delta
+          || GET_CODE (addr_delta) != CONST_INT
+          || INTVAL (addr_delta) != i * GET_MODE_SIZE (elt_mode))
 	return false;
     }
 
@@ -391,8 +383,8 @@
   enum machine_mode elt_mode;
   int count = XVECLEN (op, 0);
   unsigned int src_regno;
-  rtx dest_addr;
-  int i, off;
+  rtx first_dest_addr;
+  int i;
 
   /* Perform a quick check so we don't blow up below.  */
   if (count <= 1
@@ -402,38 +394,30 @@
     return false;
 
   src_regno = REGNO (SET_SRC (XVECEXP (op, 0, 0)));
-  dest_addr = XEXP (SET_DEST (XVECEXP (op, 0, 0)), 0);
+  first_dest_addr = XEXP (SET_DEST (XVECEXP (op, 0, 0)), 0);
   elt_mode = GET_MODE (SET_SRC (XVECEXP (op, 0, 0)));
 
-  /* Check, is base, or base + displacement.  */
-
-  if (GET_CODE (dest_addr) == REG)
-    off = 0;
-  else if (GET_CODE (dest_addr) == PLUS
-	   && GET_CODE (XEXP (dest_addr, 0)) == REG
-	   && GET_CODE (XEXP (dest_addr, 1)) == CONST_INT)
-    {
-      off = INTVAL (XEXP (dest_addr, 1));
-      dest_addr = XEXP (dest_addr, 0);
-    }
-  else
-    return false;
-
   for (i = 1; i < count; i++)
     {
       rtx elt = XVECEXP (op, 0, i);
+      rtx dest_addr;
+      rtx addr_delta;
 
       if (GET_CODE (elt) != SET
-	  || GET_CODE (SET_SRC (elt)) != REG
-	  || GET_MODE (SET_SRC (elt)) != elt_mode
-	  || REGNO (SET_SRC (elt)) != src_regno + i
-	  || GET_CODE (SET_DEST (elt)) != MEM
-	  || GET_MODE (SET_DEST (elt)) != elt_mode
-	  || GET_CODE (XEXP (SET_DEST (elt), 0)) != PLUS
-	  || ! rtx_equal_p (XEXP (XEXP (SET_DEST (elt), 0), 0), dest_addr)
-	  || GET_CODE (XEXP (XEXP (SET_DEST (elt), 0), 1)) != CONST_INT
-	  || INTVAL (XEXP (XEXP (SET_DEST (elt), 0), 1))
-	     != off + i * GET_MODE_SIZE (elt_mode))
+          || GET_CODE (SET_SRC (elt)) != REG
+          || GET_CODE (SET_DEST (elt)) != MEM)
+        return false;
+
+      if (src_regno + i != REGNO (SET_SRC (elt)))
+        return false;
+
+      dest_addr = XEXP (SET_DEST (elt), 0); 
+      addr_delta = simplify_binary_operation (MINUS, Pmode, 
+                                              dest_addr, first_dest_addr);
+
+      if (!addr_delta
+          || GET_CODE (addr_delta) != CONST_INT
+          || INTVAL (addr_delta) != i * GET_MODE_SIZE (elt_mode))
 	return false;
     }
   return true;
Index: gcc-4.1/gcc/config/s390/s390.md
===================================================================
--- gcc-4.1.orig/gcc/config/s390/s390.md	2005-09-15 10:08:02.000000000 +0200
+++ gcc-4.1/gcc/config/s390/s390.md	2005-09-16 10:10:15.000000000 +0200
@@ -190,6 +190,39 @@
   "NN,E,RR,RRE,RX,RS,RSI,RI,SI,S,SS,SSE,RXE,RSE,RIL,RIE,RXY,RSY,SIY"
   (const_string "NN"))
 
+;; Number of registers used in a load/store multiple operation
+(define_attr "regcount" "1,2,3,4,5,6,7,8,9,10,11,12,13,14,15"
+  (cond [(eq (symbol_ref "XVECLEN (operands[0], 0)") (const_int 1))
+	 (const_string "1")
+	 (eq (symbol_ref "XVECLEN (operands[0], 0)") (const_int 2))
+	 (const_string "2")
+	 (eq (symbol_ref "XVECLEN (operands[0], 0)") (const_int 3))
+	 (const_string "3")
+	 (eq (symbol_ref "XVECLEN (operands[0], 0)") (const_int 4)) 
+	 (const_string "4")
+	 (eq (symbol_ref "XVECLEN (operands[0], 0)") (const_int 5)) 
+	 (const_string "5")
+	 (eq (symbol_ref "XVECLEN (operands[0], 0)") (const_int 6)) 
+	 (const_string "6")
+	 (eq (symbol_ref "XVECLEN (operands[0], 0)") (const_int 7)) 
+	 (const_string "7")
+	 (eq (symbol_ref "XVECLEN (operands[0], 0)") (const_int 8)) 
+	 (const_string "8")
+	 (eq (symbol_ref "XVECLEN (operands[0], 0)") (const_int 9)) 
+	 (const_string "9")
+	 (eq (symbol_ref "XVECLEN (operands[0], 0)") (const_int 10)) 
+	 (const_string "10")
+	 (eq (symbol_ref "XVECLEN (operands[0], 0)") (const_int 11)) 
+	 (const_string "11")
+	 (eq (symbol_ref "XVECLEN (operands[0], 0)") (const_int 12)) 
+	 (const_string "12")
+	 (eq (symbol_ref "XVECLEN (operands[0], 0)") (const_int 13)) 
+	 (const_string "13")
+	 (eq (symbol_ref "XVECLEN (operands[0], 0)") (const_int 14)) 
+	 (const_string "14")
+	 (eq (symbol_ref "XVECLEN (operands[0], 0)") (const_int 15)) 
+	 (const_string "15")] (const_string "1")))
+
 ;; Instruction type attribute used for scheduling.
 
 (define_attr "type" "none,integer,load,lr,la,larl,lm,stm,
@@ -846,14 +879,33 @@
   [(set (match_operand:TI 0 "nonimmediate_operand" "=d,QS,d,o,Q")
         (match_operand:TI 1 "general_operand" "QS,d,dPm,d,Q"))]
   "TARGET_64BIT"
-  "@
-   lmg\t%0,%N0,%S1
-   stmg\t%1,%N1,%S0
-   #
-   #
-   #"
-  [(set_attr "op_type" "RSY,RSY,*,*,SS")
-   (set_attr "type" "lm,stm,*,*,*")])
+  "#")
+
+(define_split
+  [(set (match_operand:TI 0 "register_operand" "")
+        (match_operand:TI 1 "s_operand" ""))]
+  "TARGET_64BIT && reload_completed && !FP_REG_P (operands[0])"
+  [(parallel [(set (match_dup 2) (match_dup 4))
+	      (set (match_dup 3) (match_dup 5))])]
+{
+  operands[2] = operand_subword (operands[0], 0, 0, TImode);
+  operands[3] = operand_subword (operands[0], 1, 0, TImode);
+  operands[4] = operand_subword (operands[1], 0, 0, TImode);
+  operands[5] = operand_subword (operands[1], 1, 0, TImode);
+})
+
+(define_split
+  [(set (match_operand:TI 0 "s_operand" "")
+        (match_operand:TI 1 "register_operand" ""))]
+  "TARGET_64BIT && reload_completed && !FP_REG_P (operands[1])"
+  [(parallel [(set (match_dup 2) (match_dup 4))
+	      (set (match_dup 3) (match_dup 5))])]
+{
+  operands[2] = operand_subword (operands[0], 0, 0, TImode);
+  operands[3] = operand_subword (operands[0], 1, 0, TImode);
+  operands[4] = operand_subword (operands[1], 0, 0, TImode);
+  operands[5] = operand_subword (operands[1], 1, 0, TImode);
+})
 
 (define_split
   [(set (match_operand:TI 0 "nonimmediate_operand" "")
@@ -1030,14 +1082,12 @@
    s390_split_access_reg (operands[0], &operands[3], &operands[4]);")
 
 (define_insn "*movdi_31"
-  [(set (match_operand:DI 0 "nonimmediate_operand" "=d,d,Q,S,d,o,!*f,!*f,!*f,!R,!T,Q")
-        (match_operand:DI 1 "general_operand" "Q,S,d,d,dPm,d,*f,R,T,*f,*f,Q"))]
+  [(set (match_operand:DI 0 "nonimmediate_operand" "=d,QS,d,o,!*f,!*f,!*f,!R,!T,Q")
+        (match_operand:DI 1 "general_operand" "QS,d,dPm,d,*f,R,T,*f,*f,Q"))]
   "!TARGET_64BIT"
   "@
-   lm\t%0,%N0,%S1
-   lmy\t%0,%N0,%S1
-   stm\t%1,%N1,%S0
-   stmy\t%1,%N1,%S0
+   #
+   #
    #
    #
    ldr\t%0,%1
@@ -1046,8 +1096,34 @@
    std\t%1,%0
    stdy\t%1,%0
    #"
-  [(set_attr "op_type" "RS,RSY,RS,RSY,*,*,RR,RX,RXY,RX,RXY,SS")
-   (set_attr "type" "lm,lm,stm,stm,*,*,floaddf,floaddf,floaddf,fstoredf,fstoredf,*")])
+  [(set_attr "op_type" "RSY,RSY,*,*,RR,RX,RXY,RX,RXY,SS")
+   (set_attr "type" "*,*,*,*,floaddf,floaddf,floaddf,fstoredf,fstoredf,*")])
+
+(define_split
+  [(set (match_operand:DI 0 "register_operand" "")
+        (match_operand:DI 1 "s_operand" ""))]
+  "!TARGET_64BIT && reload_completed && !FP_REG_P (operands[0])"
+  [(parallel [(set (match_dup 2) (match_dup 4))
+	      (set (match_dup 3) (match_dup 5))])]
+{
+  operands[2] = operand_subword (operands[0], 0, 0, DImode);
+  operands[3] = operand_subword (operands[0], 1, 0, DImode);
+  operands[4] = operand_subword (operands[1], 0, 0, DImode);
+  operands[5] = operand_subword (operands[1], 1, 0, DImode);
+})
+
+(define_split
+  [(set (match_operand:DI 0 "s_operand" "")
+        (match_operand:DI 1 "register_operand" ""))]
+  "!TARGET_64BIT && reload_completed && !FP_REG_P (operands[1])"
+  [(parallel [(set (match_dup 2) (match_dup 4))
+	      (set (match_dup 3) (match_dup 5))])]
+{
+  operands[2] = operand_subword (operands[0], 0, 0, DImode);
+  operands[3] = operand_subword (operands[0], 1, 0, DImode);
+  operands[4] = operand_subword (operands[1], 0, 0, DImode);
+  operands[5] = operand_subword (operands[1], 1, 0, DImode);
+})
 
 (define_split
   [(set (match_operand:DI 0 "nonimmediate_operand" "")
@@ -1493,8 +1569,8 @@
    (set_attr "type" "fsimpdf,floaddf,floaddf,floaddf,fstoredf,fstoredf,lr,load,store,*")])
 
 (define_insn "*movdf_31"
-  [(set (match_operand:DF 0 "nonimmediate_operand" "=f,f,f,f,R,T,d,d,Q,S,d,o,Q")
-        (match_operand:DF 1 "general_operand" "G,f,R,T,f,f,Q,S,d,d,dPm,d,Q"))]
+  [(set (match_operand:DF 0 "nonimmediate_operand" "=f,f,f,f,R,T,d,QS,d,o,Q")
+        (match_operand:DF 1 "general_operand" "G,f,R,T,f,f,QS,d,dPm,d,Q"))]
   "!TARGET_64BIT"
   "@
    lzdr\t%0
@@ -1503,16 +1579,40 @@
    ldy\t%0,%1
    std\t%1,%0
    stdy\t%1,%0
-   lm\t%0,%N0,%S1
-   lmy\t%0,%N0,%S1
-   stm\t%1,%N1,%S0
-   stmy\t%1,%N1,%S0
+   #
+   #
    #
    #
    #"
-  [(set_attr "op_type" "RRE,RR,RX,RXY,RX,RXY,RS,RSY,RS,RSY,*,*,SS")
+  [(set_attr "op_type" "RRE,RR,RX,RXY,RX,RXY,RSY,RSY,*,*,SS")
    (set_attr "type" "fsimpdf,floaddf,floaddf,floaddf,fstoredf,fstoredf,\
-                     lm,lm,stm,stm,*,*,*")])
+                     *,*,*,*,*")])
+
+(define_split
+  [(set (match_operand:DF 0 "register_operand" "")
+        (match_operand:DF 1 "s_operand" ""))]
+  "!TARGET_64BIT && reload_completed && !FP_REG_P (operands[0])"
+  [(parallel [(set (match_dup 2) (match_dup 4))
+	      (set (match_dup 3) (match_dup 5))])]
+{
+  operands[2] = operand_subword (operands[0], 0, 0, DFmode);
+  operands[3] = operand_subword (operands[0], 1, 0, DFmode);
+  operands[4] = operand_subword (operands[1], 0, 0, DFmode);
+  operands[5] = operand_subword (operands[1], 1, 0, DFmode);
+})
+
+(define_split
+  [(set (match_operand:DF 0 "s_operand" "")
+        (match_operand:DF 1 "register_operand" ""))]
+  "!TARGET_64BIT && reload_completed && !FP_REG_P (operands[1])"
+  [(parallel [(set (match_dup 2) (match_dup 4))
+	      (set (match_dup 3) (match_dup 5))])]
+{
+  operands[2] = operand_subword (operands[0], 0, 0, DFmode);
+  operands[3] = operand_subword (operands[0], 1, 0, DFmode);
+  operands[4] = operand_subword (operands[1], 0, 0, DFmode);
+  operands[5] = operand_subword (operands[1], 1, 0, DFmode);
+})
 
 (define_split
   [(set (match_operand:DF 0 "nonimmediate_operand" "")
@@ -1727,7 +1827,7 @@
 
 (define_insn "*load_multiple_di"
   [(match_parallel 0 "load_multiple_operation"
-		   [(set (match_operand:DI 1 "register_operand" "=r")
+		   [(set (match_operand:DI 1 "register_operand" "")
 			 (match_operand:DI 2 "s_operand" "QS"))])]
   "reload_completed && word_mode == DImode"
 {
@@ -1740,7 +1840,7 @@
 
 (define_insn "*load_multiple_si"
   [(match_parallel 0 "load_multiple_operation"
-		   [(set (match_operand:SI 1 "register_operand" "=r,r")
+		   [(set (match_operand:SI 1 "register_operand" "")
 			 (match_operand:SI 2 "s_operand" "Q,S"))])]
   "reload_completed"
 {
@@ -1819,7 +1919,7 @@
 (define_insn "*store_multiple_di"
   [(match_parallel 0 "store_multiple_operation"
 		   [(set (match_operand:DI 1 "s_operand" "=QS")
-			 (match_operand:DI 2 "register_operand" "r"))])]
+			 (match_operand:DI 2 "register_operand" ""))])]
   "reload_completed && word_mode == DImode"
 {
   int words = XVECLEN (operands[0], 0);
@@ -1833,7 +1933,7 @@
 (define_insn "*store_multiple_si"
   [(match_parallel 0 "store_multiple_operation"
 		   [(set (match_operand:SI 1 "s_operand" "=Q,S")
-			 (match_operand:SI 2 "register_operand" "r,r"))])]
+			 (match_operand:SI 2 "register_operand" ""))])]
   "reload_completed"
 {
   int words = XVECLEN (operands[0], 0);


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